cmux-ssh-here 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/bin.js +21 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -39,3 +39,4 @@ Open the link — cmux connects on its own. `Ctrl-C` in the terminal stops the s
39
39
  ## Options
40
40
 
41
41
  - `PORT=2222 npx cmux-ssh-here` — fixed port (random free port by default).
42
+ - `CMUX_SSH_DEBUG=1 npx cmux-ssh-here` — log incoming auth/env/exec/shell requests to stderr (troubleshooting).
package/bin.js CHANGED
@@ -21,7 +21,9 @@ if (process.platform !== "win32") {
21
21
  }
22
22
  const { default: pty } = await import("node-pty");
23
23
 
24
- const token = randomBytes(9).toString("base64url"); // secret carried in user=<token>
24
+ // ponytail: hex (not base64url) cmux rejects a user that starts with "-",
25
+ // and an ssh client treats a leading-dash username as a flag. Hex is URL/ssh-safe.
26
+ const token = randomBytes(12).toString("hex"); // secret carried in user=<token>
25
27
  const { privateKey } = generateKeyPairSync("rsa", {
26
28
  // ponytail: rsa PEM parses cleanly in ssh2 (ed25519 PKCS8 is hit-or-miss)
27
29
  modulusLength: 2048,
@@ -56,10 +58,13 @@ function bridge(stream, args, term) {
56
58
  return child;
57
59
  }
58
60
 
61
+ const debug = process.env.CMUX_SSH_DEBUG ? (...a) => console.error("[debug]", ...a) : () => {};
62
+
59
63
  const server = new Server({ hostKeys: [privateKey] }, (client) => {
60
- client.on("authentication", (ctx) =>
61
- ctx.username === token ? ctx.accept() : ctx.reject()
62
- );
64
+ client.on("authentication", (ctx) => {
65
+ debug("auth", ctx.method, ctx.username);
66
+ return ctx.username === token ? ctx.accept() : ctx.reject();
67
+ });
63
68
  client.on("session", (accept) => {
64
69
  const session = accept();
65
70
  // Defaults; overwritten by pty/env requests before shell/exec.
@@ -67,12 +72,14 @@ const server = new Server({ hostKeys: [privateKey] }, (client) => {
67
72
  let child;
68
73
 
69
74
  session.on("pty", (a, _r, info) => {
75
+ debug("pty", info.term, info.cols, info.rows);
70
76
  term.term = info.term || term.term;
71
77
  term.cols = info.cols || term.cols;
72
78
  term.rows = info.rows || term.rows;
73
79
  a?.();
74
80
  });
75
81
  session.on("env", (a, _r, info) => {
82
+ debug("env", info.key, "=", info.val);
76
83
  term.env[info.key] = info.val;
77
84
  a?.();
78
85
  });
@@ -81,6 +88,7 @@ const server = new Server({ hostKeys: [privateKey] }, (client) => {
81
88
  a?.();
82
89
  });
83
90
  session.on("shell", (acc) => {
91
+ debug("shell");
84
92
  // ponytail: route the interactive shell through tmux so sessions persist
85
93
  // and are shared across LAN connections; show the session list on connect.
86
94
  // Falls back to a plain login shell when tmux is absent.
@@ -92,7 +100,15 @@ const server = new Server({ hostKeys: [privateKey] }, (client) => {
92
100
  child = bridge(acc(), ["-lc", start], term);
93
101
  });
94
102
  session.on("exec", (acc, _r, info) => {
95
- child = bridge(acc(), ["-c", info.command], term);
103
+ debug("exec", info.command);
104
+ // ponytail: login shell (-lc) so PATH includes things like homebrew tmux;
105
+ // cmux runs remote commands (tmux probes, tmux -CC) over this channel.
106
+ child = bridge(acc(), ["-lc", info.command], term);
107
+ });
108
+ session.on("subsystem", (_acc, rej, info) => {
109
+ debug("subsystem", info.name);
110
+ // ponytail: scp/sftp not supported; reject so the client fails fast
111
+ rej?.();
96
112
  });
97
113
  });
98
114
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cmux-ssh-here",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Spin up a token-auth SSH server and print a cmux deep link to connect over LAN",
5
5
  "type": "module",
6
6
  "bin": {