@push.rocks/smartproxy 25.17.10 → 26.0.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/changelog.md +8 -0
- package/dist_rust/rustproxy_linux_amd64 +0 -0
- package/dist_rust/rustproxy_linux_arm64 +0 -0
- package/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/core/index.d.ts +0 -1
- package/dist_ts/core/index.js +1 -2
- package/dist_ts/core/models/index.d.ts +0 -1
- package/dist_ts/core/models/index.js +1 -2
- package/dist_ts/core/utils/index.d.ts +0 -12
- package/dist_ts/core/utils/index.js +1 -13
- package/dist_ts/index.d.ts +0 -3
- package/dist_ts/index.js +2 -7
- package/dist_ts/protocols/http/index.d.ts +0 -1
- package/dist_ts/protocols/http/index.js +1 -2
- package/dist_ts/protocols/index.d.ts +0 -7
- package/dist_ts/protocols/index.js +1 -8
- package/dist_ts/proxies/smart-proxy/socket-handler-server.js +6 -1
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.d.ts +0 -7
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.js +50 -51
- package/dist_ts/routing/index.d.ts +0 -1
- package/dist_ts/routing/index.js +1 -3
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/index.ts +0 -1
- package/ts/core/models/index.ts +0 -1
- package/ts/core/utils/index.ts +0 -12
- package/ts/index.ts +1 -7
- package/ts/protocols/http/index.ts +1 -2
- package/ts/protocols/index.ts +0 -7
- package/ts/proxies/smart-proxy/socket-handler-server.ts +6 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.ts +60 -59
- package/ts/routing/index.ts +0 -3
- package/dist_ts/core/events/index.d.ts +0 -4
- package/dist_ts/core/events/index.js +0 -5
- package/dist_ts/core/models/socket-augmentation.d.ts +0 -15
- package/dist_ts/core/models/socket-augmentation.js +0 -18
- package/dist_ts/core/utils/async-utils.d.ts +0 -81
- package/dist_ts/core/utils/async-utils.js +0 -216
- package/dist_ts/core/utils/binary-heap.d.ts +0 -73
- package/dist_ts/core/utils/binary-heap.js +0 -193
- package/dist_ts/core/utils/enhanced-connection-pool.d.ts +0 -110
- package/dist_ts/core/utils/enhanced-connection-pool.js +0 -325
- package/dist_ts/core/utils/fs-utils.d.ts +0 -144
- package/dist_ts/core/utils/fs-utils.js +0 -252
- package/dist_ts/core/utils/ip-utils.d.ts +0 -69
- package/dist_ts/core/utils/ip-utils.js +0 -270
- package/dist_ts/core/utils/lifecycle-component.d.ts +0 -59
- package/dist_ts/core/utils/lifecycle-component.js +0 -211
- package/dist_ts/core/utils/log-deduplicator.d.ts +0 -39
- package/dist_ts/core/utils/log-deduplicator.js +0 -305
- package/dist_ts/core/utils/security-utils.d.ts +0 -111
- package/dist_ts/core/utils/security-utils.js +0 -212
- package/dist_ts/core/utils/shared-security-manager.d.ts +0 -128
- package/dist_ts/core/utils/shared-security-manager.js +0 -362
- package/dist_ts/core/utils/socket-utils.d.ts +0 -63
- package/dist_ts/core/utils/socket-utils.js +0 -249
- package/dist_ts/core/utils/template-utils.d.ts +0 -37
- package/dist_ts/core/utils/template-utils.js +0 -104
- package/dist_ts/core/utils/validation-utils.d.ts +0 -61
- package/dist_ts/core/utils/validation-utils.js +0 -149
- package/dist_ts/core/utils/websocket-utils.d.ts +0 -22
- package/dist_ts/core/utils/websocket-utils.js +0 -30
- package/dist_ts/detection/detectors/http-detector.d.ts +0 -33
- package/dist_ts/detection/detectors/http-detector.js +0 -101
- package/dist_ts/detection/detectors/quick-detector.d.ts +0 -28
- package/dist_ts/detection/detectors/quick-detector.js +0 -131
- package/dist_ts/detection/detectors/routing-extractor.d.ts +0 -28
- package/dist_ts/detection/detectors/routing-extractor.js +0 -122
- package/dist_ts/detection/detectors/tls-detector.d.ts +0 -47
- package/dist_ts/detection/detectors/tls-detector.js +0 -183
- package/dist_ts/detection/index.d.ts +0 -17
- package/dist_ts/detection/index.js +0 -22
- package/dist_ts/detection/models/detection-types.d.ts +0 -87
- package/dist_ts/detection/models/detection-types.js +0 -5
- package/dist_ts/detection/models/interfaces.d.ts +0 -97
- package/dist_ts/detection/models/interfaces.js +0 -5
- package/dist_ts/detection/protocol-detector.d.ts +0 -79
- package/dist_ts/detection/protocol-detector.js +0 -253
- package/dist_ts/detection/utils/buffer-utils.d.ts +0 -61
- package/dist_ts/detection/utils/buffer-utils.js +0 -127
- package/dist_ts/detection/utils/fragment-manager.d.ts +0 -31
- package/dist_ts/detection/utils/fragment-manager.js +0 -53
- package/dist_ts/detection/utils/parser-utils.d.ts +0 -42
- package/dist_ts/detection/utils/parser-utils.js +0 -63
- package/dist_ts/protocols/common/fragment-handler.d.ts +0 -73
- package/dist_ts/protocols/common/fragment-handler.js +0 -121
- package/dist_ts/protocols/common/index.d.ts +0 -7
- package/dist_ts/protocols/common/index.js +0 -8
- package/dist_ts/protocols/common/types.d.ts +0 -68
- package/dist_ts/protocols/common/types.js +0 -7
- package/dist_ts/protocols/http/parser.d.ts +0 -58
- package/dist_ts/protocols/http/parser.js +0 -184
- package/dist_ts/protocols/proxy/index.d.ts +0 -5
- package/dist_ts/protocols/proxy/index.js +0 -6
- package/dist_ts/protocols/proxy/types.d.ts +0 -47
- package/dist_ts/protocols/proxy/types.js +0 -6
- package/dist_ts/protocols/tls/alerts/index.d.ts +0 -4
- package/dist_ts/protocols/tls/alerts/index.js +0 -5
- package/dist_ts/protocols/tls/alerts/tls-alert.d.ts +0 -150
- package/dist_ts/protocols/tls/alerts/tls-alert.js +0 -226
- package/dist_ts/protocols/tls/index.d.ts +0 -12
- package/dist_ts/protocols/tls/index.js +0 -27
- package/dist_ts/protocols/tls/sni/client-hello-parser.d.ts +0 -100
- package/dist_ts/protocols/tls/sni/client-hello-parser.js +0 -463
- package/dist_ts/protocols/tls/sni/index.d.ts +0 -5
- package/dist_ts/protocols/tls/sni/index.js +0 -6
- package/dist_ts/protocols/tls/sni/sni-extraction.d.ts +0 -58
- package/dist_ts/protocols/tls/sni/sni-extraction.js +0 -275
- package/dist_ts/protocols/tls/utils/index.d.ts +0 -4
- package/dist_ts/protocols/tls/utils/index.js +0 -5
- package/dist_ts/protocols/tls/utils/tls-utils.d.ts +0 -158
- package/dist_ts/protocols/tls/utils/tls-utils.js +0 -187
- package/dist_ts/protocols/websocket/constants.d.ts +0 -55
- package/dist_ts/protocols/websocket/constants.js +0 -58
- package/dist_ts/protocols/websocket/index.d.ts +0 -7
- package/dist_ts/protocols/websocket/index.js +0 -8
- package/dist_ts/protocols/websocket/types.d.ts +0 -47
- package/dist_ts/protocols/websocket/types.js +0 -5
- package/dist_ts/protocols/websocket/utils.d.ts +0 -25
- package/dist_ts/protocols/websocket/utils.js +0 -103
- package/dist_ts/routing/router/http-router.d.ts +0 -89
- package/dist_ts/routing/router/http-router.js +0 -205
- package/dist_ts/routing/router/index.d.ts +0 -5
- package/dist_ts/routing/router/index.js +0 -6
- package/dist_ts/tls/index.d.ts +0 -16
- package/dist_ts/tls/index.js +0 -24
- package/dist_ts/tls/sni/index.d.ts +0 -4
- package/dist_ts/tls/sni/index.js +0 -5
- package/dist_ts/tls/sni/sni-handler.d.ts +0 -154
- package/dist_ts/tls/sni/sni-handler.js +0 -191
- package/ts/core/events/index.ts +0 -3
- package/ts/core/models/socket-augmentation.ts +0 -38
- package/ts/core/utils/async-utils.ts +0 -275
- package/ts/core/utils/binary-heap.ts +0 -225
- package/ts/core/utils/enhanced-connection-pool.ts +0 -425
- package/ts/core/utils/fs-utils.ts +0 -270
- package/ts/core/utils/ip-utils.ts +0 -303
- package/ts/core/utils/lifecycle-component.ts +0 -251
- package/ts/core/utils/log-deduplicator.ts +0 -370
- package/ts/core/utils/security-utils.ts +0 -305
- package/ts/core/utils/shared-security-manager.ts +0 -470
- package/ts/core/utils/socket-utils.ts +0 -322
- package/ts/core/utils/template-utils.ts +0 -124
- package/ts/core/utils/validation-utils.ts +0 -177
- package/ts/core/utils/websocket-utils.ts +0 -33
- package/ts/detection/detectors/http-detector.ts +0 -127
- package/ts/detection/detectors/quick-detector.ts +0 -148
- package/ts/detection/detectors/routing-extractor.ts +0 -147
- package/ts/detection/detectors/tls-detector.ts +0 -223
- package/ts/detection/index.ts +0 -25
- package/ts/detection/models/detection-types.ts +0 -102
- package/ts/detection/models/interfaces.ts +0 -115
- package/ts/detection/protocol-detector.ts +0 -319
- package/ts/detection/utils/buffer-utils.ts +0 -141
- package/ts/detection/utils/fragment-manager.ts +0 -64
- package/ts/detection/utils/parser-utils.ts +0 -77
- package/ts/protocols/common/fragment-handler.ts +0 -167
- package/ts/protocols/common/index.ts +0 -8
- package/ts/protocols/common/types.ts +0 -76
- package/ts/protocols/http/parser.ts +0 -219
- package/ts/protocols/proxy/index.ts +0 -6
- package/ts/protocols/proxy/types.ts +0 -53
- package/ts/protocols/tls/alerts/index.ts +0 -3
- package/ts/protocols/tls/alerts/tls-alert.ts +0 -259
- package/ts/protocols/tls/index.ts +0 -37
- package/ts/protocols/tls/sni/client-hello-parser.ts +0 -629
- package/ts/protocols/tls/sni/index.ts +0 -6
- package/ts/protocols/tls/sni/sni-extraction.ts +0 -353
- package/ts/protocols/tls/utils/index.ts +0 -3
- package/ts/protocols/tls/utils/tls-utils.ts +0 -201
- package/ts/protocols/websocket/constants.ts +0 -60
- package/ts/protocols/websocket/index.ts +0 -8
- package/ts/protocols/websocket/types.ts +0 -53
- package/ts/protocols/websocket/utils.ts +0 -98
- package/ts/routing/router/http-router.ts +0 -266
- package/ts/routing/router/index.ts +0 -7
- package/ts/tls/index.ts +0 -29
- package/ts/tls/sni/index.ts +0 -3
- package/ts/tls/sni/sni-handler.ts +0 -264
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
import { Buffer } from 'node:buffer';
|
|
2
|
-
import { TlsExtensionType, TlsUtils } from '../utils/tls-utils.js';
|
|
3
|
-
import {
|
|
4
|
-
ClientHelloParser,
|
|
5
|
-
type LoggerFunction
|
|
6
|
-
} from './client-hello-parser.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Connection tracking information
|
|
10
|
-
*/
|
|
11
|
-
export interface ConnectionInfo {
|
|
12
|
-
sourceIp: string;
|
|
13
|
-
sourcePort: number;
|
|
14
|
-
destIp: string;
|
|
15
|
-
destPort: number;
|
|
16
|
-
timestamp?: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Utilities for extracting SNI information from TLS handshakes
|
|
21
|
-
*/
|
|
22
|
-
export class SniExtraction {
|
|
23
|
-
/**
|
|
24
|
-
* Extracts the SNI (Server Name Indication) from a TLS ClientHello message.
|
|
25
|
-
*
|
|
26
|
-
* @param buffer The buffer containing the TLS ClientHello message
|
|
27
|
-
* @param logger Optional logging function
|
|
28
|
-
* @returns The extracted server name or undefined if not found
|
|
29
|
-
*/
|
|
30
|
-
public static extractSNI(buffer: Buffer, logger?: LoggerFunction): string | undefined {
|
|
31
|
-
const log = logger || (() => {});
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
// Parse the ClientHello
|
|
35
|
-
const parseResult = ClientHelloParser.parseClientHello(buffer, logger);
|
|
36
|
-
if (!parseResult.isValid) {
|
|
37
|
-
log(`Failed to parse ClientHello: ${parseResult.error}`);
|
|
38
|
-
return undefined;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Check if ServerName extension was found
|
|
42
|
-
if (parseResult.serverNameList && parseResult.serverNameList.length > 0) {
|
|
43
|
-
// Use the first hostname (most common case)
|
|
44
|
-
const serverName = parseResult.serverNameList[0];
|
|
45
|
-
log(`Found SNI: ${serverName}`);
|
|
46
|
-
return serverName;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
log('No SNI extension found in ClientHello');
|
|
50
|
-
return undefined;
|
|
51
|
-
} catch (error) {
|
|
52
|
-
log(`Error extracting SNI: ${error instanceof Error ? error.message : String(error)}`);
|
|
53
|
-
return undefined;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Attempts to extract SNI from the PSK extension in a TLS 1.3 ClientHello.
|
|
59
|
-
*
|
|
60
|
-
* In TLS 1.3, when a client attempts to resume a session, it may include
|
|
61
|
-
* the server name in the PSK identity hint rather than in the SNI extension.
|
|
62
|
-
*
|
|
63
|
-
* @param buffer The buffer containing the TLS ClientHello message
|
|
64
|
-
* @param logger Optional logging function
|
|
65
|
-
* @returns The extracted server name or undefined if not found
|
|
66
|
-
*/
|
|
67
|
-
public static extractSNIFromPSKExtension(
|
|
68
|
-
buffer: Buffer,
|
|
69
|
-
logger?: LoggerFunction
|
|
70
|
-
): string | undefined {
|
|
71
|
-
const log = logger || (() => {});
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
// Ensure this is a ClientHello
|
|
75
|
-
if (!TlsUtils.isClientHello(buffer)) {
|
|
76
|
-
log('Not a ClientHello message');
|
|
77
|
-
return undefined;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Parse the ClientHello to find PSK extension
|
|
81
|
-
const parseResult = ClientHelloParser.parseClientHello(buffer, logger);
|
|
82
|
-
if (!parseResult.isValid || !parseResult.extensions) {
|
|
83
|
-
return undefined;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Find the PSK extension
|
|
87
|
-
const pskExtension = parseResult.extensions.find(ext =>
|
|
88
|
-
ext.type === TlsExtensionType.PRE_SHARED_KEY);
|
|
89
|
-
|
|
90
|
-
if (!pskExtension) {
|
|
91
|
-
log('No PSK extension found');
|
|
92
|
-
return undefined;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Parse the PSK extension data
|
|
96
|
-
const data = pskExtension.data;
|
|
97
|
-
|
|
98
|
-
// PSK extension structure:
|
|
99
|
-
// 2 bytes: identities list length
|
|
100
|
-
if (data.length < 2) return undefined;
|
|
101
|
-
|
|
102
|
-
const identitiesLength = (data[0] << 8) + data[1];
|
|
103
|
-
let pos = 2;
|
|
104
|
-
|
|
105
|
-
// End of identities list
|
|
106
|
-
const identitiesEnd = pos + identitiesLength;
|
|
107
|
-
if (identitiesEnd > data.length) return undefined;
|
|
108
|
-
|
|
109
|
-
// Process each PSK identity
|
|
110
|
-
while (pos + 2 <= identitiesEnd) {
|
|
111
|
-
// Identity length (2 bytes)
|
|
112
|
-
if (pos + 2 > identitiesEnd) break;
|
|
113
|
-
|
|
114
|
-
const identityLength = (data[pos] << 8) + data[pos + 1];
|
|
115
|
-
pos += 2;
|
|
116
|
-
|
|
117
|
-
if (pos + identityLength > identitiesEnd) break;
|
|
118
|
-
|
|
119
|
-
// Try to extract hostname from identity
|
|
120
|
-
// Chrome often embeds the hostname in the PSK identity
|
|
121
|
-
// This is a heuristic as there's no standard format
|
|
122
|
-
if (identityLength > 0) {
|
|
123
|
-
const identity = data.slice(pos, pos + identityLength);
|
|
124
|
-
|
|
125
|
-
// Skip identity bytes
|
|
126
|
-
pos += identityLength;
|
|
127
|
-
|
|
128
|
-
// Skip obfuscated ticket age (4 bytes)
|
|
129
|
-
if (pos + 4 <= identitiesEnd) {
|
|
130
|
-
pos += 4;
|
|
131
|
-
} else {
|
|
132
|
-
break;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Try to parse the identity as UTF-8
|
|
136
|
-
try {
|
|
137
|
-
const identityStr = identity.toString('utf8');
|
|
138
|
-
log(`PSK identity: ${identityStr}`);
|
|
139
|
-
|
|
140
|
-
// Check if the identity contains hostname hints
|
|
141
|
-
// Chrome often embeds the hostname in a known format
|
|
142
|
-
// Try to extract using common patterns
|
|
143
|
-
|
|
144
|
-
// Pattern 1: Look for domain name pattern
|
|
145
|
-
const domainPattern =
|
|
146
|
-
/([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?/i;
|
|
147
|
-
const domainMatch = identityStr.match(domainPattern);
|
|
148
|
-
if (domainMatch && domainMatch[0]) {
|
|
149
|
-
log(`Found domain in PSK identity: ${domainMatch[0]}`);
|
|
150
|
-
return domainMatch[0];
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Pattern 2: Chrome sometimes uses a specific format with delimiters
|
|
154
|
-
// This is a heuristic approach since the format isn't standardized
|
|
155
|
-
const parts = identityStr.split('|');
|
|
156
|
-
if (parts.length > 1) {
|
|
157
|
-
for (const part of parts) {
|
|
158
|
-
if (part.includes('.') && !part.includes('/')) {
|
|
159
|
-
const possibleDomain = part.trim();
|
|
160
|
-
if (/^[a-z0-9.-]+$/i.test(possibleDomain)) {
|
|
161
|
-
log(`Found possible domain in PSK delimiter format: ${possibleDomain}`);
|
|
162
|
-
return possibleDomain;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
} catch (e) {
|
|
168
|
-
log('Failed to parse PSK identity as UTF-8');
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
log('No hostname found in PSK extension');
|
|
174
|
-
return undefined;
|
|
175
|
-
} catch (error) {
|
|
176
|
-
log(`Error parsing PSK: ${error instanceof Error ? error.message : String(error)}`);
|
|
177
|
-
return undefined;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Main entry point for SNI extraction with support for fragmented messages
|
|
183
|
-
* and session resumption edge cases.
|
|
184
|
-
*
|
|
185
|
-
* @param buffer The buffer containing TLS data
|
|
186
|
-
* @param connectionInfo Connection tracking information
|
|
187
|
-
* @param logger Optional logging function
|
|
188
|
-
* @param cachedSni Optional previously cached SNI value
|
|
189
|
-
* @returns The extracted server name or undefined
|
|
190
|
-
*/
|
|
191
|
-
public static extractSNIWithResumptionSupport(
|
|
192
|
-
buffer: Buffer,
|
|
193
|
-
connectionInfo?: ConnectionInfo,
|
|
194
|
-
logger?: LoggerFunction,
|
|
195
|
-
cachedSni?: string
|
|
196
|
-
): string | undefined {
|
|
197
|
-
const log = logger || (() => {});
|
|
198
|
-
|
|
199
|
-
// Log buffer details for debugging
|
|
200
|
-
if (logger) {
|
|
201
|
-
log(`Buffer size: ${buffer.length} bytes`);
|
|
202
|
-
log(`Buffer starts with: ${buffer.slice(0, Math.min(10, buffer.length)).toString('hex')}`);
|
|
203
|
-
|
|
204
|
-
if (buffer.length >= 5) {
|
|
205
|
-
const recordType = buffer[0];
|
|
206
|
-
const majorVersion = buffer[1];
|
|
207
|
-
const minorVersion = buffer[2];
|
|
208
|
-
const recordLength = (buffer[3] << 8) + buffer[4];
|
|
209
|
-
|
|
210
|
-
log(
|
|
211
|
-
`TLS Record: type=${recordType}, version=${majorVersion}.${minorVersion}, length=${recordLength}`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Check if we need to handle fragmented packets
|
|
217
|
-
let processBuffer = buffer;
|
|
218
|
-
if (connectionInfo) {
|
|
219
|
-
const connectionId = TlsUtils.createConnectionId(connectionInfo);
|
|
220
|
-
const reassembledBuffer = ClientHelloParser.handleFragmentedClientHello(
|
|
221
|
-
buffer,
|
|
222
|
-
connectionId,
|
|
223
|
-
logger
|
|
224
|
-
);
|
|
225
|
-
|
|
226
|
-
if (!reassembledBuffer) {
|
|
227
|
-
log(`Waiting for more fragments on connection ${connectionId}`);
|
|
228
|
-
return undefined; // Need more fragments to complete ClientHello
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
processBuffer = reassembledBuffer;
|
|
232
|
-
log(`Using reassembled buffer of length ${processBuffer.length}`);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// First try the standard SNI extraction
|
|
236
|
-
const standardSni = this.extractSNI(processBuffer, logger);
|
|
237
|
-
if (standardSni) {
|
|
238
|
-
log(`Found standard SNI: ${standardSni}`);
|
|
239
|
-
return standardSni;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// Check for session resumption when standard SNI extraction fails
|
|
243
|
-
if (TlsUtils.isClientHello(processBuffer)) {
|
|
244
|
-
const resumptionInfo = ClientHelloParser.hasSessionResumption(processBuffer, logger);
|
|
245
|
-
|
|
246
|
-
if (resumptionInfo.isResumption) {
|
|
247
|
-
log(`Detected session resumption in ClientHello without standard SNI`);
|
|
248
|
-
|
|
249
|
-
// Try to extract SNI from PSK extension
|
|
250
|
-
const pskSni = this.extractSNIFromPSKExtension(processBuffer, logger);
|
|
251
|
-
if (pskSni) {
|
|
252
|
-
log(`Extracted SNI from PSK extension: ${pskSni}`);
|
|
253
|
-
return pskSni;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// If cached SNI was provided, use it for application data packets
|
|
259
|
-
if (cachedSni && TlsUtils.isTlsApplicationData(buffer)) {
|
|
260
|
-
log(`Using provided cached SNI for application data: ${cachedSni}`);
|
|
261
|
-
return cachedSni;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
return undefined;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Unified method for processing a TLS packet and extracting SNI.
|
|
269
|
-
* Main entry point for SNI extraction that handles all edge cases.
|
|
270
|
-
*
|
|
271
|
-
* @param buffer The buffer containing TLS data
|
|
272
|
-
* @param connectionInfo Connection tracking information
|
|
273
|
-
* @param logger Optional logging function
|
|
274
|
-
* @param cachedSni Optional previously cached SNI value
|
|
275
|
-
* @returns The extracted server name or undefined
|
|
276
|
-
*/
|
|
277
|
-
public static processTlsPacket(
|
|
278
|
-
buffer: Buffer,
|
|
279
|
-
connectionInfo: ConnectionInfo,
|
|
280
|
-
logger?: LoggerFunction,
|
|
281
|
-
cachedSni?: string
|
|
282
|
-
): string | undefined {
|
|
283
|
-
const log = logger || (() => {});
|
|
284
|
-
|
|
285
|
-
// Add timestamp if not provided
|
|
286
|
-
if (!connectionInfo.timestamp) {
|
|
287
|
-
connectionInfo.timestamp = Date.now();
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Check if this is a TLS handshake or application data
|
|
291
|
-
if (!TlsUtils.isTlsHandshake(buffer) && !TlsUtils.isTlsApplicationData(buffer)) {
|
|
292
|
-
log('Not a TLS handshake or application data packet');
|
|
293
|
-
return undefined;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Create connection ID for tracking
|
|
297
|
-
const connectionId = TlsUtils.createConnectionId(connectionInfo);
|
|
298
|
-
log(`Processing TLS packet for connection ${connectionId}, buffer length: ${buffer.length}`);
|
|
299
|
-
|
|
300
|
-
// Handle application data with cached SNI (for connection racing)
|
|
301
|
-
if (TlsUtils.isTlsApplicationData(buffer)) {
|
|
302
|
-
// If explicit cachedSni was provided, use it
|
|
303
|
-
if (cachedSni) {
|
|
304
|
-
log(`Using provided cached SNI for application data: ${cachedSni}`);
|
|
305
|
-
return cachedSni;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
log('Application data packet without cached SNI, cannot determine hostname');
|
|
309
|
-
return undefined;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// Enhanced session resumption detection
|
|
313
|
-
if (TlsUtils.isClientHello(buffer)) {
|
|
314
|
-
const resumptionInfo = ClientHelloParser.hasSessionResumption(buffer, logger);
|
|
315
|
-
|
|
316
|
-
if (resumptionInfo.isResumption) {
|
|
317
|
-
log(`Session resumption detected in TLS packet`);
|
|
318
|
-
|
|
319
|
-
// Always try standard SNI extraction first
|
|
320
|
-
const standardSni = this.extractSNI(buffer, logger);
|
|
321
|
-
if (standardSni) {
|
|
322
|
-
log(`Found standard SNI in session resumption: ${standardSni}`);
|
|
323
|
-
return standardSni;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Enhanced session resumption SNI extraction
|
|
327
|
-
// Try extracting from PSK identity
|
|
328
|
-
const pskSni = this.extractSNIFromPSKExtension(buffer, logger);
|
|
329
|
-
if (pskSni) {
|
|
330
|
-
log(`Extracted SNI from PSK extension: ${pskSni}`);
|
|
331
|
-
return pskSni;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
log(`Session resumption without extractable SNI`);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// For handshake messages, try the full extraction process
|
|
339
|
-
const sni = this.extractSNIWithResumptionSupport(buffer, connectionInfo, logger);
|
|
340
|
-
|
|
341
|
-
if (sni) {
|
|
342
|
-
log(`Successfully extracted SNI: ${sni}`);
|
|
343
|
-
return sni;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// If we couldn't extract an SNI, check if this is a valid ClientHello
|
|
347
|
-
if (TlsUtils.isClientHello(buffer)) {
|
|
348
|
-
log('Valid ClientHello detected, but no SNI extracted - might need more data');
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return undefined;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../../../plugins.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* TLS record types as defined in various RFCs
|
|
5
|
-
*/
|
|
6
|
-
export enum TlsRecordType {
|
|
7
|
-
CHANGE_CIPHER_SPEC = 20,
|
|
8
|
-
ALERT = 21,
|
|
9
|
-
HANDSHAKE = 22,
|
|
10
|
-
APPLICATION_DATA = 23,
|
|
11
|
-
HEARTBEAT = 24, // RFC 6520
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* TLS handshake message types
|
|
16
|
-
*/
|
|
17
|
-
export enum TlsHandshakeType {
|
|
18
|
-
HELLO_REQUEST = 0,
|
|
19
|
-
CLIENT_HELLO = 1,
|
|
20
|
-
SERVER_HELLO = 2,
|
|
21
|
-
NEW_SESSION_TICKET = 4,
|
|
22
|
-
ENCRYPTED_EXTENSIONS = 8, // TLS 1.3
|
|
23
|
-
CERTIFICATE = 11,
|
|
24
|
-
SERVER_KEY_EXCHANGE = 12,
|
|
25
|
-
CERTIFICATE_REQUEST = 13,
|
|
26
|
-
SERVER_HELLO_DONE = 14,
|
|
27
|
-
CERTIFICATE_VERIFY = 15,
|
|
28
|
-
CLIENT_KEY_EXCHANGE = 16,
|
|
29
|
-
FINISHED = 20,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* TLS extension types
|
|
34
|
-
*/
|
|
35
|
-
export enum TlsExtensionType {
|
|
36
|
-
SERVER_NAME = 0, // SNI
|
|
37
|
-
MAX_FRAGMENT_LENGTH = 1,
|
|
38
|
-
CLIENT_CERTIFICATE_URL = 2,
|
|
39
|
-
TRUSTED_CA_KEYS = 3,
|
|
40
|
-
TRUNCATED_HMAC = 4,
|
|
41
|
-
STATUS_REQUEST = 5, // OCSP
|
|
42
|
-
SUPPORTED_GROUPS = 10, // Previously named "elliptic_curves"
|
|
43
|
-
EC_POINT_FORMATS = 11,
|
|
44
|
-
SIGNATURE_ALGORITHMS = 13,
|
|
45
|
-
APPLICATION_LAYER_PROTOCOL_NEGOTIATION = 16, // ALPN
|
|
46
|
-
SIGNED_CERTIFICATE_TIMESTAMP = 18, // Certificate Transparency
|
|
47
|
-
PADDING = 21,
|
|
48
|
-
SESSION_TICKET = 35,
|
|
49
|
-
PRE_SHARED_KEY = 41, // TLS 1.3
|
|
50
|
-
EARLY_DATA = 42, // TLS 1.3 0-RTT
|
|
51
|
-
SUPPORTED_VERSIONS = 43, // TLS 1.3
|
|
52
|
-
COOKIE = 44, // TLS 1.3
|
|
53
|
-
PSK_KEY_EXCHANGE_MODES = 45, // TLS 1.3
|
|
54
|
-
CERTIFICATE_AUTHORITIES = 47, // TLS 1.3
|
|
55
|
-
POST_HANDSHAKE_AUTH = 49, // TLS 1.3
|
|
56
|
-
SIGNATURE_ALGORITHMS_CERT = 50, // TLS 1.3
|
|
57
|
-
KEY_SHARE = 51, // TLS 1.3
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* TLS alert levels
|
|
62
|
-
*/
|
|
63
|
-
export enum TlsAlertLevel {
|
|
64
|
-
WARNING = 1,
|
|
65
|
-
FATAL = 2,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* TLS alert description codes
|
|
70
|
-
*/
|
|
71
|
-
export enum TlsAlertDescription {
|
|
72
|
-
CLOSE_NOTIFY = 0,
|
|
73
|
-
UNEXPECTED_MESSAGE = 10,
|
|
74
|
-
BAD_RECORD_MAC = 20,
|
|
75
|
-
DECRYPTION_FAILED = 21, // TLS 1.0 only
|
|
76
|
-
RECORD_OVERFLOW = 22,
|
|
77
|
-
DECOMPRESSION_FAILURE = 30, // TLS 1.2 and below
|
|
78
|
-
HANDSHAKE_FAILURE = 40,
|
|
79
|
-
NO_CERTIFICATE = 41, // SSLv3 only
|
|
80
|
-
BAD_CERTIFICATE = 42,
|
|
81
|
-
UNSUPPORTED_CERTIFICATE = 43,
|
|
82
|
-
CERTIFICATE_REVOKED = 44,
|
|
83
|
-
CERTIFICATE_EXPIRED = 45,
|
|
84
|
-
CERTIFICATE_UNKNOWN = 46,
|
|
85
|
-
ILLEGAL_PARAMETER = 47,
|
|
86
|
-
UNKNOWN_CA = 48,
|
|
87
|
-
ACCESS_DENIED = 49,
|
|
88
|
-
DECODE_ERROR = 50,
|
|
89
|
-
DECRYPT_ERROR = 51,
|
|
90
|
-
EXPORT_RESTRICTION = 60, // TLS 1.0 only
|
|
91
|
-
PROTOCOL_VERSION = 70,
|
|
92
|
-
INSUFFICIENT_SECURITY = 71,
|
|
93
|
-
INTERNAL_ERROR = 80,
|
|
94
|
-
INAPPROPRIATE_FALLBACK = 86,
|
|
95
|
-
USER_CANCELED = 90,
|
|
96
|
-
NO_RENEGOTIATION = 100, // TLS 1.2 and below
|
|
97
|
-
MISSING_EXTENSION = 109, // TLS 1.3
|
|
98
|
-
UNSUPPORTED_EXTENSION = 110, // TLS 1.3
|
|
99
|
-
CERTIFICATE_REQUIRED = 111, // TLS 1.3
|
|
100
|
-
UNRECOGNIZED_NAME = 112,
|
|
101
|
-
BAD_CERTIFICATE_STATUS_RESPONSE = 113,
|
|
102
|
-
BAD_CERTIFICATE_HASH_VALUE = 114, // TLS 1.2 and below
|
|
103
|
-
UNKNOWN_PSK_IDENTITY = 115,
|
|
104
|
-
CERTIFICATE_REQUIRED_1_3 = 116, // TLS 1.3
|
|
105
|
-
NO_APPLICATION_PROTOCOL = 120,
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* TLS version codes (major.minor)
|
|
110
|
-
*/
|
|
111
|
-
export const TlsVersion = {
|
|
112
|
-
SSL3: [0x03, 0x00],
|
|
113
|
-
TLS1_0: [0x03, 0x01],
|
|
114
|
-
TLS1_1: [0x03, 0x02],
|
|
115
|
-
TLS1_2: [0x03, 0x03],
|
|
116
|
-
TLS1_3: [0x03, 0x04],
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Utility functions for TLS protocol operations
|
|
121
|
-
*/
|
|
122
|
-
export class TlsUtils {
|
|
123
|
-
/**
|
|
124
|
-
* Checks if a buffer contains a TLS handshake record
|
|
125
|
-
* @param buffer The buffer to check
|
|
126
|
-
* @returns true if the buffer starts with a TLS handshake record
|
|
127
|
-
*/
|
|
128
|
-
public static isTlsHandshake(buffer: Buffer): boolean {
|
|
129
|
-
return buffer.length > 0 && buffer[0] === TlsRecordType.HANDSHAKE;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Checks if a buffer contains TLS application data
|
|
134
|
-
* @param buffer The buffer to check
|
|
135
|
-
* @returns true if the buffer starts with a TLS application data record
|
|
136
|
-
*/
|
|
137
|
-
public static isTlsApplicationData(buffer: Buffer): boolean {
|
|
138
|
-
return buffer.length > 0 && buffer[0] === TlsRecordType.APPLICATION_DATA;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Checks if a buffer contains a TLS alert record
|
|
143
|
-
* @param buffer The buffer to check
|
|
144
|
-
* @returns true if the buffer starts with a TLS alert record
|
|
145
|
-
*/
|
|
146
|
-
public static isTlsAlert(buffer: Buffer): boolean {
|
|
147
|
-
return buffer.length > 0 && buffer[0] === TlsRecordType.ALERT;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Checks if a buffer contains a TLS ClientHello message
|
|
152
|
-
* @param buffer The buffer to check
|
|
153
|
-
* @returns true if the buffer appears to be a ClientHello message
|
|
154
|
-
*/
|
|
155
|
-
public static isClientHello(buffer: Buffer): boolean {
|
|
156
|
-
// Minimum ClientHello size (TLS record header + handshake header)
|
|
157
|
-
if (buffer.length < 9) {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Check record type (must be TLS_HANDSHAKE_RECORD_TYPE)
|
|
162
|
-
if (buffer[0] !== TlsRecordType.HANDSHAKE) {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Skip version and length in TLS record header (5 bytes total)
|
|
167
|
-
// Check handshake type at byte 5 (must be CLIENT_HELLO)
|
|
168
|
-
return buffer[5] === TlsHandshakeType.CLIENT_HELLO;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Gets the record length from a TLS record header
|
|
173
|
-
* @param buffer Buffer containing a TLS record
|
|
174
|
-
* @returns The record length if the buffer is valid, -1 otherwise
|
|
175
|
-
*/
|
|
176
|
-
public static getTlsRecordLength(buffer: Buffer): number {
|
|
177
|
-
if (buffer.length < 5) {
|
|
178
|
-
return -1;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Bytes 3-4 contain the record length (big-endian)
|
|
182
|
-
return (buffer[3] << 8) + buffer[4];
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Creates a connection ID based on source/destination information
|
|
187
|
-
* Used to track fragmented ClientHello messages across multiple packets
|
|
188
|
-
*
|
|
189
|
-
* @param connectionInfo Object containing connection identifiers
|
|
190
|
-
* @returns A string ID for the connection
|
|
191
|
-
*/
|
|
192
|
-
public static createConnectionId(connectionInfo: {
|
|
193
|
-
sourceIp?: string;
|
|
194
|
-
sourcePort?: number;
|
|
195
|
-
destIp?: string;
|
|
196
|
-
destPort?: number;
|
|
197
|
-
}): string {
|
|
198
|
-
const { sourceIp, sourcePort, destIp, destPort } = connectionInfo;
|
|
199
|
-
return `${sourceIp}:${sourcePort}-${destIp}:${destPort}`;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebSocket Protocol Constants
|
|
3
|
-
* Based on RFC 6455
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* WebSocket opcode types
|
|
8
|
-
*/
|
|
9
|
-
export enum WebSocketOpcode {
|
|
10
|
-
CONTINUATION = 0x0,
|
|
11
|
-
TEXT = 0x1,
|
|
12
|
-
BINARY = 0x2,
|
|
13
|
-
CLOSE = 0x8,
|
|
14
|
-
PING = 0x9,
|
|
15
|
-
PONG = 0xa,
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* WebSocket close codes
|
|
20
|
-
*/
|
|
21
|
-
export enum WebSocketCloseCode {
|
|
22
|
-
NORMAL_CLOSURE = 1000,
|
|
23
|
-
GOING_AWAY = 1001,
|
|
24
|
-
PROTOCOL_ERROR = 1002,
|
|
25
|
-
UNSUPPORTED_DATA = 1003,
|
|
26
|
-
NO_STATUS_RECEIVED = 1005,
|
|
27
|
-
ABNORMAL_CLOSURE = 1006,
|
|
28
|
-
INVALID_FRAME_PAYLOAD_DATA = 1007,
|
|
29
|
-
POLICY_VIOLATION = 1008,
|
|
30
|
-
MESSAGE_TOO_BIG = 1009,
|
|
31
|
-
MISSING_EXTENSION = 1010,
|
|
32
|
-
INTERNAL_ERROR = 1011,
|
|
33
|
-
SERVICE_RESTART = 1012,
|
|
34
|
-
TRY_AGAIN_LATER = 1013,
|
|
35
|
-
BAD_GATEWAY = 1014,
|
|
36
|
-
TLS_HANDSHAKE = 1015,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* WebSocket protocol version
|
|
41
|
-
*/
|
|
42
|
-
export const WEBSOCKET_VERSION = 13;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* WebSocket magic string for handshake
|
|
46
|
-
*/
|
|
47
|
-
export const WEBSOCKET_MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* WebSocket headers
|
|
51
|
-
*/
|
|
52
|
-
export const WEBSOCKET_HEADERS = {
|
|
53
|
-
UPGRADE: 'upgrade',
|
|
54
|
-
CONNECTION: 'connection',
|
|
55
|
-
SEC_WEBSOCKET_KEY: 'sec-websocket-key',
|
|
56
|
-
SEC_WEBSOCKET_VERSION: 'sec-websocket-version',
|
|
57
|
-
SEC_WEBSOCKET_ACCEPT: 'sec-websocket-accept',
|
|
58
|
-
SEC_WEBSOCKET_PROTOCOL: 'sec-websocket-protocol',
|
|
59
|
-
SEC_WEBSOCKET_EXTENSIONS: 'sec-websocket-extensions',
|
|
60
|
-
} as const;
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebSocket Protocol Type Definitions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { WebSocketOpcode, WebSocketCloseCode } from './constants.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* WebSocket frame header
|
|
9
|
-
*/
|
|
10
|
-
export interface IWebSocketFrameHeader {
|
|
11
|
-
fin: boolean;
|
|
12
|
-
rsv1: boolean;
|
|
13
|
-
rsv2: boolean;
|
|
14
|
-
rsv3: boolean;
|
|
15
|
-
opcode: WebSocketOpcode;
|
|
16
|
-
masked: boolean;
|
|
17
|
-
payloadLength: number;
|
|
18
|
-
maskingKey?: Buffer;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* WebSocket frame
|
|
23
|
-
*/
|
|
24
|
-
export interface IWebSocketFrame {
|
|
25
|
-
header: IWebSocketFrameHeader;
|
|
26
|
-
payload: Buffer;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* WebSocket close frame payload
|
|
31
|
-
*/
|
|
32
|
-
export interface IWebSocketClosePayload {
|
|
33
|
-
code: WebSocketCloseCode;
|
|
34
|
-
reason?: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* WebSocket handshake request headers
|
|
39
|
-
*/
|
|
40
|
-
export interface IWebSocketHandshakeHeaders {
|
|
41
|
-
upgrade: string;
|
|
42
|
-
connection: string;
|
|
43
|
-
'sec-websocket-key': string;
|
|
44
|
-
'sec-websocket-version': string;
|
|
45
|
-
'sec-websocket-protocol'?: string;
|
|
46
|
-
'sec-websocket-extensions'?: string;
|
|
47
|
-
[key: string]: string | undefined;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Type for WebSocket raw data (matching ws library)
|
|
52
|
-
*/
|
|
53
|
-
export type RawData = Buffer | ArrayBuffer | Buffer[] | any;
|