remote test & lots of fixes
This commit is contained in:
parent
7b26048288
commit
e2b931d6c5
16 changed files with 211 additions and 143 deletions
|
@ -15,7 +15,8 @@ pipeline:
|
|||
commands:
|
||||
- apk add openssl
|
||||
- sh genSelfSignedCert.sh
|
||||
- node tests/tester.js ci
|
||||
- node tests/ws.js ci
|
||||
- node tests/post.js ci
|
||||
buildBin:
|
||||
image: node:18
|
||||
commands:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { eq, select, update } from "dblang";
|
||||
import { PERMISSIONS } from "../../server/permissions.js";
|
||||
import { selfTag } from "../../sys/config.js";
|
||||
import { sha256, sign } from "../../sys/crypto.js";
|
||||
import { accounts, db } from "../../sys/db.js";
|
||||
import { selfTag } from "../../sys/selfTag.js";
|
||||
import { getSettings, SETTINGS } from "../../sys/settings.js";
|
||||
import { get64 } from "../../sys/tools.js";
|
||||
import { Client, STATE } from "../user.js";
|
||||
|
|
|
@ -5,6 +5,7 @@ import { getRemote } from "../../server/serverCerts.js";
|
|||
import { oConf } from "../../sys/config.js";
|
||||
import { sha256, verify } from "../../sys/crypto.js";
|
||||
import { accounts, db, signupOTA as signupOTATable } from "../../sys/db.js";
|
||||
import { selfTag } from "../../sys/selfTag.js";
|
||||
import { get64, uts } from "../../sys/tools.js";
|
||||
import { addTempToken, postClient } from "../post.js";
|
||||
import { Act, Client, STATE } from "../user.js";
|
||||
|
@ -56,7 +57,7 @@ export const signup: Act = {
|
|||
client.state = STATE.client;
|
||||
client.accID = accID;
|
||||
client.name = data.name;
|
||||
client.server = new outbagServer(data.server, oConf.get("System", "URL") + "", oConf.get("System", "PATHexposed") + "", oConf.get("System", "PORTexposed") + "");
|
||||
client.server = new outbagServer(data.server, selfTag.host, selfTag.path, selfTag.port);
|
||||
}
|
||||
} else {
|
||||
client.suspect();
|
||||
|
@ -109,7 +110,7 @@ export const signupOTA = {
|
|||
client.state = STATE.client;
|
||||
client.accID = accID;
|
||||
client.name = data.name;
|
||||
client.server = new outbagServer(data.server, oConf.get("System", "URL") + "", oConf.get("System", "PATHexposed") + "", oConf.get("System", "PORTexposed") + "");
|
||||
client.server = new outbagServer(data.server, selfTag.host, selfTag.path, selfTag.port);
|
||||
}
|
||||
} else {
|
||||
client.suspect();
|
||||
|
@ -148,7 +149,7 @@ export const signin = {
|
|||
client.state = STATE.client;
|
||||
client.accID = accID;
|
||||
client.name = data.name;
|
||||
client.server = new outbagServer(data.server, oConf.get("System", "URL") + "", oConf.get("System", "PATHexposed") + "", oConf.get("System", "PORTexposed") + "");
|
||||
client.server = new outbagServer(data.server, selfTag.host, selfTag.path, selfTag.port);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -163,12 +164,14 @@ export const remote1 = {
|
|||
sign: "string",
|
||||
},
|
||||
func: async (client: Client, data: any, aws: (code: string, data: any) => void) => {
|
||||
let server = await outbagURLfromTag(data.server);
|
||||
try {
|
||||
let server = await outbagURLfromTag(data.server);
|
||||
var cert = await getRemote(server);
|
||||
console.log(server, cert);
|
||||
var tagAcert = `${data.name}@${server.host}:${server.port}-${data.publicKey}`;
|
||||
if (!(await verify(tagAcert, data.sign, cert))) {
|
||||
client.suspect();
|
||||
console.log("verify");
|
||||
aws("error", "signature");
|
||||
return;
|
||||
}
|
||||
|
@ -180,6 +183,7 @@ export const remote1 = {
|
|||
client.remoteKey = data.publicKey;
|
||||
aws("ok", client.challenge);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
client.suspect();
|
||||
aws("error", "signature");
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import { get64, uts } from "../sys/tools.js";
|
|||
import { addShutdownTask } from "nman";
|
||||
import { suspectRequest } from "../sys/bruteforce.js";
|
||||
import { checkSelfTag, outbagServer } from "../server/outbagURL.js";
|
||||
import { oConf, selfTag } from "../sys/config.js";
|
||||
import { selfTag } from "../sys/selfTag.js";
|
||||
|
||||
let acts = importActs as { [key: string]: Act };
|
||||
|
||||
|
@ -56,7 +56,7 @@ export const addPostMethods = (server: express.Express) => {
|
|||
aws("error", "data");
|
||||
return;
|
||||
}
|
||||
client.client.server = new outbagServer(serverTag, selfTag.host, selfTag.path, selfTag.port);;
|
||||
client.client.server = new outbagServer(serverTag, selfTag.host, selfTag.path, selfTag.port);
|
||||
let accountKey = auth?.params?.accountKey;
|
||||
|
||||
let query = await select([accounts.accID, accounts.accountKey, accounts.accountKeySalt], accounts)
|
||||
|
|
|
@ -8,7 +8,8 @@ import nman from "nman";
|
|||
import cors from "cors";
|
||||
import { WebSocketServer } from "ws";
|
||||
import { Command } from "commander";
|
||||
import { generateTag, oConf } from "./sys/config.js";
|
||||
import { oConf } from "./sys/config.js";
|
||||
import { generateTag } from "./sys/selfTag.js"
|
||||
import { error, log } from "./sys/log.js";
|
||||
import { connectToDB } from "./sys/db.js";
|
||||
import bruteforce from "./sys/bruteforce.js";
|
||||
|
@ -37,7 +38,7 @@ program
|
|||
.action(({ config, debug, setup }) => {
|
||||
let dofullSetup = false;
|
||||
global.debug = debug != null;
|
||||
if(global.debug){
|
||||
if (global.debug) {
|
||||
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
|
||||
}
|
||||
if (config) {
|
||||
|
@ -103,7 +104,7 @@ async function startServer() {
|
|||
|
||||
|
||||
async function complete_loaded() {
|
||||
startUpdateCert();
|
||||
await startUpdateCert();
|
||||
await wait(500);
|
||||
let succ = await generateTag();
|
||||
if (!succ) error("Outbag", "Could not check own Server Tag. Remote-Auth may not work! Check if the Server is reachable and the config ist correct!");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { oConf } from "../sys/config.js";
|
||||
import { selfTag } from "../sys/selfTag.js";
|
||||
|
||||
const WELL_KNOWN_PATH = "/.well-known/outbag/server";
|
||||
const DEFAULT_PORT = "7223";
|
||||
|
@ -57,5 +57,5 @@ export class outbagServer {
|
|||
};
|
||||
|
||||
export const checkSelfTag = (tag: string) => {
|
||||
return tag == oConf.get("System", "URL") || tag == oConf.get("System", "URL") + ":" + oConf.get("System", "PORTexposed")
|
||||
return tag == selfTag.host || tag == selfTag.host + ":" + selfTag.port;
|
||||
}
|
|
@ -8,7 +8,7 @@ import nman, { addShutdownTask } from "nman";
|
|||
import { insert } from "dblang";
|
||||
import { db, servers } from "../sys/db.js";
|
||||
|
||||
export const startUpdateCert = () => {
|
||||
export const startUpdateCert = async () => {
|
||||
const update = async () => {
|
||||
var exp = parseInt(await getSettings(SETTINGS.certExpires));
|
||||
if (uts() - 60 >= (exp || 0)) {
|
||||
|
@ -20,54 +20,13 @@ export const startUpdateCert = () => {
|
|||
}
|
||||
};
|
||||
let intervalId = setInterval(update, 1000 * 60);
|
||||
update();
|
||||
await update();
|
||||
|
||||
nman.addShutdownTask(() => {
|
||||
clearInterval(intervalId);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
/*async function updateRemote(server: outbagServer): Promise<boolean> {
|
||||
return new Promise((res, rej) => {
|
||||
fetch(server.httpsURL + "api/server/publicKey")
|
||||
.then(d => d.json())
|
||||
.then(async json => {
|
||||
let { publicKey, expires } = json;
|
||||
if (typeof publicKey == "string" && typeof expires == "string") {
|
||||
try {
|
||||
await insert(servers.url, servers.publicKey, servers.expires)
|
||||
.add(server.tag, publicKey, expires)
|
||||
.query(db);
|
||||
} catch (error) {
|
||||
await update(servers)
|
||||
.set(servers.publicKey, publicKey)
|
||||
.set(servers.expires, expires)
|
||||
.where(eq(servers.url, server.tag))
|
||||
.query(db);
|
||||
}
|
||||
res(true);
|
||||
} else {
|
||||
if (publicKey.length > 0) {
|
||||
res(publicKey);
|
||||
return;
|
||||
}
|
||||
res(false);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
error("serverCert", "fetch error:", e);
|
||||
res(false);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const getRemote = async (server: outbagServer) => {
|
||||
await updateRemote(server);
|
||||
let query = await select([servers.publicKey, servers.expires], servers)
|
||||
.where(eq(servers.url, server.tag))
|
||||
.query(db);
|
||||
return query[0][servers.publicKey];
|
||||
};*/
|
||||
const deleteafter = 60 * 60;
|
||||
|
||||
const certList: { [key: string]: { exp: number, cert: string } } = {};
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import juml from "juml";
|
||||
import { outbagServer, outbagURLfromTag } from "../server/outbagURL.js";
|
||||
import { debug } from "./log.js";
|
||||
|
||||
const conf_struct = {
|
||||
System: {
|
||||
|
@ -31,40 +29,4 @@ const conf_struct = {
|
|||
}
|
||||
};
|
||||
|
||||
export const oConf = new juml(conf_struct);
|
||||
|
||||
export let selfTag: outbagServer = new outbagServer(
|
||||
"localhost",
|
||||
oConf.get("System", "URL") + "",
|
||||
oConf.get("System", "PATHexposed") + "",
|
||||
oConf.get("System", "PORTexposed") + "",
|
||||
);
|
||||
|
||||
export const generateTag = async () => {
|
||||
try {
|
||||
selfTag = new outbagServer(
|
||||
"localhost",
|
||||
oConf.get("System", "URL") + "",
|
||||
oConf.get("System", "PATHexposed") + "",
|
||||
oConf.get("System", "PORTexposed") + "",
|
||||
);
|
||||
let initselfTag = selfTag;
|
||||
let mainServerHost: outbagServer | null = null;
|
||||
try {
|
||||
mainServerHost = await outbagURLfromTag(oConf.get("System", "URL"));
|
||||
} catch (error) { }
|
||||
let serverHostPort = await outbagURLfromTag(
|
||||
oConf.get("System", "URL") + ":" + oConf.get("System", "PORTexposed"));
|
||||
if (mainServerHost == null || mainServerHost.tag != serverHostPort.tag) {
|
||||
selfTag = serverHostPort;
|
||||
} else selfTag = mainServerHost;
|
||||
if (initselfTag.httpsURL != selfTag.httpsURL) {
|
||||
console.log(initselfTag, initselfTag.httpsURL, selfTag.httpsURL);
|
||||
debug("Outbag", "Not matching Server host, port, path and expected server link.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
export const oConf = new juml(conf_struct);
|
|
@ -33,7 +33,6 @@ export const warn = (name: string, ...args: any[]) => {
|
|||
};
|
||||
|
||||
export const error = (name: string, ...args: any[]) => {
|
||||
args = consorArgs(args);
|
||||
console.error(
|
||||
"\x1b[33m%s\x1b[0m" +
|
||||
"\x1b[1m\x1b[41m%s\x1b[0m\x1b[41m",
|
||||
|
|
39
src/sys/selfTag.ts
Normal file
39
src/sys/selfTag.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { outbagServer, outbagURLfromTag } from "../server/outbagURL.js";
|
||||
import {oConf} from "./config.js"
|
||||
import { debug } from "./log.js";
|
||||
|
||||
export let selfTag: outbagServer = new outbagServer(
|
||||
"localhost",
|
||||
oConf.get("System", "URL") + "",
|
||||
oConf.get("System", "PATHexposed") + "",
|
||||
oConf.get("System", "PORTexposed") + "",
|
||||
);
|
||||
|
||||
export const generateTag = async () => {
|
||||
try {
|
||||
selfTag = new outbagServer(
|
||||
"localhost",
|
||||
oConf.get("System", "URL") + "",
|
||||
oConf.get("System", "PATHexposed") + "",
|
||||
oConf.get("System", "PORTexposed") + "",
|
||||
);
|
||||
let initselfTag = selfTag;
|
||||
let mainServerHost: outbagServer | null = null;
|
||||
try {
|
||||
mainServerHost = await outbagURLfromTag(oConf.get("System", "URL"));
|
||||
} catch (error) { }
|
||||
let serverHostPort = await outbagURLfromTag(
|
||||
oConf.get("System", "URL") + ":" + oConf.get("System", "PORTexposed"));
|
||||
if (mainServerHost == null || mainServerHost.tag != serverHostPort.tag) {
|
||||
selfTag = serverHostPort;
|
||||
} else selfTag = mainServerHost;
|
||||
if (initselfTag.httpsURL != selfTag.httpsURL) {
|
||||
console.log(initselfTag, initselfTag.httpsURL, selfTag.httpsURL);
|
||||
debug("Outbag", "Not matching Server host, port, path and expected server link.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
|
@ -1,3 +1,3 @@
|
|||
export async function postTester(){
|
||||
async function postTester(){
|
||||
|
||||
}
|
|
@ -10,12 +10,12 @@ process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
|
|||
|
||||
ls.stdout.on('data', (data) => {
|
||||
process.stdout.write(data);
|
||||
if(data.includes("Listening...")) test();
|
||||
if (data.includes("Listening...")) test();
|
||||
});
|
||||
|
||||
ls.stderr.on('data', (data) => {
|
||||
console.error(`stderr: ${data}`);
|
||||
|
||||
|
||||
});
|
||||
|
||||
ls.on('close', (code) => {
|
||||
|
@ -30,7 +30,7 @@ function kill() {
|
|||
let startet = false;
|
||||
|
||||
async function test() {
|
||||
if(startet) return;
|
||||
if (startet) return;
|
||||
startet = true;
|
||||
console.log("Start testing");
|
||||
let url = "localhost:7224";
|
||||
|
|
81
tests/tests/ws.js
Normal file
81
tests/tests/ws.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
import { generateSigningKey, sign } from '../../dist/sys/crypto.js';
|
||||
|
||||
let name1 = "testUser1";
|
||||
let name2 = "testUser2";
|
||||
let name3 = "testUser3";
|
||||
let accountKey = "123456789";
|
||||
|
||||
let { privateKey, publicKey } = await generateSigningKey();
|
||||
|
||||
const list = [
|
||||
["signup", async (handler, req, newHandler) => {
|
||||
await req(handler, "signup", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "ok", "");
|
||||
await req(handler, "signup", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "error", "wrongstate");
|
||||
await req(await newHandler(), "signup", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "error", "existence");
|
||||
await req(await newHandler(), "signup", {
|
||||
name: name2,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "ok", "");
|
||||
await req(await newHandler(), "signup", {
|
||||
name: name3,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "error", "config");
|
||||
}], ["remote", async (handler, req, newHandler) => {
|
||||
await req(handler, "signin", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "ok", "");
|
||||
let signature = await req(handler, "createSignature", {
|
||||
publicKey
|
||||
}, "ok", null);
|
||||
let falseSignature = await sign("lol", privateKey);
|
||||
let h2 = await newHandler();
|
||||
await req(h2, "remote1", {
|
||||
name: name1,
|
||||
server: "localhost:7223",
|
||||
publicKey,
|
||||
sign: signature
|
||||
}, "error", "signature");
|
||||
await req(h2, "remote1", {
|
||||
name: name1,
|
||||
server: "localhost:7223",
|
||||
publicKey,
|
||||
sign: falseSignature
|
||||
}, "error", "signature");
|
||||
let challenge = await req(h2, "remote1", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
publicKey,
|
||||
sign: signature
|
||||
}, "ok", null);
|
||||
await req(h2, "remote1", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
publicKey,
|
||||
sign: signature
|
||||
}, "error", "wrongstate");
|
||||
await req(h2, "remote2", {
|
||||
sign: await sign(challenge + "lol", privateKey)
|
||||
}, "error", "signature");
|
||||
await req(h2, "remote2", {
|
||||
sign: await sign(challenge, privateKey)
|
||||
}, "ok", "");
|
||||
}]
|
||||
];
|
||||
|
||||
export default list;
|
75
tests/ws.js
75
tests/ws.js
|
@ -1,7 +1,28 @@
|
|||
import WebSocket from 'ws';
|
||||
import { generateSigningKey, sign } from '../dist/sys/crypto.js';
|
||||
import { uts, wait } from '../dist/sys/tools.js';
|
||||
import * as ws from "./ws/ws.js"
|
||||
import ws from "./tests/ws.js"
|
||||
import { spawn } from "child_process";
|
||||
import { oConf } from "../dist/sys/config.js"
|
||||
import mariadb from "mariadb";
|
||||
|
||||
let inCI = process.argv.includes("ci");
|
||||
|
||||
oConf.connect(inCI ? 'test.juml' : 'testLocal.juml');
|
||||
|
||||
const connection = await mariadb.createConnection({
|
||||
host: oConf.get("Database", "host"),
|
||||
port: oConf.get("Database", "port"),
|
||||
user: oConf.get("Database", "user"),
|
||||
password: oConf.get("Database", "password"),
|
||||
database: oConf.get("Database", "database"),
|
||||
multipleStatements: true
|
||||
});
|
||||
await wait(100);
|
||||
|
||||
let req = await connection.query("SELECT table_name as n FROM information_schema.tables WHERE table_schema = ?;", [oConf.get("Database", "database")]);
|
||||
let sql = [...req].map(d => "DROP TABLE IF EXISTS `" + d.n + "`;").join("");
|
||||
if (sql.length > 5) await connection.query("SET FOREIGN_KEY_CHECKS = 0;" + sql + "SET FOREIGN_KEY_CHECKS = 1;", []);
|
||||
connection.close();
|
||||
|
||||
function conn(url) {
|
||||
const ws = new WebSocket(url);
|
||||
|
@ -78,7 +99,7 @@ function shallowEqual(object1, object2) {
|
|||
|
||||
|
||||
|
||||
export async function wsTester(url, kill) {
|
||||
async function wsTester(url) {
|
||||
async function test(conn, act, data, expState, expData) {
|
||||
console.log("Testing Act:", act, "with Data:", data);
|
||||
let resp = await conn.req(act, data);
|
||||
|
@ -93,7 +114,7 @@ export async function wsTester(url, kill) {
|
|||
kill();
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
} else if (expData != null) {
|
||||
if (expData != resp.data) {
|
||||
console.error(`Expected data: '${expData}', but got: '${resp.data}'`);
|
||||
kill();
|
||||
|
@ -103,14 +124,14 @@ export async function wsTester(url, kill) {
|
|||
return resp.data;
|
||||
}
|
||||
|
||||
for (const k in ws) {
|
||||
console.log(`Testing '${k}':`);
|
||||
for (let i = 0; i < ws.length; i++) {
|
||||
const currTest = ws[i];
|
||||
console.log(`Testing '${currTest[0]}':`);
|
||||
const handler = [new conn(url)];
|
||||
await wait(100);
|
||||
const currTest = ws[k];
|
||||
let resp = true;
|
||||
try {
|
||||
resp = await currTest(handler[0], test, async ()=>{
|
||||
resp = await currTest[1](handler[0], test, async () => {
|
||||
let h = new conn(url);
|
||||
await wait(100);
|
||||
handler.push(h);
|
||||
|
@ -121,8 +142,8 @@ export async function wsTester(url, kill) {
|
|||
kill();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
handler.forEach(h=>h.close());
|
||||
|
||||
handler.forEach(h => h.close());
|
||||
if (resp === false) {
|
||||
console.log("Test respond with error indication!");
|
||||
kill();
|
||||
|
@ -130,3 +151,37 @@ export async function wsTester(url, kill) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const ls = spawn('node', ['.', '-c', inCI ? 'test.juml' : 'testLocal.juml', '-d']);
|
||||
|
||||
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
|
||||
|
||||
ls.stdout.on('data', (data) => {
|
||||
process.stdout.write(data);
|
||||
if (data.includes("Listening...")) test();
|
||||
});
|
||||
|
||||
ls.stderr.on('data', (data) => {
|
||||
console.error(`stderr: ${data}`);
|
||||
});
|
||||
|
||||
ls.on('close', (code) => {
|
||||
console.log(`child process exited with code ${code}`);
|
||||
process.exit(code);
|
||||
});
|
||||
|
||||
function kill() {
|
||||
ls.kill('SIGINT');
|
||||
}
|
||||
|
||||
let startet = false;
|
||||
|
||||
async function test() {
|
||||
if (startet) return;
|
||||
startet = true;
|
||||
console.log("Start testing");
|
||||
await wsTester("wss://localhost:7224/");
|
||||
kill();
|
||||
process.exit(0);
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
let name1 = "testUser1";
|
||||
let name2 = "testUser2";
|
||||
let name3 = "testUser3";
|
||||
let accountKey = "123456789";
|
||||
|
||||
export const signup = async (handler, req, newHandler) => {
|
||||
await req(handler, "signup", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "ok", "");
|
||||
await req(handler, "signup", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "error", "wrongstate");
|
||||
await req(await newHandler(), "signup", {
|
||||
name: name1,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "error", "existence");
|
||||
await req(await newHandler(), "signup", {
|
||||
name: name2,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "ok", "");
|
||||
await req(await newHandler(), "signup", {
|
||||
name: name2,
|
||||
server: "localhost:7224",
|
||||
accountKey
|
||||
}, "error", "config");
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
export * from "./login.js";
|
Loading…
Reference in a new issue