@erfan_bahramali/tping 1.0.0 → 1.1.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 +76 -55
- package/dist/crypto/x25519.d.ts +10 -0
- package/dist/crypto/x25519.d.ts.map +1 -0
- package/dist/crypto/x25519.js +51 -0
- package/dist/crypto/x25519.js.map +1 -0
- package/dist/index.js +82 -39
- package/dist/index.js.map +1 -1
- package/dist/lib/attempt.d.ts +31 -0
- package/dist/lib/attempt.d.ts.map +1 -0
- package/dist/lib/attempt.js +94 -0
- package/dist/lib/attempt.js.map +1 -0
- package/dist/lib/checker.d.ts +21 -3
- package/dist/lib/checker.d.ts.map +1 -1
- package/dist/lib/checker.js +133 -49
- package/dist/lib/checker.js.map +1 -1
- package/dist/lib/datacenters.d.ts +15 -0
- package/dist/lib/datacenters.d.ts.map +1 -0
- package/dist/lib/datacenters.js +20 -0
- package/dist/lib/datacenters.js.map +1 -0
- package/dist/lib/parser.d.ts +18 -3
- package/dist/lib/parser.d.ts.map +1 -1
- package/dist/lib/parser.js +174 -78
- package/dist/lib/parser.js.map +1 -1
- package/dist/lib/ping.d.ts +13 -6
- package/dist/lib/ping.d.ts.map +1 -1
- package/dist/lib/ping.js +44 -44
- package/dist/lib/ping.js.map +1 -1
- package/dist/mtproto/exchange.d.ts +10 -0
- package/dist/mtproto/exchange.d.ts.map +1 -0
- package/dist/mtproto/exchange.js +20 -0
- package/dist/mtproto/exchange.js.map +1 -0
- package/dist/mtproto/fake-tls.d.ts +36 -44
- package/dist/mtproto/fake-tls.d.ts.map +1 -1
- package/dist/mtproto/fake-tls.js +174 -148
- package/dist/mtproto/fake-tls.js.map +1 -1
- package/dist/mtproto/messages.d.ts +23 -36
- package/dist/mtproto/messages.d.ts.map +1 -1
- package/dist/mtproto/messages.js +64 -90
- package/dist/mtproto/messages.js.map +1 -1
- package/dist/mtproto/obfuscation.d.ts +23 -20
- package/dist/mtproto/obfuscation.d.ts.map +1 -1
- package/dist/mtproto/obfuscation.js +64 -64
- package/dist/mtproto/obfuscation.js.map +1 -1
- package/dist/mtproto/secret.d.ts +28 -0
- package/dist/mtproto/secret.d.ts.map +1 -0
- package/dist/mtproto/secret.js +68 -0
- package/dist/mtproto/secret.js.map +1 -0
- package/dist/mtproto/transport.d.ts +28 -0
- package/dist/mtproto/transport.d.ts.map +1 -0
- package/dist/mtproto/transport.js +78 -0
- package/dist/mtproto/transport.js.map +1 -0
- package/dist/net/http-client.d.ts +37 -0
- package/dist/net/http-client.d.ts.map +1 -0
- package/dist/net/http-client.js +93 -0
- package/dist/net/http-client.js.map +1 -0
- package/dist/net/http-proxy.d.ts +26 -0
- package/dist/net/http-proxy.d.ts.map +1 -0
- package/dist/net/http-proxy.js +71 -0
- package/dist/net/http-proxy.js.map +1 -0
- package/dist/net/socks5.d.ts +15 -0
- package/dist/net/socks5.d.ts.map +1 -0
- package/dist/net/socks5.js +112 -0
- package/dist/net/socks5.js.map +1 -0
- package/dist/net/stream.d.ts +54 -0
- package/dist/net/stream.d.ts.map +1 -0
- package/dist/net/stream.js +142 -0
- package/dist/net/stream.js.map +1 -0
- package/dist/net/websocket.d.ts +19 -0
- package/dist/net/websocket.d.ts.map +1 -0
- package/dist/net/websocket.js +123 -0
- package/dist/net/websocket.js.map +1 -0
- package/dist/types/index.d.ts +40 -17
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/format.d.ts +7 -14
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +101 -87
- package/dist/utils/format.js.map +1 -1
- package/dist/webproxy/check.d.ts +15 -0
- package/dist/webproxy/check.d.ts.map +1 -0
- package/dist/webproxy/check.js +423 -0
- package/dist/webproxy/check.js.map +1 -0
- package/dist/webproxy/frames.d.ts +30 -0
- package/dist/webproxy/frames.d.ts.map +1 -0
- package/dist/webproxy/frames.js +59 -0
- package/dist/webproxy/frames.js.map +1 -0
- package/dist/webproxy/link.d.ts +27 -0
- package/dist/webproxy/link.d.ts.map +1 -0
- package/dist/webproxy/link.js +107 -0
- package/dist/webproxy/link.js.map +1 -0
- package/package.json +16 -11
- package/dist/mtproto/connection.d.ts +0 -59
- package/dist/mtproto/connection.d.ts.map +0 -1
- package/dist/mtproto/connection.js +0 -198
- package/dist/mtproto/connection.js.map +0 -1
- package/dist/mtproto/socks5.d.ts +0 -36
- package/dist/mtproto/socks5.d.ts.map +0 -1
- package/dist/mtproto/socks5.js +0 -148
- package/dist/mtproto/socks5.js.map +0 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createHmac } from 'crypto';
|
|
2
|
+
import { isIP } from 'net';
|
|
3
|
+
import { domainToASCII } from 'url';
|
|
4
|
+
/**
|
|
5
|
+
* WEB proxy addressing and secrets, per telegramdesktop/tproxy-server
|
|
6
|
+
* (PROTOCOL.md, BASE_PATH.md).
|
|
7
|
+
*/
|
|
8
|
+
const MAX_BASE_PATH = 128;
|
|
9
|
+
const PATH_MARKER = 0x70;
|
|
10
|
+
const toAscii = (host) => domainToASCII(host.toLowerCase());
|
|
11
|
+
export const validateHostname = (host) => {
|
|
12
|
+
if (!host || host.length > 253 || host.endsWith('.') || /[:/@?#[\]]/.test(host)) {
|
|
13
|
+
return 'must be a DNS hostname without scheme, port, path, query or trailing dot';
|
|
14
|
+
}
|
|
15
|
+
if (isIP(host) || !host.includes('.')) {
|
|
16
|
+
return 'IP addresses and single-label names are not allowed';
|
|
17
|
+
}
|
|
18
|
+
for (const label of host.split('.')) {
|
|
19
|
+
if (!label || label.length > 63 || label.startsWith('-') || label.endsWith('-') || !/^[a-z0-9-]+$/.test(label)) {
|
|
20
|
+
return 'invalid DNS label';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
};
|
|
25
|
+
export const validateBasePath = (path) => {
|
|
26
|
+
if (path === '') {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
if (path.length > MAX_BASE_PATH) {
|
|
30
|
+
return `base path must be at most ${MAX_BASE_PATH} characters`;
|
|
31
|
+
}
|
|
32
|
+
return path.split('/').every((segment) => /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(segment))
|
|
33
|
+
? null
|
|
34
|
+
: 'base path segments must match [A-Za-z0-9][A-Za-z0-9_-]*';
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Parse the `server` field: `host` or `host/base/path`.
|
|
38
|
+
*/
|
|
39
|
+
export const parseWebProxyServer = (value) => {
|
|
40
|
+
const trimmed = value.trim();
|
|
41
|
+
const slash = trimmed.indexOf('/');
|
|
42
|
+
const rawHost = slash === -1 ? trimmed : trimmed.slice(0, slash);
|
|
43
|
+
const basePath = slash === -1 ? '' : trimmed.slice(slash + 1);
|
|
44
|
+
const host = toAscii(rawHost);
|
|
45
|
+
const hostError = host ? validateHostname(host) : 'invalid hostname';
|
|
46
|
+
if (hostError) {
|
|
47
|
+
return `server ${hostError}`;
|
|
48
|
+
}
|
|
49
|
+
if (slash !== -1 && basePath === '') {
|
|
50
|
+
return 'base path must not be empty';
|
|
51
|
+
}
|
|
52
|
+
const pathError = validateBasePath(basePath);
|
|
53
|
+
return pathError ?? { host, basePath };
|
|
54
|
+
};
|
|
55
|
+
const decodeRaw = (value) => {
|
|
56
|
+
const text = value.trim();
|
|
57
|
+
if ((text.length === 32 || text.length === 34) && /^[0-9a-fA-F]+$/.test(text)) {
|
|
58
|
+
return Buffer.from(text, 'hex');
|
|
59
|
+
}
|
|
60
|
+
if (/^[A-Za-z0-9_-]+={0,2}$/.test(text) || /^[A-Za-z0-9+/]+={0,2}$/.test(text)) {
|
|
61
|
+
const decoded = Buffer.from(text.replace(/-/g, '+').replace(/_/g, '/').replace(/=+$/, ''), 'base64');
|
|
62
|
+
return decoded.length > 0 ? decoded : null;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Decode a WEB proxy secret. A link with a base path must carry the marked
|
|
68
|
+
* form (0x70 || secret, base64url); the marker is stripped.
|
|
69
|
+
*
|
|
70
|
+
* @returns the MTProxy secret bytes (16, or 17 starting with 0xdd), or an error message
|
|
71
|
+
*/
|
|
72
|
+
export const decodeWebSecret = (value, hasBasePath) => {
|
|
73
|
+
if (/^ee[0-9a-f]{34,}$/i.test(value.trim())) {
|
|
74
|
+
return 'WEB proxies do not support Fake TLS (ee) secrets';
|
|
75
|
+
}
|
|
76
|
+
let bytes = decodeRaw(value);
|
|
77
|
+
if (!bytes) {
|
|
78
|
+
return 'secret is neither hex nor base64url';
|
|
79
|
+
}
|
|
80
|
+
const marked = bytes.length >= 17 && bytes[0] === PATH_MARKER;
|
|
81
|
+
if (marked) {
|
|
82
|
+
bytes = bytes.subarray(1);
|
|
83
|
+
}
|
|
84
|
+
if (hasBasePath && !marked) {
|
|
85
|
+
return 'a WEB proxy link with a base path must use the marked secret form';
|
|
86
|
+
}
|
|
87
|
+
if (bytes.length > 17 && bytes[0] === 0xee) {
|
|
88
|
+
return 'WEB proxies do not support Fake TLS (ee) secrets';
|
|
89
|
+
}
|
|
90
|
+
if (bytes.length === 16 || (bytes.length === 17 && bytes[0] === 0xdd)) {
|
|
91
|
+
return Buffer.from(bytes);
|
|
92
|
+
}
|
|
93
|
+
return 'WEB proxy secret must be 16 bytes, optionally prefixed with dd';
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Bridge capability: base64url(HMAC-SHA256(secret, context)), where context
|
|
97
|
+
* binds the hostname (v1) or the hostname and base path (v2).
|
|
98
|
+
*/
|
|
99
|
+
export const deriveCapability = (address, secret) => {
|
|
100
|
+
const context = address.basePath === ''
|
|
101
|
+
? `tdesktop-web-proxy-bridge-v1\n${address.host}`
|
|
102
|
+
: `tdesktop-web-proxy-bridge-v2\n${address.host}\n${address.basePath}`;
|
|
103
|
+
return createHmac('sha256', secret).update(context, 'utf8').digest('base64url');
|
|
104
|
+
};
|
|
105
|
+
/** Path prefix of every relay endpoint: "/" or "/<base>/". */
|
|
106
|
+
export const basePrefix = (basePath) => (basePath === '' ? '/' : `/${basePath}/`);
|
|
107
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/webproxy/link.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@erfan_bahramali/tping",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Ping for Telegram Proxies -
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Ping for Telegram Proxies - real MTProto handshake through MTProto (simple, dd, Fake TLS), SOCKS5 and HTTP proxies",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"telegram",
|
|
7
|
-
"mtproto",
|
|
8
|
-
"proxy",
|
|
9
6
|
"checker",
|
|
10
7
|
"cli",
|
|
11
|
-
"validator",
|
|
12
|
-
"ping",
|
|
13
8
|
"connection-test",
|
|
14
|
-
"
|
|
9
|
+
"fake-tls",
|
|
10
|
+
"mtproto",
|
|
11
|
+
"mtproxy",
|
|
12
|
+
"network-tool",
|
|
13
|
+
"ping",
|
|
14
|
+
"proxy",
|
|
15
|
+
"socks5",
|
|
16
|
+
"telegram",
|
|
17
|
+
"validator"
|
|
15
18
|
],
|
|
16
19
|
"author": "Erfan Bahramali",
|
|
17
20
|
"license": "MIT",
|
|
@@ -34,10 +37,12 @@
|
|
|
34
37
|
},
|
|
35
38
|
"scripts": {
|
|
36
39
|
"dev": "bun src/index.ts",
|
|
37
|
-
"clean": "
|
|
40
|
+
"clean": "rm -rf dist",
|
|
38
41
|
"prebuild": "bun run clean",
|
|
39
|
-
"build": "
|
|
40
|
-
"
|
|
42
|
+
"build": "tsc",
|
|
43
|
+
"test": "bun test",
|
|
44
|
+
"typecheck": "tsc --noEmit",
|
|
45
|
+
"prepublishOnly": "bun run typecheck && bun test && bun run build"
|
|
41
46
|
},
|
|
42
47
|
"files": [
|
|
43
48
|
"dist",
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
export interface MTProtoConnectionOptions {
|
|
2
|
-
host: string;
|
|
3
|
-
port: number;
|
|
4
|
-
secret: string;
|
|
5
|
-
dcId?: number;
|
|
6
|
-
timeout?: number;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* MTProto proxy connection supporting both simple (dd) and fake TLS (ee) modes.
|
|
10
|
-
*
|
|
11
|
-
* A ping is a real MTProto handshake: req_pq_multi is sent and a valid ResPQ
|
|
12
|
-
* must come back from the Telegram datacenter. In fake TLS mode the proxy's
|
|
13
|
-
* ServerHello is also verified against an HMAC of the proxy secret, so a wrong
|
|
14
|
-
* secret is detected immediately.
|
|
15
|
-
*/
|
|
16
|
-
export declare class MTProtoConnection {
|
|
17
|
-
private options;
|
|
18
|
-
private socket;
|
|
19
|
-
private encryptor?;
|
|
20
|
-
private decryptor?;
|
|
21
|
-
private isFakeTLS;
|
|
22
|
-
private receiveBuffer;
|
|
23
|
-
private pending;
|
|
24
|
-
private phase;
|
|
25
|
-
private clientRandom?;
|
|
26
|
-
constructor(options: MTProtoConnectionOptions);
|
|
27
|
-
/**
|
|
28
|
-
* Connect to the MTProto proxy and perform the obfuscation (+ fake TLS) handshake.
|
|
29
|
-
* Resolves only after the proxy's ServerHello is HMAC-verified (fake TLS mode).
|
|
30
|
-
*/
|
|
31
|
-
connect(): Promise<void>;
|
|
32
|
-
/**
|
|
33
|
-
* Send a real MTProto ping: req_pq_multi and wait for a valid ResPQ.
|
|
34
|
-
*
|
|
35
|
-
* @returns Round-trip time in ms
|
|
36
|
-
*/
|
|
37
|
-
ping(timeout?: number): Promise<number>;
|
|
38
|
-
/**
|
|
39
|
-
* Connect + single real ping in one call. Closes the connection afterwards.
|
|
40
|
-
*/
|
|
41
|
-
static pingOnce(options: MTProtoConnectionOptions, timeout?: number): Promise<number>;
|
|
42
|
-
/**
|
|
43
|
-
* Handle incoming socket data depending on the current phase.
|
|
44
|
-
*/
|
|
45
|
-
private onData;
|
|
46
|
-
/**
|
|
47
|
-
* Wait until the FakeTLS ServerHello can be verified.
|
|
48
|
-
*/
|
|
49
|
-
private awaitVerdict;
|
|
50
|
-
/**
|
|
51
|
-
* Reject any pending waiters (socket closed mid-handshake/ping).
|
|
52
|
-
*/
|
|
53
|
-
private failPending;
|
|
54
|
-
/**
|
|
55
|
-
* Close the connection.
|
|
56
|
-
*/
|
|
57
|
-
close(): void;
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/mtproto/connection.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAUhB,OAAO,CAAC,OAAO;IAT3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,YAAY,CAAC,CAAS;gBAEV,OAAO,EAAE,wBAAwB;IAOrD;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6C9B;;;;OAIG;IACG,IAAI,CAAC,OAAO,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IA2C5C;;OAEG;WACU,QAAQ,CAAC,OAAO,EAAE,wBAAwB,EAAE,OAAO,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAU1F;;OAEG;IACH,OAAO,CAAC,MAAM;IA4Bd;;OAEG;YACW,YAAY;IAyB1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { Socket } from 'net';
|
|
2
|
-
import { randomBytes } from 'crypto';
|
|
3
|
-
import { initObfuscation } from './obfuscation.js';
|
|
4
|
-
import { parseSecret, generateFakeTLSClientHello, wrapInTLSRecords, extractTlsRecords, tryVerifyFakeTLSServerHello, } from './fake-tls.js';
|
|
5
|
-
import { buildReqPqMulti, buildUnencryptedMessage, generateMessageId, parseResPQ, } from './messages.js';
|
|
6
|
-
/**
|
|
7
|
-
* MTProto proxy connection supporting both simple (dd) and fake TLS (ee) modes.
|
|
8
|
-
*
|
|
9
|
-
* A ping is a real MTProto handshake: req_pq_multi is sent and a valid ResPQ
|
|
10
|
-
* must come back from the Telegram datacenter. In fake TLS mode the proxy's
|
|
11
|
-
* ServerHello is also verified against an HMAC of the proxy secret, so a wrong
|
|
12
|
-
* secret is detected immediately.
|
|
13
|
-
*/
|
|
14
|
-
export class MTProtoConnection {
|
|
15
|
-
options;
|
|
16
|
-
socket;
|
|
17
|
-
encryptor;
|
|
18
|
-
decryptor;
|
|
19
|
-
isFakeTLS = false;
|
|
20
|
-
receiveBuffer = Buffer.alloc(0);
|
|
21
|
-
pending = null;
|
|
22
|
-
phase = 'handshake';
|
|
23
|
-
clientRandom;
|
|
24
|
-
constructor(options) {
|
|
25
|
-
this.options = options;
|
|
26
|
-
this.socket = new Socket();
|
|
27
|
-
this.socket.on('data', (data) => this.onData(data));
|
|
28
|
-
this.socket.on('error', () => { });
|
|
29
|
-
this.socket.on('close', () => this.failPending('Connection closed by proxy'));
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Connect to the MTProto proxy and perform the obfuscation (+ fake TLS) handshake.
|
|
33
|
-
* Resolves only after the proxy's ServerHello is HMAC-verified (fake TLS mode).
|
|
34
|
-
*/
|
|
35
|
-
async connect() {
|
|
36
|
-
const { host, port, secret, dcId = 2, timeout = 10000 } = this.options;
|
|
37
|
-
const parsed = parseSecret(secret);
|
|
38
|
-
this.isFakeTLS = parsed.isFakeTLS;
|
|
39
|
-
const { header, encryptor, decryptor } = initObfuscation(parsed.secret, dcId);
|
|
40
|
-
this.encryptor = encryptor;
|
|
41
|
-
this.decryptor = decryptor;
|
|
42
|
-
await new Promise((resolve, reject) => {
|
|
43
|
-
const timer = setTimeout(() => {
|
|
44
|
-
this.socket.destroy();
|
|
45
|
-
reject(new Error('Connection timeout'));
|
|
46
|
-
}, timeout);
|
|
47
|
-
const onError = (err) => {
|
|
48
|
-
clearTimeout(timer);
|
|
49
|
-
reject(err);
|
|
50
|
-
};
|
|
51
|
-
this.socket.once('error', onError);
|
|
52
|
-
this.socket.connect(port, host, () => {
|
|
53
|
-
clearTimeout(timer);
|
|
54
|
-
this.socket.off('error', onError);
|
|
55
|
-
resolve();
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
this.socket.write(header);
|
|
59
|
-
if (this.isFakeTLS && parsed.domain) {
|
|
60
|
-
const clientHello = generateFakeTLSClientHello(parsed.domain, parsed.secret);
|
|
61
|
-
this.clientRandom = clientHello.subarray(11, 43);
|
|
62
|
-
this.socket.write(clientHello);
|
|
63
|
-
// ServerHello = ServerHello + ChangeCipherSpec + one ApplicationData record.
|
|
64
|
-
const verdict = await this.awaitVerdict(parsed.secret, timeout);
|
|
65
|
-
if (verdict === 'invalid') {
|
|
66
|
-
throw new Error('FakeTLS handshake failed (bad secret or not a proxy)');
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Send a real MTProto ping: req_pq_multi and wait for a valid ResPQ.
|
|
72
|
-
*
|
|
73
|
-
* @returns Round-trip time in ms
|
|
74
|
-
*/
|
|
75
|
-
async ping(timeout = 10000) {
|
|
76
|
-
if (!this.encryptor || !this.decryptor) {
|
|
77
|
-
throw new Error('Not connected');
|
|
78
|
-
}
|
|
79
|
-
const nonce = randomBytes(16);
|
|
80
|
-
const message = buildUnencryptedMessage(buildReqPqMulti(nonce), generateMessageId());
|
|
81
|
-
// Intermediate transport framing: 4-byte LE length prefix before the message.
|
|
82
|
-
const framed = Buffer.alloc(4 + message.length);
|
|
83
|
-
framed.writeUInt32LE(message.length, 0);
|
|
84
|
-
message.copy(framed, 4);
|
|
85
|
-
const payload = this.isFakeTLS
|
|
86
|
-
? wrapInTLSRecords(this.encryptor.encrypt(framed))
|
|
87
|
-
: this.encryptor.encrypt(framed);
|
|
88
|
-
const start = Date.now();
|
|
89
|
-
this.phase = 'ping';
|
|
90
|
-
this.receiveBuffer = Buffer.alloc(0);
|
|
91
|
-
const response = await new Promise((resolve, reject) => {
|
|
92
|
-
const timer = setTimeout(() => {
|
|
93
|
-
this.pending = null;
|
|
94
|
-
reject(new Error('Ping timeout'));
|
|
95
|
-
}, timeout);
|
|
96
|
-
this.pending = (data) => {
|
|
97
|
-
clearTimeout(timer);
|
|
98
|
-
this.pending = null;
|
|
99
|
-
resolve(data);
|
|
100
|
-
};
|
|
101
|
-
this.socket.write(payload);
|
|
102
|
-
});
|
|
103
|
-
this.phase = 'done';
|
|
104
|
-
const parsed = parseResPQ(response);
|
|
105
|
-
if (!parsed || !parsed.nonce.equals(nonce)) {
|
|
106
|
-
throw new Error('Invalid ResPQ response');
|
|
107
|
-
}
|
|
108
|
-
return Date.now() - start;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Connect + single real ping in one call. Closes the connection afterwards.
|
|
112
|
-
*/
|
|
113
|
-
static async pingOnce(options, timeout = 10000) {
|
|
114
|
-
const conn = new MTProtoConnection(options);
|
|
115
|
-
try {
|
|
116
|
-
await conn.connect();
|
|
117
|
-
return await conn.ping(timeout);
|
|
118
|
-
}
|
|
119
|
-
finally {
|
|
120
|
-
conn.close();
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Handle incoming socket data depending on the current phase.
|
|
125
|
-
*/
|
|
126
|
-
onData(data) {
|
|
127
|
-
if (this.phase === 'handshake') {
|
|
128
|
-
this.receiveBuffer = Buffer.concat([this.receiveBuffer, data]);
|
|
129
|
-
const handler = this.pending;
|
|
130
|
-
if (handler)
|
|
131
|
-
handler(this.receiveBuffer);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (this.phase !== 'ping' || !this.decryptor) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
// Ping phase: decrypt, strip TLS records, feed the MTProto stream.
|
|
138
|
-
const decrypted = this.decryptor.encrypt(data);
|
|
139
|
-
const { payload } = this.isFakeTLS ? extractTlsRecords(decrypted) : { payload: decrypted };
|
|
140
|
-
this.receiveBuffer = Buffer.concat([this.receiveBuffer, payload]);
|
|
141
|
-
// Intermediate framed message: 4-byte LE length then the message.
|
|
142
|
-
// Pass the whole frame (length prefix included) so parseResPQ sees it.
|
|
143
|
-
if (this.receiveBuffer.length >= 4) {
|
|
144
|
-
const len = this.receiveBuffer.readUInt32LE(0);
|
|
145
|
-
if (this.receiveBuffer.length >= 4 + len) {
|
|
146
|
-
const handler = this.pending;
|
|
147
|
-
if (handler)
|
|
148
|
-
handler(this.receiveBuffer.subarray(0, 4 + len));
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Wait until the FakeTLS ServerHello can be verified.
|
|
154
|
-
*/
|
|
155
|
-
async awaitVerdict(proxySecret, timeout) {
|
|
156
|
-
const clientRandom = this.clientRandom;
|
|
157
|
-
const started = this.receiveBuffer;
|
|
158
|
-
this.receiveBuffer = Buffer.alloc(0);
|
|
159
|
-
return new Promise((resolve, reject) => {
|
|
160
|
-
const timer = setTimeout(() => {
|
|
161
|
-
this.pending = null;
|
|
162
|
-
reject(new Error('FakeTLS handshake timeout'));
|
|
163
|
-
}, timeout);
|
|
164
|
-
const check = (data) => {
|
|
165
|
-
const verdict = tryVerifyFakeTLSServerHello(data, clientRandom, proxySecret);
|
|
166
|
-
if (verdict !== 'incomplete') {
|
|
167
|
-
clearTimeout(timer);
|
|
168
|
-
this.pending = null;
|
|
169
|
-
resolve(verdict);
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
this.pending = check;
|
|
173
|
-
if (started.length > 0)
|
|
174
|
-
check(started);
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Reject any pending waiters (socket closed mid-handshake/ping).
|
|
179
|
-
*/
|
|
180
|
-
failPending(_reason) {
|
|
181
|
-
const handler = this.pending;
|
|
182
|
-
this.pending = null;
|
|
183
|
-
if (handler) {
|
|
184
|
-
if (this.phase === 'ping') {
|
|
185
|
-
handler(Buffer.alloc(0)); // empty data -> parse fails -> error surfaces
|
|
186
|
-
}
|
|
187
|
-
// Handshake waiters resolve via their timeout; socket is gone anyway.
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Close the connection.
|
|
192
|
-
*/
|
|
193
|
-
close() {
|
|
194
|
-
this.phase = 'done';
|
|
195
|
-
this.socket.destroy();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
//# sourceMappingURL=connection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/mtproto/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/mtproto/socks5.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export interface SOCKS5Options {
|
|
2
|
-
host: string;
|
|
3
|
-
port: number;
|
|
4
|
-
username?: string;
|
|
5
|
-
password?: string;
|
|
6
|
-
timeout?: number;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Simple SOCKS5 client for testing proxy connectivity.
|
|
10
|
-
* Connects to Telegram servers through SOCKS5 proxy.
|
|
11
|
-
*/
|
|
12
|
-
export declare class SOCKS5Client {
|
|
13
|
-
private options;
|
|
14
|
-
private socket;
|
|
15
|
-
private connected;
|
|
16
|
-
constructor(options: SOCKS5Options);
|
|
17
|
-
/**
|
|
18
|
-
* Connect to SOCKS5 proxy and authenticate.
|
|
19
|
-
*/
|
|
20
|
-
connect(): Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* Authenticate with username/password.
|
|
23
|
-
*/
|
|
24
|
-
private authenticate;
|
|
25
|
-
/**
|
|
26
|
-
* Test connection by connecting to Telegram server through SOCKS5.
|
|
27
|
-
*
|
|
28
|
-
* @returns True if connection successful
|
|
29
|
-
*/
|
|
30
|
-
testConnection(): Promise<boolean>;
|
|
31
|
-
/**
|
|
32
|
-
* Close the connection.
|
|
33
|
-
*/
|
|
34
|
-
close(): void;
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=socks5.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"socks5.d.ts","sourceRoot":"","sources":["../../src/mtproto/socks5.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,YAAY;IAIX,OAAO,CAAC,OAAO;IAH3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAkB;gBAEf,OAAO,EAAE,aAAa;IAI1C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA4D9B;;OAEG;YACW,YAAY;IA2B1B;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IA0CxC;;OAEG;IACH,KAAK,IAAI,IAAI;CAMd"}
|
package/dist/mtproto/socks5.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { Socket } from 'net';
|
|
2
|
-
/**
|
|
3
|
-
* Simple SOCKS5 client for testing proxy connectivity.
|
|
4
|
-
* Connects to Telegram servers through SOCKS5 proxy.
|
|
5
|
-
*/
|
|
6
|
-
export class SOCKS5Client {
|
|
7
|
-
options;
|
|
8
|
-
socket;
|
|
9
|
-
connected = false;
|
|
10
|
-
constructor(options) {
|
|
11
|
-
this.options = options;
|
|
12
|
-
this.socket = new Socket();
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Connect to SOCKS5 proxy and authenticate.
|
|
16
|
-
*/
|
|
17
|
-
async connect() {
|
|
18
|
-
const { host, port, username, password, timeout = 10000 } = this.options;
|
|
19
|
-
return new Promise((resolve, reject) => {
|
|
20
|
-
const timer = setTimeout(() => {
|
|
21
|
-
this.socket.destroy();
|
|
22
|
-
reject(new Error('Connection timeout'));
|
|
23
|
-
}, timeout);
|
|
24
|
-
this.socket.on('error', (err) => {
|
|
25
|
-
clearTimeout(timer);
|
|
26
|
-
reject(err);
|
|
27
|
-
});
|
|
28
|
-
this.socket.connect(port, host, () => {
|
|
29
|
-
clearTimeout(timer);
|
|
30
|
-
// SOCKS5 handshake
|
|
31
|
-
const authMethods = username && password ? [0x00, 0x02] : [0x00]; // No auth or Username/Password
|
|
32
|
-
const handshake = Buffer.from([
|
|
33
|
-
0x05, // SOCKS version 5
|
|
34
|
-
authMethods.length, // Number of methods
|
|
35
|
-
...authMethods,
|
|
36
|
-
]);
|
|
37
|
-
this.socket.write(handshake);
|
|
38
|
-
this.socket.once('data', async (data) => {
|
|
39
|
-
try {
|
|
40
|
-
// Check SOCKS5 response
|
|
41
|
-
if (data[0] !== 0x05) {
|
|
42
|
-
throw new Error('Invalid SOCKS5 response');
|
|
43
|
-
}
|
|
44
|
-
const authMethod = data[1];
|
|
45
|
-
// If username/password auth required
|
|
46
|
-
if (authMethod === 0x02) {
|
|
47
|
-
if (!username || !password) {
|
|
48
|
-
throw new Error('Authentication required but not provided');
|
|
49
|
-
}
|
|
50
|
-
await this.authenticate(username, password);
|
|
51
|
-
}
|
|
52
|
-
else if (authMethod === 0x00) {
|
|
53
|
-
// No authentication required
|
|
54
|
-
this.connected = true;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
throw new Error('Unsupported authentication method');
|
|
58
|
-
}
|
|
59
|
-
resolve();
|
|
60
|
-
}
|
|
61
|
-
catch (err) {
|
|
62
|
-
this.socket.destroy();
|
|
63
|
-
reject(err);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Authenticate with username/password.
|
|
71
|
-
*/
|
|
72
|
-
async authenticate(username, password) {
|
|
73
|
-
return new Promise((resolve, reject) => {
|
|
74
|
-
const userBuf = Buffer.from(username, 'utf8');
|
|
75
|
-
const passBuf = Buffer.from(password, 'utf8');
|
|
76
|
-
const authPacket = Buffer.concat([
|
|
77
|
-
Buffer.from([0x01]), // Auth version
|
|
78
|
-
Buffer.from([userBuf.length]),
|
|
79
|
-
userBuf,
|
|
80
|
-
Buffer.from([passBuf.length]),
|
|
81
|
-
passBuf,
|
|
82
|
-
]);
|
|
83
|
-
this.socket.write(authPacket);
|
|
84
|
-
this.socket.once('data', (data) => {
|
|
85
|
-
if (data[0] === 0x01 && data[1] === 0x00) {
|
|
86
|
-
this.connected = true;
|
|
87
|
-
resolve();
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
this.socket.destroy();
|
|
91
|
-
reject(new Error('Authentication failed'));
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Test connection by connecting to Telegram server through SOCKS5.
|
|
98
|
-
*
|
|
99
|
-
* @returns True if connection successful
|
|
100
|
-
*/
|
|
101
|
-
async testConnection() {
|
|
102
|
-
if (!this.connected) {
|
|
103
|
-
throw new Error('Not connected to SOCKS5 proxy');
|
|
104
|
-
}
|
|
105
|
-
return new Promise((resolve) => {
|
|
106
|
-
// Connect to Telegram server
|
|
107
|
-
const telegramHost = '149.154.167.50'; // DC 2
|
|
108
|
-
const telegramPort = 443;
|
|
109
|
-
const hostBuf = Buffer.from(telegramHost, 'utf8');
|
|
110
|
-
const connectCmd = Buffer.concat([
|
|
111
|
-
Buffer.from([
|
|
112
|
-
0x05, // SOCKS version
|
|
113
|
-
0x01, // Connect command
|
|
114
|
-
0x00, // Reserved
|
|
115
|
-
0x03, // Domain name
|
|
116
|
-
hostBuf.length, // Domain length
|
|
117
|
-
]),
|
|
118
|
-
hostBuf,
|
|
119
|
-
Buffer.from([
|
|
120
|
-
(telegramPort >> 8) & 0xff, // Port high byte
|
|
121
|
-
telegramPort & 0xff, // Port low byte
|
|
122
|
-
]),
|
|
123
|
-
]);
|
|
124
|
-
this.socket.write(connectCmd);
|
|
125
|
-
this.socket.once('data', (data) => {
|
|
126
|
-
// Check SOCKS5 response
|
|
127
|
-
if (data[0] === 0x05 && data[1] === 0x00) {
|
|
128
|
-
// Success
|
|
129
|
-
resolve(true);
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
resolve(false);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
setTimeout(() => resolve(false), 5000);
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Close the connection.
|
|
140
|
-
*/
|
|
141
|
-
close() {
|
|
142
|
-
if (this.socket) {
|
|
143
|
-
this.socket.destroy();
|
|
144
|
-
this.connected = false;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
//# sourceMappingURL=socks5.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"socks5.js","sourceRoot":"","sources":["../../src/mtproto/socks5.ts"],"names":[],"mappings":"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"}
|