claude-cac 1.2.0 → 1.3.0

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.
@@ -19,12 +19,18 @@ if (fakeMac) {
19
19
  const _origNetworkInterfaces = os.networkInterfaces.bind(os);
20
20
  os.networkInterfaces = () => {
21
21
  const ifaces = _origNetworkInterfaces();
22
+ const macParts = fakeMac.split(':').map(h => parseInt(h, 16));
23
+ let ifIdx = 0;
22
24
  for (const name of Object.keys(ifaces)) {
23
25
  for (const info of ifaces[name]) {
24
26
  if (info.mac && info.mac !== '00:00:00:00:00:00') {
25
- info.mac = fakeMac;
27
+ // Derive per-interface MAC: XOR last octet with interface index
28
+ const derived = macParts.slice();
29
+ derived[5] = (derived[5] ^ ifIdx) & 0xff;
30
+ info.mac = derived.map(b => b.toString(16).padStart(2, '0')).join(':');
26
31
  }
27
32
  }
33
+ ifIdx++;
28
34
  }
29
35
  return ifaces;
30
36
  };
@@ -98,8 +104,14 @@ function makeFakeChildProcess() {
98
104
  cp.stdout = new EventEmitter();
99
105
  cp.stderr = new EventEmitter();
100
106
  cp.stdin = null;
107
+ cp.stdio = [null, cp.stdout, cp.stderr];
101
108
  cp.pid = 0;
102
- cp.kill = () => {};
109
+ cp.exitCode = null;
110
+ cp.signalCode = null;
111
+ cp.killed = false;
112
+ cp.spawnargs = [];
113
+ cp.spawnfile = '';
114
+ cp.kill = () => false;
103
115
  return cp;
104
116
  }
105
117
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-cac",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Isolate, protect, and manage your Claude Code — versions, environments, identity, and proxy.",
5
5
  "bin": {
6
6
  "cac": "cac"
package/relay.js CHANGED
@@ -133,15 +133,15 @@ function httpConnect(targetHost, targetPort, cb) {
133
133
  connectReq += '\r\n';
134
134
  sock.write(connectReq);
135
135
 
136
- let buf = '';
136
+ let buf = Buffer.alloc(0);
137
137
  sock.on('data', function onData(chunk) {
138
- buf += chunk.toString();
138
+ buf = Buffer.concat([buf, chunk]);
139
139
  const idx = buf.indexOf('\r\n\r\n');
140
140
  if (idx === -1) return;
141
141
 
142
- const statusLine = buf.substring(0, buf.indexOf('\r\n'));
142
+ const statusLine = buf.slice(0, buf.indexOf('\r\n')).toString();
143
143
  const statusCode = parseInt(statusLine.split(' ')[1], 10);
144
- const remaining = Buffer.from(buf.substring(idx + 4));
144
+ const remaining = buf.slice(idx + 4);
145
145
 
146
146
  sock.removeListener('data', onData);
147
147
 
@@ -207,16 +207,18 @@ const server = net.createServer({ pauseOnConnect: true }, (clientSock) => {
207
207
 
208
208
  function handleConnect(clientSock, targetHost, targetPort, headerRest) {
209
209
  // Consume remaining headers until \r\n\r\n
210
- let restBuf = headerRest;
210
+ // Keep as Buffer to avoid corrupting binary data (e.g. TLS ClientHello)
211
+ // that may arrive in the same chunk as the last header bytes.
212
+ let restBuf = Buffer.from(headerRest);
211
213
  const consumeHeaders = () => {
212
214
  const endIdx = restBuf.indexOf('\r\n\r\n');
213
215
  if (endIdx !== -1) {
214
- const trailing = restBuf.substring(endIdx + 4);
216
+ const trailing = restBuf.slice(endIdx + 4);
215
217
  doConnect(trailing);
216
218
  return;
217
219
  }
218
220
  clientSock.once('data', (chunk) => {
219
- restBuf += chunk.toString();
221
+ restBuf = Buffer.concat([restBuf, chunk]);
220
222
  consumeHeaders();
221
223
  });
222
224
  };
@@ -235,8 +237,9 @@ function handleConnect(clientSock, targetHost, targetPort, headerRest) {
235
237
  upstreamSock.pipe(clientSock);
236
238
 
237
239
  // Send any extra data that came in after handshake
240
+ // upstreamExtra is data from the target server; write it to the client.
238
241
  if (upstreamExtra && upstreamExtra.length > 0) {
239
- clientSock.unshift(upstreamExtra);
242
+ clientSock.write(upstreamExtra);
240
243
  }
241
244
  if (trailingData && trailingData.length > 0) {
242
245
  upstreamSock.write(trailingData);
@@ -253,7 +256,12 @@ function handleConnect(clientSock, targetHost, targetPort, headerRest) {
253
256
  function handlePlainHttp(clientSock, firstLine, headerRest) {
254
257
  // For plain HTTP requests, forward directly to upstream proxy
255
258
  const sock = net.connect(upstreamPort, upstreamHost, () => {
256
- sock.write(firstLine + '\r\n' + headerRest);
259
+ let authHeader = '';
260
+ if (upstreamUser) {
261
+ const cred = Buffer.from(upstreamUser + ':' + upstreamPass).toString('base64');
262
+ authHeader = 'Proxy-Authorization: Basic ' + cred + '\r\n';
263
+ }
264
+ sock.write(firstLine + '\r\n' + authHeader + headerRest);
257
265
  clientSock.pipe(sock);
258
266
  sock.pipe(clientSock);
259
267
  });