Add support for extionsions in auth expressions
This commit is contained in:
1 parent
e26fffa761
commit
f21ce3053a
4 files changed
+83
-33
No files matched your search
+5
-1
@@ -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) {
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in new issue
Block a user