>>4&15)+e.charAt(15&t);return o}function v(n){return unescape(encodeURIComponent(n))}function m(n){return d(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this);
-
-if (lwsgs_user.substring(0, 1) == "$") {
- alert("lwsgs.js: lws generic sessions misconfigured and not providing vars");
-}
-function lwsgs_san(s)
-{
- if (s.search("<") != -1)
- return "invalid string";
-
- return s;
-}
-
-function lwsgs_update()
-{
- var en_login = 1, en_forgot = 1;
-
- if (document.getElementById('password').value.length &&
- document.getElementById('password').value.length < 8)
- en_login = 0;
-
- if (!document.getElementById('username').value ||
- !document.getElementById('password').value)
- en_login = 0;
-
- if (!document.getElementById('username').value ||
- document.getElementById('password').value)
- en_forgot = 0;
-
- document.getElementById('login').disabled = !en_login;
- document.getElementById('forgot').disabled = !en_forgot;
-
- if (lwsgs_user)
- document.getElementById("curuser").innerHTML = lwsgs_san(lwsgs_user);
-
- if (lwsgs_user === "")
- document.getElementById("dlogin").style.display = "inline";
- else
- document.getElementById("dlogout").style.display = "inline";
- }
-
-function lwsgs_open_registration()
-{
- document.getElementById("dadmin").style.display = "none";
- document.getElementById("dlogin").style.display = "none";
- document.getElementById("dlogout").style.display = "none";
- document.getElementById("dchange").style.display = "none";
- document.getElementById("dregister").style.display = "inline";
-}
-
-function lwsgs_cancel_registration()
-{
- document.getElementById("dadmin").style.display = "none";
- document.getElementById("dregister").style.display = "none";
- document.getElementById("dchange").style.display = "none";
-
- if (lwsgs_user === "")
- document.getElementById("dlogin").style.display = "inline";
- else
- document.getElementById("dlogout").style.display = "inline";
-}
-
-function lwsgs_select_change()
-{
- document.getElementById("dlogin").style.display = "none";
- document.getElementById("dlogout").style.display = "none";
- document.getElementById("dregister").style.display = "none";
- if (lwsgs_auth & 2) {
- document.getElementById("dadmin").style.display = "inline";
- document.getElementById("dchange").style.display = "none";
- } else {
- document.getElementById("dadmin").style.display = "none";
- document.getElementById("dchange").style.display = "inline";
- }
-
- event.preventDefault()
-}
-
-var lwsgs_user_check = '0';
-var lwsgs_email_check = '0';
-
-function lwsgs_rupdate()
-{
- var en_register = 1, en_forgot = 0, op;
-
- if (document.getElementById('rpassword').value ==
- document.getElementById('password2').value) {
- if (document.getElementById('rpassword').value.length)
- document.getElementById('match').innerHTML =
- "\u2713";
- else
- document.getElementById('match').innerHTML = "";
- document.getElementById('pw2').style = "";
- } else {
- if (document.getElementById('password2').value ||
- document.getElementById('email').value) { // ie, he is filling in "register" path and cares
- document.getElementById('match').innerHTML =
- "\u2718 Passwords do not match";
- } else
- document.getElementById('match').innerHTML =
- "\u2718 Passwords do not match";
-
- en_register = 0;
- }
-
- if (document.getElementById('rpassword').value.length &&
- document.getElementById('rpassword').value.length < 8) {
- en_register = 0;
- document.getElementById('rpw1').innerHTML = "Need 8 chars";
- } else
- if (document.getElementById('rpassword').value.length)
- document.getElementById('rpw1').innerHTML = "\u2713";
- else
- document.getElementById('rpw1').innerHTML = "";
-
- if (!document.getElementById('rpassword').value ||
- !document.getElementById('password2').value ||
- !document.getElementById('rusername').value ||
- !document.getElementById('email').value ||
- lwsgs_email_check === '1'||
- lwsgs_user_check === '1')
- en_register = 0;
-
- document.getElementById('register').disabled = !en_register;
- document.getElementById('rpassword').disabled = lwsgs_user_check === '1';
- document.getElementById('password2').disabled = lwsgs_user_check === '1';
- document.getElementById('email').disabled = lwsgs_user_check === '1';
-
- if (lwsgs_user_check === '0') {
- var uc = document.getElementById('uchk');
-
- if (uc) {
- if (document.getElementById('rusername').value)
- uc.innerHTML = "\u2713";
- else
- uc.innerHTML = "";
- }
- } else {
- if (document.getElementById('uchk'))
- ocument.getElementById('uchk').innerHTML = "\u2718 Already registered";
- en_forgot = 1;
- }
-
- if (lwsgs_email_check === '0') {
- var ec = document.getElementById('echk');
-
- if (ec) {
- if (document.getElementById('email').value)
- ec.innerHTML = "\u2713";
- else
- ec.innerHTML = "";
- }
- } else {
- if (document.getElementById('echk'))
- document.getElementById('echk').innerHTML = "\u2718 Already registered";
- en_forgot = 1;
- }
-
- if (en_forgot)
- document.getElementById('rforgot').style.display = "inline";
- else
- document.getElementById('rforgot').style.display = "none";
-
- if (lwsgs_user_check === '1')
- op = '0.5';
- else
- op = '1.0';
- document.getElementById('rpassword').style.opacity = op;
- document.getElementById('password2').style.opacity = op;
- document.getElementById('email').style.opacity = op;
- }
-
-function lwsgs_cupdate()
-{
- var en_change = 1, en_forgot = 1, pwok = 1, op;
-
- if (lwsgs_auth & 8) {
- document.getElementById('ccurpw').style.display = "none";
- document.getElementById('ccurpw_name').style.display = "none";
- } else {
- if (!document.getElementById('ccurpw').value ||
- document.getElementById('ccurpw').value.length < 8) {
- en_change = 0;
- pwok = 0;
- document.getElementById('cuchk').innerHTML = "\u2718";
- } else {
- en_forgot = 0;
- document.getElementById('cuchk').innerHTML = "";
- }
- document.getElementById('ccurpw').style.display = "inline";
- document.getElementById('ccurpw_name').style.display = "inline";
- }
-
- if (document.getElementById('cpassword').value ==
- document.getElementById('cpassword2').value) {
- if (document.getElementById('cpassword').value.length)
- document.getElementById('cmatch').innerHTML = "\u2713";
- else
- document.getElementById('cmatch').innerHTML = "";
- document.getElementById('pw2').style = "";
- } else {
- if (document.getElementById('cpassword2').value //||
- //document.getElementById('cemail').value
- ) { // ie, he is filling in "register" path and cares
- document.getElementById('cmatch').innerHTML =
- "\u2718 Passwords do not match";
- } else
- document.getElementById('cmatch').innerHTML = "\u2718 Passwords do not match";
-
- en_change = 0;
- }
-
- if (document.getElementById('cpassword').value.length &&
- document.getElementById('cpassword').value.length < 8) {
- en_change = 0;
- document.getElementById('cpw1').innerHTML = "Need 8 chars";
- } else {
- var cpw = document.getElementById('cpw1');
-
- if (cpw) {
- if (document.getElementById('cpassword').value.length)
- cpw.innerHTML = "\u2713";
- else
- cpw.innerHTML = "";
- }
- }
-
- if (!document.getElementById('cpassword').value ||
- !document.getElementById('cpassword2').value ||
- pwok === 0)
- en_change = 0;
-
- if (document.getElementById('showdel').checked)
- document.getElementById('delete').style.display = "inline";
- else
- document.getElementById('delete').style.display = "none";
-
- document.getElementById('change').disabled = !en_change;
- document.getElementById('cpassword').disabled = pwok === 0;
- document.getElementById('cpassword2').disabled = pwok === 0;
- document.getElementById('showdel').disabled = pwok === 0;
- document.getElementById('delete').disabled = pwok === 0;
- //document.getElementById('cemail').disabled = pwok === 0;
-
- /*
- if (lwsgs_auth & 8) {
- document.getElementById('cemail').style.display = "none";
- document.getElementById('cemail_name').style.display = "none";
- } else {
- document.getElementById('cemail').style.display = "inline";
- document.getElementById('cemail_name').style.display = "inline";
- if (lwsgs_email_check === '0' &&
- document.getElementById('cemail').value != lwsgs_email) {
- if (document.getElementById('cemail').value)
- document.getElementById('cechk').innerHTML = "\u2713";
- else
- document.getElementById('cechk').innerHTML = "";
- } else {
- document.getElementById('cechk').innerHTML = "\u2718 Already registered";
- en_forgot = 1;
- }
- } */
-
- if (lwsgs_auth & 8)
- en_forgot = 0;
-
- if (en_forgot)
- document.getElementById('cforgot').style.display = "inline";
- else
- document.getElementById('cforgot').style.display = "none";
-
- if (pwok === 0)
- op = '0.5';
- else
- op = '1.0';
- document.getElementById('cpassword').style.opacity = op;
- document.getElementById('cpassword2').style.opacity = op;
- // document.getElementById('cemail').style.opacity = op;
- }
-
-function lwsgs_check_user()
-{
- var xmlHttp = new XMLHttpRequest();
- xmlHttp.onreadystatechange = function() {
- if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
- lwsgs_user_check = xmlHttp.responseText;
- lwsgs_rupdate();
- }
- }
- xmlHttp.open("GET", "lwsgs-check?username="+document.getElementById('rusername').value, true);
- xmlHttp.send(null);
-}
-
-function lwsgs_check_email(id)
-{
- var xmlHttp = new XMLHttpRequest();
- xmlHttp.onreadystatechange = function() {
- if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
- lwsgs_email_check = xmlHttp.responseText;
- lwsgs_rupdate();
- }
- }
- xmlHttp.open("GET", "lwsgs-check?email="+document.getElementById(id).value, true);
- xmlHttp.send(null);
-}
-
-function rupdate_user()
-{
- lwsgs_rupdate();
- lwsgs_check_user();
-}
-
-function rupdate_email()
-{
- lwsgs_rupdate();
- lwsgs_check_email('email');
-}
-
-function cupdate_email()
-{
- lwsgs_cupdate();
- lwsgs_check_email('cemail');
-}
-
-
-function lwsgs_initial()
-{
- document.getElementById('lwsgs').innerHTML = lwsgs_html;
-
- if (lwsgs_user) {
- document.getElementById("curuser").innerHTML =
- "currently logged in as " + lwsgs_san(lwsgs_user) + "";
-
- document.getElementById("ccuruser").innerHTML =
- "Login settings for " +
- lwsgs_san(lwsgs_user) + "";
- }
-
- document.getElementById('username').oninput = lwsgs_update;
- document.getElementById('username').onchange = lwsgs_update;
- document.getElementById('password').oninput = lwsgs_update;
- document.getElementById('password').onchange = lwsgs_update;
- document.getElementById('doreg').onclick = lwsgs_open_registration;
- document.getElementById('clink').onclick = lwsgs_select_change;
- document.getElementById('cancel').onclick =lwsgs_cancel_registration;
- document.getElementById('cancel2').onclick =lwsgs_cancel_registration;
- document.getElementById('rpassword').oninput = lwsgs_rupdate;
- document.getElementById('password2').oninput = lwsgs_rupdate;
- document.getElementById('rusername').oninput = rupdate_user;
- document.getElementById('email').oninput = rupdate_email;
- document.getElementById('ccurpw').oninput = lwsgs_cupdate;
- document.getElementById('cpassword').oninput = lwsgs_cupdate;
- document.getElementById('cpassword2').oninput = lwsgs_cupdate;
-
- document.getElementById('showdel').onchange = lwsgs_cupdate;
-
- if (lwsgs_email)
- document.getElementById('grav').innerHTML =
- "
";
- //if (lwsgs_email)
- //document.getElementById('cemail').placeholder = lwsgs_email;
- document.getElementById('cusername').value = lwsgs_user;
- lwsgs_update();
- lwsgs_cupdate();
-}
-
-window.addEventListener("load", function() {
- lwsgs_initial();
- document.getElementById("nolog").style.display = !!lwsgs_user ? "none" : "inline-block";
- document.getElementById("logged").style.display = !lwsgs_user ? "none" : "inline-block";
-
- document.getElementById("msg").onkeyup = mupd;
- document.getElementById("msg").onchange = mupd;
-
- var ws;
-
- function mb_format(s)
- {
- var r = "", n, wos = 0;
-
- for (n = 0; n < s.length; n++) {
- if (s[n] == ' ')
- wos = 0;
- else {
- wos++;
- if (wos === 40) {
- wos = 0;
- r = r + ' ';
- }
- }
- if (s[n] == '<') {
- r = r + "<";
- continue;
- }
- if (s[n] == '\n') {
- r = r + "
";
- continue;
- }
-
- r = r + s[n];
- }
-
- return r;
- }
-
- function add_div(n, m)
- {
- var q = document.getElementById(n);
- var d = new Date(m.time * 1000);
-
- q.innerHTML = "
" +
- " " +
- "" + lwsgs_san(m.username) + " " +
- "" + d.toDateString() +
- " " + d.toTimeString() + " " +
- "IP: " + lwsgs_san(m.ip) +
- " | " +
- mb_format(m.content) +
- " |
" + q.innerHTML;
- }
-
- function get_appropriate_ws_url()
- {
- var pcol;
- var u = document.URL;
-
- if (u.substring(0, 5) == "https") {
- pcol = "wss://";
- u = u.substr(8);
- } else {
- pcol = "ws://";
- if (u.substring(0, 4) == "http")
- u = u.substr(7);
- }
- u = u.split('/');
-
- return pcol + u[0] + "/xxx";
- }
-
- if (lwsgs_user) {
- ws = new WebSocket(get_appropriate_ws_url(),
- "protocol-lws-messageboard");
-
- try {
- ws.onopen = function() {
- document.getElementById("debug").textContent = "ws opened";
- }
- ws.onmessage =function got_packet(msg) {
- add_div("messages", JSON.parse(msg.data));
- }
- ws.onclose = function(){
- }
- } catch(exception) {
- alert('Error' + exception);
- }
- }
-
- function mupd()
- {
- document.getElementById("send").disabled = !document.getElementById("msg").value;
- }
-}, false);
diff --git a/plugins/generic-sessions/assets/md5.min.js b/plugins/generic-sessions/assets/md5.min.js
deleted file mode 100644
index 4bd9de1e9..000000000
--- a/plugins/generic-sessions/assets/md5.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t),e=(n>>16)+(t>>16)+(r>>16);return e<<16|65535&r}function r(n,t){return n<>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<>>9<<4)+14]=r;var e,i,a,h,d,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e>5]>>>t%32&255);return r}function h(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t>5]|=(255&n.charCodeAt(t/8))<16&&(o=i(o,8*n.length)),r=0;16>r;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(h(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="0123456789abcdef",o="";for(r=0;r>>4&15)+e.charAt(15&t);return o}function v(n){return unescape(encodeURIComponent(n))}function m(n){return d(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this);
-//# sourceMappingURL=md5.min.js.map
\ No newline at end of file
diff --git a/plugins/generic-sessions/assets/post-forgot-fail.html b/plugins/generic-sessions/assets/post-forgot-fail.html
deleted file mode 100644
index ead3d13ec..000000000
--- a/plugins/generic-sessions/assets/post-forgot-fail.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-Sorry, something went wrong.
-
-Click here to continue.
-
diff --git a/plugins/generic-sessions/assets/post-forgot-ok.html b/plugins/generic-sessions/assets/post-forgot-ok.html
deleted file mode 100644
index 3e8e9cf59..000000000
--- a/plugins/generic-sessions/assets/post-forgot-ok.html
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This is a one-time password recovery login.
-
-Please click here and click your username at the top to reset your password.
-
-
diff --git a/plugins/generic-sessions/assets/post-register-fail.html b/plugins/generic-sessions/assets/post-register-fail.html
deleted file mode 100644
index 063c3c50f..000000000
--- a/plugins/generic-sessions/assets/post-register-fail.html
+++ /dev/null
@@ -1 +0,0 @@
-Registration failed, sorry
diff --git a/plugins/generic-sessions/assets/post-register-ok.html b/plugins/generic-sessions/assets/post-register-ok.html
deleted file mode 100644
index c00c3f3d2..000000000
--- a/plugins/generic-sessions/assets/post-register-ok.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
- |
-
-
-
- Your registration as is accepted,
- you will receive an email shortly with instructions
- to verify and enable the account for normal use.
- The link is only valid for an hour, after that if it has
- not been verified your account will be deleted.
- |
-
-
-
-
-
-
diff --git a/plugins/generic-sessions/assets/post-verify-fail.html b/plugins/generic-sessions/assets/post-verify-fail.html
deleted file mode 100644
index d1d89ca56..000000000
--- a/plugins/generic-sessions/assets/post-verify-fail.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
- |
-
-
-
- Sorry, the link was invalid.
- |
-
-
-
-
-
diff --git a/plugins/generic-sessions/assets/post-verify-ok.html b/plugins/generic-sessions/assets/post-verify-ok.html
deleted file mode 100644
index ae647fc5c..000000000
--- a/plugins/generic-sessions/assets/post-verify-ok.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
- |
-
-
-
- Thanks for signing up, your registration as is verified.
-
- Click here to continue.
- |
-
-
-
-
-
-
diff --git a/plugins/generic-sessions/assets/seats.jpg b/plugins/generic-sessions/assets/seats.jpg
deleted file mode 100644
index 5bed40d91..000000000
Binary files a/plugins/generic-sessions/assets/seats.jpg and /dev/null differ
diff --git a/plugins/generic-sessions/assets/sent-forgot-fail.html b/plugins/generic-sessions/assets/sent-forgot-fail.html
deleted file mode 100644
index ead3d13ec..000000000
--- a/plugins/generic-sessions/assets/sent-forgot-fail.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-Sorry, something went wrong.
-
-Click here to continue.
-
diff --git a/plugins/generic-sessions/assets/sent-forgot-ok.html b/plugins/generic-sessions/assets/sent-forgot-ok.html
deleted file mode 100644
index 83df7510a..000000000
--- a/plugins/generic-sessions/assets/sent-forgot-ok.html
+++ /dev/null
@@ -1,4 +0,0 @@
-An email has been sent to your registered address.
-
-Please follow the instructions to reset your password.
-
diff --git a/plugins/generic-sessions/assets/successful-login.html b/plugins/generic-sessions/assets/successful-login.html
deleted file mode 100644
index dfc25cf74..000000000
--- a/plugins/generic-sessions/assets/successful-login.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-This is an example destination that will appear after successful non-Admin login
-
-
diff --git a/plugins/generic-sessions/handlers.c b/plugins/generic-sessions/handlers.c
deleted file mode 100644
index 604841248..000000000
--- a/plugins/generic-sessions/handlers.c
+++ /dev/null
@@ -1,663 +0,0 @@
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "private-lwsgs.h"
-
-#if defined(LWS_WITH_SMTP)
-
-static int
-lwsgs_smtp_client_done(struct lws_smtp_email *e, void *buf, size_t len)
-{
- free(e);
-
- return 0;
-}
-
-static int
-lwsgs_smtp_client_done_sentvfy(struct lws_smtp_email *e, void *buf, size_t len)
-{
- struct per_vhost_data__gs *vhd = (struct per_vhost_data__gs *)e->data;
- const char *username = (const char *)e->extra;
- char s[200], esc[96];
-
- lwsl_notice("%s: registration email sent: %s\n", __func__, username);
-
- /* mark the user as having sent the verification email */
- lws_snprintf(s, sizeof(s) - 1,
- "update users set verified=1 where username='%s' and verified==0;",
- lws_sql_purify(esc, username, sizeof(esc) - 1));
- if (sqlite3_exec(vhd->pdb, s, NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("%s: Unable to update user: %s\n", __func__,
- sqlite3_errmsg(vhd->pdb));
- return 1;
- }
-
- free(e);
-
- return 0;
-}
-#endif
-
-/* handle account confirmation links */
-
-int
-lwsgs_handler_confirm(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss)
-{
- char cookie[1024], s[256], esc[90];
- struct lws_gs_event_args a;
- struct lwsgs_user u;
-
- if (lws_hdr_copy_fragment(wsi, cookie, sizeof(cookie),
- WSI_TOKEN_HTTP_URI_ARGS, 0) < 0) {
- lwsl_err("%s: missing URI_ARGS\n", __func__);
- goto verf_fail;
- }
-
- if (strncmp(cookie, "token=", 6)) {
- lwsl_err("%s: missing URI_ARGS token=\n", __func__);
- goto verf_fail;
- }
-
- u.username[0] = '\0';
- u.verified = -1;
- lws_snprintf(s, sizeof(s) - 1,
- "select username,email,verified from users where token = '%s';",
- lws_sql_purify(esc, &cookie[6], sizeof(esc) - 1));
- puts(s);
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback_user, &u, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
- goto verf_fail;
- }
-
- if (!u.username[0] || u.verified != 1) {
- lwsl_notice("verify token %s doesn't map to unverified user (user='%s', verified=%d)\n",
- &cookie[6], u.username, u.verified);
- goto verf_fail;
- }
-
- lwsl_notice("Verifying %s\n", u.username);
- lws_snprintf(s, sizeof(s) - 1,
- "update users set verified=%d where username='%s';",
- LWSGS_VERIFIED_ACCEPTED,
- lws_sql_purify(esc, u.username, sizeof(esc) - 1));
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback_user, &u, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- goto verf_fail;
- }
-
- lwsl_notice("deleting account\n");
-
- a.event = LWSGSE_CREATED;
- a.username = u.username;
- a.email = u.email;
- lws_callback_vhost_protocols_vhost(lws_get_vhost(wsi),
- LWS_CALLBACK_GS_EVENT, &a, 0);
-
- lws_snprintf(pss->onward, sizeof(pss->onward),
- "%s/post-verify-ok.html", vhd->email_confirm_url);
-
- pss->login_expires = lws_now_secs() + vhd->timeout_absolute_secs;
-
- pss->delete_session.id[0] = '\0';
- lwsgs_get_sid_from_wsi(wsi, &pss->delete_session);
-
- /* we need to create a new, authorized session */
-
- if (lwsgs_new_session_id(vhd, &pss->login_session, u.username,
- pss->login_expires))
- goto verf_fail;
-
- lwsl_notice("Creating new session: %s, redir to %s\n",
- pss->login_session.id, pss->onward);
-
- return 0;
-
-verf_fail:
- pss->delete_session.id[0] = '\0';
- lwsgs_get_sid_from_wsi(wsi, &pss->delete_session);
- pss->login_expires = 0;
-
- lws_snprintf(pss->onward, sizeof(pss->onward), "%s/post-verify-fail.html",
- vhd->email_confirm_url);
-
- return 1;
-}
-
-/* handle forgot password confirmation links */
-
-int
-lwsgs_handler_forgot(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss)
-{
- char cookie[1024], s[256], esc[96];
- struct lwsgs_user u;
- const char *a;
-
- a = lws_get_urlarg_by_name(wsi, "token=", cookie, sizeof(cookie));
- if (!a)
- goto forgot_fail;
-
- u.username[0] = '\0';
- lws_snprintf(s, sizeof(s) - 1,
- "select username,verified from users where verified=%d and "
- "token = '%s' and token_time != 0;",
- LWSGS_VERIFIED_ACCEPTED,
- lws_sql_purify(esc, &cookie[6], sizeof(esc) - 1));
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback_user, &u, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- goto forgot_fail;
- }
-
- if (!u.username[0]) {
- puts(s);
- lwsl_notice("forgot token doesn't map to verified user\n");
- goto forgot_fail;
- }
-
- /* mark user as having validated forgot flow just now */
-
- lws_snprintf(s, sizeof(s) - 1,
- "update users set token_time=0,last_forgot_validated=%lu "
- "where username='%s';",
- (unsigned long)lws_now_secs(),
- lws_sql_purify(esc, u.username, sizeof(esc) - 1));
-
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback_user, &u, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
- goto forgot_fail;
- }
-
- a = lws_get_urlarg_by_name(wsi, "good=", cookie, sizeof(cookie));
- if (!a)
- a = "broken-forget-post-good-url";
-
- lws_snprintf(pss->onward, sizeof(pss->onward),
- "%s/%s", vhd->email_confirm_url, a);
-
- pss->login_expires = lws_now_secs() + vhd->timeout_absolute_secs;
-
- pss->delete_session.id[0] = '\0';
- lwsgs_get_sid_from_wsi(wsi, &pss->delete_session);
-
- /* we need to create a new, authorized session */
- if (lwsgs_new_session_id(vhd, &pss->login_session,
- u.username,
- pss->login_expires))
- goto forgot_fail;
-
- lwsl_notice("Creating new session: %s, redir to %s\n",
- pss->login_session.id, pss->onward);
-
- return 0;
-
-forgot_fail:
- pss->delete_session.id[0] = '\0';
- lwsgs_get_sid_from_wsi(wsi, &pss->delete_session);
- pss->login_expires = 0;
-
- a = lws_get_urlarg_by_name(wsi, "bad=", cookie, sizeof(cookie));
- if (!a)
- a = "broken-forget-post-bad-url";
-
- lws_snprintf(pss->onward, sizeof(pss->onward), "%s/%s",
- vhd->email_confirm_url, a);
-
- return 1;
-}
-
-/* support dynamic username / email checking */
-
-int
-lwsgs_handler_check(struct per_vhost_data__gs *vhd,
- struct lws *wsi, struct per_session_data__gs *pss,
- const char *in)
-{
- static const char * const colname[] = { "username", "email" };
- char s[256], esc[96], *pc;
- unsigned char *p, *start, *end, buffer[LWS_PRE + 1024];
- struct lwsgs_user u;
- int n;
-
- /*
- * either /check/email=xxx@yyy or: /check/username=xxx
- * returns '0' if not already registered, else '1'
- */
-
- u.username[0] = '\0';
-
- n = !strncmp(in, "email=", 6);
- pc = strchr(in, '=');
- if (!pc) {
- lwsl_notice("cookie has no =\n");
- goto reply;
- }
- pc++;
-
- /* admin user cannot be registered in user db */
- if (!strcmp(vhd->admin_user, pc)) {
- u.username[0] = 'a';
- goto reply;
- }
-
- lws_snprintf(s, sizeof(s) - 1,
- "select username, email from users where %s = '%s';",
- colname[n], lws_sql_purify(esc, pc, sizeof(esc) - 1));
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback_user, &u, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
- goto reply;
- }
-
-reply:
- s[0] = '0' + !!u.username[0];
- p = buffer + LWS_PRE;
- start = p;
- end = p + sizeof(buffer) - LWS_PRE;
-
- if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
- return -1;
- if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
- (unsigned char *)"text/plain", 10,
- &p, end))
- return -1;
-
- if (lws_add_http_header_content_length(wsi, 1, &p, end))
- return -1;
-
- if (lws_finalize_http_header(wsi, &p, end))
- return -1;
-
- n = lws_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS);
- if (n != (p - start)) {
- lwsl_err("_write returned %d from %ld\n", n, (long)(p - start));
- return -1;
- }
-
- pss->check_response_value = s[0];
- pss->check_response = 1;
-
- lws_callback_on_writable(wsi);
-
- return 0;
-}
-
-/* handle forgot password confirmation links */
-
-int
-lwsgs_handler_change_password(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss)
-{
- char s[256], esc[96], username[96];
- struct lwsgs_user u;
- lwsgw_hash sid;
- int n = 0;
-
- /* see if he's logged in */
- username[0] = '\0';
- if (!lwsgs_get_sid_from_wsi(wsi, &sid)) {
- u.username[0] = '\0';
- if (!lwsgs_lookup_session(vhd, &sid, username, sizeof(username))) {
- n = 1; /* yes, logged in */
- if (lwsgs_lookup_user(vhd, username, &u))
- return 1;
-
- /* did a forgot pw ? */
- if (u.last_forgot_validated > (time_t)lws_now_secs() - 300) {
- n |= LWSGS_AUTH_FORGOT_FLOW;
- lwsl_debug("within forgot password flow\n");
- }
- }
- }
-
- lwsl_debug("auth value %d\n", n);
-
- /* if he just did forgot pw flow, don't need old pw */
- if ((n & (LWSGS_AUTH_FORGOT_FLOW | 1)) != (LWSGS_AUTH_FORGOT_FLOW | 1)) {
- /* otherwise user:pass must be right */
- lwsl_debug("checking pw\n");
- if (lwsgs_check_credentials(vhd,
- lws_spa_get_string(pss->spa, FGS_USERNAME),
- lws_spa_get_string(pss->spa, FGS_CURPW))) {
- lwsl_notice("credentials bad\n");
- return 1;
- }
-
- lwsl_debug("current pw checks out\n");
-
- lws_strncpy(u.username, lws_spa_get_string(pss->spa, FGS_USERNAME),
- sizeof(u.username));
- }
-
- /* does he want to delete his account? */
-
- if (lws_spa_get_length(pss->spa, FGS_DELETE)) {
- struct lws_gs_event_args a;
-
- lwsl_notice("deleting account\n");
-
- a.event = LWSGSE_DELETED;
- a.username = u.username;
- a.email = "";
- lws_callback_vhost_protocols_vhost(lws_get_vhost(wsi),
- LWS_CALLBACK_GS_EVENT, &a, 0);
-
- lws_snprintf(s, sizeof(s) - 1,
- "delete from users where username='%s';"
- "delete from sessions where username='%s';",
- lws_sql_purify(esc, u.username, sizeof(esc) - 1),
- lws_sql_purify(esc, u.username, sizeof(esc) - 1));
- goto sql;
- }
-
- if (lwsgs_hash_password(vhd, lws_spa_get_string(pss->spa, FGS_PASSWORD), &u))
- return 1;
-
- lwsl_notice("updating password hash\n");
-
- lws_snprintf(s, sizeof(s) - 1,
- "update users set pwhash='%s', pwsalt='%s', "
- "last_forgot_validated=0 where username='%s';",
- u.pwhash.id, u.pwsalt.id,
- lws_sql_purify(esc, u.username, sizeof(esc) - 1));
-
-sql:
- if (sqlite3_exec(vhd->pdb, s, NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("Unable to update pw hash: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 1;
- }
-
- return 0;
-}
-
-int
-lwsgs_handler_forgot_pw_form(struct per_vhost_data__gs *vhd,
- struct lws *wsi, struct per_session_data__gs *pss)
-{
- char esc[96], esc1[96], esc2[96], esc3[96], esc4[96];
- char s[LWSGS_EMAIL_CONTENT_SIZE];
- unsigned char sid_rand[32];
-#if defined(LWS_WITH_SMTP)
- lws_smtp_email_t *em;
-#endif
- struct lwsgs_user u;
- lwsgw_hash hash;
- int n;
-
- lwsl_notice("FORGOT %s %s\n",
- lws_spa_get_string(pss->spa, FGS_USERNAME),
- lws_spa_get_string(pss->spa, FGS_EMAIL));
-
- if (!lws_spa_get_string(pss->spa, FGS_USERNAME) &&
- !lws_spa_get_string(pss->spa, FGS_EMAIL)) {
- lwsl_err("Form must provide either "
- "username or email\n");
- return -1;
- }
-
- if (!lws_spa_get_string(pss->spa, FGS_FORGOT_GOOD) ||
- !lws_spa_get_string(pss->spa, FGS_FORGOT_BAD) ||
- !lws_spa_get_string(pss->spa, FGS_FORGOT_POST_GOOD) ||
- !lws_spa_get_string(pss->spa, FGS_FORGOT_POST_BAD)) {
- lwsl_err("Form must provide reg-good "
- "and reg-bad (and post-*)"
- "targets\n");
- return -1;
- }
-
- u.username[0] = '\0';
- if (lws_spa_get_string(pss->spa, FGS_USERNAME))
- lws_snprintf(s, sizeof(s) - 1,
- "select username,email "
- "from users where username = '%s';",
- lws_sql_purify(esc, lws_spa_get_string(pss->spa, FGS_USERNAME),
- sizeof(esc) - 1));
- else
- lws_snprintf(s, sizeof(s) - 1,
- "select username,email "
- "from users where email = '%s';",
- lws_sql_purify(esc, lws_spa_get_string(pss->spa, FGS_EMAIL), sizeof(esc) - 1));
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback_user, &u, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 1;
- }
- if (!u.username[0]) {
- lwsl_err("No match found %s\n", s);
- return 1;
- }
-
- lws_get_peer_simple(wsi, pss->ip, sizeof(pss->ip));
- if (lws_get_random(vhd->context, sid_rand,
- sizeof(sid_rand)) !=
- sizeof(sid_rand)) {
- lwsl_err("Problem getting random for token\n");
- return 1;
- }
- sha256_to_lwsgw_hash(sid_rand, &hash);
-
- lws_snprintf(s, sizeof(s) - 1,
- "update users set token='%s',token_time='%ld' where username='%s';",
- hash.id, (long)lws_now_secs(),
- lws_sql_purify(esc, u.username, sizeof(esc) - 1));
- if (sqlite3_exec(vhd->pdb, s, NULL, NULL, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to set token: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 1;
- }
-
- n = lws_snprintf(s, sizeof(s),
- "From: Forgot Password Assistant Noreply <%s>\n"
- "To: %s <%s>\n"
- "Subject: Password reset request\n"
- "\n"
- "Hello, %s\n\n"
- "We received a password reset request from IP %s for this email,\n"
- "to confirm you want to do that, please click the link below.\n\n",
- lws_sql_purify(esc, vhd->email_from, sizeof(esc) - 1),
- lws_sql_purify(esc1, u.username, sizeof(esc1) - 1),
- lws_sql_purify(esc2, u.email, sizeof(esc2) - 1),
- lws_sql_purify(esc3, u.username, sizeof(esc3) - 1),
- lws_sql_purify(esc4, pss->ip, sizeof(esc4) - 1));
- lws_snprintf(s + n, sizeof(s) - n,
- "%s/lwsgs-forgot?token=%s"
- "&good=%s"
- "&bad=%s\n\n"
- "If this request is unexpected, please ignore it and\n"
- "no further action will be taken.\n\n"
- "If you have any questions or concerns about this\n"
- "automated email, you can contact a real person at\n"
- "%s.\n"
- "\n.\n",
- vhd->email_confirm_url, hash.id,
- lws_urlencode(esc1,
- lws_spa_get_string(pss->spa, FGS_FORGOT_POST_GOOD),
- sizeof(esc1) - 1),
- lws_urlencode(esc3,
- lws_spa_get_string(pss->spa, FGS_FORGOT_POST_BAD),
- sizeof(esc3) - 1),
- vhd->email_contact_person);
-
- puts(s);
-#if defined(LWS_WITH_SMTP)
-
- em = lws_smtpc_alloc_email_helper(s, n, vhd->email_from, u.email,
- u.username, strlen(u.username),
- vhd, lwsgs_smtp_client_done);
- if (!em)
- return 1;
- if (lws_smtpc_add_email(vhd->smtp_client, em))
- return 1;
-#endif
- return 0;
-}
-
-int
-lwsgs_handler_register_form(struct per_vhost_data__gs *vhd,
- struct lws *wsi,
- struct per_session_data__gs *pss)
-{
- unsigned char buffer[LWS_PRE + LWSGS_EMAIL_CONTENT_SIZE];
- char esc[96], esc1[96], esc2[96], esc3[96], esc4[96];
- char s[LWSGS_EMAIL_CONTENT_SIZE];
- unsigned char sid_rand[32];
-#if defined(LWS_WITH_SMTP)
- lws_smtp_email_t *em;
-#endif
- struct lwsgs_user u;
- lwsgw_hash hash;
- size_t n;
-
- lwsl_notice("REGISTER %s %s %s\n",
- lws_spa_get_string(pss->spa, FGS_USERNAME),
- lws_spa_get_string(pss->spa, FGS_PASSWORD),
- lws_spa_get_string(pss->spa, FGS_EMAIL));
- if (lwsgs_get_sid_from_wsi(wsi,
- &pss->login_session))
- return 1;
-
- lws_get_peer_simple(wsi, pss->ip, sizeof(pss->ip));
- lwsl_notice("IP=%s\n", pss->ip);
-
- if (!lws_spa_get_string(pss->spa, FGS_REG_GOOD) ||
- !lws_spa_get_string(pss->spa, FGS_REG_BAD)) {
- lwsl_info("Form must provide reg-good and reg-bad targets\n");
- return -1;
- }
-
- /* admin user cannot be registered in user db */
- if (!strcmp(vhd->admin_user,
- lws_spa_get_string(pss->spa, FGS_USERNAME)))
- return 1;
-
- if (!lwsgs_lookup_user(vhd,
- lws_spa_get_string(pss->spa, FGS_USERNAME), &u)) {
- lwsl_notice("user %s already registered\n",
- lws_spa_get_string(pss->spa, FGS_USERNAME));
- return 1;
- }
-
- u.username[0] = '\0';
- lws_snprintf(s, sizeof(s) - 1, "select username, email from users where email = '%s';",
- lws_sql_purify(esc, lws_spa_get_string(pss->spa, FGS_EMAIL),
- sizeof(esc) - 1));
-
- if (sqlite3_exec(vhd->pdb, s,
- lwsgs_lookup_callback_user, &u, NULL) != SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 1;
- }
-
- if (u.username[0]) {
- lwsl_notice("email %s already in use\n",
- lws_spa_get_string(pss->spa, FGS_USERNAME));
- return 1;
- }
-
- if (lwsgs_hash_password(vhd, lws_spa_get_string(pss->spa, FGS_PASSWORD),
- &u)) {
- lwsl_err("Password hash failed\n");
- return 1;
- }
-
- if (lws_get_random(vhd->context, sid_rand, sizeof(sid_rand)) !=
- sizeof(sid_rand)) {
- lwsl_err("Problem getting random for token\n");
- return 1;
- }
- sha256_to_lwsgw_hash(sid_rand, &hash);
-
- lws_snprintf((char *)buffer, sizeof(buffer) - 1,
- "insert into users(username,"
- " creation_time, ip, email, verified,"
- " pwhash, pwsalt, token, last_forgot_validated)"
- " values ('%s', %lu, '%s', '%s', 0,"
- " '%s', '%s', '%s', 0);",
- lws_sql_purify(esc, lws_spa_get_string(pss->spa, FGS_USERNAME), sizeof(esc) - 1),
- (unsigned long)lws_now_secs(),
- lws_sql_purify(esc1, pss->ip, sizeof(esc1) - 1),
- lws_sql_purify(esc2, lws_spa_get_string(pss->spa, FGS_EMAIL), sizeof(esc2) - 1),
- u.pwhash.id, u.pwsalt.id, hash.id);
-
- if (sqlite3_exec(vhd->pdb, (char *)buffer, NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("Unable to insert user: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 1;
- }
-
- n = lws_snprintf(s, sizeof(s),
- "From: Noreply <%s>\n"
- "To: %s <%s>\n"
- "Subject: Registration verification\n"
- "\n"
- "Hello, %s\n\n"
- "We received a registration from IP %s using this email,\n"
- "to confirm it is legitimate, please click the link below.\n\n"
- "%s/lwsgs-confirm?token=%s\n\n"
- "If this request is unexpected, please ignore it and\n"
- "no further action will be taken.\n\n"
- "If you have any questions or concerns about this\n"
- "automated email, you can contact a real person at\n"
- "%s.\n"
- "\n.\n",
- lws_sql_purify(esc, vhd->email_from, sizeof(esc) - 1),
- lws_sql_purify(esc1, lws_spa_get_string(pss->spa, FGS_USERNAME), sizeof(esc1) - 1),
- lws_sql_purify(esc2, lws_spa_get_string(pss->spa, FGS_EMAIL), sizeof(esc2) - 1),
- lws_sql_purify(esc3, lws_spa_get_string(pss->spa, FGS_USERNAME), sizeof(esc3) - 1),
- lws_sql_purify(esc4, pss->ip, sizeof(esc4) - 1),
- vhd->email_confirm_url, hash.id,
- vhd->email_contact_person);
-
-#if defined(LWS_WITH_SMTP)
- em = lws_smtpc_alloc_email_helper(s, n, vhd->email_from,
- lws_spa_get_string(pss->spa, FGS_EMAIL),
- lws_spa_get_string(pss->spa, FGS_USERNAME),
- strlen(lws_spa_get_string(pss->spa, FGS_USERNAME)),
- vhd, lwsgs_smtp_client_done_sentvfy);
- if (!em)
- return 1;
-
- if (lws_smtpc_add_email(vhd->smtp_client, em))
- return 1;
-#else
- (void)n;
-#endif
-
- return 0;
-}
diff --git a/plugins/generic-sessions/private-lwsgs.h b/plugins/generic-sessions/private-lwsgs.h
deleted file mode 100644
index 157679e71..000000000
--- a/plugins/generic-sessions/private-lwsgs.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#define LWS_DLL
-#define LWS_INTERNAL
-#include
-
-#include
-#include
-
-#define LWSGS_VERIFIED_ACCEPTED 100
-
-enum {
- FGS_USERNAME,
- FGS_PASSWORD,
- FGS_PASSWORD2,
- FGS_EMAIL,
- FGS_REGISTER,
- FGS_GOOD,
- FGS_BAD,
- FGS_REG_GOOD,
- FGS_REG_BAD,
- FGS_ADMIN,
- FGS_FORGOT,
- FGS_FORGOT_GOOD,
- FGS_FORGOT_BAD,
- FGS_FORGOT_POST_GOOD,
- FGS_FORGOT_POST_BAD,
- FGS_CHANGE,
- FGS_CURPW,
- FGS_DELETE,
-};
-
-struct lwsgs_user {
- char username[32];
- char ip[16];
- lwsgw_hash pwhash;
- lwsgw_hash pwsalt;
- lwsgw_hash token;
- time_t created;
- time_t last_forgot_validated;
- char email[100];
- int verified;
-};
-
-struct per_vhost_data__gs {
- lws_abs_t *smtp_client;
- struct lwsgs_user u;
- lws_token_map_t transport_tokens[3];
- lws_token_map_t protocol_tokens[2];
- char helo[64], ip[64];
- struct lws_context *context;
- char session_db[256];
- char admin_user[32];
- char urlroot[48];
- char confounder[32];
- char email_contact_person[128];
- char email_title[128];
- char email_template[128];
- char email_confirm_url[128];
- char email_from[128];
- lwsgw_hash admin_password_sha256;
- sqlite3 *pdb;
- int timeout_idle_secs;
- int timeout_absolute_secs;
- int timeout_anon_absolute_secs;
- int timeout_email_secs;
- time_t last_session_expire;
-};
-
-struct per_session_data__gs {
- struct lws_spa *spa;
- lwsgw_hash login_session;
- lwsgw_hash delete_session;
- unsigned int login_expires;
- char onward[256];
- char result[500 + LWS_PRE];
- char urldec[500 + LWS_PRE];
- int result_len;
- char ip[46];
- struct lws_process_html_state phs;
- int spos;
- char check_response_value;
-
- unsigned int logging_out:1;
- unsigned int check_response:1;
-};
-
-/* utils.c */
-
-int
-lwsgs_lookup_callback_user(void *priv, int cols, char **col_val,
- char **col_name);
-void
-lwsgw_cookie_from_session(lwsgw_hash *sid, time_t expires, char **p, char *end);
-int
-lwsgs_get_sid_from_wsi(struct lws *wsi, lwsgw_hash *sid);
-int
-lwsgs_lookup_session(struct per_vhost_data__gs *vhd,
- const lwsgw_hash *sid, char *username, int len);
-int
-lwsgs_get_auth_level(struct per_vhost_data__gs *vhd,
- const char *username);
-int
-lwsgs_check_credentials(struct per_vhost_data__gs *vhd,
- const char *username, const char *password);
-void
-sha256_to_lwsgw_hash(unsigned char *hash, lwsgw_hash *shash);
-unsigned int
-lwsgs_now_secs(void);
-int
-lwsgw_check_admin(struct per_vhost_data__gs *vhd,
- const char *username, const char *password);
-int
-lwsgs_hash_password(struct per_vhost_data__gs *vhd,
- const char *password, struct lwsgs_user *u);
-int
-lwsgs_new_session_id(struct per_vhost_data__gs *vhd,
- lwsgw_hash *sid, const char *username, int exp);
-int
-lwsgs_lookup_user(struct per_vhost_data__gs *vhd,
- const char *username, struct lwsgs_user *u);
-int
-lwsgw_update_session(struct per_vhost_data__gs *vhd,
- lwsgw_hash *hash, const char *user);
-int
-lwsgw_expire_old_sessions(struct per_vhost_data__gs *vhd);
-
-
-/* handlers.c */
-
-int
-lwsgs_handler_confirm(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss);
-int
-lwsgs_handler_forgot(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss);
-int
-lwsgs_handler_check(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss, const char *in);
-int
-lwsgs_handler_change_password(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss);
-int
-lwsgs_handler_forgot_pw_form(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss);
-int
-lwsgs_handler_register_form(struct per_vhost_data__gs *vhd, struct lws *wsi,
- struct per_session_data__gs *pss);
-
diff --git a/plugins/generic-sessions/protocol_generic_sessions.c b/plugins/generic-sessions/protocol_generic_sessions.c
deleted file mode 100644
index 7622187d6..000000000
--- a/plugins/generic-sessions/protocol_generic_sessions.c
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "private-lwsgs.h"
-#include
-
-/* keep changes in sync with the enum in lwsgs.h */
-static const char * const param_names[] = {
- "username",
- "password",
- "password2",
- "email",
- "register",
- "good",
- "bad",
- "reg-good",
- "reg-bad",
- "admin",
- "forgot",
- "forgot-good",
- "forgot-bad",
- "forgot-post-good",
- "forgot-post-bad",
- "change",
- "curpw",
- "delete"
-};
-
-struct lwsgs_fill_args {
- char *buf;
- int len;
-};
-
-static const struct lws_protocols protocols[];
-
-struct lwsgs_subst_args
-{
- struct per_session_data__gs *pss;
- struct per_vhost_data__gs *vhd;
- struct lws *wsi;
-};
-
-static const char *
-lwsgs_subst(void *data, int index)
-{
- struct lwsgs_subst_args *a = (struct lwsgs_subst_args *)data;
- struct lwsgs_user u;
- lwsgw_hash sid;
- char esc[96], s[100];
- int n;
-
- a->pss->result[0] = '\0';
- u.email[0] = '\0';
- if (!lwsgs_get_sid_from_wsi(a->wsi, &sid)) {
- if (lwsgs_lookup_session(a->vhd, &sid, a->pss->result, 31)) {
- lwsl_notice("sid lookup for %s failed\n", sid.id);
- a->pss->delete_session = sid;
- return NULL;
- }
- lws_snprintf(s, sizeof(s) - 1, "select username,email "
- "from users where username = '%s';",
- lws_sql_purify(esc, a->pss->result, sizeof(esc) - 1));
- if (sqlite3_exec(a->vhd->pdb, s, lwsgs_lookup_callback_user,
- &u, NULL) != SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(a->vhd->pdb));
- a->pss->delete_session = sid;
- return NULL;
- }
- } else
- lwsl_notice("no sid\n");
-
- lws_strncpy(a->pss->result + 32, u.email, 100);
-
- switch (index) {
- case 0:
- return a->pss->result;
-
- case 1:
- n = lwsgs_get_auth_level(a->vhd, a->pss->result);
- sprintf(a->pss->result, "%d", n);
- return a->pss->result;
- case 2:
- return a->pss->result + 32;
- }
-
- return NULL;
-}
-
-static int
-lws_get_effective_host(struct lws *wsi, char *buf, size_t buflen)
-{
-#if defined(LWS_ROLE_H2)
- /* h2 */
- if (lws_hdr_copy(wsi, buf, buflen - 1,
- WSI_TOKEN_HTTP_COLON_AUTHORITY) > 0)
- return 0;
-#endif
- /* h1 */
- if (lws_hdr_copy(wsi, buf, buflen - 1, WSI_TOKEN_HOST) > 0)
- return 0;
-
- return 1;
-}
-
-static int
-callback_generic_sessions(struct lws *wsi, enum lws_callback_reasons reason,
- void *user, void *in, size_t len)
-{
- struct per_session_data__gs *pss = (struct per_session_data__gs *)user;
- const struct lws_protocol_vhost_options *pvo;
- struct per_vhost_data__gs *vhd = (struct per_vhost_data__gs *)
- lws_protocol_vh_priv_get(lws_get_vhost(wsi),
- lws_vhost_name_to_protocol(lws_get_vhost(wsi),
- "protocol-generic-sessions"));
- char cookie[1024], username[32], *pc = cookie;
- unsigned char buffer[LWS_PRE + LWSGS_EMAIL_CONTENT_SIZE];
- struct lws_process_html_args *args = in;
- struct lws_session_info *sinfo;
- char s[LWSGS_EMAIL_CONTENT_SIZE];
- unsigned char *p, *start, *end;
- const char *cp, *cp1;
- sqlite3_stmt *sm;
- lwsgw_hash sid;
-#if defined(LWS_WITH_SMTP)
- lws_abs_t abs;
-#endif
- int n;
-
- switch (reason) {
- case LWS_CALLBACK_PROTOCOL_INIT: /* per vhost */
-
- vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
- lws_get_protocol(wsi), sizeof(struct per_vhost_data__gs));
- if (!vhd)
- return 1;
- vhd->context = lws_get_context(wsi);
-
- /* defaults */
- vhd->timeout_idle_secs = 600;
- vhd->timeout_absolute_secs = 36000;
- vhd->timeout_anon_absolute_secs = 1200;
- vhd->timeout_email_secs = 24 * 3600;
-
-
- strcpy(vhd->helo, "unconfigured.com");
- strcpy(vhd->ip, "127.0.0.1");
- strcpy(vhd->email_from, "noreply@unconfigured.com");
- strcpy(vhd->email_title, "Registration Email from unconfigured");
- vhd->urlroot[0] = '\0';
-
- pvo = (const struct lws_protocol_vhost_options *)in;
- while (pvo) {
- if (!strcmp(pvo->name, "admin-user"))
- lws_strncpy(vhd->admin_user, pvo->value,
- sizeof(vhd->admin_user));
- if (!strcmp(pvo->name, "urlroot"))
- lws_strncpy(vhd->urlroot, pvo->value,
- sizeof(vhd->urlroot));
- if (!strcmp(pvo->name, "admin-password-sha256"))
- lws_strncpy(vhd->admin_password_sha256.id, pvo->value,
- sizeof(vhd->admin_password_sha256.id));
- if (!strcmp(pvo->name, "session-db"))
- lws_strncpy(vhd->session_db, pvo->value,
- sizeof(vhd->session_db));
- if (!strcmp(pvo->name, "confounder"))
- lws_strncpy(vhd->confounder, pvo->value,
- sizeof(vhd->confounder));
- if (!strcmp(pvo->name, "email-from"))
- lws_strncpy(vhd->email_from, pvo->value,
- sizeof(vhd->email_from));
- if (!strcmp(pvo->name, "email-helo"))
- lws_strncpy(vhd->helo, pvo->value, sizeof(vhd->helo));
- if (!strcmp(pvo->name, "email-template"))
- lws_strncpy(vhd->email_template, pvo->value,
- sizeof(vhd->email_template));
- if (!strcmp(pvo->name, "email-title"))
- lws_strncpy(vhd->email_title, pvo->value,
- sizeof(vhd->email_title));
- if (!strcmp(pvo->name, "email-contact-person"))
- lws_strncpy(vhd->email_contact_person, pvo->value,
- sizeof(vhd->email_contact_person));
- if (!strcmp(pvo->name, "email-confirm-url-base"))
- lws_strncpy(vhd->email_confirm_url, pvo->value,
- sizeof(vhd->email_confirm_url));
- if (!strcmp(pvo->name, "email-server-ip"))
- lws_strncpy(vhd->ip, pvo->value, sizeof(vhd->ip));
-
- if (!strcmp(pvo->name, "timeout-idle-secs"))
- vhd->timeout_idle_secs = atoi(pvo->value);
- if (!strcmp(pvo->name, "timeout-absolute-secs"))
- vhd->timeout_absolute_secs = atoi(pvo->value);
- if (!strcmp(pvo->name, "timeout-anon-absolute-secs"))
- vhd->timeout_anon_absolute_secs = atoi(pvo->value);
- if (!strcmp(pvo->name, "email-expire"))
- vhd->timeout_email_secs = atoi(pvo->value);
- pvo = pvo->next;
- }
- if (!vhd->admin_user[0] ||
- !vhd->admin_password_sha256.id[0] ||
- !vhd->session_db[0]) {
- lwsl_err("generic-sessions: "
- "You must give \"admin-user\", "
- "\"admin-password-sha256\", "
- "and \"session_db\" per-vhost options\n");
- return 1;
- }
-
- if (lws_struct_sq3_open(lws_get_context(wsi),
- vhd->session_db, 1, &vhd->pdb)) {
- lwsl_err("Unable to open session db %s: %s\n",
- vhd->session_db, sqlite3_errmsg(vhd->pdb));
-
- return 1;
- }
-
- if (sqlite3_prepare(vhd->pdb,
- "create table if not exists sessions ("
- " name char(65),"
- " username varchar(32),"
- " expire integer"
- ");",
- -1, &sm, NULL) != SQLITE_OK) {
- lwsl_err("Unable to prepare session table init: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- return 1;
- }
-
- if (sqlite3_step(sm) != SQLITE_DONE) {
- lwsl_err("Unable to run session table init: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- return 1;
- }
- sqlite3_finalize(sm);
-
- if (sqlite3_exec(vhd->pdb,
- "create table if not exists users ("
- " username varchar(32),"
- " creation_time integer,"
- " ip varchar(46),"
- " email varchar(100),"
- " pwhash varchar(65),"
- " pwsalt varchar(65),"
- " pwchange_time integer,"
- " token varchar(65),"
- " verified integer,"
- " token_time integer,"
- " last_forgot_validated integer,"
- " primary key (username)"
- ");",
- NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("Unable to create user table: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- return 1;
- }
-
-#if defined(LWS_WITH_SMTP)
-
- memset(&abs, 0, sizeof(abs));
- abs.vh = lws_get_vhost(wsi);
-
- /* select the protocol and bind its tokens */
-
- abs.ap = lws_abs_protocol_get_by_name("smtp");
- if (!abs.ap)
- return 1;
-
- vhd->protocol_tokens[0].name_index = LTMI_PSMTP_V_HELO;
- vhd->protocol_tokens[0].u.value = vhd->helo;
-
- abs.ap_tokens = vhd->protocol_tokens;
-
- /* select the transport and bind its tokens */
-
- abs.at = lws_abs_transport_get_by_name("raw_skt");
- if (!abs.at)
- return 1;
-
- vhd->transport_tokens[0].name_index = LTMI_PEER_V_DNS_ADDRESS;
- vhd->transport_tokens[0].u.value = vhd->ip;
- vhd->transport_tokens[1].name_index = LTMI_PEER_LV_PORT;
- vhd->transport_tokens[1].u.lvalue = 25;
-
- abs.at_tokens = vhd->transport_tokens;
-
- vhd->smtp_client = lws_abs_bind_and_create_instance(&abs);
- if (!vhd->smtp_client)
- return 1;
-
- lwsl_notice("%s: created SMTP client\n", __func__);
-#endif
- break;
-
- case LWS_CALLBACK_PROTOCOL_DESTROY:
- // lwsl_notice("gs: LWS_CALLBACK_PROTOCOL_DESTROY: v=%p, ctx=%p\n", vhd, vhd->context);
- if (vhd->pdb) {
- sqlite3_close(vhd->pdb);
- vhd->pdb = NULL;
- }
-#if defined(LWS_WITH_SMTP)
- if (vhd->smtp_client)
- lws_abs_destroy_instance(&vhd->smtp_client);
-#endif
- break;
-
- case LWS_CALLBACK_HTTP_WRITEABLE:
- if (!pss->check_response)
- break;
- pss->check_response = 0;
- n = lws_write(wsi, (unsigned char *)&pss->check_response_value,
- 1, LWS_WRITE_HTTP | LWS_WRITE_H2_STREAM_END);
- if (n != 1)
- return -1;
- goto try_to_reuse;
-
- case LWS_CALLBACK_HTTP:
- if (!pss) {
- lwsl_err("%s: no valid pss\n", __func__);
- return 1;
- }
-
- pss->login_session.id[0] = '\0';
- pss->phs.pos = 0;
-
- cp = in;
- if ((*(const char *)in == '/'))
- cp++;
-
- if (lws_get_effective_host(wsi, cookie, sizeof(cookie))) {
- lwsl_err("%s: HTTP: no effective host\n", __func__);
- return 1;
- }
-
- lwsl_notice("LWS_CALLBACK_HTTP: %s, HOST '%s'\n",
- (const char *)in, cookie);
-
- n = strlen(cp);
-
- lws_snprintf(pss->onward, sizeof(pss->onward),
- "%s%s", vhd->urlroot, (const char *)in);
-
- if (n >= 12 &&
- !strcmp(cp + n - 12, "lwsgs-forgot")) {
- lwsgs_handler_forgot(vhd, wsi, pss);
- goto redirect_with_cookie;
- }
-
- if (n >= 13 &&
- !strcmp(cp + n - 13, "lwsgs-confirm")) {
- lwsgs_handler_confirm(vhd, wsi, pss);
- goto redirect_with_cookie;
- }
- cp1 = strstr(cp, "lwsgs-check/");
- if (cp1) {
- lwsgs_handler_check(vhd, wsi, pss, cp1 + 12);
- /* second, async part will complete transaction */
- break;
- }
-
- if (n >= 11 && cp && !strcmp(cp + n - 11, "lwsgs-login"))
- break;
- if (n >= 12 && cp && !strcmp(cp + n - 12, "lwsgs-logout"))
- break;
- if (n >= 12 && cp && !strcmp(cp + n - 12, "lwsgs-forgot"))
- break;
- if (n >= 12 && cp && !strcmp(cp + n - 12, "lwsgs-change"))
- break;
-
- /* if no legitimate url for GET, return 404 */
-
- lwsl_err("%s: http doing 404 on %s\n", __func__, cp ? cp : "null");
- lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL);
-
- return -1;
- //goto try_to_reuse;
-
- case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
- args = (struct lws_process_html_args *)in;
- if (!args->chunked)
- break;
- case LWS_CALLBACK_CHECK_ACCESS_RIGHTS:
- n = 0;
- username[0] = '\0';
- sid.id[0] = '\0';
- args = (struct lws_process_html_args *)in;
- lwsl_notice("%s: LWS_CALLBACK_CHECK_ACCESS_RIGHTS: need 0x%x\n",
- __func__, args->max_len);
- if (!lwsgs_get_sid_from_wsi(wsi, &sid)) {
- if (lwsgs_lookup_session(vhd, &sid, username,
- sizeof(username))) {
-
- /*
- * if we're authenticating for ws, we don't
- * want to redirect it or gain a cookie on that,
- * he'll need to get the cookie from http
- * interactions outside of this.
- */
- if (args->chunked) {
- lwsl_notice("%s: ws auth failed\n",
- __func__);
-
- return 1;
- }
-
- lwsl_notice("session lookup for %s failed, "
- "probably expired\n", sid.id);
- pss->delete_session = sid;
- args->final = 1; /* signal we dealt with it */
- lws_snprintf(pss->onward, sizeof(pss->onward) - 1,
- "%s%s", vhd->urlroot, args->p);
- lwsl_notice("redirecting to ourselves with "
- "cookie refresh\n");
- /* we need a redirect to ourselves,
- * session cookie is expired */
- goto redirect_with_cookie;
- }
- } else
- lwsl_notice("%s: failed to get sid from wsi\n", __func__);
-
- n = lwsgs_get_auth_level(vhd, username);
- lwsl_notice("%s: lwsgs_get_auth_level '%s' says %d\n", __func__, username, n);
-
- if ((args->max_len & n) != args->max_len) {
- lwsl_notice("Access rights fail 0x%X vs 0x%X (cookie %s)\n",
- args->max_len, n, sid.id);
- return 1;
- }
- lwsl_debug("Access rights OK\n");
- break;
-
- case LWS_CALLBACK_SESSION_INFO:
- {
- struct lwsgs_user u;
- sinfo = (struct lws_session_info *)in;
- sinfo->username[0] = '\0';
- sinfo->email[0] = '\0';
- sinfo->ip[0] = '\0';
- sinfo->session[0] = '\0';
- sinfo->mask = 0;
-
- sid.id[0] = '\0';
- lwsl_debug("LWS_CALLBACK_SESSION_INFO\n");
- if (lwsgs_get_sid_from_wsi(wsi, &sid))
- break;
- if (lwsgs_lookup_session(vhd, &sid, username, sizeof(username)))
- break;
-
- lws_snprintf(s, sizeof(s) - 1,
- "select username, email from users where username='%s';",
- username);
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback_user, &u, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
- break;
- }
- lws_strncpy(sinfo->username, u.username, sizeof(sinfo->username));
- lws_strncpy(sinfo->email, u.email, sizeof(sinfo->email));
- lws_strncpy(sinfo->session, sid.id, sizeof(sinfo->session));
- sinfo->mask = lwsgs_get_auth_level(vhd, username);
- lws_get_peer_simple(wsi, sinfo->ip, sizeof(sinfo->ip));
- }
-
- break;
-
- case LWS_CALLBACK_PROCESS_HTML:
-
- args = (struct lws_process_html_args *)in;
- {
- static const char * const vars[] = {
- "$lwsgs_user",
- "$lwsgs_auth",
- "$lwsgs_email"
- };
- struct lwsgs_subst_args a;
-
- a.vhd = vhd;
- a.pss = pss;
- a.wsi = wsi;
-
- pss->phs.vars = vars;
- pss->phs.count_vars = LWS_ARRAY_SIZE(vars);
- pss->phs.replace = lwsgs_subst;
- pss->phs.data = &a;
-
- if (lws_chunked_html_process(args, &pss->phs))
- return -1;
- }
- break;
-
- case LWS_CALLBACK_HTTP_BODY:
- if (len < 2) {
- lwsl_err("%s: HTTP_BODY: len %d < 2\n", __func__, (int)len);
- break;
- }
-
- if (!pss->spa) {
- pss->spa = lws_spa_create(wsi, param_names,
- LWS_ARRAY_SIZE(param_names), 1024,
- NULL, NULL);
- if (!pss->spa)
- return -1;
- }
-
- if (lws_spa_process(pss->spa, in, len)) {
- lwsl_notice("spa process blew\n");
- return -1;
- }
- break;
-
- case LWS_CALLBACK_HTTP_BODY_COMPLETION:
-
- lwsl_debug("%s: LWS_CALLBACK_HTTP_BODY_COMPLETION\n", __func__);
-
- if (!pss->spa)
- break;
-
- cp1 = (const char *)pss->onward;
- if (*cp1 == '/')
- cp1++;
-
-
- lws_spa_finalize(pss->spa);
- n = strlen(cp1);
-
- if (lws_get_effective_host(wsi, cookie, sizeof(cookie)))
- return 1;
-
- if (!strcmp(cp1 + n - 12, "lwsgs-change")) {
- if (!lwsgs_handler_change_password(vhd, wsi, pss)) {
- cp = lws_spa_get_string(pss->spa, FGS_GOOD);
- goto pass;
- }
-
- cp = lws_spa_get_string(pss->spa, FGS_BAD);
- lwsl_notice("user/password no good %s\n",
- lws_spa_get_string(pss->spa, FGS_USERNAME));
- lws_snprintf(pss->onward, sizeof(pss->onward),
- "%s%s", vhd->urlroot, cp);
-
- pss->onward[sizeof(pss->onward) - 1] = '\0';
- goto completion_flow;
- }
-
- if (!strcmp(cp1 + n - 11, "lwsgs-login")) {
- lwsl_err("%s: lwsgs-login\n", __func__);
- if (lws_spa_get_string(pss->spa, FGS_FORGOT) &&
- lws_spa_get_string(pss->spa, FGS_FORGOT)[0]) {
- if (lwsgs_handler_forgot_pw_form(vhd, wsi, pss)) {
- n = FGS_FORGOT_BAD;
- goto reg_done;
- }
-#if defined(LWS_WITH_SMTP)
- /* get the email monitor to take a look */
- lws_smtpc_kick(vhd->smtp_client);
-#endif
- n = FGS_FORGOT_GOOD;
- goto reg_done;
- }
-
- if (!lws_spa_get_string(pss->spa, FGS_USERNAME) ||
- !lws_spa_get_string(pss->spa, FGS_PASSWORD)) {
- lwsl_notice("username '%s' or pw '%s' missing\n",
- lws_spa_get_string(pss->spa, FGS_USERNAME),
- lws_spa_get_string(pss->spa, FGS_PASSWORD));
- return -1;
- }
-
- if (lws_spa_get_string(pss->spa, FGS_REGISTER) &&
- lws_spa_get_string(pss->spa, FGS_REGISTER)[0]) {
-
- if (lwsgs_handler_register_form(vhd, wsi, pss))
- n = FGS_REG_BAD;
- else {
- n = FGS_REG_GOOD;
-#if defined(LWS_WITH_SMTP)
- /* get the email monitor to take a look */
- lws_smtpc_kick(vhd->smtp_client);
-#endif
- }
-reg_done:
- lws_snprintf(pss->onward, sizeof(pss->onward),
- "%s%s", vhd->urlroot,
- lws_spa_get_string(pss->spa, n));
-
- pss->login_expires = 0;
- pss->logging_out = 1;
- goto completion_flow;
- }
-
- /* we have the username and password... check if admin */
- if (lwsgw_check_admin(vhd, lws_spa_get_string(pss->spa, FGS_USERNAME),
- lws_spa_get_string(pss->spa, FGS_PASSWORD))) {
- if (lws_spa_get_string(pss->spa, FGS_ADMIN))
- cp = lws_spa_get_string(pss->spa, FGS_ADMIN);
- else
- if (lws_spa_get_string(pss->spa, FGS_GOOD))
- cp = lws_spa_get_string(pss->spa, FGS_GOOD);
- else {
- lwsl_info("No admin or good target url in form\n");
- return -1;
- }
- lwsl_debug("admin\n");
- goto pass;
- }
-
- /* check users in database */
-
- if (!lwsgs_check_credentials(vhd,
- lws_spa_get_string(pss->spa, FGS_USERNAME),
- lws_spa_get_string(pss->spa, FGS_PASSWORD))) {
- lwsl_notice("pw hash check met\n");
- cp = lws_spa_get_string(pss->spa, FGS_GOOD);
- goto pass;
- } else
- lwsl_notice("user/password no good %s %s\n",
- lws_spa_get_string(pss->spa, FGS_USERNAME),
- lws_spa_get_string(pss->spa, FGS_PASSWORD));
-
- if (!lws_spa_get_string(pss->spa, FGS_BAD)) {
- lwsl_info("No admin or good target url in form\n");
- return -1;
- }
-
- lws_snprintf(pss->onward, sizeof(pss->onward),
- "%s%s", vhd->urlroot,
- lws_spa_get_string(pss->spa, FGS_BAD));
-
- lwsl_notice("failed: %s\n", pss->onward);
-
- goto completion_flow;
- }
-
- if (!strcmp(cp1 + n - 12, "lwsgs-logout")) {
-
- lwsl_notice("/logout\n");
-
- if (lwsgs_get_sid_from_wsi(wsi, &pss->login_session)) {
- lwsl_notice("not logged in...\n");
- return 1;
- }
-
- /*
- * We keep the same session, but mark it as not
- * being associated to any authenticated user
- */
-
- lwsgw_update_session(vhd, &pss->login_session, "");
-
- if (!lws_spa_get_string(pss->spa, FGS_GOOD)) {
- lwsl_info("No admin or good target url in form\n");
- return -1;
- }
-
- lws_snprintf(pss->onward, sizeof(pss->onward),
- "%s%s", vhd->urlroot,
- lws_spa_get_string(pss->spa, FGS_GOOD));
-
- pss->login_expires = 0;
- pss->logging_out = 1;
-
- goto completion_flow;
- }
-
- break;
-
-pass:
- lws_snprintf(pss->onward, sizeof(pss->onward),
- "%s%s", vhd->urlroot, cp);
-
- if (lwsgs_get_sid_from_wsi(wsi, &sid))
- sid.id[0] = '\0';
-
- pss->login_expires = lws_now_secs() +
- vhd->timeout_absolute_secs;
-
- if (!sid.id[0]) {
- /* we need to create a new, authorized session */
-
- if (lwsgs_new_session_id(vhd, &pss->login_session,
- lws_spa_get_string(pss->spa, FGS_USERNAME),
- pss->login_expires))
- goto try_to_reuse;
-
- lwsl_notice("%s: Creating new session: %s\n", __func__,
- pss->login_session.id);
- } else {
- /*
- * we can just update the existing session to be
- * authorized
- */
- lwsl_notice("%s: Authorizing existing session %s, name %s\n",
- __func__, sid.id,
- lws_spa_get_string(pss->spa, FGS_USERNAME));
- lwsgw_update_session(vhd, &sid,
- lws_spa_get_string(pss->spa, FGS_USERNAME));
- pss->login_session = sid;
- }
-
-completion_flow:
- lwsgw_expire_old_sessions(vhd);
- goto redirect_with_cookie;
-
- case LWS_CALLBACK_HTTP_DROP_PROTOCOL:
- if (pss && pss->spa) {
- lws_spa_destroy(pss->spa);
- pss->spa = NULL;
- }
- break;
-
- case LWS_CALLBACK_ADD_HEADERS:
- lwsgw_expire_old_sessions(vhd);
-
- lwsl_warn("ADD_HEADERS\n");
-
- args = (struct lws_process_html_args *)in;
- if (!pss)
- return 1;
- if (pss->delete_session.id[0]) {
- pc = cookie;
- lwsgw_cookie_from_session(&pss->delete_session, 0, &pc,
- cookie + sizeof(cookie) - 1);
-
- lwsl_notice("deleting cookie '%s'\n", cookie);
-
- if (lws_add_http_header_by_name(wsi,
- (unsigned char *)"set-cookie:",
- (unsigned char *)cookie, pc - cookie,
- (unsigned char **)&args->p,
- (unsigned char *)args->p + args->max_len))
- return 1;
- }
-
- if (!pss->login_session.id[0])
- lwsgs_get_sid_from_wsi(wsi, &pss->login_session);
-
- if (!pss->login_session.id[0] && !pss->logging_out) {
-
- pss->login_expires = lws_now_secs() +
- vhd->timeout_anon_absolute_secs;
- if (lwsgs_new_session_id(vhd, &pss->login_session, "",
- pss->login_expires))
- goto try_to_reuse;
- pc = cookie;
- lwsgw_cookie_from_session(&pss->login_session,
- pss->login_expires, &pc,
- cookie + sizeof(cookie) - 1);
-
- lwsl_info("LWS_CALLBACK_ADD_HEADERS: setting cookie '%s'\n", cookie);
- if (lws_add_http_header_by_name(wsi,
- (unsigned char *)"set-cookie:",
- (unsigned char *)cookie, pc - cookie,
- (unsigned char **)&args->p,
- (unsigned char *)args->p + args->max_len))
- return 1;
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-
-redirect_with_cookie:
- p = buffer + LWS_PRE;
- start = p;
- end = p + sizeof(buffer) - LWS_PRE;
-
- lwsl_warn("%s: redirect_with_cookie\n", __func__);
-
- if (lws_add_http_header_status(wsi, HTTP_STATUS_SEE_OTHER, &p, end))
- return 1;
-
- {
- char loc[1024], uria[128];
-
- uria[0] = '\0';
- lws_hdr_copy_fragment(wsi, uria, sizeof(uria),
- WSI_TOKEN_HTTP_URI_ARGS, 0);
- n = lws_snprintf(loc, sizeof(loc), "%s?%s",
- pss->onward, uria);
- lwsl_notice("%s: redirect to '%s'\n", __func__, loc);
- if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_LOCATION,
- (unsigned char *)loc, n, &p, end))
- return 1;
- }
-
- if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
- (unsigned char *)"text/html", 9, &p, end))
- return 1;
- if (lws_add_http_header_content_length(wsi, 0, &p, end))
- return 1;
-
- if (pss->delete_session.id[0]) {
- lwsgw_cookie_from_session(&pss->delete_session, 0, &pc,
- cookie + sizeof(cookie) - 1);
-
- lwsl_notice("deleting cookie '%s'\n", cookie);
-
- if (lws_add_http_header_by_name(wsi,
- (unsigned char *)"set-cookie:",
- (unsigned char *)cookie, pc - cookie,
- &p, end)) {
- lwsl_err("fail0\n");
- return 1;
- }
- }
-
- if (!pss->login_session.id[0]) {
- pss->login_expires = lws_now_secs() +
- vhd->timeout_anon_absolute_secs;
- if (lwsgs_new_session_id(vhd, &pss->login_session, "",
- pss->login_expires)) {
- lwsl_err("fail1\n");
- return 1;
- }
- } else
- pss->login_expires = lws_now_secs() +
- vhd->timeout_absolute_secs;
-
- if (pss->login_session.id[0] || pss->logging_out) {
- /*
- * we succeeded to login, we must issue a login
- * cookie with the prepared data
- */
- pc = cookie;
-
- lwsgw_cookie_from_session(&pss->login_session,
- pss->login_expires, &pc,
- cookie + sizeof(cookie) - 1);
-
- lwsl_err("%s: setting cookie '%s'\n", __func__, cookie);
-
- pss->logging_out = 0;
-
- if (lws_add_http_header_by_name(wsi,
- (unsigned char *)"set-cookie:",
- (unsigned char *)cookie, pc - cookie,
- &p, end)) {
- lwsl_err("fail2\n");
- return 1;
- }
- }
-
- if (lws_finalize_http_header(wsi, &p, end))
- return 1;
-
- // lwsl_hexdump_notice(start, p - start);
-
- n = lws_write(wsi, start, p - start, LWS_WRITE_H2_STREAM_END |
- LWS_WRITE_HTTP_HEADERS);
- if (n < 0)
- return 1;
-
- /* fallthru */
-
-try_to_reuse:
- if (lws_http_transaction_completed(wsi))
- return -1;
-
- return 0;
-}
-
-static const struct lws_protocols protocols[] = {
- {
- "protocol-generic-sessions",
- callback_generic_sessions,
- sizeof(struct per_session_data__gs),
- 1024,
- },
-};
-
-LWS_VISIBLE int
-init_protocol_generic_sessions(struct lws_context *context,
- struct lws_plugin_capability *c)
-{
- if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
- lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
- c->api_magic);
- return 1;
- }
-
- c->protocols = protocols;
- c->count_protocols = LWS_ARRAY_SIZE(protocols);
- c->extensions = NULL;
- c->count_extensions = 0;
-
- return 0;
-}
-
-LWS_VISIBLE int
-destroy_protocol_generic_sessions(struct lws_context *context)
-{
- return 0;
-}
diff --git a/plugins/generic-sessions/protocol_lws_messageboard.c b/plugins/generic-sessions/protocol_lws_messageboard.c
deleted file mode 100644
index 94c01ab8f..000000000
--- a/plugins/generic-sessions/protocol_lws_messageboard.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-
-#define LWS_DLL
-#define LWS_INTERNAL
-#include
-
-#include
-#include
-#include
-
-struct per_vhost_data__gs_mb {
- struct lws_vhost *vh;
- const struct lws_protocols *gsp;
- sqlite3 *pdb;
- char message_db[256];
- unsigned long last_idx;
-};
-
-struct per_session_data__gs_mb {
- void *pss_gs; /* for use by generic-sessions */
- struct lws_session_info sinfo;
- struct lws_spa *spa;
- unsigned long last_idx;
- unsigned int our_form:1;
- char second_http_part;
-};
-
-static const char * const param_names[] = {
- "send",
- "msg",
-};
-enum {
- MBSPA_SUBMIT,
- MBSPA_MSG,
-};
-
-#define MAX_MSG_LEN 512
-
-struct message {
- unsigned long idx;
- unsigned long time;
- char username[32];
- char email[100];
- char ip[72];
- char content[MAX_MSG_LEN];
-};
-
-static int
-lookup_cb(void *priv, int cols, char **col_val, char **col_name)
-{
- struct message *m = (struct message *)priv;
- int n;
-
- for (n = 0; n < cols; n++) {
-
- if (!strcmp(col_name[n], "idx") ||
- !strcmp(col_name[n], "MAX(idx)")) {
- if (!col_val[n])
- m->idx = 0;
- else
- m->idx = atol(col_val[n]);
- continue;
- }
- if (!strcmp(col_name[n], "time")) {
- m->time = atol(col_val[n]);
- continue;
- }
- if (!strcmp(col_name[n], "username")) {
- lws_strncpy(m->username, col_val[n], sizeof(m->username));
- continue;
- }
- if (!strcmp(col_name[n], "email")) {
- lws_strncpy(m->email, col_val[n], sizeof(m->email));
- continue;
- }
- if (!strcmp(col_name[n], "ip")) {
- lws_strncpy(m->ip, col_val[n], sizeof(m->ip));
- continue;
- }
- if (!strcmp(col_name[n], "content")) {
- lws_strncpy(m->content, col_val[n], sizeof(m->content));
- continue;
- }
- }
- return 0;
-}
-
-static unsigned long
-get_last_idx(struct per_vhost_data__gs_mb *vhd)
-{
- struct message m;
-
- if (sqlite3_exec(vhd->pdb, "SELECT MAX(idx) FROM msg;",
- lookup_cb, &m, NULL) != SQLITE_OK) {
- lwsl_err("Unable to lookup token: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 0;
- }
-
- return m.idx;
-}
-
-static int
-post_message(struct lws *wsi, struct per_vhost_data__gs_mb *vhd,
- struct per_session_data__gs_mb *pss)
-{
- struct lws_session_info sinfo;
- char s[MAX_MSG_LEN + 512];
- char esc[MAX_MSG_LEN + 256];
-
- vhd->gsp->callback(wsi, LWS_CALLBACK_SESSION_INFO,
- pss->pss_gs, &sinfo, 0);
-
- lws_snprintf((char *)s, sizeof(s) - 1,
- "insert into msg(time, username, email, ip, content)"
- " values (%lu, '%s', '%s', '%s', '%s');",
- (unsigned long)lws_now_secs(), sinfo.username, sinfo.email, sinfo.ip,
- lws_sql_purify(esc, lws_spa_get_string(pss->spa, MBSPA_MSG),
- sizeof(esc) - 1));
- if (sqlite3_exec(vhd->pdb, s, NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("Unable to insert msg: %s\n", sqlite3_errmsg(vhd->pdb));
- return 1;
- }
- vhd->last_idx = get_last_idx(vhd);
-
- /* let everybody connected by this protocol on this vhost know */
- lws_callback_on_writable_all_protocol_vhost(lws_get_vhost(wsi),
- lws_get_protocol(wsi));
-
- return 0;
-}
-
-static int
-callback_messageboard(struct lws *wsi, enum lws_callback_reasons reason,
- void *user, void *in, size_t len)
-{
- struct per_session_data__gs_mb *pss = (struct per_session_data__gs_mb *)user;
- const struct lws_protocol_vhost_options *pvo;
- struct per_vhost_data__gs_mb *vhd = (struct per_vhost_data__gs_mb *)
- lws_protocol_vh_priv_get(lws_get_vhost(wsi), lws_get_protocol(wsi));
- unsigned char *p, *start, *end, buffer[LWS_PRE + 4096];
- char s[512];
- int n;
-
- switch (reason) {
- case LWS_CALLBACK_PROTOCOL_INIT: /* per vhost */
-
- vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
- lws_get_protocol(wsi), sizeof(struct per_vhost_data__gs_mb));
- if (!vhd)
- return 1;
- vhd->vh = lws_get_vhost(wsi);
- vhd->gsp = lws_vhost_name_to_protocol(vhd->vh,
- "protocol-generic-sessions");
- if (!vhd->gsp) {
- lwsl_err("messageboard: requires generic-sessions\n");
- return 1;
- }
-
- pvo = (const struct lws_protocol_vhost_options *)in;
- while (pvo) {
- if (!strcmp(pvo->name, "message-db"))
- strncpy(vhd->message_db, pvo->value,
- sizeof(vhd->message_db) - 1);
- pvo = pvo->next;
- }
- if (!vhd->message_db[0]) {
- lwsl_err("messageboard: \"message-db\" pvo missing\n");
- return 1;
- }
-
- if (lws_struct_sq3_open(lws_get_context(wsi),
- vhd->message_db, 1, &vhd->pdb)) {
- lwsl_err("Unable to open message db %s: %s\n",
- vhd->message_db, sqlite3_errmsg(vhd->pdb));
-
- return 1;
- }
- if (sqlite3_exec(vhd->pdb, "create table if not exists msg ("
- " idx integer primary key, time integer,"
- " username varchar(32), email varchar(100),"
- " ip varchar(80), content blob);",
- NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("Unable to create msg table: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- return 1;
- }
-
- vhd->last_idx = get_last_idx(vhd);
- break;
-
- case LWS_CALLBACK_PROTOCOL_DESTROY:
- if (vhd && vhd->pdb)
- sqlite3_close(vhd->pdb);
- goto passthru;
-
- case LWS_CALLBACK_ESTABLISHED:
- vhd->gsp->callback(wsi, LWS_CALLBACK_SESSION_INFO,
- pss->pss_gs, &pss->sinfo, 0);
- if (!pss->sinfo.username[0]) {
- lwsl_notice("messageboard ws attempt with no session\n");
-
- return -1;
- }
-
- lws_callback_on_writable(wsi);
- break;
-
- case LWS_CALLBACK_CLOSED:
- lwsl_debug("%s: LWS_CALLBACK_CLOSED\n", __func__);
- if (pss && pss->pss_gs) {
- free(pss->pss_gs);
- pss->pss_gs = NULL;
- }
- break;
-
- case LWS_CALLBACK_SERVER_WRITEABLE:
- {
- struct message m;
- char j[MAX_MSG_LEN + 512], e[MAX_MSG_LEN + 512],
- *p = j + LWS_PRE, *start = p,
- *end = j + sizeof(j) - LWS_PRE;
-
- if (pss->last_idx == vhd->last_idx)
- break;
-
- /* restrict to last 10 */
- if (!pss->last_idx)
- if (vhd->last_idx >= 10)
- pss->last_idx = vhd->last_idx - 10;
-
- sprintf(s, "select idx, time, username, email, ip, content "
- "from msg where idx > %lu order by idx limit 1;",
- pss->last_idx);
- if (sqlite3_exec(vhd->pdb, s, lookup_cb, &m, NULL) != SQLITE_OK) {
- lwsl_err("Unable to lookup msg: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 0;
- }
-
- /* format in JSON */
- p += lws_snprintf(p, end - p,
- "{\"idx\":\"%lu\",\"time\":\"%lu\",",
- m.idx, m.time);
- p += lws_snprintf(p, end - p, " \"username\":\"%s\",",
- lws_json_purify(e, m.username, sizeof(e), NULL));
- p += lws_snprintf(p, end - p, " \"email\":\"%s\",",
- lws_json_purify(e, m.email, sizeof(e), NULL));
- p += lws_snprintf(p, end - p, " \"ip\":\"%s\",",
- lws_json_purify(e, m.ip, sizeof(e), NULL));
- p += lws_snprintf(p, end - p, " \"content\":\"%s\"}",
- lws_json_purify(e, m.content, sizeof(e), NULL));
-
- if (lws_write(wsi, (unsigned char *)start, p - start,
- LWS_WRITE_TEXT) < 0)
- return -1;
-
- pss->last_idx = m.idx;
- if (pss->last_idx == vhd->last_idx)
- break;
-
- lws_callback_on_writable(wsi); /* more to do */
- }
- break;
-
- case LWS_CALLBACK_HTTP:
- pss->our_form = 0;
-
- /* ie, it's our messageboard new message form */
- if (!strcmp((const char *)in, "/msg") ||
- !strcmp((const char *)in, "msg")) {
- pss->our_form = 1;
- break;
- }
-
- goto passthru;
-
- case LWS_CALLBACK_HTTP_BODY:
- if (!pss->our_form)
- goto passthru;
-
- if (len < 2)
- break;
- if (!pss->spa) {
- pss->spa = lws_spa_create(wsi, param_names,
- LWS_ARRAY_SIZE(param_names),
- MAX_MSG_LEN + 1024, NULL, NULL);
- if (!pss->spa)
- return -1;
- }
-
- if (lws_spa_process(pss->spa, in, len)) {
- lwsl_notice("spa process blew\n");
- return -1;
- }
- break;
-
- case LWS_CALLBACK_HTTP_WRITEABLE:
- if (!pss->second_http_part)
- goto passthru;
-
- s[0] = '0';
- n = lws_write(wsi, (unsigned char *)s, 1, LWS_WRITE_HTTP|
- LWS_WRITE_H2_STREAM_END);
- if (n != 1)
- return -1;
-
- goto try_to_reuse;
-
- case LWS_CALLBACK_HTTP_BODY_COMPLETION:
- if (!pss->our_form)
- goto passthru;
-
- if (post_message(wsi, vhd, pss))
- return -1;
-
- p = buffer + LWS_PRE;
- start = p;
- end = p + sizeof(buffer) - LWS_PRE;
-
- if (lws_add_http_header_status(wsi, HTTP_STATUS_OK, &p, end))
- return -1;
- if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE,
- (unsigned char *)"text/plain", 10, &p, end))
- return -1;
- if (lws_add_http_header_content_length(wsi, 1, &p, end))
- return -1;
- if (lws_finalize_http_header(wsi, &p, end))
- return -1;
-
- n = lws_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS);
- if (n != (p - start)) {
- lwsl_err("_write returned %d from %ld\n", n, (long)(p - start));
- return -1;
- }
- pss->second_http_part = 1;
- lws_callback_on_writable(wsi);
- break;
-
- case LWS_CALLBACK_HTTP_BIND_PROTOCOL:
- if (!pss || !vhd || pss->pss_gs)
- break;
-
- pss->pss_gs = malloc(vhd->gsp->per_session_data_size);
- if (!pss->pss_gs)
- return -1;
-
- memset(pss->pss_gs, 0, vhd->gsp->per_session_data_size);
- break;
-
- case LWS_CALLBACK_HTTP_DROP_PROTOCOL:
- if (vhd->gsp->callback(wsi, reason, pss ? pss->pss_gs : NULL, in, len))
- return -1;
-
- if (pss && pss->spa) {
- lws_spa_destroy(pss->spa);
- pss->spa = NULL;
- }
- if (pss && pss->pss_gs) {
- free(pss->pss_gs);
- pss->pss_gs = NULL;
- }
- break;
-
- default:
-passthru:
- if (!pss || !vhd)
- break;
-
- return vhd->gsp->callback(wsi, reason, pss->pss_gs, in, len);
- }
-
- return 0;
-
-
-try_to_reuse:
- if (lws_http_transaction_completed(wsi))
- return -1;
-
- return 0;
-}
-
-static const struct lws_protocols protocols[] = {
- {
- "protocol-lws-messageboard",
- callback_messageboard,
- sizeof(struct per_session_data__gs_mb),
- 4096,
- },
-};
-
-LWS_VISIBLE int
-init_protocol_lws_messageboard(struct lws_context *context,
- struct lws_plugin_capability *c)
-{
- if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
- lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
- c->api_magic);
- return 1;
- }
-
- c->protocols = protocols;
- c->count_protocols = LWS_ARRAY_SIZE(protocols);
- c->extensions = NULL;
- c->count_extensions = 0;
-
- return 0;
-}
-
-LWS_VISIBLE int
-destroy_protocol_lws_messageboard(struct lws_context *context)
-{
- return 0;
-}
diff --git a/plugins/generic-sessions/utils.c b/plugins/generic-sessions/utils.c
deleted file mode 100644
index 9e603ea71..000000000
--- a/plugins/generic-sessions/utils.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "private-lwsgs.h"
-#include
-
-void
-sha256_to_lwsgw_hash(unsigned char *hash, lwsgw_hash *shash)
-{
- static const char *hex = "0123456789abcdef";
- char *p = shash->id;
- int n;
-
- for (n = 0; n < (int)lws_genhash_size(LWS_GENHASH_TYPE_SHA256); n++) {
- *p++ = hex[(hash[n] >> 4) & 0xf];
- *p++ = hex[hash[n] & 15];
- }
-
- *p = '\0';
-}
-
-int
-lwsgw_check_admin(struct per_vhost_data__gs *vhd,
- const char *username, const char *password)
-{
- lwsgw_hash_bin hash_bin;
- lwsgw_hash pw_hash;
-
- if (strcmp(vhd->admin_user, username))
- return 0;
-
- lws_SHA1((unsigned char *)password, strlen(password), hash_bin.bin);
- sha256_to_lwsgw_hash(hash_bin.bin, &pw_hash);
-
- return !strcmp(vhd->admin_password_sha256.id, pw_hash.id);
-}
-
-/*
- * secure cookie: it can only be passed over https where it cannot be
- * snooped in transit
- * HttpOnly: it can only be accessed via http[s] transport, it cannot be
- * gotten at by JS
- */
-void
-lwsgw_cookie_from_session(lwsgw_hash *sid, time_t expires, char **p, char *end)
-{
- struct tm *tm = gmtime(&expires);
- time_t n = lws_now_secs();
-
- *p += lws_snprintf(*p, end - *p, "id=%s;Expires=", sid->id);
-#ifdef WIN32
- *p += strftime(*p, end - *p, "%Y %H:%M %Z", tm);
-#else
- *p += strftime(*p, end - *p, "%F %H:%M %Z", tm);
-#endif
- *p += lws_snprintf(*p, end - *p, ";path=/");
- *p += lws_snprintf(*p, end - *p, ";Max-Age=%lu", (unsigned long)(expires - n));
-// *p += lws_snprintf(*p, end - *p, ";secure");
- *p += lws_snprintf(*p, end - *p, ";HttpOnly");
-}
-
-int
-lwsgw_expire_old_sessions(struct per_vhost_data__gs *vhd)
-{
- time_t n = lws_now_secs();
- char s[200];
-
- if (n - vhd->last_session_expire < 5)
- return 0;
-
- vhd->last_session_expire = n;
-
- lws_snprintf(s, sizeof(s) - 1,
- "delete from sessions where "
- "expire <= %lu;", (unsigned long)n);
-
- if (sqlite3_exec(vhd->pdb, s, NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("Unable to expire sessions: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 1;
- }
-
- return 0;
-}
-
-int
-lwsgw_update_session(struct per_vhost_data__gs *vhd,
- lwsgw_hash *hash, const char *user)
-{
- time_t n = lws_now_secs();
- char s[200], esc[96], esc1[96];
-
- if (user[0])
- n += vhd->timeout_absolute_secs;
- else
- n += vhd->timeout_anon_absolute_secs;
-
- lws_snprintf(s, sizeof(s) - 1,
- "update sessions set expire=%lu,username='%s' where name='%s';",
- (unsigned long)n,
- lws_sql_purify(esc, user, sizeof(esc)),
- lws_sql_purify(esc1, hash->id, sizeof(esc1)));
-
- if (sqlite3_exec(vhd->pdb, s, NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("Unable to update session: %s\n",
- sqlite3_errmsg(vhd->pdb));
- return 1;
- }
-
- puts(s);
-
- return 0;
-}
-
-static int
-lwsgw_session_from_cookie(const char *cookie, lwsgw_hash *sid)
-{
- const char *p = cookie;
- int n;
-
- while (*p) {
- if (p[0] == 'i' && p[1] == 'd' && p[2] == '=') {
- p += 3;
- break;
- }
- p++;
- }
- if (!*p) {
- lwsl_info("no id= in cookie\n");
- return 1;
- }
-
- for (n = 0; n < (int)sizeof(sid->id) - 1 && *p; n++) {
- /* our SID we issue only has these chars */
- if ((*p >= '0' && *p <= '9') ||
- (*p >= 'a' && *p <= 'f'))
- sid->id[n] = *p++;
- else {
- lwsl_info("bad chars in cookie id %c\n", *p);
- return 1;
- }
- }
-
- if (n < (int)sizeof(sid->id) - 1) {
- lwsl_info("cookie id too short\n");
- return 1;
- }
-
- sid->id[sizeof(sid->id) - 1] = '\0';
-
- return 0;
-}
-
-int
-lwsgs_get_sid_from_wsi(struct lws *wsi, lwsgw_hash *sid)
-{
- char cookie[1024];
-
- /* fail it on no cookie */
- if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COOKIE)) {
- lwsl_info("%s: no cookie\n", __func__);
- return 1;
- }
- if (lws_hdr_copy(wsi, cookie, sizeof cookie, WSI_TOKEN_HTTP_COOKIE) < 0) {
- lwsl_info("cookie copy failed\n");
- return 1;
- }
- /* extract the sid from the cookie */
- if (lwsgw_session_from_cookie(cookie, sid)) {
- lwsl_info("%s: session from cookie failed\n", __func__);
- return 1;
- }
-
- return 0;
-}
-
-struct lla {
- char *username;
- int len;
- int results;
-};
-
-static int
-lwsgs_lookup_callback(void *priv, int cols, char **col_val, char **col_name)
-{
- struct lla *lla = (struct lla *)priv;
-
- //lwsl_err("%s: %d\n", __func__, cols);
-
- if (cols)
- lla->results = 0;
- if (col_val && col_val[0]) {
- lws_strncpy(lla->username, col_val[0], lla->len + 1);
- lwsl_info("%s: %s\n", __func__, lla->username);
- }
-
- return 0;
-}
-
-int
-lwsgs_lookup_session(struct per_vhost_data__gs *vhd,
- const lwsgw_hash *sid, char *username, int len)
-{
- struct lla lla = { username, len, 1 };
- char s[150], esc[96];
-
- lwsgw_expire_old_sessions(vhd);
-
- lws_snprintf(s, sizeof(s) - 1,
- "select username from sessions where name = '%s';",
- lws_sql_purify(esc, sid->id, sizeof(esc) - 1));
-
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback, &lla, NULL) != SQLITE_OK) {
- lwsl_err("Unable to create user table: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- return 1;
- }
-
- /* 0 if found */
- return lla.results;
-}
-
-int
-lwsgs_lookup_callback_user(void *priv, int cols, char **col_val, char **col_name)
-{
- struct lwsgs_user *u = (struct lwsgs_user *)priv;
- int n;
-
- for (n = 0; n < cols; n++) {
- if (!strcmp(col_name[n], "username")) {
- lws_strncpy(u->username, col_val[n], sizeof(u->username));
- continue;
- }
- if (!strcmp(col_name[n], "ip")) {
- lws_strncpy(u->ip, col_val[n], sizeof(u->ip));
- continue;
- }
- if (!strcmp(col_name[n], "creation_time")) {
- u->created = atol(col_val[n]);
- continue;
- }
- if (!strcmp(col_name[n], "last_forgot_validated")) {
- if (col_val[n])
- u->last_forgot_validated = atol(col_val[n]);
- else
- u->last_forgot_validated = 0;
- continue;
- }
- if (!strcmp(col_name[n], "email")) {
- lws_strncpy(u->email, col_val[n], sizeof(u->email));
- continue;
- }
- if (!strcmp(col_name[n], "verified")) {
- u->verified = atoi(col_val[n]);
- continue;
- }
- if (!strcmp(col_name[n], "pwhash")) {
- lws_strncpy(u->pwhash.id, col_val[n], sizeof(u->pwhash.id));
- continue;
- }
- if (!strcmp(col_name[n], "pwsalt")) {
- lws_strncpy(u->pwsalt.id, col_val[n], sizeof(u->pwsalt.id));
- continue;
- }
- if (!strcmp(col_name[n], "token")) {
- lws_strncpy(u->token.id, col_val[n], sizeof(u->token.id));
- continue;
- }
- }
- return 0;
-}
-
-int
-lwsgs_lookup_user(struct per_vhost_data__gs *vhd,
- const char *username, struct lwsgs_user *u)
-{
- char s[150], esc[96];
-
- u->username[0] = '\0';
- lws_snprintf(s, sizeof(s) - 1,
- "select username,creation_time,ip,email,verified,pwhash,pwsalt,last_forgot_validated "
- "from users where username = '%s';",
- lws_sql_purify(esc, username, sizeof(esc) - 1));
-
- if (sqlite3_exec(vhd->pdb, s, lwsgs_lookup_callback_user, u, NULL) !=
- SQLITE_OK) {
- lwsl_err("Unable to lookup user: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- return -1;
- }
-
- return !u->username[0];
-}
-
-int
-lwsgs_new_session_id(struct per_vhost_data__gs *vhd,
- lwsgw_hash *sid, const char *username, int exp)
-{
- unsigned char sid_rand[32];
- const char *u;
- char s[300], esc[96], esc1[96];
-
- if (username)
- u = username;
- else
- u = "";
-
- if (!sid) {
- lwsl_err("%s: NULL sid\n", __func__);
- return 1;
- }
-
- memset(sid, 0, sizeof(*sid));
-
- if (lws_get_random(vhd->context, sid_rand, sizeof(sid_rand)) !=
- sizeof(sid_rand))
- return 1;
-
- sha256_to_lwsgw_hash(sid_rand, sid);
-
- lws_snprintf(s, sizeof(s) - 1,
- "insert into sessions(name, username, expire) "
- "values ('%s', '%s', %u);",
- lws_sql_purify(esc, sid->id, sizeof(esc) - 1),
- lws_sql_purify(esc1, u, sizeof(esc1) - 1), exp);
-
- if (sqlite3_exec(vhd->pdb, s, NULL, NULL, NULL) != SQLITE_OK) {
- lwsl_err("Unable to insert session: %s\n",
- sqlite3_errmsg(vhd->pdb));
-
- return 1;
- }
-
- lwsl_notice("%s: created session %s\n", __func__, sid->id);
-
- return 0;
-}
-
-int
-lwsgs_get_auth_level(struct per_vhost_data__gs *vhd, const char *username)
-{
- struct lwsgs_user u;
- int n = 0;
-
- /* we are logged in as some kind of user */
- if (username[0]) {
- /* we are logged in as admin */
- if (!strcmp(username, vhd->admin_user))
- /* automatically verified */
- n |= LWSGS_AUTH_VERIFIED | LWSGS_AUTH_ADMIN;
- }
-
- if (!lwsgs_lookup_user(vhd, username, &u)) {
- if ((u.verified & 0xff) == LWSGS_VERIFIED_ACCEPTED)
- n |= LWSGS_AUTH_LOGGED_IN | LWSGS_AUTH_VERIFIED;
-
- if (u.last_forgot_validated > (time_t)lws_now_secs() - 300)
- n |= LWSGS_AUTH_FORGOT_FLOW;
- }
-
- return n;
-}
-
-int
-lwsgs_check_credentials(struct per_vhost_data__gs *vhd,
- const char *username, const char *password)
-{
- struct lws_genhash_ctx hash_ctx;
- lwsgw_hash_bin hash_bin;
- struct lwsgs_user u;
- lwsgw_hash hash;
-
- if (lwsgs_lookup_user(vhd, username, &u))
- return -1;
-
- lwsl_info("user %s found, salt '%s'\n", username, u.pwsalt.id);
-
- /* sha256sum of password + salt */
-
- if (lws_genhash_init(&hash_ctx, LWS_GENHASH_TYPE_SHA256) ||
- lws_genhash_update(&hash_ctx, password, strlen(password)) ||
- lws_genhash_update(&hash_ctx, "-", 1) ||
- lws_genhash_update(&hash_ctx, vhd->confounder, strlen(vhd->confounder)) ||
- lws_genhash_update(&hash_ctx, "-", 1) ||
- lws_genhash_update(&hash_ctx, u.pwsalt.id, strlen(u.pwsalt.id)) ||
- lws_genhash_destroy(&hash_ctx, hash_bin.bin)) {
- lws_genhash_destroy(&hash_ctx, NULL);
-
- return 1;
- }
-
- sha256_to_lwsgw_hash(&hash_bin.bin[0], &hash);
-
- return !!strcmp(hash.id, u.pwhash.id);
-}
-
-/* sets u->pwsalt and u->pwhash */
-
-int
-lwsgs_hash_password(struct per_vhost_data__gs *vhd,
- const char *password, struct lwsgs_user *u)
-{
- unsigned char sid_rand[32];
- struct lws_genhash_ctx hash_ctx;
- lwsgw_hash_bin hash_bin;
-
- /* create a random salt as big as the hash */
-
- if (lws_get_random(vhd->context, sid_rand,
- sizeof(sid_rand)) !=
- sizeof(sid_rand)) {
- lwsl_err("Problem getting random for salt\n");
- return 1;
- }
- sha256_to_lwsgw_hash(sid_rand, &u->pwsalt);
-/*
- if (lws_get_random(vhd->context, sid_rand,
- sizeof(sid_rand)) !=
- sizeof(sid_rand)) {
- lwsl_err("Problem getting random for token\n");
- return 1;
- }
- sha256_to_lwsgw_hash(sid_rand, &hash);
-*/
- /* sha256sum of password + salt */
-
- if (lws_genhash_init(&hash_ctx, LWS_GENHASH_TYPE_SHA256) ||
- lws_genhash_update(&hash_ctx, password, strlen(password)) ||
- lws_genhash_update(&hash_ctx, "-", 1) ||
- lws_genhash_update(&hash_ctx, vhd->confounder, strlen(vhd->confounder)) ||
- lws_genhash_update(&hash_ctx, "-", 1) ||
- lws_genhash_update(&hash_ctx, u->pwsalt.id, strlen(u->pwsalt.id)) ||
- lws_genhash_destroy(&hash_ctx, hash_bin.bin)) {
- lws_genhash_destroy(&hash_ctx, NULL);
-
- return 1;
- }
-
- sha256_to_lwsgw_hash(&hash_bin.bin[0], &u->pwhash);
-
- return 0;
-}
diff --git a/plugins/generic-table/assets/index.html b/plugins/generic-table/assets/index.html
deleted file mode 100644
index 635d02aa4..000000000
--- a/plugins/generic-table/assets/index.html
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
-
-
-
-
-
-
- LWS Generic Table demo
- |
-
- This is a demo of lws generic table, using a protocol plugin
- "protocol-lws-table-dirlisting". It shows a directory listing,
- but unlike an oldstyle directory listing done on the
- server side with a script, this is static html that connects
- back to the server with a websocket, and gets live JSON from
- that.
-
- Actually the static html is extremely simple, since it uses
- lwsgt, LWS Generic Table, JS include on the client-side that
- handles all the table generation from a template sent in JSON
- over the ws link. It means there is no custom JS required
- clientside either. It's just CSS, this text and a call to
- initialize lwsgt with the appropriate ws protocol.
- |
- |
-
- There's no problem having multiple independent instances per
- page...
- |
- |
-
-
-
-
-
-
diff --git a/plugins/generic-table/assets/lwsgt.js b/plugins/generic-table/assets/lwsgt.js
deleted file mode 100644
index 5e4365a23..000000000
--- a/plugins/generic-table/assets/lwsgt.js
+++ /dev/null
@@ -1,139 +0,0 @@
-function lwsgt_get_appropriate_ws_url()
-{
- var pcol;
- var u = document.URL;
-
- if (u.substring(0, 5) === "https") {
- pcol = "wss://";
- u = u.substr(8);
- } else {
- pcol = "ws://";
- if (u.substring(0, 4) === "http")
- u = u.substr(7);
- }
-
- return pcol + u;
-}
-
-function lwsgt_app_hdr(j, bc, ws)
-{
- var s = "", n, m = 0;
-
- ws.bcq = 0;
-
- for (n = 0; n < j.cols.length; n++)
- if (!j.cols[n].hide)
- m++;
-
- s = "" +
- ws.lwsgt_title + " |
";
-
- if (!!bc) {
- s += "";
- for (n = 0; n < bc.length; n++) {
- s += " / ";
- if (!bc[n].url && bc[n].url !== "")
- s += " " + lws_san(bc[n].name) + " ";
- else {
- s += "" +
- lws_san(bc[n].name) + " ";
- ws.bcq++;
- }
- }
- s += " |
";
- }
- s += "";
- for (n = 0; n < j.cols.length; n++)
- if (!j.cols[n].hide)
- s = s + "" + lws_san(j.cols[n].name) +
- " | ";
-
- s += "
";
-
- return s;
-}
-
-function lwsgt_click_callthru()
-{
- window[this.getAttribute("h")](this.getAttribute("p"), this.getAttribute("aa"), this.getAttribute("m"), this.getAttribute("n"));
- event.preventDefault();
-}
-
-function lwsgt_initial(title, pcol, divname, cb, gname)
-{
- this.divname = divname;
-
- lws_gray_out(true,{"zindex":"499"});
-
- this.lwsgt_ws = new WebSocket(lwsgt_get_appropriate_ws_url(), pcol);
- this.lwsgt_ws.divname = divname;
- this.lwsgt_ws.lwsgt_cb = cb;
- this.lwsgt_ws.lwsgt_parent = gname;
- this.lwsgt_ws.lwsgt_title = title;
- try {
- this.lwsgt_ws.onopen = function() {
- lws_gray_out(false);
- // document.getElementById("debug").textContent =
- // "ws opened " + lwsgt_get_appropriate_ws_url();
- };
- this.lwsgt_ws.onmessage = function got_packet(msg) {
- var s, m, n, j = JSON.parse(msg.data);
- document.getElementById("debug").textContent = msg.data;
- if (j.cols) {
- this.hdr = j;
- }
- if (j.breadcrumbs)
- this.breadcrumbs = j.breadcrumbs;
-
- if (j.data) {
- var q = 0;
- s = "" +
- lwsgt_app_hdr(this.hdr, this.breadcrumbs, this);
- for (m = 0; m < j.data.length; m++) {
- s = s + "";
- for (n = 0; n < this.hdr.cols.length; n++) {
- if (!this.hdr.cols[n].hide) {
- if (!this.hdr.cols[n].align)
- s = s + "";
- else
- s = s + " | ";
-
- if (this.hdr.cols[n].href &&
- !!j.data[m][this.hdr.cols[n].href]) {
- s = s + "" +
- lws_san(j.data[m][this.hdr.cols[n].name]) +
- "";
- q++;
- }
- else
- s = s + lws_san(j.data[m][this.hdr.cols[n].name]);
-
- s = s + " | ";
- }
- }
-
- s = s + "
";
- }
- s = s + "
";
- document.getElementById(this.divname).innerHTML = s;
- for (n = 0; n < q; n++)
- document.getElementById(this.divname + n).onclick =
- lwsgt_click_callthru;
-
- for (n = 0; n < this.bcq; n++)
- document.getElementById("bc_" + this.divname + n).onclick =
- lwsgt_click_callthru;
-
- }
- };
- this.lwsgt_ws.onclose = function(){
- lws_gray_out(true,{"zindex":"499"});
- };
- } catch(exception) {
- alert("Error" + exception);
- }
-}
-
diff --git a/plugins/generic-table/protocol_table_dirlisting.c b/plugins/generic-table/protocol_table_dirlisting.c
deleted file mode 100644
index 8537b6156..000000000
--- a/plugins/generic-table/protocol_table_dirlisting.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * libwebsockets - small server side websockets and web server implementation
- *
- * Copyright (C) 2010 - 2019 Andy Green
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#define LWS_DLL
-#define LWS_INTERNAL
-#include
-
-#include
-#include
-#include
-
-struct fobj {
- struct fobj *next;
- const char *name, *uri, *icon, *date;
- time_t m;
- unsigned long size;
-};
-
-struct per_session_data__tbl_dir {
- struct fobj base;
- char strings[64 * 1024];
- char reldir[256];
- char *p;
- const char *dir;
-
-#if UV_VERSION_MAJOR > 0
- uv_fs_event_t *event_req;
-#endif
- struct lws *wsi;
-};
-
-#if UV_VERSION_MAJOR > 0
-static void
-mon_cb(uv_fs_event_t *handle, const char *filename, int events, int status)
-{
- struct per_session_data__tbl_dir *pss = handle->data;
-
- //lwsl_notice("%s\n", __func__);
-
- if (pss && pss->wsi)
- lws_callback_on_writable(pss->wsi);
-}
-
-static void lws_uv_close_cb(uv_handle_t *handle)
-{
- free(handle);
-}
-
-static void
-lws_protocol_dir_kill_monitor(struct per_session_data__tbl_dir *pss)
-{
- if (!pss->event_req)
- return;
- pss->wsi = NULL;
- pss->event_req->data = NULL;
- uv_fs_event_stop(pss->event_req);
- uv_close((uv_handle_t *)pss->event_req, lws_uv_close_cb);
- pss->event_req = NULL;
-}
-#endif
-
-static int
-scan_dir(struct lws *wsi, struct per_session_data__tbl_dir *pss)
-{
-/* uuh travis... */
-#if UV_VERSION_MAJOR > 0
- uv_loop_t *loop = lws_uv_getloop(lws_get_context(wsi), 0);
- char *end = &(pss->strings[sizeof(pss->strings) - 1]);
- struct fobj *prev = &pss->base;
- char path[512], da[200];
- const char *icon;
- uv_dirent_t dent;
- struct fobj *f;
- struct stat st;
- struct tm *tm;
- int ret = 0, n;
- uv_fs_t req;
-
- lws_protocol_dir_kill_monitor(pss);
-
- lws_snprintf(path, sizeof(path) - 1, "%s/%s", pss->dir, pss->reldir);
- //lwsl_notice("path = %s\n", path);
-
- pss->event_req = malloc(sizeof(*pss->event_req));
- if (!pss->event_req)
- return 2;
-
- pss->wsi = wsi;
- pss->event_req->data = pss;
-
- uv_fs_event_init(lws_uv_getloop(lws_get_context(wsi), 0),
- pss->event_req);
- // The recursive flag watches subdirectories too.
- n = uv_fs_event_start(pss->event_req, mon_cb, path, UV_FS_EVENT_RECURSIVE);
- //lwsl_notice("monitoring %s (%d)\n", path, n);
-
- if (!uv_fs_scandir(loop, &req, path, 0, NULL)) {
- lwsl_err("Scandir on %s failed\n", path);
- return 2;
- }
-
- pss->p = pss->strings;
-
- while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
- lws_snprintf(path, sizeof(path) - 1, "%s/%s/%s", pss->dir, pss->reldir, dent.name);
-
- if (stat(path, &st)) {
- lwsl_info("unable to stat %s\n", path);
- continue;
- }
- f = malloc(sizeof(*f));
- f->next = NULL;
- f->name = pss->p;
- n = lws_snprintf(pss->p, end - pss->p, "%s", dent.name);
- pss->p += n + 1;
- f->uri = NULL;
- if ((S_IFMT & st.st_mode) == S_IFDIR) {
- n = lws_snprintf(pss->p, end - pss->p, "=%s/%s", pss->reldir, dent.name);
- f->uri = pss->p;
- }
- if (lws_get_mimetype(dent.name, NULL)) {
- n = lws_snprintf(pss->p, end - pss->p, "./serve/%s/%s", pss->reldir, dent.name);
- f->uri = pss->p;
- }
- if (f->uri)
- pss->p += n + 1;
-
- if (end - pss->p < 100) {
- free(f);
- break;
- }
-
- icon = " ";
- if ((S_IFMT & st.st_mode) == S_IFDIR)
- icon = "📂";
-
- f->icon = pss->p;
- n = lws_snprintf(pss->p, end - pss->p, "%s", icon);
- pss->p += n + 1;
-
- f->date = pss->p;
- tm = gmtime(&st.st_mtime);
- strftime(da, sizeof(da), "%Y-%b-%d %H:%M:%S %z", tm);
- n = lws_snprintf(pss->p, end - pss->p, "%s", da);
- pss->p += n + 1;
-
- f->size = st.st_size;
- f->m = st.st_mtime;
- prev->next = f;
- prev = f;
- }
-
- uv_fs_req_cleanup(&req);
-
- return ret;
-#else
- return 0;
-#endif
-}
-
-static void
-free_scan_dir(struct per_session_data__tbl_dir *pss)
-{
- struct fobj *f = pss->base.next, *f1;
-
- while (f) {
- f1 = f->next;
- free(f);
- f = f1;
- }
-
- pss->base.next = NULL;
-}
-
-static int
-callback_lws_table_dirlisting(struct lws *wsi, enum lws_callback_reasons reason,
- void *user, void *in, size_t len)
-{
- struct per_session_data__tbl_dir *pss = (struct per_session_data__tbl_dir *)user;
- char j[LWS_PRE + 16384], *p = j + LWS_PRE, *start = p, *q, *q1, *w,
- *end = j + sizeof(j) - LWS_PRE, e[384], s[384], s1[384];
- const struct lws_protocol_vhost_options *pmo;
- struct fobj *f;
- int n, first = 1;
-
- switch (reason) {
- case LWS_CALLBACK_PROTOCOL_INIT: /* per vhost */
- break;
-
- case LWS_CALLBACK_ESTABLISHED:
- lwsl_debug("LWS_CALLBACK_ESTABLISHED\n");
- /*
- * send client the lwsgt table layout
- */
- start = "{\"cols\":["
- " {\"name\": \"Date\"},"
- " {\"name\": \"Size\", \"align\": \"right\"},"
- " {\"name\": \"Icon\"},"
- " {\"name\": \"Name\", \"href\": \"uri\"},"
- " {\"name\": \"uri\", \"hide\": \"1\" }"
- " ]"
- "}";
- if (lws_write(wsi, (unsigned char *)start, strlen(start),
- LWS_WRITE_TEXT) < 0)
- return -1;
-
- /* send a view update next */
- lws_callback_on_writable(wsi);
- break;
-
- case LWS_CALLBACK_RECEIVE:
- if (len > sizeof(pss->reldir) - 1)
- len = sizeof(pss->reldir) - 1;
- if (!strstr(in, "..") && !strchr(in, '~'))
- lws_strncpy(pss->reldir, in, len + 1);
- else
- len = 0;
- pss->reldir[len] = '\0';
- if (pss->reldir[0] == '/' && !pss->reldir[1])
- pss->reldir[0] = '\0';
- lwsl_info("%s\n", pss->reldir);
- lws_callback_on_writable(wsi);
- break;
-
- case LWS_CALLBACK_SERVER_WRITEABLE:
-
- if (scan_dir(wsi, pss))
- return 1;
-
- p += lws_snprintf(p, end - p, "{\"breadcrumbs\":[");
- q = pss->reldir;
-
- if (!q[0])
- p += lws_snprintf(p, end - p, "{\"name\":\"top\"}");
-
- while (*q) {
-
- q1 = strchr(q, '/');
- if (!q1) {
- if (first)
- strcpy(s, "top1");
- else
- strcpy(s, q);
- s1[0] = '\0';
- q += strlen(q);
- } else {
- n = lws_ptr_diff(q1, q);
- if (n > (int)sizeof(s) - 1)
- n = sizeof(s) - 1;
- if (first) {
- strcpy(s1, "/");
- strcpy(s, "top");
- } else {
- lws_strncpy(s, q, n + 1);
-
- n = lws_ptr_diff(q1, pss->reldir);
- if (n > (int)sizeof(s1) - 1)
- n = sizeof(s1) - 1;
- lws_strncpy(s1, pss->reldir, n + 1);
- }
- q = q1 + 1;
- }
- if (!first)
- p += lws_snprintf(p, end - p, ",");
- else
- first = 0;
-
- p += lws_snprintf(p, end - p, "{\"name\":\"%s\"",
- lws_json_purify(e, s, sizeof(e), NULL));
- if (*q) {
- w = s1;
- while (w[0] == '/' && w[1] == '/')
- w++;
- p += lws_snprintf(p, end - p, ",\"url\":\"%s\"",
- lws_json_purify(e, w, sizeof(e), NULL));
- }
- p += lws_snprintf(p, end - p, "}");
- if (!q1)
- break;
- }
-
- p += lws_snprintf(p, end - p, "],\"data\":[");
-
- f = pss->base.next;
- while (f) {
- /* format in JSON */
- p += lws_snprintf(p, end - p, "{\"Icon\":\"%s\",",
- lws_json_purify(e, f->icon, sizeof(e), NULL));
- p += lws_snprintf(p, end - p, " \"Date\":\"%s\",",
- lws_json_purify(e, f->date, sizeof(e), NULL));
- p += lws_snprintf(p, end - p, " \"Size\":\"%ld\",",
- f->size);
- if (f->uri)
- p += lws_snprintf(p, end - p, " \"uri\":\"%s\",",
- lws_json_purify(e, f->uri, sizeof(e), NULL));
- p += lws_snprintf(p, end - p, " \"Name\":\"%s\"}",
- lws_json_purify(e, f->name, sizeof(e), NULL));
-
- f = f->next;
-
- if (f)
- p += lws_snprintf(p, end - p, ",");
- }
-
- p += lws_snprintf(p, end - p, "]}");
-
- free_scan_dir(pss);
-
- if (lws_write(wsi, (unsigned char *)start, p - start,
- LWS_WRITE_TEXT) < 0)
- return -1;
-
- break;
-
- case LWS_CALLBACK_HTTP_PMO:
- /* find the per-mount options we're interested in */
- lwsl_debug("LWS_CALLBACK_HTTP_PMO\n");
- pmo = (struct lws_protocol_vhost_options *)in;
- while (pmo) {
- if (!strcmp(pmo->name, "dir")) /* path to list files */
- pss->dir = pmo->value;
- pmo = pmo->next;
- }
- if (!pss->dir[0]) {
- lwsl_err("dirlisting: \"dir\" pmo missing\n");
- return 1;
- }
- break;
-
- case LWS_CALLBACK_HTTP_DROP_PROTOCOL:
- //lwsl_notice("LWS_CALLBACK_HTTP_DROP_PROTOCOL\n");
-#if UV_VERSION_MAJOR > 0
- lws_protocol_dir_kill_monitor(pss);
-#endif
- break;
-
- default:
- return 0;
- }
-
- return 0;
-
-}
-
-static const struct lws_protocols protocols[] = {
- {
- "protocol-lws-table-dirlisting",
- callback_lws_table_dirlisting,
- sizeof(struct per_session_data__tbl_dir),
- 0,
- },
-};
-
-LWS_VISIBLE int
-init_protocol_lws_table_dirlisting(struct lws_context *context,
- struct lws_plugin_capability *c)
-{
- if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
- lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
- c->api_magic);
- return 1;
- }
-
- c->protocols = protocols;
- c->count_protocols = LWS_ARRAY_SIZE(protocols);
- c->extensions = NULL;
- c->count_extensions = 0;
-
- return 0;
-}
-
-LWS_VISIBLE int
-destroy_protocol_lws_table_dirlisting(struct lws_context *context)
-{
- return 0;
-}