@libp2p/webrtc 6.0.27-05b15b2b1 → 6.0.27-68794c8e2
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/dist/index.min.js +15 -15
- package/dist/index.min.js.map +3 -3
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +1 -0
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +18 -12
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -1
- package/dist/src/private-to-public/utils/stun-listener.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/stun-listener.js +2 -5
- package/dist/src/private-to-public/utils/stun-listener.js.map +1 -1
- package/dist/src/util.d.ts +4 -2
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +21 -0
- package/dist/src/util.js.map +1 -1
- package/package.json +9 -9
- package/src/private-to-public/utils/get-rtcpeerconnection.ts +21 -12
- package/src/private-to-public/utils/stun-listener.ts +2 -7
- package/src/util.ts +29 -2
|
@@ -14,6 +14,7 @@ export declare class DirectRTCPeerConnection extends RTCPeerConnection {
|
|
|
14
14
|
constructor(init: DirectRTCPeerConnectionInit);
|
|
15
15
|
createOffer(): Promise<globalThis.RTCSessionDescriptionInit | any>;
|
|
16
16
|
createAnswer(): Promise<globalThis.RTCSessionDescriptionInit | any>;
|
|
17
|
+
private setLocalUfrag;
|
|
17
18
|
remoteFingerprint(): CertificateFingerprint;
|
|
18
19
|
}
|
|
19
20
|
export interface CreateDialerRTCPeerConnectionOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-rtcpeerconnection.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/get-rtcpeerconnection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-rtcpeerconnection.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/get-rtcpeerconnection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAE7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAGxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAI9D,UAAU,2BAA4B,SAAQ,gBAAgB;IAC5D,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,cAAc,CAAA;CAC/B;AAED,qBAAa,uBAAwB,SAAQ,iBAAiB;IAC5D,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;gBAEjB,IAAI,EAAE,2BAA2B;IAmBxC,WAAW,IAAK,OAAO,CAAC,UAAU,CAAC,yBAAyB,GAAG,GAAG,CAAC;IAOnE,YAAY,IAAK,OAAO,CAAC,UAAU,CAAC,yBAAyB,GAAG,GAAG,CAAC;IAS1E,OAAO,CAAC,aAAa;IAerB,iBAAiB,IAAK,sBAAsB;CAO7C;AAkBD,MAAM,WAAW,oCAAoC;IACnD,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAA;IAC1F,WAAW,CAAC,EAAE,oBAAoB,CAAA;IAClC,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,WAAW,CAAC,EAAE,kBAAkB,CAAA;CACjC;AAED,wBAAsB,6BAA6B,CAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oCAAoC,GAAG,OAAO,CAAC;IAAE,cAAc,EAAE,UAAU,CAAC,iBAAiB,CAAC;IAAC,YAAY,EAAE,uBAAuB,CAAA;CAAE,CAAC,CAAA;AACrO,wBAAsB,6BAA6B,CAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oCAAoC,GAAG,OAAO,CAAC;IAAE,cAAc,EAAE,uBAAuB,CAAC;IAAC,YAAY,EAAE,uBAAuB,CAAA;CAAE,CAAC,CAAA"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { InvalidParametersError } from '@libp2p/interface';
|
|
1
2
|
import { Crypto } from '@peculiar/webcrypto';
|
|
2
3
|
import { PeerConnection } from 'node-datachannel';
|
|
3
4
|
import { RTCPeerConnection } from 'node-datachannel/polyfill';
|
|
4
5
|
import { DEFAULT_ICE_SERVERS, MAX_MESSAGE_SIZE } from "../../constants.js";
|
|
5
6
|
import { DataChannelMuxerFactory } from "../../muxer.js";
|
|
7
|
+
import { isValidUfrag } from "../../util.js";
|
|
6
8
|
import { generateTransportCertificate } from "./generate-certificates.js";
|
|
7
9
|
const crypto = new Crypto();
|
|
8
10
|
export class DirectRTCPeerConnection extends RTCPeerConnection {
|
|
@@ -26,24 +28,28 @@ export class DirectRTCPeerConnection extends RTCPeerConnection {
|
|
|
26
28
|
}
|
|
27
29
|
async createOffer() {
|
|
28
30
|
// have to set ufrag before creating offer
|
|
29
|
-
|
|
30
|
-
this.peerConnection?.setLocalDescription('offer', {
|
|
31
|
-
iceUfrag: this.ufrag,
|
|
32
|
-
icePwd: this.ufrag
|
|
33
|
-
});
|
|
34
|
-
}
|
|
31
|
+
this.setLocalUfrag('offer');
|
|
35
32
|
return super.createOffer();
|
|
36
33
|
}
|
|
37
34
|
async createAnswer() {
|
|
38
35
|
// have to set ufrag before creating answer
|
|
39
|
-
|
|
40
|
-
this.peerConnection?.setLocalDescription('answer', {
|
|
41
|
-
iceUfrag: this.ufrag,
|
|
42
|
-
icePwd: this.ufrag
|
|
43
|
-
});
|
|
44
|
-
}
|
|
36
|
+
this.setLocalUfrag('answer');
|
|
45
37
|
return super.createAnswer();
|
|
46
38
|
}
|
|
39
|
+
// this.ufrag is reused as the ICE password; an invalid value aborts the process
|
|
40
|
+
// inside the native ICE stack, so reject it with a recoverable error first
|
|
41
|
+
setLocalUfrag(type) {
|
|
42
|
+
if (this.connectionState !== 'new') {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!isValidUfrag(this.ufrag)) {
|
|
46
|
+
throw new InvalidParametersError('ufrag is not a valid ICE credential');
|
|
47
|
+
}
|
|
48
|
+
this.peerConnection?.setLocalDescription(type, {
|
|
49
|
+
iceUfrag: this.ufrag,
|
|
50
|
+
icePwd: this.ufrag
|
|
51
|
+
});
|
|
52
|
+
}
|
|
47
53
|
remoteFingerprint() {
|
|
48
54
|
if (this.peerConnection == null) {
|
|
49
55
|
throw new Error('Invalid state: peer connection not set');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-rtcpeerconnection.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/get-rtcpeerconnection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAA;AAKzE,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;AAO3B,MAAM,OAAO,uBAAwB,SAAQ,iBAAiB;IACpD,cAAc,CAAgB;IACrB,KAAK,CAAQ;IAE9B,YAAa,IAAiC;QAC5C,KAAK,CAAC,IAAI,CAAC,CAAA;QAEX,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAA;QACzC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QAEvB,qDAAqD;QACrD,qFAAqF;QACrF,IAAI,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAClD,QAAQ,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC7B,KAAK,QAAQ;oBACX,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAA;oBAC3B,MAAK;gBACP;oBACE,MAAK;YACT,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,WAAW;QACf,0CAA0C;QAC1C,IAAI,
|
|
1
|
+
{"version":3,"file":"get-rtcpeerconnection.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/get-rtcpeerconnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stun-listener.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stun-listener.d.ts","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,UAAU;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,OAAO,IAAI,WAAW,CAAA;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9D;AAED,wBAAsB,YAAY,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAkB9G"}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { isIPv4 } from '@chainsafe/is-ip';
|
|
2
2
|
import { IceUdpMuxListener } from 'node-datachannel';
|
|
3
|
+
import { handleStunRequest } from "../../util.js";
|
|
3
4
|
export async function stunListener(host, port, log, cb) {
|
|
4
5
|
const listener = new IceUdpMuxListener(port, host);
|
|
5
6
|
listener.onUnhandledStunRequest(request => {
|
|
6
|
-
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
log.trace('incoming STUN packet from %s:%d %s', request.host, request.port, request.ufrag);
|
|
10
|
-
cb(request.ufrag, request.host, request.port);
|
|
7
|
+
handleStunRequest(request, log, cb);
|
|
11
8
|
});
|
|
12
9
|
return {
|
|
13
10
|
close: async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stun-listener.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"stun-listener.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/stun-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAajD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAE,IAAY,EAAE,IAAY,EAAE,GAAW,EAAE,EAAY;IACvF,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAClD,QAAQ,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE;QACxC,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,QAAQ,CAAC,IAAI,EAAE,CAAA;QACjB,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;gBACtC,IAAI;aACL,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/src/util.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { LoggerOptions } from '@libp2p/interface';
|
|
1
|
+
import type { Logger, LoggerOptions } from '@libp2p/interface';
|
|
2
2
|
import type { Duplex } from 'it-stream-types';
|
|
3
|
-
import type { PeerConnection } from 'node-datachannel';
|
|
3
|
+
import type { IceUdpMuxRequest, PeerConnection } from 'node-datachannel';
|
|
4
4
|
export declare const nopSource: () => AsyncGenerator<Uint8Array, any, unknown>;
|
|
5
5
|
export declare const nopSink: (_: any) => Promise<void>;
|
|
6
6
|
export declare function inertDuplex(): Duplex<any, any, any>;
|
|
@@ -12,4 +12,6 @@ export interface AbortPromiseOptions {
|
|
|
12
12
|
export declare function isPeerConnection(obj: any): obj is PeerConnection;
|
|
13
13
|
export declare function getRtcConfiguration(config?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>)): Promise<RTCConfiguration>;
|
|
14
14
|
export declare const genUfrag: (len?: number) => string;
|
|
15
|
+
export declare const isValidUfrag: (ufrag: string) => boolean;
|
|
16
|
+
export declare function handleStunRequest(request: IceUdpMuxRequest, log: Logger, cb: (ufrag: string, host: string, port: number) => void): void;
|
|
15
17
|
//# sourceMappingURL=util.d.ts.map
|
package/dist/src/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAU,MAAM,iBAAiB,CAAA;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAExE,eAAO,MAAM,SAAS,QAA4B,cAAc,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,CAAI,CAAA;AAE7F,eAAO,MAAM,OAAO,GAAU,GAAG,GAAG,KAAG,OAAO,CAAC,IAAI,CAAO,CAAA;AAG1D,wBAAgB,WAAW,IAAK,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAiBpD;AAED,wBAAgB,aAAa,CAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,YAA6B,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI,CA8C1J;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,gBAAgB,CAAE,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,cAAc,CAEjE;AAED,wBAAsB,mBAAmB,CAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CActJ;AAED,eAAO,MAAM,QAAQ,GAAI,MAAK,MAAW,KAAG,MAE3C,CAAA;AAOD,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,OAE5C,CAAA;AAKD,wBAAgB,iBAAiB,CAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAaxI"}
|
package/dist/src/util.js
CHANGED
|
@@ -81,4 +81,25 @@ export async function getRtcConfiguration(config) {
|
|
|
81
81
|
export const genUfrag = (len = 32) => {
|
|
82
82
|
return UFRAG_PREFIX + [...Array(len)].map(() => UFRAG_ALPHABET.at(Math.floor(Math.random() * UFRAG_ALPHABET.length))).join('');
|
|
83
83
|
};
|
|
84
|
+
// WebRTC-direct reuses the ufrag as the ICE password, which RFC 8445 requires to
|
|
85
|
+
// be 22-256 chars from the ice-char set [a-zA-Z0-9+/]; other values crash the
|
|
86
|
+
// process during native ICE setup, so reject them beforehand.
|
|
87
|
+
const ICE_CREDENTIAL_REGEX = /^[a-zA-Z0-9+/]{22,256}$/;
|
|
88
|
+
export const isValidUfrag = (ufrag) => {
|
|
89
|
+
return ICE_CREDENTIAL_REGEX.test(ufrag);
|
|
90
|
+
};
|
|
91
|
+
// Validate and forward a STUN request received by the UDP mux listener. The ufrag
|
|
92
|
+
// is attacker-controlled and reused as the ICE password in native setup, where an
|
|
93
|
+
// invalid value aborts the process, so drop anything that is not a valid credential.
|
|
94
|
+
export function handleStunRequest(request, log, cb) {
|
|
95
|
+
if (request.ufrag == null) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (!isValidUfrag(request.ufrag)) {
|
|
99
|
+
log.trace('dropping incoming STUN packet from %s:%d with invalid ufrag', request.host, request.port);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
log.trace('incoming STUN packet from %s:%d %s', request.host, request.port, request.ufrag);
|
|
103
|
+
cb(request.ufrag, request.host, request.port);
|
|
104
|
+
}
|
|
84
105
|
//# sourceMappingURL=util.js.map
|
package/dist/src/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/webrtc",
|
|
3
|
-
"version": "6.0.27-
|
|
3
|
+
"version": "6.0.27-68794c8e2",
|
|
4
4
|
"description": "A libp2p transport using WebRTC connections",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/transport-webrtc#readme",
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@chainsafe/is-ip": "^2.1.0",
|
|
49
49
|
"@chainsafe/libp2p-noise": "^17.0.0",
|
|
50
|
-
"@libp2p/crypto": "5.1.21-
|
|
51
|
-
"@libp2p/interface": "3.2.5-
|
|
52
|
-
"@libp2p/interface-internal": "3.1.9-
|
|
53
|
-
"@libp2p/keychain": "6.1.4-
|
|
54
|
-
"@libp2p/peer-id": "6.0.12-
|
|
55
|
-
"@libp2p/utils": "7.3.0-
|
|
50
|
+
"@libp2p/crypto": "5.1.21-68794c8e2",
|
|
51
|
+
"@libp2p/interface": "3.2.5-68794c8e2",
|
|
52
|
+
"@libp2p/interface-internal": "3.1.9-68794c8e2",
|
|
53
|
+
"@libp2p/keychain": "6.1.4-68794c8e2",
|
|
54
|
+
"@libp2p/peer-id": "6.0.12-68794c8e2",
|
|
55
|
+
"@libp2p/utils": "7.3.0-68794c8e2",
|
|
56
56
|
"@multiformats/multiaddr": "^13.0.3",
|
|
57
57
|
"@multiformats/multiaddr-matcher": "^3.0.2",
|
|
58
58
|
"@peculiar/webcrypto": "^1.5.0",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"uint8arrays": "^6.1.1"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@libp2p/logger": "6.2.10-
|
|
84
|
-
"@types/sinon": "^
|
|
83
|
+
"@libp2p/logger": "6.2.10-68794c8e2",
|
|
84
|
+
"@types/sinon": "^22.0.0",
|
|
85
85
|
"aegir": "^48.1.1",
|
|
86
86
|
"any-signal": "^4.1.1",
|
|
87
87
|
"datastore-core": "^12.0.1",
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { InvalidParametersError } from '@libp2p/interface'
|
|
1
2
|
import { Crypto } from '@peculiar/webcrypto'
|
|
2
3
|
import { PeerConnection } from 'node-datachannel'
|
|
3
4
|
import { RTCPeerConnection } from 'node-datachannel/polyfill'
|
|
4
5
|
import { DEFAULT_ICE_SERVERS, MAX_MESSAGE_SIZE } from '../../constants.ts'
|
|
5
6
|
import { DataChannelMuxerFactory } from '../../muxer.ts'
|
|
7
|
+
import { isValidUfrag } from '../../util.ts'
|
|
6
8
|
import { generateTransportCertificate } from './generate-certificates.ts'
|
|
7
9
|
import type { DataChannelOptions, TransportCertificate } from '../../index.ts'
|
|
8
10
|
import type { CounterGroup } from '@libp2p/interface'
|
|
@@ -40,28 +42,35 @@ export class DirectRTCPeerConnection extends RTCPeerConnection {
|
|
|
40
42
|
|
|
41
43
|
async createOffer (): Promise<globalThis.RTCSessionDescriptionInit | any> {
|
|
42
44
|
// have to set ufrag before creating offer
|
|
43
|
-
|
|
44
|
-
this.peerConnection?.setLocalDescription('offer', {
|
|
45
|
-
iceUfrag: this.ufrag,
|
|
46
|
-
icePwd: this.ufrag
|
|
47
|
-
})
|
|
48
|
-
}
|
|
45
|
+
this.setLocalUfrag('offer')
|
|
49
46
|
|
|
50
47
|
return super.createOffer()
|
|
51
48
|
}
|
|
52
49
|
|
|
53
50
|
async createAnswer (): Promise<globalThis.RTCSessionDescriptionInit | any> {
|
|
54
51
|
// have to set ufrag before creating answer
|
|
55
|
-
|
|
56
|
-
this.peerConnection?.setLocalDescription('answer', {
|
|
57
|
-
iceUfrag: this.ufrag,
|
|
58
|
-
icePwd: this.ufrag
|
|
59
|
-
})
|
|
60
|
-
}
|
|
52
|
+
this.setLocalUfrag('answer')
|
|
61
53
|
|
|
62
54
|
return super.createAnswer()
|
|
63
55
|
}
|
|
64
56
|
|
|
57
|
+
// this.ufrag is reused as the ICE password; an invalid value aborts the process
|
|
58
|
+
// inside the native ICE stack, so reject it with a recoverable error first
|
|
59
|
+
private setLocalUfrag (type: 'offer' | 'answer'): void {
|
|
60
|
+
if (this.connectionState !== 'new') {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!isValidUfrag(this.ufrag)) {
|
|
65
|
+
throw new InvalidParametersError('ufrag is not a valid ICE credential')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this.peerConnection?.setLocalDescription(type, {
|
|
69
|
+
iceUfrag: this.ufrag,
|
|
70
|
+
icePwd: this.ufrag
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
65
74
|
remoteFingerprint (): CertificateFingerprint {
|
|
66
75
|
if (this.peerConnection == null) {
|
|
67
76
|
throw new Error('Invalid state: peer connection not set')
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isIPv4 } from '@chainsafe/is-ip'
|
|
2
2
|
import { IceUdpMuxListener } from 'node-datachannel'
|
|
3
|
+
import { handleStunRequest } from '../../util.ts'
|
|
3
4
|
import type { Logger } from '@libp2p/interface'
|
|
4
5
|
import type { AddressInfo } from 'node:net'
|
|
5
6
|
|
|
@@ -15,13 +16,7 @@ export interface Callback {
|
|
|
15
16
|
export async function stunListener (host: string, port: number, log: Logger, cb: Callback): Promise<StunServer> {
|
|
16
17
|
const listener = new IceUdpMuxListener(port, host)
|
|
17
18
|
listener.onUnhandledStunRequest(request => {
|
|
18
|
-
|
|
19
|
-
return
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
log.trace('incoming STUN packet from %s:%d %s', request.host, request.port, request.ufrag)
|
|
23
|
-
|
|
24
|
-
cb(request.ufrag, request.host, request.port)
|
|
19
|
+
handleStunRequest(request, log, cb)
|
|
25
20
|
})
|
|
26
21
|
|
|
27
22
|
return {
|
package/src/util.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import pDefer from 'p-defer'
|
|
2
2
|
import pTimeout from 'p-timeout'
|
|
3
3
|
import { DATA_CHANNEL_DRAIN_TIMEOUT, DEFAULT_ICE_SERVERS, UFRAG_ALPHABET, UFRAG_PREFIX } from './constants.ts'
|
|
4
|
-
import type { LoggerOptions } from '@libp2p/interface'
|
|
4
|
+
import type { Logger, LoggerOptions } from '@libp2p/interface'
|
|
5
5
|
import type { Duplex, Source } from 'it-stream-types'
|
|
6
|
-
import type { PeerConnection } from 'node-datachannel'
|
|
6
|
+
import type { IceUdpMuxRequest, PeerConnection } from 'node-datachannel'
|
|
7
7
|
|
|
8
8
|
export const nopSource = async function * nop (): AsyncGenerator<Uint8Array, any, unknown> {}
|
|
9
9
|
|
|
@@ -105,3 +105,30 @@ export async function getRtcConfiguration (config?: RTCConfiguration | (() => RT
|
|
|
105
105
|
export const genUfrag = (len: number = 32): string => {
|
|
106
106
|
return UFRAG_PREFIX + [...Array(len)].map(() => UFRAG_ALPHABET.at(Math.floor(Math.random() * UFRAG_ALPHABET.length))).join('')
|
|
107
107
|
}
|
|
108
|
+
|
|
109
|
+
// WebRTC-direct reuses the ufrag as the ICE password, which RFC 8445 requires to
|
|
110
|
+
// be 22-256 chars from the ice-char set [a-zA-Z0-9+/]; other values crash the
|
|
111
|
+
// process during native ICE setup, so reject them beforehand.
|
|
112
|
+
const ICE_CREDENTIAL_REGEX = /^[a-zA-Z0-9+/]{22,256}$/
|
|
113
|
+
|
|
114
|
+
export const isValidUfrag = (ufrag: string): boolean => {
|
|
115
|
+
return ICE_CREDENTIAL_REGEX.test(ufrag)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Validate and forward a STUN request received by the UDP mux listener. The ufrag
|
|
119
|
+
// is attacker-controlled and reused as the ICE password in native setup, where an
|
|
120
|
+
// invalid value aborts the process, so drop anything that is not a valid credential.
|
|
121
|
+
export function handleStunRequest (request: IceUdpMuxRequest, log: Logger, cb: (ufrag: string, host: string, port: number) => void): void {
|
|
122
|
+
if (request.ufrag == null) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!isValidUfrag(request.ufrag)) {
|
|
127
|
+
log.trace('dropping incoming STUN packet from %s:%d with invalid ufrag', request.host, request.port)
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
log.trace('incoming STUN packet from %s:%d %s', request.host, request.port, request.ufrag)
|
|
132
|
+
|
|
133
|
+
cb(request.ufrag, request.host, request.port)
|
|
134
|
+
}
|