mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-16 00:00:07 +01:00

Thanks to Fabrice Gilot for reporting the problem that led to uncovering this. Due to a misunderstanding of the return value of snprintf (it is not truncated according to the max size passed in) in several places relying on snprintf to truncate the length overflows are possible. This patch wraps snprintf with a new lws_snprintf() which does truncate its length to allow the buffer limiting scheme to work properly. All users should update with these fixes.
599 lines
17 KiB
C
599 lines
17 KiB
C
/*
|
|
* ws protocol handler plugin for "generic sessions"
|
|
*
|
|
* Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation:
|
|
* version 2.1 of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "private-lwsgs.h"
|
|
|
|
/* 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[50];
|
|
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)
|
|
goto verf_fail;
|
|
|
|
if (strncmp(cookie, "token=", 6))
|
|
goto verf_fail;
|
|
|
|
u.username[0] = '\0';
|
|
lws_snprintf(s, sizeof(s) - 1,
|
|
"select username,email,verified from users where token = '%s';",
|
|
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 verf_fail;
|
|
}
|
|
|
|
if (!u.username[0] || u.verified != 1) {
|
|
lwsl_notice("verify token doesn't map to unverified user\n");
|
|
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(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[50];
|
|
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)
|
|
{
|
|
static const char * const colname[] = { "username", "email" };
|
|
char cookie[1024], s[256], esc[50], *pc;
|
|
unsigned char *p, *start, *end, buffer[LWS_PRE + 256];
|
|
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';
|
|
if (lws_hdr_copy_fragment(wsi, cookie, sizeof(cookie),
|
|
WSI_TOKEN_HTTP_URI_ARGS, 0) < 0)
|
|
goto reply;
|
|
|
|
n = !strncmp(cookie, "email=", 6);
|
|
pc = strchr(cookie, '=');
|
|
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, 200, &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 %d\n", n, (p - start));
|
|
return -1;
|
|
}
|
|
n = lws_write(wsi, (unsigned char *)s, 1, LWS_WRITE_HTTP);
|
|
if (n != 1)
|
|
return -1;
|
|
|
|
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[50], username[50];
|
|
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 > lws_now_secs() - 300)
|
|
n |= LWSGS_AUTH_FORGOT_FLOW;
|
|
}
|
|
}
|
|
|
|
/* if he just did forgot pw flow, don't need old pw */
|
|
if (!(n & (LWSGS_AUTH_FORGOT_FLOW | 1))) {
|
|
/* otherwise user:pass must be right */
|
|
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;
|
|
}
|
|
|
|
strncpy(u.username, lws_spa_get_string(pss->spa, FGS_USERNAME), sizeof(u.username) - 1);
|
|
u.username[sizeof(u.username) - 1] = '\0';
|
|
}
|
|
|
|
/* 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(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 s[LWSGS_EMAIL_CONTENT_SIZE];
|
|
unsigned char buffer[LWS_PRE + LWSGS_EMAIL_CONTENT_SIZE];
|
|
char esc[50], esc1[50], esc2[50], esc3[50], esc4[50];
|
|
struct lwsgs_user u;
|
|
lwsgw_hash hash;
|
|
unsigned char sid_rand[20];
|
|
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;
|
|
}
|
|
sha1_to_lwsgw_hash(sid_rand, &hash);
|
|
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.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);
|
|
|
|
lws_snprintf((char *)buffer, sizeof(buffer) - 1,
|
|
"insert into email(username, content)"
|
|
" values ('%s', '%s');",
|
|
lws_sql_purify(esc, u.username, sizeof(esc) - 1), s);
|
|
if (sqlite3_exec(vhd->pdb, (char *)buffer, NULL,
|
|
NULL, NULL) != SQLITE_OK) {
|
|
lwsl_err("Unable to insert email: %s\n",
|
|
sqlite3_errmsg(vhd->pdb));
|
|
return 1;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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[50], esc1[50], esc2[50], esc3[50], esc4[50];
|
|
char s[LWSGS_EMAIL_CONTENT_SIZE];
|
|
unsigned char sid_rand[20];
|
|
struct lwsgs_user u;
|
|
lwsgw_hash hash;
|
|
|
|
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;
|
|
}
|
|
sha1_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;
|
|
}
|
|
|
|
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.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);
|
|
|
|
lws_snprintf((char *)buffer, sizeof(buffer) - 1,
|
|
"insert into email(username, content) values ('%s', '%s');",
|
|
lws_sql_purify(esc, lws_spa_get_string(pss->spa, FGS_USERNAME),
|
|
sizeof(esc) - 1), s);
|
|
|
|
if (sqlite3_exec(vhd->pdb, (char *)buffer, NULL, NULL, NULL) != SQLITE_OK) {
|
|
lwsl_err("Unable to insert email: %s\n",
|
|
sqlite3_errmsg(vhd->pdb));
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|