Skip to content

Commit bbad1bb

Browse files
UI improvements and Windows color support
1 parent c679735 commit bbad1bb

File tree

6 files changed

+71
-18
lines changed

6 files changed

+71
-18
lines changed

README.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ $ curl --proxy 'socks5://127.0.0.1:1080' 'http://10.0.0.2'
4444
```
4545

4646
You can also generate a connection key with `resocks generate` and pass it to
47-
the `listen` command to avoid generating a new connection key every time.
47+
the `listen` command to avoid generating a new connection key every time. It
48+
can also be specified via an environment variable:
49+
50+
```bash
51+
$ export RESOCKS_KEY="$(resocks generate)"
52+
$ resocks listen
53+
```
4854

4955
## Security
5056

@@ -117,3 +123,10 @@ directly into the binary, use the following command:
117123
go run . generate # generate a connection key
118124
go build -ldflags="-X main.defaultConnectionKey=YOUR_CONNECTION_KEY"
119125
```
126+
127+
Similarly, the default connect back address can also be statically compiled into
128+
the binary:
129+
130+
```bash
131+
go build -ldflags="-X main.defaultConnectBackAddress=192.0.2.1"
132+
```

main.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ const (
2626
ConnectionKeyEnvVariable = "RESOCKS_KEY"
2727
)
2828

29-
var defaultConnectionKey = ""
29+
var (
30+
defaultConnectionKey = ""
31+
defaultConnectBackAddress = ""
32+
)
3033

3134
func main() {
3235
err := run()

relay.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,25 @@ func relayCommand() *cobra.Command {
1919
connectionKey := fromEnvWithFallback(ConnectionKeyEnvVariable, defaultConnectionKey)
2020
insecure := false
2121

22+
cobraArgs := cobra.ExactArgs(1)
23+
if defaultConnectBackAddress != "" {
24+
cobraArgs = cobra.MaximumNArgs(1)
25+
}
26+
2227
relayCmd := &cobra.Command{
2328
Use: fmt.Sprintf("%s <connect back address> --key <connection key>", binaryName()),
2429
Short: fmt.Sprintf("Connect back to an %s listener and relay the SOCKS5 traffic", binaryName()),
2530
SilenceErrors: true,
2631
SilenceUsage: true,
27-
Args: cobra.ExactArgs(1),
32+
Args: cobraArgs,
2833
RunE: func(cmd *cobra.Command, args []string) error {
34+
connectBackAddress := defaultConnectBackAddress
35+
if len(args) > 0 {
36+
connectBackAddress = args[0]
37+
}
38+
2939
return runRemoteProxyRelay(
30-
withDefaultPort(args[0], DefaultListenPort), // connect back address
40+
withDefaultPort(connectBackAddress, DefaultListenPort),
3141
connectionKey,
3242
timeout,
3343
reconnectAfter,

ui.go

+25-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"os"
66
"strings"
7+
"sync"
78
"time"
89

910
"resocks/kbtls"
@@ -40,6 +41,8 @@ type model struct {
4041
socksAddress string
4142

4243
noColor bool
44+
45+
lock sync.Mutex
4346
}
4447

4548
var _ tea.Model = &model{}
@@ -57,7 +60,9 @@ func startUI(
5760
})
5861

5962
if !noColor {
60-
err := enableVirtualTerminalProcessing()
63+
resetTerminal, err := prepareTerminal()
64+
defer resetTerminal()
65+
6166
if err != nil {
6267
fmt.Fprintf(os.Stderr, "Warning: Could not enable virtual terminal processing: %v, "+
6368
"disabling colored output\n", err)
@@ -96,6 +101,9 @@ func (m *model) Init() tea.Cmd {
96101
}
97102

98103
func (m *model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
104+
m.lock.Lock()
105+
defer m.lock.Unlock()
106+
99107
switch msg := message.(type) {
100108
case proxyrelay.Event:
101109
switch msg.Type {
@@ -128,6 +136,11 @@ func (m *model) Update(message tea.Msg) (tea.Model, tea.Cmd) {
128136
case tea.KeyMsg:
129137
if msg.String() == "ctrl+c" {
130138
m.quitting = true
139+
if m.connection != nil {
140+
m.connection.End = time.Now()
141+
m.connection.Error = "shutdown"
142+
m.connection = nil
143+
}
131144

132145
return m, tea.Quit
133146
}
@@ -181,13 +194,20 @@ func (m *model) errorsView() string {
181194
}
182195

183196
func (m *model) listenerConfigView() string {
184-
listeningLineStyle := bold
197+
address := m.listenAddress
198+
if strings.HasPrefix(address, ":") {
199+
address = "*" + address
200+
}
201+
202+
addressStyle := m.style(brightMagenta, bold)
203+
185204
if m.socksActive {
186-
listeningLineStyle = dim
205+
addressStyle = m.style(dim)
206+
address += " (inactive)"
187207
}
188208

189-
view := m.style(listeningLineStyle) + "Listening On : " + m.style() +
190-
m.style(brightMagenta, listeningLineStyle) + m.listenAddress + m.style()
209+
view := m.style(bold) + "Listening On : " + m.style() +
210+
addressStyle + address + m.style()
191211
view += m.style(bold) + "\nConnection Key: " + m.style() + m.style(brightMagenta, bold) + m.connectionKey + m.style()
192212

193213
if m.insecure {

ui_default.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
package main
44

5-
func enableVirtualTerminalProcessing() error {
6-
return nil // we only have to do this on Windows
5+
func prepareTerminal() (reset func(), err error) {
6+
return func() {}, nil // we only have to do this on Windows
77
}

ui_windows.go

+14-7
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,39 @@ import (
99
"golang.org/x/sys/windows"
1010
)
1111

12-
func enableVirtualTerminalProcessing() error {
12+
func prepareTerminal() (reset func(), err error) {
1313
var mode uint32
1414

1515
stdoutHandle := windows.Handle(os.Stdout.Fd())
1616

17-
err := windows.GetConsoleMode(stdoutHandle, &mode)
17+
err = windows.GetConsoleMode(stdoutHandle, &mode)
1818
if err != nil {
19-
return fmt.Errorf("stdout: get console mode: %w", err)
19+
return nil, fmt.Errorf("stdout: get console mode: %w", err)
2020
}
2121

2222
err = windows.SetConsoleMode(stdoutHandle, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
2323
if err != nil {
24-
return fmt.Errorf("stdout: set console mode: %w", err)
24+
return nil, fmt.Errorf("stdout: set console mode: %w", err)
2525
}
2626

2727
stderrHandle := windows.Handle(os.Stderr.Fd())
2828

2929
err = windows.GetConsoleMode(stderrHandle, &mode)
3030
if err != nil {
31-
return fmt.Errorf("stderr: get console mode: %w", err)
31+
return func() {
32+
_ = windows.SetConsoleMode(stdoutHandle, mode)
33+
}, fmt.Errorf("stderr: get console mode: %w", err)
3234
}
3335

3436
err = windows.SetConsoleMode(stderrHandle, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
3537
if err != nil {
36-
return fmt.Errorf("stderr: set console mode: %w", err)
38+
return func() {
39+
_ = windows.SetConsoleMode(stdoutHandle, mode)
40+
}, fmt.Errorf("stderr: set console mode: %w", err)
3741
}
3842

39-
return nil
43+
return func() {
44+
_ = windows.SetConsoleMode(stdoutHandle, mode)
45+
_ = windows.SetConsoleMode(stderrHandle, mode)
46+
}, nil
4047
}

0 commit comments

Comments
 (0)