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.
- package/README.md +42 -30
- package/cac +564 -229
- package/fingerprint-hook.js +14 -2
- package/package.json +1 -1
- package/relay.js +17 -9
package/fingerprint-hook.js
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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
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
|
|
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.
|
|
142
|
+
const statusLine = buf.slice(0, buf.indexOf('\r\n')).toString();
|
|
143
143
|
const statusCode = parseInt(statusLine.split(' ')[1], 10);
|
|
144
|
-
const remaining =
|
|
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
|
-
|
|
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.
|
|
216
|
+
const trailing = restBuf.slice(endIdx + 4);
|
|
215
217
|
doConnect(trailing);
|
|
216
218
|
return;
|
|
217
219
|
}
|
|
218
220
|
clientSock.once('data', (chunk) => {
|
|
219
|
-
restBuf
|
|
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.
|
|
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
|
-
|
|
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
|
});
|