■ ■ ■ ■ ■ ■
internal/server/commands/listen.go
| skipped 10 lines |
11 | 11 | | "github.com/NHAS/reverse_ssh/internal" |
12 | 12 | | "github.com/NHAS/reverse_ssh/internal/server/clients" |
13 | 13 | | "github.com/NHAS/reverse_ssh/internal/server/multiplexer" |
| 14 | + | "github.com/NHAS/reverse_ssh/internal/server/observers" |
14 | 15 | | "github.com/NHAS/reverse_ssh/internal/terminal" |
15 | 16 | | "github.com/NHAS/reverse_ssh/internal/terminal/autocomplete" |
16 | 17 | | "github.com/NHAS/reverse_ssh/pkg/logger" |
| 18 | + | "github.com/NHAS/reverse_ssh/pkg/observer" |
17 | 19 | | "golang.org/x/crypto/ssh" |
18 | 20 | | ) |
19 | 21 | | |
| 22 | + | type autostartEntry struct { |
| 23 | + | ObserverID string |
| 24 | + | Criteria string |
| 25 | + | } |
| 26 | + | |
| 27 | + | var autoStartServerPort = map[internal.RemoteForwardRequest]autostartEntry{} |
| 28 | + | |
20 | 29 | | type listen struct { |
21 | 30 | | log logger.Logger |
22 | 31 | | } |
23 | 32 | | |
24 | | - | func server(tty io.ReadWriter, line terminal.ParsedLine) error { |
| 33 | + | func (l *listen) server(tty io.ReadWriter, line terminal.ParsedLine) error { |
25 | 34 | | if line.IsSet("l") { |
26 | 35 | | listeners := multiplexer.ServerMultiplexer.GetListeners() |
27 | 36 | | |
| skipped 44 lines |
72 | 81 | | return nil |
73 | 82 | | } |
74 | 83 | | |
75 | | - | func client(tty io.ReadWriter, line terminal.ParsedLine) error { |
| 84 | + | func (l *listen) client(tty io.ReadWriter, line terminal.ParsedLine) error { |
| 85 | + | |
| 86 | + | auto := line.IsSet("auto") |
| 87 | + | if line.IsSet("l") && auto { |
| 88 | + | for k, v := range autoStartServerPort { |
| 89 | + | fmt.Fprintf(tty, "%s %s:%d\n", v.Criteria, k.BindAddr, k.BindPort) |
| 90 | + | } |
| 91 | + | return nil |
| 92 | + | } |
76 | 93 | | |
77 | 94 | | specifier, err := line.GetArgString("c") |
78 | 95 | | if err != nil { |
| skipped 8 lines |
87 | 104 | | return err |
88 | 105 | | } |
89 | 106 | | |
90 | | - | if len(foundClients) == 0 { |
| 107 | + | if len(foundClients) == 0 && !auto { |
91 | 108 | | return fmt.Errorf("No clients matched '%s'", specifier) |
92 | 109 | | } |
93 | 110 | | |
| skipped 57 lines |
151 | 168 | | for c, sc := range foundClients { |
152 | 169 | | result, message, err := sc.SendRequest("tcpip-forward", true, b) |
153 | 170 | | if !result { |
154 | | - | fmt.Fprintln(tty, "failed to start port on: ", c, ": ", string(message)) |
| 171 | + | fmt.Fprintln(tty, "failed to start port on (client may not support it): ", c, ": ", string(message)) |
155 | 172 | | continue |
156 | 173 | | } |
157 | 174 | | |
| skipped 1 lines |
159 | 176 | | fmt.Fprintln(tty, "error starting port on: ", c, ": ", err) |
160 | 177 | | } |
161 | 178 | | } |
| 179 | + | |
| 180 | + | if auto { |
| 181 | + | var entry autostartEntry |
| 182 | + | |
| 183 | + | entry.ObserverID = observers.ConnectionState.Register(func(m observer.Message) { |
| 184 | + | c := m.(observers.ClientState) |
| 185 | + | |
| 186 | + | if !clients.Matches(specifier, c.ID, c.IP) || c.Status == "disconnected" { |
| 187 | + | return |
| 188 | + | } |
| 189 | + | |
| 190 | + | client, err := clients.Get(c.ID) |
| 191 | + | if err != nil { |
| 192 | + | return |
| 193 | + | } |
| 194 | + | |
| 195 | + | result, message, err := client.SendRequest("tcpip-forward", true, b) |
| 196 | + | if !result { |
| 197 | + | l.log.Warning("failed to start server tcpip-forward on client: %s: %s", c.ID, message) |
| 198 | + | return |
| 199 | + | } |
| 200 | + | |
| 201 | + | if err != nil { |
| 202 | + | l.log.Warning("error auto starting port on: %s: %s", c.ID, err) |
| 203 | + | return |
| 204 | + | } |
| 205 | + | |
| 206 | + | }) |
| 207 | + | |
| 208 | + | entry.Criteria = specifier |
| 209 | + | |
| 210 | + | autoStartServerPort[r] = entry |
| 211 | + | |
| 212 | + | } |
162 | 213 | | } |
163 | 214 | | |
164 | 215 | | } |
| skipped 37 lines |
202 | 253 | | fmt.Fprintln(tty, "error stop port on: ", c, ": ", err) |
203 | 254 | | } |
204 | 255 | | } |
| 256 | + | |
| 257 | + | if auto { |
| 258 | + | if _, ok := autoStartServerPort[r]; ok { |
| 259 | + | observers.ConnectionState.Deregister(autoStartServerPort[r].Criteria) |
| 260 | + | } |
| 261 | + | delete(autoStartServerPort, r) |
| 262 | + | } |
205 | 263 | | } |
206 | 264 | | } |
207 | 265 | | |
| skipped 7 lines |
215 | 273 | | } |
216 | 274 | | |
217 | 275 | | if line.IsSet("server") || line.IsSet("s") { |
218 | | - | return server(tty, line) |
219 | | - | } else if line.IsSet("client") || line.IsSet("c") { |
220 | | - | return client(tty, line) |
| 276 | + | return w.server(tty, line) |
| 277 | + | } else if line.IsSet("client") || line.IsSet("c") || line.IsSet("auto") { |
| 278 | + | return w.client(tty, line) |
221 | 279 | | } |
222 | 280 | | |
223 | 281 | | return errors.New("neither server or client were specified, please choose one") |
| skipped 19 lines |
243 | 301 | | return terminal.MakeHelpText( |
244 | 302 | | "listen [OPTION] [PORT]", |
245 | 303 | | "listen starts or stops listening control ports", |
246 | | - | "\t--client (-c)\tSpecify client/s to act on, e.g -c *, --client your.hostname.here", |
247 | | - | "\t--server (-s)\tSpecify to change the server listeners", |
| 304 | + | "it allows you to change the servers listening port, or open the servers control port on an rssh client, so that forwarding is easier", |
| 305 | + | "\t--client (-c)\tOpen server port on client/s takes a pattern, e.g -c *, --client your.hostname.here", |
| 306 | + | "\t--server (-s)\tChange the server listeners", |
248 | 307 | | "\t--on\tTurn on port, e.g --on :8080 127.0.0.1:4444", |
| 308 | + | "\t--auto\tAutomatically turn on server control port on clients that match criteria, (use --off --auto to disable and --l --auto to view)", |
249 | 309 | | "\t--off\tTurn off port, e.g --off :8080 127.0.0.1:4444", |
250 | 310 | | "\t-l\tList all enabled addresses", |
251 | 311 | | ) |
| skipped 8 lines |