AmendHub

Download

jcs

/

subtext

/

signup.c

 

(View History)

jcs   signup: Error-path fixes, use strlcpy Latest amendment: 620 on 2025-12-11

1 /*
2 * Copyright (c) 2022 joshua stein <jcs@jcs.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <stdarg.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "subtext.h"
23 #include "session.h"
24 #include "signup.h"
25 #include "user.h"
26 #include "util.h"
27
28 struct user *
29 signup(struct session *s)
30 {
31 struct user *user = NULL;
32 char *username = NULL, *password = NULL, *password_confirm = NULL,
33 *error = NULL;
34
35 session_logf(s, "Signing up for an account");
36
37 session_printf(s, "{{B}}Create Account{{/B}} "
38 "(^C to cancel)\r\n"
39 "{{B}}----------------------------{{/B}}\r\n");
40 session_output_view_or_printf(s, DB_VIEW_SIGNUP,
41 "[ Signup instructions missing ]\r\n\r\n");
42 session_flush(s);
43
44 for (;;) {
45 session_printf(s, "{{B}}Username{{/B}} (Up to %d letters/numbers): ",
46 DB_USERNAME_LENGTH);
47 session_flush(s);
48
49 username = session_field_input(s, DB_USERNAME_LENGTH + 1,
50 DB_USERNAME_LENGTH, NULL, false, 0);
51 session_output(s, "\r\n", 2);
52 session_flush(s);
53
54 if (username == NULL)
55 goto signup_done;
56 if (username[0] == '\0' || s->ending) {
57 xfree(&username);
58 goto signup_done;
59 }
60
61 if (!user_valid_username(NULL, username, &error)) {
62 session_printf(s, "{{B}}Error:{{/B}} %s\r\n", error);
63 xfree(&error);
64 xfree(&username);
65 continue;
66 }
67
68 break;
69 }
70
71 for (;;) {
72 session_printf(s, "{{B}}Password:{{/B}} ");
73 session_flush(s);
74 password = session_field_input(s, 64, 64, NULL, false, '*');
75 session_output(s, "\r\n", 2);
76 session_flush(s);
77
78 if (password == NULL || s->ending)
79 goto signup_done;
80
81 if (password[0] == '\0') {
82 session_printf(s, "{{B}}Error:{{/B}} "
83 "Password cannot be blank\r\n");
84 xfree(&password);
85 continue;
86 }
87
88 session_printf(s, "{{B}}Password (again):{{/B}} ");
89 session_flush(s);
90 password_confirm = session_field_input(s, 64, 64, NULL, false,
91 '*');
92 session_output(s, "\r\n", 2);
93 session_flush(s);
94
95 if (password_confirm == NULL || s->ending)
96 goto signup_done;
97
98 if (strcmp(password_confirm, password) != 0) {
99 session_printf(s, "{{B}}Error:{{/B}} "
100 "Passwords do not match\r\n");
101 xfree(&password);
102 xfree(&password_confirm);
103 continue;
104 }
105
106 break;
107 }
108
109 user = xmalloczero(sizeof(struct user));
110 if (user == NULL)
111 goto signup_done;
112 strlcpy(user->username, username, sizeof(user->username));
113 user->created_at = Time;
114 user->is_enabled = 1;
115 user_set_password(user, password);
116 if (!user_save(user)) {
117 session_logf(s, "Failed creating new user account for %s",
118 user->username);
119 xfree(&user);
120 goto signup_done;
121 }
122 user_cache_usernames();
123
124 session_logf(s, "New user account created for %s", user->username);
125
126 session_printf(s, "\r\nWelcome, {{B}}%s{{/B}}!\r\n", user->username);
127 session_flush(s);
128
129 signup_done:
130 if (username != NULL)
131 xfree(&username);
132 if (password != NULL)
133 xfree(&password);
134 if (password_confirm != NULL)
135 xfree(&password_confirm);
136
137 return user;
138 }