mirror of
https://github.com/koush/scrypted.git
synced 2026-04-17 22:00:27 +01:00
rebroadcast: Fix rtsp client auth bugs
This commit is contained in:
@@ -178,7 +178,7 @@ const quote = (str: string): string => `"${str.replace(/"/g, '\\"')}"`;
|
||||
export class RtspClient extends RtspBase {
|
||||
cseq = 0;
|
||||
session: string;
|
||||
authorization: string;
|
||||
wwwAuthenticate: string;
|
||||
requestTimeout: number;
|
||||
rfc4571 = new PassThrough();
|
||||
needKeepAlive = false;
|
||||
@@ -224,9 +224,10 @@ export class RtspClient extends RtspBase {
|
||||
const line = `${method} ${fullUrl} RTSP/1.0`;
|
||||
const cseq = this.cseq++;
|
||||
headers['CSeq'] = cseq.toString();
|
||||
headers['User-Agent'] = 'Scrypted';
|
||||
|
||||
if (this.authorization)
|
||||
headers['Authorization'] = this.authorization;
|
||||
if (this.wwwAuthenticate)
|
||||
headers['Authorization'] = this.createAuthorizationHeader(method);
|
||||
|
||||
if (this.session)
|
||||
headers['Session'] = this.session;
|
||||
@@ -285,6 +286,39 @@ export class RtspClient extends RtspBase {
|
||||
}
|
||||
}
|
||||
|
||||
createAuthorizationHeader(method: string) {
|
||||
if (!this.wwwAuthenticate)
|
||||
throw new Error('no WWW-Authenticate found');
|
||||
|
||||
const parsedUrl = new URL(this.url);
|
||||
|
||||
if (this.wwwAuthenticate.includes('Basic')) {
|
||||
const hash = BASIC.computeHash(parsedUrl);
|
||||
return `Basic ${hash}`;
|
||||
}
|
||||
|
||||
const wwwAuth = DIGEST.parseWWWAuthenticateRest(this.wwwAuthenticate);
|
||||
|
||||
const username = decodeURIComponent(parsedUrl.username);
|
||||
const password = decodeURIComponent(parsedUrl.password);
|
||||
|
||||
const ha1 = crypto.createHash('md5').update(`${username}:${wwwAuth.realm}:${password}`).digest('hex');
|
||||
const ha2 = crypto.createHash('md5').update(`${method}:${parsedUrl.pathname}`).digest('hex');
|
||||
const hash = crypto.createHash('md5').update(`${ha1}:${wwwAuth.nonce}:${ha2}`).digest('hex');
|
||||
|
||||
const params = {
|
||||
username,
|
||||
realm: wwwAuth.realm,
|
||||
nonce: wwwAuth.nonce,
|
||||
uri: parsedUrl.pathname,
|
||||
algorithm: 'MD5',
|
||||
response: hash,
|
||||
};
|
||||
|
||||
const paramsString = Object.entries(params).map(([key, value]) => `${key}=${value && quote(value)}`).join(', ');
|
||||
return `Digest ${paramsString}`;
|
||||
}
|
||||
|
||||
async request(method: string, headers?: Headers, path?: string, body?: Buffer, authenticating?: boolean): Promise<{
|
||||
headers: Headers,
|
||||
body: Buffer
|
||||
@@ -302,34 +336,7 @@ export class RtspClient extends RtspBase {
|
||||
if (authenticating)
|
||||
throw new Error('auth failed');
|
||||
|
||||
const parsedUrl = new URL(this.url);
|
||||
|
||||
if (wwwAuthenticate.includes('Basic')) {
|
||||
const hash = BASIC.computeHash(parsedUrl);
|
||||
this.authorization = `Basic ${hash}`;
|
||||
}
|
||||
else {
|
||||
const wwwAuth = DIGEST.parseWWWAuthenticateRest(wwwAuthenticate);
|
||||
|
||||
const username = decodeURIComponent(parsedUrl.username);
|
||||
const password = decodeURIComponent(parsedUrl.password);
|
||||
|
||||
const ha1 = crypto.createHash('md5').update(`${username}:${wwwAuth.realm}:${password}`).digest('hex');
|
||||
const ha2 = crypto.createHash('md5').update(`${method}:${parsedUrl.pathname}`).digest('hex');
|
||||
const hash = crypto.createHash('md5').update(`${ha1}:${wwwAuth.nonce}:${ha2}`).digest('hex');
|
||||
|
||||
const params = {
|
||||
username,
|
||||
realm: wwwAuth.realm,
|
||||
nonce: wwwAuth.nonce,
|
||||
uri: parsedUrl.pathname,
|
||||
algorithm: 'MD5',
|
||||
response: hash,
|
||||
};
|
||||
|
||||
const paramsString = Object.entries(params).map(([key, value]) => `${key}=${value && quote(value)}`).join(', ');
|
||||
this.authorization = `Digest ${paramsString}`;
|
||||
}
|
||||
this.wwwAuthenticate = wwwAuthenticate;
|
||||
|
||||
return this.request(method, headers, path, body, true);
|
||||
}
|
||||
|
||||
4
plugins/prebuffer-mixin/package-lock.json
generated
4
plugins/prebuffer-mixin/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/prebuffer-mixin",
|
||||
"version": "0.1.237",
|
||||
"version": "0.1.238",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/prebuffer-mixin",
|
||||
"version": "0.1.237",
|
||||
"version": "0.1.238",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@scrypted/common": "file:../../common",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/prebuffer-mixin",
|
||||
"version": "0.1.237",
|
||||
"version": "0.1.238",
|
||||
"description": "Rebroadcast and Prebuffer for VideoCameras.",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
Reference in New Issue
Block a user