add wtv-ticket store api
- fix broken session bust crap from before - properly resume session as user when server restarted - api available to store other things in the wtv-ticket
This commit is contained in:
@@ -71,9 +71,8 @@ minisrv-no-mail-count: true
|
|||||||
Content-Type: text/html`;
|
Content-Type: text/html`;
|
||||||
if (client_challenge_response) {
|
if (client_challenge_response) {
|
||||||
headers += `
|
headers += `
|
||||||
wtv-encrypted: true
|
wtv-encrypted: true`;
|
||||||
wtv-ticket: ${wtvsec_login.ticket_b64}
|
if (wtvsec_login) ssid_sessions[socket.ssid].data_store.wtvsec_login.update_ticket = true;
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
if (limitedLoginRegistered) gourl = "wtv-head-waiter:/password?";
|
if (limitedLoginRegistered) gourl = "wtv-head-waiter:/password?";
|
||||||
headers += `
|
headers += `
|
||||||
|
|||||||
@@ -39,14 +39,28 @@ else {
|
|||||||
} else {
|
} else {
|
||||||
var userid = ssid_sessions[socket.ssid].getSessionData("subscriber_userid")
|
var userid = ssid_sessions[socket.ssid].getSessionData("subscriber_userid")
|
||||||
var nickname = ssid_sessions[socket.ssid].getSessionData("subscriber_username");
|
var nickname = ssid_sessions[socket.ssid].getSessionData("subscriber_username");
|
||||||
var human_name = ssid_sessions[socket.ssid].getSessionData("subscriber_name");
|
var human_name = ssid_sessions[socket.ssid].getSessionData("subscriber_name") || nickname;
|
||||||
var messenger_enabled = ssid_sessions[socket.ssid].getSessionData("messenger_enabled") || 0;
|
var messenger_enabled = ssid_sessions[socket.ssid].getSessionData("messenger_enabled") || 0;
|
||||||
var messenger_authorized = ssid_sessions[socket.ssid].getSessionData("messenger_authorized") || 0;
|
var messenger_authorized = ssid_sessions[socket.ssid].getSessionData("messenger_authorized") || 0;
|
||||||
var home_url = "wtv-home:/splash?";
|
var home_url = "wtv-home:/splash?";
|
||||||
}
|
}
|
||||||
var limitedLogin = ssid_sessions[socket.ssid].lockdown;
|
var limitedLogin = ssid_sessions[socket.ssid].lockdown;
|
||||||
var limitedLoginRegistered = (limitedLogin || (ssid_sessions[socket.ssid].isRegistered() && ssid_sessions[socket.ssid].getSessionData('password_valid')));
|
var limitedLoginRegistered = (limitedLogin || (ssid_sessions[socket.ssid].isRegistered() && ssid_sessions[socket.ssid].getSessionData('password_valid')));
|
||||||
var offline_user_list = CryptoJS.enc.Latin1.parse("<user-list>\n\t<user userid=\"" + userid + " user-name=\"" + nickname + "\" first-name=\"" + minisrv_config.config.service_name + "User \" last-name=\\" + namerand + "\" password=\"\" mail-enabled=\"true\" />\n</user-list>").toString(CryptoJS.enc.Base64);
|
var offline_user_list = null;
|
||||||
|
if (ssid_sessions[socket.ssid].isRegistered() && ssid_sessions[socket.ssid].user_id == 0) {
|
||||||
|
var accounts = ssid_sessions[socket.ssid].listPrimaryAccountUsers();
|
||||||
|
console.log(accounts);
|
||||||
|
var num_accounts = ssid_sessions[socket.ssid].getNumberOfUserAccounts();
|
||||||
|
var offline_user_list_str = "<user-list>\n";
|
||||||
|
var i = 0;
|
||||||
|
Object.keys(accounts).forEach((k) => {
|
||||||
|
var account_display_name = (accounts[k].subscriber_name) ? accounts[k].subscriber_name : accounts[k].subscriber_username
|
||||||
|
offline_user_list_str += "\t" + '<user userid="' + i + '" user-name="' + accounts[k].subscriber_username + '" first-name="' + account_display_name + '" last-name="" passsword="" mail-enabled=true />' + "\n";
|
||||||
|
i++;
|
||||||
|
});
|
||||||
|
offline_user_list_str += "</user-list>\n";
|
||||||
|
offline_user_list = CryptoJS.enc.Latin1.parse(offline_user_list_str).toString(CryptoJS.enc.Base64);
|
||||||
|
}
|
||||||
|
|
||||||
if (limitedLoginRegistered) var home_url = "wtv-head-waiter:/password?";
|
if (limitedLoginRegistered) var home_url = "wtv-head-waiter:/password?";
|
||||||
|
|
||||||
@@ -74,8 +88,8 @@ wtv-login-timeout: 7200
|
|||||||
if (!limitedLogin) {
|
if (!limitedLogin) {
|
||||||
|
|
||||||
headers += getServiceString('all', { "exceptions": ["wtv-register"] });
|
headers += getServiceString('all', { "exceptions": ["wtv-register"] });
|
||||||
headers += `wtv-offline-user-list: ${offline_user_list}
|
if (offline_user_list) headers += "wtv-offline-user-list: " + offline_user_list + "\n";
|
||||||
wtv-messenger-authorized: ${messenger_authorized}
|
headers += `wtv-messenger-authorized: ${messenger_authorized}
|
||||||
wtv-messenger-enable: ${messenger_enabled}
|
wtv-messenger-enable: ${messenger_enabled}
|
||||||
wtv-messagewatch-checktimeoffset: off
|
wtv-messagewatch-checktimeoffset: off
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ if (!request_headers.query.registering ||
|
|||||||
ssid_sessions[socket.ssid].setSessionData("subscriber_username", request_headers.query.subscriber_username);
|
ssid_sessions[socket.ssid].setSessionData("subscriber_username", request_headers.query.subscriber_username);
|
||||||
ssid_sessions[socket.ssid].setSessionData("subscriber_contact", request_headers.query.subscriber_contact);
|
ssid_sessions[socket.ssid].setSessionData("subscriber_contact", request_headers.query.subscriber_contact);
|
||||||
ssid_sessions[socket.ssid].setSessionData("subscriber_contact_method", request_headers.query.subscriber_contact_method);
|
ssid_sessions[socket.ssid].setSessionData("subscriber_contact_method", request_headers.query.subscriber_contact_method);
|
||||||
ssid_sessions[socket.ssid].setSessionData("subscriber_userid", '1' + Math.floor(Math.random() * 1000000000000000000));
|
ssid_sessions[socket.ssid].setSessionData("subscriber_userid", 0);
|
||||||
ssid_sessions[socket.ssid].setSessionData("registered", true);
|
ssid_sessions[socket.ssid].setSessionData("registered", true);
|
||||||
if (!ssid_sessions[socket.ssid].storeSessionData(true)) {
|
if (!ssid_sessions[socket.ssid].storeSessionData(true)) {
|
||||||
var errpage = wtvshared.doErrorPage(400);
|
var errpage = wtvshared.doErrorPage(400);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ if (errpage) {
|
|||||||
var freeUserId = ssid_sessions[socket.ssid].findFreeUserSlot(ssid_sessions[socket.ssid]);
|
var freeUserId = ssid_sessions[socket.ssid].findFreeUserSlot(ssid_sessions[socket.ssid]);
|
||||||
if (freeUserId) {
|
if (freeUserId) {
|
||||||
userSession.user_id = freeUserId;
|
userSession.user_id = freeUserId;
|
||||||
|
userSession.setSessionData("subscriber_userid", freeUserId);
|
||||||
userSession.setSessionData("subscriber_name", request_headers.query.display_name);
|
userSession.setSessionData("subscriber_name", request_headers.query.display_name);
|
||||||
userSession.setSessionData("subscriber_username", request_headers.query.user_name);
|
userSession.setSessionData("subscriber_username", request_headers.query.user_name);
|
||||||
userSession.setSessionData("registered", true);
|
userSession.setSessionData("registered", true);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const { lib } = require('crypto-js');
|
const { lib } = require('crypto-js');
|
||||||
const CryptoJS = require('crypto-js');
|
const CryptoJS = require('crypto-js');
|
||||||
const WTVMail = require('./WTVMail.js')
|
const WTVMail = require('./WTVMail.js')
|
||||||
|
const WTVSec = require('./WTVSec.js');
|
||||||
class WTVClientSessionData {
|
class WTVClientSessionData {
|
||||||
|
|
||||||
fs = require('fs');
|
fs = require('fs');
|
||||||
@@ -54,10 +55,31 @@ class WTVClientSessionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switchUserID(user_id, update_mail = true) {
|
switchUserID(user_id, update_mail = true, update_ticket = true) {
|
||||||
this.user_id = user_id;
|
this.user_id = user_id;
|
||||||
this.loadSessionData();
|
this.loadSessionData();
|
||||||
this.mailstore = new WTVMail(this.minisrv_config, this.ssid, this)
|
this.mailstore = new WTVMail(this.minisrv_config, this.ssid, this)
|
||||||
|
if (this.data_store.wtvsec_login && update_ticket) this.setTicketData('user_id', user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTicketData(key, value) {
|
||||||
|
if (this.data_store.wtvsec_login) this.data_store.wtvsec_login.setTicketData(key, value);
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTicketData(key) {
|
||||||
|
if (this.data_store.wtvsec_login) return this.data_store.wtvsec_login.getTicketData(key);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTicketData(key) {
|
||||||
|
if (this.data_store.wtvsec_login) this.data_store.wtvsec_login.deleteTicketData(key);
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
findFreeUserSlot() {
|
findFreeUserSlot() {
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ class WTVSec {
|
|||||||
hRC4_Key2 = null;
|
hRC4_Key2 = null;
|
||||||
RC4Session = new Array();
|
RC4Session = new Array();
|
||||||
minisrv_config = [];
|
minisrv_config = [];
|
||||||
|
update_ticket = false;
|
||||||
|
ticket_store = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -87,11 +89,15 @@ class WTVSec {
|
|||||||
*/
|
*/
|
||||||
PrepareTicket() {
|
PrepareTicket() {
|
||||||
// store last challenge response in ticket
|
// store last challenge response in ticket
|
||||||
var ticket_data = this.challenge_raw;
|
if (this.minisrv_config.config.debug_flags.debug) console.log(" * Preparing a new ticket with ticket_store:", this.ticket_store)
|
||||||
|
var ticket_data_raw = this.challenge_raw;
|
||||||
try {
|
try {
|
||||||
var ticket_data_enc = CryptoJS.DES.encrypt(ticket_data, this.initial_shared_key, {
|
var ticket_data = ticket_data_raw.toString(CryptoJS.enc.Hex) + CryptoJS.enc.Utf8.parse(JSON.stringify(this.ticket_store)).toString(CryptoJS.enc.Hex);
|
||||||
|
|
||||||
|
ticket_data_raw = CryptoJS.enc.Hex.parse(ticket_data);
|
||||||
|
var ticket_data_enc = CryptoJS.DES.encrypt(ticket_data_raw, this.initial_shared_key, {
|
||||||
mode: CryptoJS.mode.ECB,
|
mode: CryptoJS.mode.ECB,
|
||||||
padding: CryptoJS.pad.NoPadding
|
padding: CryptoJS.pad.Pkcs7
|
||||||
});
|
});
|
||||||
// create a copy of WordArray since concat modifies the original
|
// create a copy of WordArray since concat modifies the original
|
||||||
var challenge_signed_key = this.DuplicateWordArray(this.challenge_signed_key);
|
var challenge_signed_key = this.DuplicateWordArray(this.challenge_signed_key);
|
||||||
@@ -103,6 +109,17 @@ class WTVSec {
|
|||||||
return this.ticket_b64;
|
return this.ticket_b64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tryDecodeJSON(json_string) {
|
||||||
|
var out;
|
||||||
|
try {
|
||||||
|
out = JSON.parse(json_string);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
out = {};
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes a wtv-ticket to set up this instance
|
* Decodes a wtv-ticket to set up this instance
|
||||||
*
|
*
|
||||||
@@ -112,6 +129,7 @@ class WTVSec {
|
|||||||
var ticket_hex = CryptoJS.enc.Base64.parse(ticket_b64).toString(CryptoJS.enc.Hex);
|
var ticket_hex = CryptoJS.enc.Base64.parse(ticket_b64).toString(CryptoJS.enc.Hex);
|
||||||
var challenge_key = CryptoJS.enc.Hex.parse(ticket_hex.substring(0, 16));
|
var challenge_key = CryptoJS.enc.Hex.parse(ticket_hex.substring(0, 16));
|
||||||
var challenge_enc = CryptoJS.enc.Hex.parse(ticket_hex.substring(16));
|
var challenge_enc = CryptoJS.enc.Hex.parse(ticket_hex.substring(16));
|
||||||
|
|
||||||
var ticket_dec = CryptoJS.DES.decrypt(
|
var ticket_dec = CryptoJS.DES.decrypt(
|
||||||
{
|
{
|
||||||
ciphertext: challenge_enc
|
ciphertext: challenge_enc
|
||||||
@@ -119,11 +137,46 @@ class WTVSec {
|
|||||||
this.initial_shared_key,
|
this.initial_shared_key,
|
||||||
{
|
{
|
||||||
mode: CryptoJS.mode.ECB,
|
mode: CryptoJS.mode.ECB,
|
||||||
padding: CryptoJS.pad.NoPadding
|
padding: CryptoJS.pad.Pkcs7
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.ProcessChallenge(ticket_dec.toString(CryptoJS.enc.Base64), challenge_key);
|
var data_offset = 216; // (108 * 2);
|
||||||
console.log(" * Decoded session from wtv-ticket");
|
var challenge_code = ticket_dec.toString().substring(0, data_offset);
|
||||||
|
var challenge_code_b64 = CryptoJS.enc.Hex.parse(challenge_code).toString(CryptoJS.enc.Base64);
|
||||||
|
if ((ticket_dec.sigBytes * 2) >= challenge_code.length) {
|
||||||
|
var ticket_data_dec = CryptoJS.enc.Hex.parse(ticket_dec.toString().substring(data_offset)).toString(CryptoJS.enc.Utf8);
|
||||||
|
this.ticket_store = this.tryDecodeJSON(ticket_data_dec);
|
||||||
|
} else {
|
||||||
|
this.ticket_store = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ProcessChallenge(challenge_code_b64, challenge_key);
|
||||||
|
if (this.minisrv_config.config.debug_flags.debug) console.log(" * Decoded session from wtv-ticket with ticket_store:", this.ticket_store);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTicketData(key = null) {
|
||||||
|
if (typeof (this.ticket_store) === 'session_store') return null;
|
||||||
|
else if (key === null) return this.ticket_store;
|
||||||
|
else return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTicketData(key, value) {
|
||||||
|
if (key === null) throw ("WTVSec.ssetTicketDataet(): invalid key provided");
|
||||||
|
if (typeof (this.ticket_store) === 'undefined') this.ticket_store = {};
|
||||||
|
this.ticket_store[key] = value;
|
||||||
|
if (this.ticket_b64) this.PrepareTicket();
|
||||||
|
this.update_ticket = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTicketData(key) {
|
||||||
|
if (key === null) throw ("WTVSec.deleteTicketData(): invalid key provided");
|
||||||
|
if (typeof (this.ticket_store) === 'undefined') {
|
||||||
|
this.ticket_store = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete this.ticket_store[key];
|
||||||
|
if (this.ticket_b64) this.PrepareTicket();
|
||||||
|
this.update_ticket = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -405,19 +405,6 @@ Location: " + minisrv_config.config.unauthorized_url`;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (ssid_sessions[socket.ssid].isRegistered(false) && !ssid_sessions[socket.ssid].isAuthorized(shortURL, 'login', true)) {
|
|
||||||
if (!ssid_sessions[socket.ssid].getSessionData("subscriber_username")) {
|
|
||||||
headers = `300 Session Error
|
|
||||||
Location: client:relogin`;
|
|
||||||
data = "";
|
|
||||||
sendToClient(socket, headers, data);
|
|
||||||
console.log(" * Session error: Asking client to relogin via socket ID", socket.id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Check URL for :/, but not :// (to differentiate wtv urls)
|
// Check URL for :/, but not :// (to differentiate wtv urls)
|
||||||
if (shortURL.indexOf(':/') >= 0 && shortURL.indexOf('://') == -1) {
|
if (shortURL.indexOf(':/') >= 0 && shortURL.indexOf('://') == -1) {
|
||||||
var ssid = socket.ssid;
|
var ssid = socket.ssid;
|
||||||
@@ -802,6 +789,7 @@ async function sendToClient(socket, headers_obj, data) {
|
|||||||
if (headers_obj["secure"]) delete headers_obj["secure"];
|
if (headers_obj["secure"]) delete headers_obj["secure"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// calculate content length
|
// calculate content length
|
||||||
// make sure we are using our Content-length and not one set in a script.
|
// make sure we are using our Content-length and not one set in a script.
|
||||||
if (headers_obj["Content-Length"]) delete headers_obj["Content-Length"];
|
if (headers_obj["Content-Length"]) delete headers_obj["Content-Length"];
|
||||||
@@ -809,13 +797,14 @@ async function sendToClient(socket, headers_obj, data) {
|
|||||||
|
|
||||||
headers_obj["Content-length"] = content_length;
|
headers_obj["Content-length"] = content_length;
|
||||||
|
|
||||||
|
// Send wtv-ticket if it has been flagged as updated
|
||||||
if (ssid_sessions[socket.ssid]) {
|
if (ssid_sessions[socket.ssid]) {
|
||||||
if (ssid_sessions[socket.ssid].data_store.wtvsec_login) {
|
if (ssid_sessions[socket.ssid].data_store.wtvsec_login) {
|
||||||
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64) {
|
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64) {
|
||||||
if (ssid_sessions[socket.ssid].data_store.update_ticket) {
|
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.update_ticket) {
|
||||||
headers_obj["wtv-ticket"] = ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64;
|
headers_obj["wtv-ticket"] = ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64;
|
||||||
headers_obj = moveObjectElement("wtv-ticket", "Connection", headers_obj);
|
headers_obj = moveObjectElement("wtv-ticket", "Connection", headers_obj);
|
||||||
ssid_sessions[socket.ssid].data_store.update_ticket = false;
|
ssid_sessions[socket.ssid].data_store.wtvsec_login.update_ticket = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1077,12 +1066,21 @@ async function processRequest(socket, data_hex, skipSecure = false, encryptedReq
|
|||||||
if (headers["wtv-incarnation"]) ssid_sessions[socket.ssid].data_store.wtvsec_login.set_incarnation(headers["wtv-incarnation"]);
|
if (headers["wtv-incarnation"]) ssid_sessions[socket.ssid].data_store.wtvsec_login.set_incarnation(headers["wtv-incarnation"]);
|
||||||
ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 = headers["wtv-ticket"];
|
ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 = headers["wtv-ticket"];
|
||||||
ssid_sessions[socket.ssid].data_store.wtvsec_login.DecodeTicket(ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64);
|
ssid_sessions[socket.ssid].data_store.wtvsec_login.DecodeTicket(ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64);
|
||||||
|
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_store.user_id) {
|
||||||
|
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_store.user_id > 0)
|
||||||
|
ssid_sessions[socket.ssid].switchUserID(ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_store.user_id, true, false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 != headers["wtv-ticket"]) {
|
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 != headers["wtv-ticket"])
|
||||||
|
if (!ssid_sessions[socket.ssid].data_store.wtvsec_login.update_ticket) {
|
||||||
if (minisrv_config.config.debug_flags.debug) console.log(" # New ticket from client");
|
if (minisrv_config.config.debug_flags.debug) console.log(" # New ticket from client");
|
||||||
ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 = headers["wtv-ticket"];
|
ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 = headers["wtv-ticket"];
|
||||||
ssid_sessions[socket.ssid].data_store.wtvsec_login.DecodeTicket(ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64);
|
ssid_sessions[socket.ssid].data_store.wtvsec_login.DecodeTicket(ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64);
|
||||||
if (headers["wtv-incarnation"]) ssid_sessions[socket.ssid].data_store.wtvsec_login.set_incarnation(headers["wtv-incarnation"]);
|
if (headers["wtv-incarnation"]) ssid_sessions[socket.ssid].data_store.wtvsec_login.set_incarnation(headers["wtv-incarnation"]);
|
||||||
|
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_store.user_id > 0) {
|
||||||
|
if (ssid_sessions[socket.ssid].user_id != ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_store.user_id)
|
||||||
|
switchUserID(ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_store.user_id, true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user