Add support for extionsions in auth expressions

This commit is contained in:
Shweelan Samson authored and Zaid Abdulla committed 2019-06-05 00:17:36 -07:00
1 parent e26fffa761
commit f21ce3053a
4 files changed
+83 -33

No files matched your search

+5 -1
View File
@@ -9,6 +9,7 @@ import * as logger from "../lib/logger";
import * as cluster from "../lib/cluster"; import * as cluster from "../lib/cluster";
import * as server from "../lib/server"; import * as server from "../lib/server";
import { listener } from "../lib/ui"; import { listener } from "../lib/ui";
import * as extensions from "../lib/extensions";
import * as db from "../lib/ui/db"; import * as db from "../lib/ui/db";
import * as db2 from "../lib/db"; import * as db2 from "../lib/db";
import * as cache from "../lib/cache"; import * as cache from "../lib/cache";
@@ -23,11 +24,14 @@ function exitWorkerGracefully(): void {
db.disconnect(); db.disconnect();
db2.disconnect(); db2.disconnect();
cache.disconnect(); cache.disconnect();
extensions.killAll();
cluster.worker.disconnect(); cluster.worker.disconnect();
} }
function exitWorkerUngracefully(): void { function exitWorkerUngracefully(): void {
process.exit(1); extensions.killAll().then(() => {
process.exit(1);
});
} }
if (!cluster.worker) { if (!cluster.worker) {
+1 -1
View File
@@ -119,7 +119,7 @@ export async function connectionRequest(deviceId): Promise<void> {
udpProm = udpConnectionRequest( udpProm = udpConnectionRequest(
udpConnectionRequestAddress, udpConnectionRequestAddress,
authExp, authExp,
db.configCollection, context,
UDP_CONNECTION_REQUEST_PORT UDP_CONNECTION_REQUEST_PORT
); );
} }
+48 -17
View File
@@ -21,29 +21,44 @@ import * as crypto from "crypto";
import * as dgram from "dgram"; import * as dgram from "dgram";
import { parse } from "url"; import { parse } from "url";
import * as http from "http"; import * as http from "http";
import { evaluate } from "./common/expression"; import { evaluateAsync } from "./common/expression";
import { Expression } from "./types"; import { Expression } from "./types";
import * as auth from "./auth"; import * as auth from "./auth";
import * as extensions from "./extensions";
function extractAuth( async function extractAuth(
exp: Expression, exp: Expression,
context: {}, context: {},
now: number, now: number,
dflt: any dflt: any
): [string, string, Expression] { ): Promise<[string, string, Expression]> {
let username, password; let username, password;
exp = evaluate(exp, context, now, e => { const _exp = await evaluateAsync(
if (!username && Array.isArray(e) && e[0] === "FUNC" && e[1] === "AUTH") { exp,
if (!Array.isArray(e[2]) && !Array.isArray(e[3])) { context,
username = e[2]; now,
password = e[3]; async (e: Expression): Promise<Expression> => {
} if (!username && Array.isArray(e) && e[0] === "FUNC") {
return dflt; if (e[1] === "EXT") {
} if (typeof e[2] !== "string" || typeof e[3] !== "string") return null;
return e;
});
return [username, password, exp]; for (let i = 4; i < e.length; i++)
if (Array.isArray(e[i])) return null;
const { fault, value } = await extensions.run(e.slice(2));
return fault ? null : value;
} else if (e[1] === "AUTH") {
if (!Array.isArray(e[2]) && !Array.isArray(e[3])) {
username = e[2];
password = e[3];
}
return dflt;
}
}
return e;
}
);
return [username, password, _exp];
} }
function httpGet( function httpGet(
@@ -137,7 +152,12 @@ export async function httpConnectionRequest(
authHeader = auth.parseWwwAuthenticateHeader( authHeader = auth.parseWwwAuthenticateHeader(
res.headers["www-authenticate"] res.headers["www-authenticate"]
); );
[username, password, authExp] = extractAuth(authExp, context, now, false); [username, password, authExp] = await extractAuth(
authExp,
context,
now,
false
);
} else { } else {
throw new Error( throw new Error(
`Unexpected response code from device: ${res.statusCode}` `Unexpected response code from device: ${res.statusCode}`
@@ -169,7 +189,13 @@ export async function udpConnectionRequest(
let username: string; let username: string;
let password: string; let password: string;
[username, password, authExp] = extractAuth(authExp, context, now, null); [username, password, authExp] = await extractAuth(
authExp,
context,
now,
null
);
if (username == null) username = ""; if (username == null) username = "";
if (password == null) password = ""; if (password == null) password = "";
while (username != null && password != null) { while (username != null && password != null) {
@@ -194,7 +220,12 @@ export async function udpConnectionRequest(
}); });
} }
[username, password, authExp] = extractAuth(authExp, context, now, null); [username, password, authExp] = await extractAuth(
authExp,
context,
now,
null
);
} }
client.close(); client.close();
} }
+29 -14
View File
@@ -26,7 +26,7 @@ import * as config from "./config";
import * as common from "./common"; import * as common from "./common";
import * as soap from "./soap"; import * as soap from "./soap";
import * as session from "./session"; import * as session from "./session";
import { evaluate, extractParams } from "./common/expression"; import { evaluateAsync, evaluate, extractParams } from "./common/expression";
import * as device from "./device"; import * as device from "./device";
import * as cache from "./cache"; import * as cache from "./cache";
import * as localCache from "./local-cache"; import * as localCache from "./local-cache";
@@ -34,6 +34,7 @@ import * as db from "./db";
import * as logger from "./logger"; import * as logger from "./logger";
import * as scheduling from "./scheduling"; import * as scheduling from "./scheduling";
import Path from "./common/path"; import Path from "./common/path";
import * as extensions from "./extensions";
import { import {
SessionContext, SessionContext,
AcsRequest, AcsRequest,
@@ -64,7 +65,7 @@ const stats = {
initiatedSessions: 0 initiatedSessions: 0
}; };
function authenticate(sessionContext: SessionContext): boolean { async function authenticate(sessionContext: SessionContext): Promise<boolean> {
const authExpression: Expression = localCache.getConfigExpression( const authExpression: Expression = localCache.getConfigExpression(
sessionContext.cacheSnapshot, sessionContext.cacheSnapshot,
"cwmp.auth" "cwmp.auth"
@@ -80,19 +81,29 @@ function authenticate(sessionContext: SessionContext): boolean {
} }
const now = Date.now(); const now = Date.now();
const res = evaluate( const res = await evaluateAsync(
authExpression, authExpression,
sessionContext.configContext, sessionContext.configContext,
now, now,
(e: Expression): Expression => { async (e: Expression): Promise<Expression> => {
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "AUTH") { if (Array.isArray(e) && e[0] === "FUNC") {
if (authentication && authentication["method"] === "Basic") { if (e[1] === "EXT") {
return ( if (typeof e[2] !== "string" || typeof e[3] !== "string") return null;
authentication["username"] === e[2] &&
authentication["password"] === e[3] for (let i = 4; i < e.length; i++)
); if (Array.isArray(e[i])) return null;
} else {
return false; const { fault, value } = await extensions.run(e.slice(2));
return fault ? null : value;
} else if (e[1] === "AUTH") {
if (authentication && authentication["method"] === "Basic") {
return (
authentication["username"] === e[2] &&
authentication["password"] === e[3]
);
} else {
return false;
}
} }
} }
return e; return e;
@@ -1160,7 +1171,10 @@ async function listenerAsync(
} }
if (sessionContext) { if (sessionContext) {
if (sessionContext.state === 0 && !authenticate(sessionContext)) { const authenticated =
sessionContext.state === 0 ? await authenticate(sessionContext) : true;
if (!authenticated) {
logger.accessError({ logger.accessError({
message: "Authentication failure", message: "Authentication failure",
sessionContext: sessionContext sessionContext: sessionContext
@@ -1248,7 +1262,8 @@ async function listenerAsync(
} }
} }
if (!authenticate(_sessionContext)) { const authenticated = await authenticate(_sessionContext);
if (!authenticated) {
logger.accessError({ logger.accessError({
message: "Authentication failure", message: "Authentication failure",
sessionContext: _sessionContext sessionContext: _sessionContext