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

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