1 /*
2 * lws-minimal-http-server-generic-sessions
3 *
4 * Copyright (C) 2019 Andy Green <andy@warmcat.com>
5 *
6 * This file is made available under the Creative Commons CC0 1.0
7 * Universal Public Domain Dedication.
8 *
9 * This demonstrates setting up and using generic sessions
10 */
11
12 #include <libwebsockets.h>
13 #include <string.h>
14 #include <signal.h>
15
16 static int interrupted;
17 struct lws_context *context;
18
19 static const struct lws_protocol_vhost_options
20 pvo_mm1 = {
21 NULL, NULL, "message-db", (void *)"/var/www/sessions/messageboard.sqlite3"
22 }, pvo_m1 = {
23 NULL, &pvo_mm1, "protocol-lws-messageboard", ""
24 },
25
26 pvo13 = {
27 NULL, NULL, "email-confirm-url-base", (void *)"https://localhost:7681/"
28 }, pvo12 = {
29 &pvo13, NULL, "urlroot", (void *)"https://127.0.0.1:7681/"
30 }, pvo11 = {
31 &pvo12, NULL, "email-contact-person", (void *)"andy@warmcat.com"
32 }, pvo10 = {
33 &pvo11, NULL, "email-helo", (void *)"warmcat.com"
34 }, pvo9 = {
35 &pvo10, NULL, "email-expire", (void *)"3600"
36 }, pvo8 = {
37 &pvo9, NULL, "email-smtp-ip", (void *)"127.0.0.1"
38 }, pvo7 = {
39 &pvo8, NULL, "email-from", (void *)"noreply@warmcat.com"
40 }, pvo6 = {
41 &pvo7, NULL, "confounder", (void *)"some kind of secret confounder"
42 }, pvo5 = {
43 &pvo6, NULL, "timeout-anon-idle-secs", (void *)"1200"
44 }, pvo4 = {
45 &pvo5, NULL, "timeout-idle-secs", (void *)"6000"
46 }, pvo3 = {
47 &pvo4, NULL, "session-db", (void *)"/var/www/sessions/lws.sqlite3"
48 }, pvo2 = {
49 &pvo3, NULL, "admin-password-sha256",
50 (void *)"25d08521d996bad92605f5a40fe71179dc968e70f669cb1db6190dcd53258200" /* pvo value */
51 }, pvo1 = {
52 &pvo2, NULL, "admin-user", (void *)"admin"
53 }, pvo = {
54 &pvo_m1, &pvo1, "protocol-generic-sessions", ""
55 },
56
57 interpret1 = {
58 NULL, NULL, ".js", "protocol-lws-messageboard"
59 },
60
61 pvo_hsbph[] = {{
62 NULL, NULL, "referrer-policy:", "no-referrer"
63 }, {
64 &pvo_hsbph[0], NULL, "x-xss-protection:", "1; mode=block"
65 }, {
66 &pvo_hsbph[1], NULL, "x-content-type-options:", "nosniff"
67 }, {
68 &pvo_hsbph[2], NULL, "content-security-policy:",
69 "default-src 'self'; "
70 "img-src https://www.gravatar.com 'self' data: ; "
71 "script-src 'self'; "
72 "font-src 'self'; "
73 "style-src 'self'; "
74 "connect-src 'self'; "
75 "frame-ancestors 'self'; "
76 "base-uri 'none'; "
77 "form-action 'self';"
78 }};
79
80 static const struct lws_http_mount mount2 = {
81 /* .mount_next */ NULL, /* linked-list "next" */
82 /* .mountpoint */ "/needadmin", /* mountpoint URL */
83 /* .origin */ "./mount-origin/needadmin", /* serve from dir */
84 /* .def */ "index.html", /* default filename */
85 /* .protocol */ "protocol-lws-messageboard",
86 /* .cgienv */ NULL,
87 /* .extra_mimetypes */ NULL,
88 /* .interpret */ &interpret1,
89 /* .cgi_timeout */ 0,
90 /* .cache_max_age */ 0,
91 /* .auth_mask */ 7,
92 /* .cache_reusable */ 0,
93 /* .cache_revalidate */ 0,
94 /* .cache_intermediaries */ 0,
95 /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */
96 /* .mountpoint_len */ 1, /* char count */
97 /* .basic_auth_login_file */ NULL,
98 };
99
100 static const struct lws_http_mount mount1 = {
101 /* .mount_next */ &mount2, /* linked-list "next" */
102 /* .mountpoint */ "/needauth", /* mountpoint URL */
103 /* .origin */ "./mount-origin/needauth", /* serve from dir */
104 /* .def */ "index.html", /* default filename */
105 /* .protocol */ "protocol-lws-messageboard",
106 /* .cgienv */ NULL,
107 /* .extra_mimetypes */ NULL,
108 /* .interpret */ &interpret1,
109 /* .cgi_timeout */ 0,
110 /* .cache_max_age */ 0,
111 /* .auth_mask */ 5,
112 /* .cache_reusable */ 0,
113 /* .cache_revalidate */ 0,
114 /* .cache_intermediaries */ 0,
115 /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */
116 /* .mountpoint_len */ 1, /* char count */
117 /* .basic_auth_login_file */ NULL,
118 };
119
120 static const struct lws_http_mount mount = {
121 /* .mount_next */ &mount1, /* linked-list "next" */
122 /* .mountpoint */ "/", /* mountpoint URL */
123 /* .origin */ "./mount-origin", /* serve from dir */
124 /* .def */ "index.html", /* default filename */
125 /* .protocol */ "protocol-lws-messageboard",
126 /* .cgienv */ NULL,
127 /* .extra_mimetypes */ NULL,
128 /* .interpret */ &interpret1,
129 /* .cgi_timeout */ 0,
130 /* .cache_max_age */ 0,
131 /* .auth_mask */ 0,
132 /* .cache_reusable */ 0,
133 /* .cache_revalidate */ 0,
134 /* .cache_intermediaries */ 0,
135 /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */
136 /* .mountpoint_len */ 1, /* char count */
137 /* .basic_auth_login_file */ NULL,
138 };
139
sigint_handler(int sig)140 void sigint_handler(int sig)
141 {
142 lws_context_destroy(context);
143
144 interrupted = 1;
145 }
146
main(int argc,const char ** argv)147 int main(int argc, const char **argv)
148 {
149 struct lws_context_creation_info info;
150 const char *p, *plugin_dirs[] = {
151 "/usr/local/share/libwebsockets-test-server/plugins",
152 NULL };
153 int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
154 /* for LLL_ verbosity above NOTICE to be built into lws,
155 * lws must have been configured and built with
156 * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
157 /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
158 /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
159 /* | LLL_DEBUG */;
160
161 if ((p = lws_cmdline_option(argc, argv, "-d")))
162 logs = atoi(p);
163
164 lws_set_log_level(logs, NULL);
165 lwsl_user("LWS minimal http server TLS | visit https://localhost:7681\n");
166
167 signal(SIGINT, sigint_handler);
168
169 memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
170 info.port = 7681;
171 info.mounts = &mount;
172 info.error_document_404 = "/404.html";
173 info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |
174 LWS_SERVER_OPTION_EXPLICIT_VHOSTS;
175 info.ssl_cert_filepath = "localhost-100y.cert";
176 info.ssl_private_key_filepath = "localhost-100y.key";
177 info.plugin_dirs = plugin_dirs;
178 info.pvo = &pvo;
179
180 if (lws_cmdline_option(argc, argv, "-h"))
181 info.options |= LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK;
182
183 context = lws_create_context(&info);
184 if (!context) {
185 lwsl_err("lws init failed\n");
186 return 1;
187 }
188
189 info.headers = &pvo_hsbph[3];
190
191 if (!lws_create_vhost(context, &info)) {
192 lwsl_err("lws init failed\n");
193 return 1;
194 }
195
196 while (n >= 0 && !interrupted)
197 n = lws_service(context, 0);
198
199 lws_context_destroy(context);
200
201 return 0;
202 }
203