blob: 543fe479424d278f4c52b18a1ba7d46ff8f670de [file] [log] [blame]
Andy Greencd0c6962016-03-28 10:12:37 +08001/*
2 * libwebsockets web server application
3 *
Andy Greenf44e38f2018-08-02 19:13:53 +08004 * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com>
Andy Greencd0c6962016-03-28 10:12:37 +08005 *
Andy Green0c984012016-09-19 19:16:47 +08006 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
Andy Greencd0c6962016-03-28 10:12:37 +080010 *
Andy Green0c984012016-09-19 19:16:47 +080011 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
Andy Greencd0c6962016-03-28 10:12:37 +080015 *
Andy Green0c984012016-09-19 19:16:47 +080016 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301 USA
Andy Greencd0c6962016-03-28 10:12:37 +080020 */
21
Andy Greende064fd2018-05-03 10:49:36 +080022#include "core/private.h"
Andy Green3358c532016-05-26 21:12:11 +080023
24#ifndef _WIN32
25/* this is needed for Travis CI */
26#include <dirent.h>
27#endif
Andy Greencd0c6962016-03-28 10:12:37 +080028
Andy Green0aa382f2016-07-06 10:48:41 +080029#define ESC_INSTALL_DATADIR "_lws_ddir_"
30
Andy Greencd0c6962016-03-28 10:12:37 +080031static const char * const paths_global[] = {
32 "global.uid",
33 "global.gid",
Andy Greencd0c6962016-03-28 10:12:37 +080034 "global.count-threads",
35 "global.init-ssl",
Andy Greenb21c20b2016-04-15 13:33:52 +080036 "global.server-string",
Andy Greenf32d2502016-07-15 13:41:38 +080037 "global.plugin-dir",
38 "global.ws-pingpong-secs",
Andy Green58a26eb2017-01-02 19:57:54 +080039 "global.timeout-secs",
Andy Green3b93e342016-10-13 06:32:57 +080040 "global.reject-service-keywords[].*",
41 "global.reject-service-keywords[]",
Andy Greenaa816e92018-04-12 15:56:38 +080042 "global.default-alpn",
Andy Greencd0c6962016-03-28 10:12:37 +080043};
44
45enum lejp_global_paths {
46 LEJPGP_UID,
47 LEJPGP_GID,
Andy Greencd0c6962016-03-28 10:12:37 +080048 LEJPGP_COUNT_THREADS,
49 LWJPGP_INIT_SSL,
Andy Greenb21c20b2016-04-15 13:33:52 +080050 LEJPGP_SERVER_STRING,
Andy Greenf32d2502016-07-15 13:41:38 +080051 LEJPGP_PLUGIN_DIR,
52 LWJPGP_PINGPONG_SECS,
Andy Green58a26eb2017-01-02 19:57:54 +080053 LWJPGP_TIMEOUT_SECS,
Andy Green3b93e342016-10-13 06:32:57 +080054 LWJPGP_REJECT_SERVICE_KEYWORDS_NAME,
Andy Greenaa816e92018-04-12 15:56:38 +080055 LWJPGP_REJECT_SERVICE_KEYWORDS,
56 LWJPGP_DEFAULT_ALPN,
Andy Greencd0c6962016-03-28 10:12:37 +080057};
58
59static const char * const paths_vhosts[] = {
60 "vhosts[]",
61 "vhosts[].mounts[]",
62 "vhosts[].name",
63 "vhosts[].port",
Andy Green1042b342016-04-14 11:50:05 +080064 "vhosts[].interface",
Andy Greena1ab2012016-04-14 12:18:33 +080065 "vhosts[].unix-socket",
Andy Green868b9f22016-04-14 12:37:21 +080066 "vhosts[].sts",
Andy Greencd0c6962016-03-28 10:12:37 +080067 "vhosts[].host-ssl-key",
68 "vhosts[].host-ssl-cert",
69 "vhosts[].host-ssl-ca",
Andy Green2f0bc932016-04-15 12:00:23 +080070 "vhosts[].access-log",
Andy Greencd0c6962016-03-28 10:12:37 +080071 "vhosts[].mounts[].mountpoint",
72 "vhosts[].mounts[].origin",
Andy Green7a2fc442016-05-19 15:28:31 +080073 "vhosts[].mounts[].protocol",
Andy Green37098ae2016-04-08 13:25:34 +080074 "vhosts[].mounts[].default",
Andy Green7a2fc442016-05-19 15:28:31 +080075 "vhosts[].mounts[].auth-mask",
Andy Greenf5efa742016-04-13 11:42:53 +080076 "vhosts[].mounts[].cgi-timeout",
Andy Greena5e73a12016-04-13 11:49:07 +080077 "vhosts[].mounts[].cgi-env[].*",
Andy Green42e8b182016-04-22 08:53:49 +080078 "vhosts[].mounts[].cache-max-age",
79 "vhosts[].mounts[].cache-reuse",
80 "vhosts[].mounts[].cache-revalidate",
Andy Greenee946212016-12-03 15:13:15 +080081 "vhosts[].mounts[].basic-auth",
Andy Green42e8b182016-04-22 08:53:49 +080082 "vhosts[].mounts[].cache-intermediaries",
Andy Green8ef14c02016-05-14 10:00:21 +080083 "vhosts[].mounts[].extra-mimetypes.*",
Andy Green7a2fc442016-05-19 15:28:31 +080084 "vhosts[].mounts[].interpret.*",
Andy Green37098ae2016-04-08 13:25:34 +080085 "vhosts[].ws-protocols[].*.*",
86 "vhosts[].ws-protocols[].*",
Andy Greend459a6f2016-04-08 18:30:45 +080087 "vhosts[].ws-protocols[]",
Andy Greenb46e4a82016-04-12 16:26:03 +080088 "vhosts[].keepalive_timeout",
Andy Greenfb8be052016-05-12 19:39:29 +080089 "vhosts[].enable-client-ssl",
Andy Green6954daa2016-05-14 09:50:34 +080090 "vhosts[].ciphers",
91 "vhosts[].ecdh-curve",
Andy Green2dc7dde2016-06-03 21:19:40 +080092 "vhosts[].noipv6",
Andy Green011f9152016-06-04 09:01:28 +080093 "vhosts[].ipv6only",
Andy Green1ec8ba82016-06-10 08:37:26 +080094 "vhosts[].ssl-option-set",
95 "vhosts[].ssl-option-clear",
Andy Greencd6a7062016-07-06 07:37:34 +080096 "vhosts[].mounts[].pmo[].*",
Andy Greene35d91a2016-08-27 17:07:06 +080097 "vhosts[].headers[].*",
98 "vhosts[].headers[]",
Joel Winarske390ba342017-02-20 20:53:58 -080099 "vhosts[].client-ssl-key",
100 "vhosts[].client-ssl-cert",
101 "vhosts[].client-ssl-ca",
102 "vhosts[].client-ssl-ciphers",
Andy Green7597ac32017-10-16 16:59:57 +0800103 "vhosts[].onlyraw",
Andy Greenc2488dd2017-11-07 08:30:57 +0800104 "vhosts[].client-cert-required",
Andy Greena5514d22017-11-02 06:22:44 +0800105 "vhosts[].ignore-missing-cert",
Andy Greenb4900792018-03-07 19:57:34 +0800106 "vhosts[].error-document-404",
Andy Greenaa816e92018-04-12 15:56:38 +0800107 "vhosts[].alpn",
Andy Green20fb5592018-10-26 09:44:58 +0800108 "vhosts[].ssl-client-option-set",
109 "vhosts[].ssl-client-option-clear",
Andy Green93d4e182018-10-27 08:05:21 +0800110 "vhosts[].tls13-ciphers",
111 "vhosts[].client-tls13-ciphers",
Andy Greenf6ae0ed2018-11-13 09:33:13 +0800112 "vhosts[].strict-host-check",
Andy Greenb3188772018-11-29 08:47:49 +0800113
114 "vhosts[].listen-accept-role",
115 "vhosts[].listen-accept-protocol",
116 "vhosts[].apply-listen-accept", /* deprecates "onlyraw" */
117 "vhosts[].fallback-listen-accept",
118 "vhosts[].allow-non-tls",
119 "vhosts[].redirect-http",
120 "vhosts[].allow-http-on-https",
Andy Green3a31c472019-02-22 14:27:21 +0800121
122 "vhosts[].disable-no-protocol-ws-upgrades",
Andy Greencd0c6962016-03-28 10:12:37 +0800123};
124
125enum lejp_vhost_paths {
126 LEJPVP,
127 LEJPVP_MOUNTS,
128 LEJPVP_NAME,
129 LEJPVP_PORT,
Andy Green1042b342016-04-14 11:50:05 +0800130 LEJPVP_INTERFACE,
Andy Greena1ab2012016-04-14 12:18:33 +0800131 LEJPVP_UNIXSKT,
Andy Green868b9f22016-04-14 12:37:21 +0800132 LEJPVP_STS,
Andy Greencd0c6962016-03-28 10:12:37 +0800133 LEJPVP_HOST_SSL_KEY,
134 LEJPVP_HOST_SSL_CERT,
135 LEJPVP_HOST_SSL_CA,
Andy Green2f0bc932016-04-15 12:00:23 +0800136 LEJPVP_ACCESS_LOG,
Andy Greencd0c6962016-03-28 10:12:37 +0800137 LEJPVP_MOUNTPOINT,
138 LEJPVP_ORIGIN,
Andy Green7a2fc442016-05-19 15:28:31 +0800139 LEJPVP_MOUNT_PROTOCOL,
Andy Greencd0c6962016-03-28 10:12:37 +0800140 LEJPVP_DEFAULT,
Andy Green7a2fc442016-05-19 15:28:31 +0800141 LEJPVP_DEFAULT_AUTH_MASK,
Andy Greenf5efa742016-04-13 11:42:53 +0800142 LEJPVP_CGI_TIMEOUT,
Andy Greena5e73a12016-04-13 11:49:07 +0800143 LEJPVP_CGI_ENV,
Andy Green42e8b182016-04-22 08:53:49 +0800144 LEJPVP_MOUNT_CACHE_MAX_AGE,
145 LEJPVP_MOUNT_CACHE_REUSE,
146 LEJPVP_MOUNT_CACHE_REVALIDATE,
Andy Greenee946212016-12-03 15:13:15 +0800147 LEJPVP_MOUNT_BASIC_AUTH,
Andy Green42e8b182016-04-22 08:53:49 +0800148 LEJPVP_MOUNT_CACHE_INTERMEDIARIES,
Andy Green8ef14c02016-05-14 10:00:21 +0800149 LEJPVP_MOUNT_EXTRA_MIMETYPES,
Andy Green7a2fc442016-05-19 15:28:31 +0800150 LEJPVP_MOUNT_INTERPRET,
Andy Green37098ae2016-04-08 13:25:34 +0800151 LEJPVP_PROTOCOL_NAME_OPT,
152 LEJPVP_PROTOCOL_NAME,
153 LEJPVP_PROTOCOL,
Andy Greenb46e4a82016-04-12 16:26:03 +0800154 LEJPVP_KEEPALIVE_TIMEOUT,
Andy Greenfb8be052016-05-12 19:39:29 +0800155 LEJPVP_ENABLE_CLIENT_SSL,
Andy Green6954daa2016-05-14 09:50:34 +0800156 LEJPVP_CIPHERS,
157 LEJPVP_ECDH_CURVE,
Andy Green2dc7dde2016-06-03 21:19:40 +0800158 LEJPVP_NOIPV6,
Andy Green011f9152016-06-04 09:01:28 +0800159 LEJPVP_IPV6ONLY,
Andy Green1ec8ba82016-06-10 08:37:26 +0800160 LEJPVP_SSL_OPTION_SET,
161 LEJPVP_SSL_OPTION_CLEAR,
Andy Greene35d91a2016-08-27 17:07:06 +0800162 LEJPVP_PMO,
163 LEJPVP_HEADERS_NAME,
164 LEJPVP_HEADERS,
Joel Winarske390ba342017-02-20 20:53:58 -0800165 LEJPVP_CLIENT_SSL_KEY,
166 LEJPVP_CLIENT_SSL_CERT,
167 LEJPVP_CLIENT_SSL_CA,
168 LEJPVP_CLIENT_CIPHERS,
Andy Green7597ac32017-10-16 16:59:57 +0800169 LEJPVP_FLAG_ONLYRAW,
Andy Greenc2488dd2017-11-07 08:30:57 +0800170 LEJPVP_FLAG_CLIENT_CERT_REQUIRED,
Andy Greena5514d22017-11-02 06:22:44 +0800171 LEJPVP_IGNORE_MISSING_CERT,
Andy Greenb4900792018-03-07 19:57:34 +0800172 LEJPVP_ERROR_DOCUMENT_404,
Andy Greenaa816e92018-04-12 15:56:38 +0800173 LEJPVP_ALPN,
Andy Green20fb5592018-10-26 09:44:58 +0800174 LEJPVP_SSL_CLIENT_OPTION_SET,
175 LEJPVP_SSL_CLIENT_OPTION_CLEAR,
Andy Green93d4e182018-10-27 08:05:21 +0800176 LEJPVP_TLS13_CIPHERS,
177 LEJPVP_CLIENT_TLS13_CIPHERS,
Andy Greenf6ae0ed2018-11-13 09:33:13 +0800178 LEJPVP_FLAG_STRICT_HOST_CHECK,
Andy Greenb3188772018-11-29 08:47:49 +0800179
180 LEJPVP_LISTEN_ACCEPT_ROLE,
181 LEJPVP_LISTEN_ACCEPT_PROTOCOL,
182 LEJPVP_FLAG_APPLY_LISTEN_ACCEPT,
183 LEJPVP_FLAG_FALLBACK_LISTEN_ACCEPT,
184 LEJPVP_FLAG_ALLOW_NON_TLS,
185 LEJPVP_FLAG_REDIRECT_HTTP,
186 LEJPVP_FLAG_ALLOW_HTTP_ON_HTTPS,
Andy Green3a31c472019-02-22 14:27:21 +0800187
188 LEJPVP_FLAG_DISABLE_NO_PROTOCOL_WS_UPGRADES,
Andy Greencd0c6962016-03-28 10:12:37 +0800189};
190
Andy Greencae57ad2016-05-02 10:03:25 +0800191#define MAX_PLUGIN_DIRS 10
192
Andy Greencd0c6962016-03-28 10:12:37 +0800193struct jpargs {
194 struct lws_context_creation_info *info;
195 struct lws_context *context;
196 const struct lws_protocols *protocols;
Andy Green00790992019-03-10 05:34:02 +0800197 const struct lws_protocols **pprotocols;
Andy Greencd0c6962016-03-28 10:12:37 +0800198 const struct lws_extension *extensions;
199 char *p, *end, valid;
200 struct lws_http_mount *head, *last;
Andy Green42e8b182016-04-22 08:53:49 +0800201
Andy Green37098ae2016-04-08 13:25:34 +0800202 struct lws_protocol_vhost_options *pvo;
Andy Green8ef14c02016-05-14 10:00:21 +0800203 struct lws_protocol_vhost_options *pvo_em;
Andy Green7a2fc442016-05-19 15:28:31 +0800204 struct lws_protocol_vhost_options *pvo_int;
Andy Green42e8b182016-04-22 08:53:49 +0800205 struct lws_http_mount m;
Andy Greencae57ad2016-05-02 10:03:25 +0800206 const char **plugin_dirs;
207 int count_plugin_dirs;
Andy Greenfb8be052016-05-12 19:39:29 +0800208
Andy Green3a31c472019-02-22 14:27:21 +0800209 unsigned int reject_ws_with_no_protocol:1;
Andy Greenfb8be052016-05-12 19:39:29 +0800210 unsigned int enable_client_ssl:1;
Andy Green8ef14c02016-05-14 10:00:21 +0800211 unsigned int fresh_mount:1;
Andy Green92b0d8a2016-05-22 07:01:35 +0800212 unsigned int any_vhosts:1;
Andy Green844b7792018-08-24 16:00:33 +0800213 unsigned int chunk:1;
Andy Greencd0c6962016-03-28 10:12:37 +0800214};
215
Andy Green37098ae2016-04-08 13:25:34 +0800216static void *
217lwsws_align(struct jpargs *a)
218{
Andy Green7262e142017-07-07 08:32:04 +0800219 if ((lws_intptr_t)(a->p) & 15)
220 a->p += 16 - ((lws_intptr_t)(a->p) & 15);
Andy Green37098ae2016-04-08 13:25:34 +0800221
Andy Green844b7792018-08-24 16:00:33 +0800222 a->chunk = 0;
223
Andy Green37098ae2016-04-08 13:25:34 +0800224 return a->p;
225}
226
Andy Greena1ab2012016-04-14 12:18:33 +0800227static int
228arg_to_bool(const char *s)
Andy Greencd0c6962016-03-28 10:12:37 +0800229{
230 static const char * const on[] = { "on", "yes", "true" };
231 int n = atoi(s);
232
233 if (n)
234 return 1;
235
Andy Greend461f462018-08-16 19:10:32 +0800236 for (n = 0; n < (int)LWS_ARRAY_SIZE(on); n++)
Andy Greencd0c6962016-03-28 10:12:37 +0800237 if (!strcasecmp(s, on[n]))
238 return 1;
239
240 return 0;
241}
242
Andy Greenb3188772018-11-29 08:47:49 +0800243static void
244set_reset_flag(unsigned int *p, const char *state, unsigned int flag)
245{
246 if (arg_to_bool(state))
247 *p |= flag;
248 else
249 *p &= ~(flag);
250}
251
Andy Green5a0b5292017-10-25 02:53:27 +0800252static signed char
Andy Greencd0c6962016-03-28 10:12:37 +0800253lejp_globals_cb(struct lejp_ctx *ctx, char reason)
254{
255 struct jpargs *a = (struct jpargs *)ctx->user;
Andy Green3b93e342016-10-13 06:32:57 +0800256 struct lws_protocol_vhost_options *rej;
257 int n;
Andy Greencd0c6962016-03-28 10:12:37 +0800258
259 /* we only match on the prepared path strings */
260 if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match)
261 return 0;
262
Andy Green3b93e342016-10-13 06:32:57 +0800263 /* this catches, eg, vhosts[].headers[].xxx */
264 if (reason == LEJPCB_VAL_STR_END &&
265 ctx->path_match == LWJPGP_REJECT_SERVICE_KEYWORDS_NAME + 1) {
266 rej = lwsws_align(a);
267 a->p += sizeof(*rej);
268
Andy Green253942c2018-08-23 11:29:45 +0800269 n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
Andy Green3b93e342016-10-13 06:32:57 +0800270 rej->next = a->info->reject_service_keywords;
271 a->info->reject_service_keywords = rej;
272 rej->name = a->p;
273 lwsl_notice(" adding rej %s=%s\n", a->p, ctx->buf);
274 a->p += n - 1;
275 *(a->p++) = '\0';
276 rej->value = a->p;
277 rej->options = NULL;
278 goto dostring;
279 }
280
Andy Greencd0c6962016-03-28 10:12:37 +0800281 switch (ctx->path_match - 1) {
282 case LEJPGP_UID:
283 a->info->uid = atoi(ctx->buf);
284 return 0;
285 case LEJPGP_GID:
286 a->info->gid = atoi(ctx->buf);
287 return 0;
Andy Greencd0c6962016-03-28 10:12:37 +0800288 case LEJPGP_COUNT_THREADS:
289 a->info->count_threads = atoi(ctx->buf);
290 return 0;
291 case LWJPGP_INIT_SSL:
292 if (arg_to_bool(ctx->buf))
293 a->info->options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
294 return 0;
Andy Greenb21c20b2016-04-15 13:33:52 +0800295 case LEJPGP_SERVER_STRING:
296 a->info->server_string = a->p;
297 break;
Andy Greencae57ad2016-05-02 10:03:25 +0800298 case LEJPGP_PLUGIN_DIR:
299 if (a->count_plugin_dirs == MAX_PLUGIN_DIRS - 1) {
300 lwsl_err("Too many plugin dirs\n");
301 return -1;
302 }
303 a->plugin_dirs[a->count_plugin_dirs++] = a->p;
304 break;
Andy Greencd0c6962016-03-28 10:12:37 +0800305
Andy Greenf32d2502016-07-15 13:41:38 +0800306 case LWJPGP_PINGPONG_SECS:
307 a->info->ws_ping_pong_interval = atoi(ctx->buf);
308 return 0;
309
Andy Green58a26eb2017-01-02 19:57:54 +0800310 case LWJPGP_TIMEOUT_SECS:
311 a->info->timeout_secs = atoi(ctx->buf);
312 return 0;
313
Andy Greenaa816e92018-04-12 15:56:38 +0800314 case LWJPGP_DEFAULT_ALPN:
315 a->info->alpn = a->p;
316 break;
317
Andy Greencd0c6962016-03-28 10:12:37 +0800318 default:
319 return 0;
320 }
321
Andy Green3b93e342016-10-13 06:32:57 +0800322dostring:
Andy Greena4967002016-09-15 02:22:57 +0800323 a->p += lws_snprintf(a->p, a->end - a->p, "%s", ctx->buf);
Andy Greene35d91a2016-08-27 17:07:06 +0800324 *(a->p)++ = '\0';
Andy Greencd0c6962016-03-28 10:12:37 +0800325
326 return 0;
327}
328
Andy Green5a0b5292017-10-25 02:53:27 +0800329static signed char
Andy Greencd0c6962016-03-28 10:12:37 +0800330lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
331{
332 struct jpargs *a = (struct jpargs *)ctx->user;
Andy Greene35d91a2016-08-27 17:07:06 +0800333 struct lws_protocol_vhost_options *pvo, *mp_cgienv, *headers;
Andy Greencd0c6962016-03-28 10:12:37 +0800334 struct lws_http_mount *m;
Andy Green0aa382f2016-07-06 10:48:41 +0800335 char *p, *p1;
Andy Greencd0c6962016-03-28 10:12:37 +0800336 int n;
337
Andy Greena5e73a12016-04-13 11:49:07 +0800338#if 0
339 lwsl_notice(" %d: %s (%d)\n", reason, ctx->path, ctx->path_match);
340 for (n = 0; n < ctx->wildcount; n++)
341 lwsl_notice(" %d\n", ctx->wild[n]);
342#endif
Andy Green37098ae2016-04-08 13:25:34 +0800343
Andy Greencd0c6962016-03-28 10:12:37 +0800344 if (reason == LEJPCB_OBJECT_START && ctx->path_match == LEJPVP + 1) {
Andy Greenfeeca912018-03-23 07:50:44 +0800345 uint32_t i[4];
346 const char *ss;
347
Andy Green37098ae2016-04-08 13:25:34 +0800348 /* set the defaults for this vhost */
Andy Green3a31c472019-02-22 14:27:21 +0800349 a->reject_ws_with_no_protocol = 0;
Andy Greencd0c6962016-03-28 10:12:37 +0800350 a->valid = 1;
351 a->head = NULL;
352 a->last = NULL;
Andy Greenfeeca912018-03-23 07:50:44 +0800353
354 i[0] = a->info->count_threads;
355 i[1] = a->info->options & (
356 LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME |
357 LWS_SERVER_OPTION_LIBUV |
358 LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |
359 LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
360 LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN |
361 LWS_SERVER_OPTION_LIBEVENT |
362 LWS_SERVER_OPTION_LIBEV
363 );
364 ss = a->info->server_string;
365 i[2] = a->info->ws_ping_pong_interval;
366 i[3] = a->info->timeout_secs;
367
368 memset(a->info, 0, sizeof(*a->info));
369
370 a->info->count_threads = i[0];
371 a->info->options = i[1];
372 a->info->server_string = ss;
373 a->info->ws_ping_pong_interval = i[2];
374 a->info->timeout_secs = i[3];
375
Andy Greencd0c6962016-03-28 10:12:37 +0800376 a->info->protocols = a->protocols;
Andy Green00790992019-03-10 05:34:02 +0800377 a->info->pprotocols = a->pprotocols;
Andy Greencd0c6962016-03-28 10:12:37 +0800378 a->info->extensions = a->extensions;
Andy Green126be3c2018-04-11 13:39:42 +0800379#if defined(LWS_WITH_TLS)
Joel Winarske390ba342017-02-20 20:53:58 -0800380 a->info->client_ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
381 "ECDHE-RSA-AES256-GCM-SHA384:"
382 "DHE-RSA-AES256-GCM-SHA384:"
383 "ECDHE-RSA-AES256-SHA384:"
384 "HIGH:!aNULL:!eNULL:!EXPORT:"
385 "!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:"
386 "!SHA1:!DHE-RSA-AES128-GCM-SHA256:"
387 "!DHE-RSA-AES128-SHA256:"
388 "!AES128-GCM-SHA256:"
389 "!AES128-SHA256:"
390 "!DHE-RSA-AES256-SHA256:"
391 "!AES256-GCM-SHA384:"
392 "!AES256-SHA256";
Anzeya903d732018-01-04 10:42:07 +0800393#endif
Andy Greencd0c6962016-03-28 10:12:37 +0800394 a->info->ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
395 "ECDHE-RSA-AES256-GCM-SHA384:"
396 "DHE-RSA-AES256-GCM-SHA384:"
397 "ECDHE-RSA-AES256-SHA384:"
398 "HIGH:!aNULL:!eNULL:!EXPORT:"
399 "!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:"
400 "!SHA1:!DHE-RSA-AES128-GCM-SHA256:"
401 "!DHE-RSA-AES128-SHA256:"
402 "!AES128-GCM-SHA256:"
403 "!AES128-SHA256:"
404 "!DHE-RSA-AES256-SHA256:"
405 "!AES256-GCM-SHA384:"
406 "!AES256-SHA256";
Andy Green7acf76c2016-07-23 14:18:25 +0800407 a->info->keepalive_timeout = 5;
Andy Greencd0c6962016-03-28 10:12:37 +0800408 }
409
410 if (reason == LEJPCB_OBJECT_START &&
Andy Green8ef14c02016-05-14 10:00:21 +0800411 ctx->path_match == LEJPVP_MOUNTS + 1) {
412 a->fresh_mount = 1;
Andy Green42e8b182016-04-22 08:53:49 +0800413 memset(&a->m, 0, sizeof(a->m));
Andy Green8ef14c02016-05-14 10:00:21 +0800414 }
Andy Greencd0c6962016-03-28 10:12:37 +0800415
Andy Green37098ae2016-04-08 13:25:34 +0800416 /* this catches, eg, vhosts[].ws-protocols[].xxx-protocol */
417 if (reason == LEJPCB_OBJECT_START &&
418 ctx->path_match == LEJPVP_PROTOCOL_NAME + 1) {
419 a->pvo = lwsws_align(a);
420 a->p += sizeof(*a->pvo);
421
Andy Green253942c2018-08-23 11:29:45 +0800422 n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
Andy Green37098ae2016-04-08 13:25:34 +0800423 /* ie, enable this protocol, no options yet */
424 a->pvo->next = a->info->pvo;
425 a->info->pvo = a->pvo;
426 a->pvo->name = a->p;
Andy Green09f59ba2017-10-29 16:22:54 +0800427 lwsl_info(" adding protocol %s\n", a->p);
Andy Green37098ae2016-04-08 13:25:34 +0800428 a->p += n;
429 a->pvo->value = a->p;
430 a->pvo->options = NULL;
Andy Green0aa382f2016-07-06 10:48:41 +0800431 goto dostring;
Andy Green37098ae2016-04-08 13:25:34 +0800432 }
433
Andy Greene35d91a2016-08-27 17:07:06 +0800434 /* this catches, eg, vhosts[].headers[].xxx */
Andy Green844b7792018-08-24 16:00:33 +0800435 if ((reason == LEJPCB_VAL_STR_END || reason == LEJPCB_VAL_STR_CHUNK) &&
Andy Greene35d91a2016-08-27 17:07:06 +0800436 ctx->path_match == LEJPVP_HEADERS_NAME + 1) {
Andy Greene35d91a2016-08-27 17:07:06 +0800437
Andy Green844b7792018-08-24 16:00:33 +0800438 if (!a->chunk) {
439 headers = lwsws_align(a);
440 a->p += sizeof(*headers);
441
442 n = lejp_get_wildcard(ctx, 0, a->p,
443 lws_ptr_diff(a->end, a->p));
444 /* ie, add this header */
445 headers->next = a->info->headers;
446 a->info->headers = headers;
447 headers->name = a->p;
448
449 lwsl_notice(" adding header %s=%s\n", a->p, ctx->buf);
450 a->p += n - 1;
451 *(a->p++) = ':';
452 if (a->p < a->end)
453 *(a->p++) = '\0';
454 else
455 *(a->p - 1) = '\0';
456 headers->value = a->p;
457 headers->options = NULL;
458 }
459 a->chunk = reason == LEJPCB_VAL_STR_CHUNK;
Andy Greene35d91a2016-08-27 17:07:06 +0800460 goto dostring;
461 }
462
Andy Greencd0c6962016-03-28 10:12:37 +0800463 if (reason == LEJPCB_OBJECT_END &&
464 (ctx->path_match == LEJPVP + 1 || !ctx->path[0]) &&
465 a->valid) {
466
Andy Greenfb8be052016-05-12 19:39:29 +0800467 struct lws_vhost *vhost;
468
Andy Greencd0c6962016-03-28 10:12:37 +0800469 //lwsl_notice("%s\n", ctx->path);
Andy Greenf44e38f2018-08-02 19:13:53 +0800470 if (!a->info->port &&
471 !(a->info->options & LWS_SERVER_OPTION_UNIX_SOCK)) {
472 lwsl_err("Port required (eg, 443)\n");
Andy Greencd0c6962016-03-28 10:12:37 +0800473 return 1;
474 }
475 a->valid = 0;
Andy Green4664f712016-05-02 04:59:54 +0800476 a->info->mounts = a->head;
Andy Greencd0c6962016-03-28 10:12:37 +0800477
Andy Greenfb8be052016-05-12 19:39:29 +0800478 vhost = lws_create_vhost(a->context, a->info);
479 if (!vhost) {
Andy Greencd0c6962016-03-28 10:12:37 +0800480 lwsl_err("Failed to create vhost %s\n",
481 a->info->vhost_name);
482 return 1;
483 }
Andy Green92b0d8a2016-05-22 07:01:35 +0800484 a->any_vhosts = 1;
Andy Greencd0c6962016-03-28 10:12:37 +0800485
Andy Green3a31c472019-02-22 14:27:21 +0800486 if (a->reject_ws_with_no_protocol) {
487 a->reject_ws_with_no_protocol = 0;
488
489 vhost->default_protocol_index = 255;
490 }
491
Andy Green126be3c2018-04-11 13:39:42 +0800492#if defined(LWS_WITH_TLS)
Andy Greenfb8be052016-05-12 19:39:29 +0800493 if (a->enable_client_ssl) {
Andy Green9bed6d62018-11-23 08:47:56 +0800494 const char *cert_filepath =
495 a->info->client_ssl_cert_filepath;
496 const char *private_key_filepath =
497 a->info->client_ssl_private_key_filepath;
498 const char *ca_filepath =
499 a->info->client_ssl_ca_filepath;
500 const char *cipher_list =
501 a->info->client_ssl_cipher_list;
502
Andy Greenfb8be052016-05-12 19:39:29 +0800503 memset(a->info, 0, sizeof(*a->info));
Joel Winarske390ba342017-02-20 20:53:58 -0800504 a->info->client_ssl_cert_filepath = cert_filepath;
Andy Green9bed6d62018-11-23 08:47:56 +0800505 a->info->client_ssl_private_key_filepath =
506 private_key_filepath;
Joel Winarske390ba342017-02-20 20:53:58 -0800507 a->info->client_ssl_ca_filepath = ca_filepath;
508 a->info->client_ssl_cipher_list = cipher_list;
Andy Greenfb8be052016-05-12 19:39:29 +0800509 a->info->options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
510 lws_init_vhost_client_ssl(a->info, vhost);
511 }
Anzeya903d732018-01-04 10:42:07 +0800512#endif
Andy Greenfb8be052016-05-12 19:39:29 +0800513
Andy Greencd0c6962016-03-28 10:12:37 +0800514 return 0;
515 }
516
517 if (reason == LEJPCB_OBJECT_END &&
518 ctx->path_match == LEJPVP_MOUNTS + 1) {
Andy Green42e8b182016-04-22 08:53:49 +0800519 static const char * const mount_protocols[] = {
520 "http://",
521 "https://",
522 "file://",
523 "cgi://",
524 ">http://",
525 ">https://",
Andy Green19cc7ac2017-03-03 12:38:10 +0800526 "callback://",
527 "gzip://",
Andy Green42e8b182016-04-22 08:53:49 +0800528 };
529
Andy Green8ef14c02016-05-14 10:00:21 +0800530 if (!a->fresh_mount)
531 return 0;
532
Andy Green42e8b182016-04-22 08:53:49 +0800533 if (!a->m.mountpoint || !a->m.origin) {
Andy Greencd0c6962016-03-28 10:12:37 +0800534 lwsl_err("mountpoint and origin required\n");
535 return 1;
536 }
Andy Green8ef14c02016-05-14 10:00:21 +0800537 lwsl_debug("adding mount %s\n", a->m.mountpoint);
Andy Green42e8b182016-04-22 08:53:49 +0800538 m = lwsws_align(a);
539 memcpy(m, &a->m, sizeof(*m));
540 if (a->last)
541 a->last->mount_next = m;
Andy Greencd0c6962016-03-28 10:12:37 +0800542
Andy Greend461f462018-08-16 19:10:32 +0800543 for (n = 0; n < (int)LWS_ARRAY_SIZE(mount_protocols); n++)
Andy Green42e8b182016-04-22 08:53:49 +0800544 if (!strncmp(a->m.origin, mount_protocols[n],
545 strlen(mount_protocols[n]))) {
Andy Green904a9c02017-10-13 10:33:02 +0800546 lwsl_info("----%s\n", a->m.origin);
Andy Green42e8b182016-04-22 08:53:49 +0800547 m->origin_protocol = n;
Andy Green7a2fc442016-05-19 15:28:31 +0800548 m->origin = a->m.origin +
549 strlen(mount_protocols[n]);
Andy Green42e8b182016-04-22 08:53:49 +0800550 break;
551 }
552
Andy Greend461f462018-08-16 19:10:32 +0800553 if (n == (int)LWS_ARRAY_SIZE(mount_protocols)) {
Andy Green42e8b182016-04-22 08:53:49 +0800554 lwsl_err("unsupported protocol:// %s\n", a->m.origin);
Andy Greencd0c6962016-03-28 10:12:37 +0800555 return 1;
Andy Green42e8b182016-04-22 08:53:49 +0800556 }
557
558 a->p += sizeof(*m);
Andy Greencd0c6962016-03-28 10:12:37 +0800559 if (!a->head)
560 a->head = m;
561
562 a->last = m;
Andy Green8ef14c02016-05-14 10:00:21 +0800563 a->fresh_mount = 0;
Andy Greencd0c6962016-03-28 10:12:37 +0800564 }
565
566 /* we only match on the prepared path strings */
567 if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match)
568 return 0;
569
570 switch (ctx->path_match - 1) {
571 case LEJPVP_NAME:
572 a->info->vhost_name = a->p;
573 break;
574 case LEJPVP_PORT:
575 a->info->port = atoi(ctx->buf);
576 return 0;
Andy Green1042b342016-04-14 11:50:05 +0800577 case LEJPVP_INTERFACE:
578 a->info->iface = a->p;
579 break;
Andy Greena1ab2012016-04-14 12:18:33 +0800580 case LEJPVP_UNIXSKT:
581 if (arg_to_bool(ctx->buf))
582 a->info->options |= LWS_SERVER_OPTION_UNIX_SOCK;
583 else
584 a->info->options &= ~(LWS_SERVER_OPTION_UNIX_SOCK);
585 return 0;
Andy Green868b9f22016-04-14 12:37:21 +0800586 case LEJPVP_STS:
587 if (arg_to_bool(ctx->buf))
588 a->info->options |= LWS_SERVER_OPTION_STS;
589 else
590 a->info->options &= ~(LWS_SERVER_OPTION_STS);
591 return 0;
Andy Greencd0c6962016-03-28 10:12:37 +0800592 case LEJPVP_HOST_SSL_KEY:
593 a->info->ssl_private_key_filepath = a->p;
594 break;
595 case LEJPVP_HOST_SSL_CERT:
596 a->info->ssl_cert_filepath = a->p;
597 break;
598 case LEJPVP_HOST_SSL_CA:
599 a->info->ssl_ca_filepath = a->p;
600 break;
Andy Green2f0bc932016-04-15 12:00:23 +0800601 case LEJPVP_ACCESS_LOG:
602 a->info->log_filepath = a->p;
603 break;
Andy Greencd0c6962016-03-28 10:12:37 +0800604 case LEJPVP_MOUNTPOINT:
Andy Green42e8b182016-04-22 08:53:49 +0800605 a->m.mountpoint = a->p;
Andy Green7a9970f2016-05-15 08:29:37 +0800606 a->m.mountpoint_len = (unsigned char)strlen(ctx->buf);
Andy Greencd0c6962016-03-28 10:12:37 +0800607 break;
608 case LEJPVP_ORIGIN:
Andy Green7a2fc442016-05-19 15:28:31 +0800609 if (!strncmp(ctx->buf, "callback://", 11))
610 a->m.protocol = a->p + 11;
611
612 if (!a->m.origin)
613 a->m.origin = a->p;
Andy Greencd0c6962016-03-28 10:12:37 +0800614 break;
615 case LEJPVP_DEFAULT:
Andy Green42e8b182016-04-22 08:53:49 +0800616 a->m.def = a->p;
Andy Greencd0c6962016-03-28 10:12:37 +0800617 break;
Andy Green7a2fc442016-05-19 15:28:31 +0800618 case LEJPVP_DEFAULT_AUTH_MASK:
619 a->m.auth_mask = atoi(ctx->buf);
620 return 0;
Andy Green42e8b182016-04-22 08:53:49 +0800621 case LEJPVP_MOUNT_CACHE_MAX_AGE:
622 a->m.cache_max_age = atoi(ctx->buf);
623 return 0;
624 case LEJPVP_MOUNT_CACHE_REUSE:
625 a->m.cache_reusable = arg_to_bool(ctx->buf);
626 return 0;
627 case LEJPVP_MOUNT_CACHE_REVALIDATE:
628 a->m.cache_revalidate = arg_to_bool(ctx->buf);
629 return 0;
630 case LEJPVP_MOUNT_CACHE_INTERMEDIARIES:
631 a->m.cache_intermediaries = arg_to_bool(ctx->buf);;
632 return 0;
Andy Greenee946212016-12-03 15:13:15 +0800633 case LEJPVP_MOUNT_BASIC_AUTH:
634 a->m.basic_auth_login_file = a->p;
635 break;
Andy Greenf5efa742016-04-13 11:42:53 +0800636 case LEJPVP_CGI_TIMEOUT:
Andy Green42e8b182016-04-22 08:53:49 +0800637 a->m.cgi_timeout = atoi(ctx->buf);
Andy Greenf5efa742016-04-13 11:42:53 +0800638 return 0;
Andy Greenb46e4a82016-04-12 16:26:03 +0800639 case LEJPVP_KEEPALIVE_TIMEOUT:
640 a->info->keepalive_timeout = atoi(ctx->buf);
641 return 0;
Andy Green126be3c2018-04-11 13:39:42 +0800642#if defined(LWS_WITH_TLS)
Joel Winarske390ba342017-02-20 20:53:58 -0800643 case LEJPVP_CLIENT_CIPHERS:
644 a->info->client_ssl_cipher_list = a->p;
645 break;
Anzeya903d732018-01-04 10:42:07 +0800646#endif
Andy Green6954daa2016-05-14 09:50:34 +0800647 case LEJPVP_CIPHERS:
648 a->info->ssl_cipher_list = a->p;
649 break;
Andy Green93d4e182018-10-27 08:05:21 +0800650 case LEJPVP_TLS13_CIPHERS:
651 a->info->tls1_3_plus_cipher_list = a->p;
652 break;
653 case LEJPVP_CLIENT_TLS13_CIPHERS:
654 a->info->client_tls_1_3_plus_cipher_list = a->p;
655 break;
656
Andy Green6954daa2016-05-14 09:50:34 +0800657 case LEJPVP_ECDH_CURVE:
658 a->info->ecdh_curve = a->p;
659 break;
Andy Greencd6a7062016-07-06 07:37:34 +0800660 case LEJPVP_PMO:
Andy Greena5e73a12016-04-13 11:49:07 +0800661 case LEJPVP_CGI_ENV:
662 mp_cgienv = lwsws_align(a);
Andy Green42e8b182016-04-22 08:53:49 +0800663 a->p += sizeof(*a->m.cgienv);
Andy Green37098ae2016-04-08 13:25:34 +0800664
Andy Green42e8b182016-04-22 08:53:49 +0800665 mp_cgienv->next = a->m.cgienv;
666 a->m.cgienv = mp_cgienv;
Andy Greena5e73a12016-04-13 11:49:07 +0800667
Andy Green253942c2018-08-23 11:29:45 +0800668 n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
Andy Greena5e73a12016-04-13 11:49:07 +0800669 mp_cgienv->name = a->p;
670 a->p += n;
671 mp_cgienv->value = a->p;
672 mp_cgienv->options = NULL;
Andy Green9bed6d62018-11-23 08:47:56 +0800673 //lwsl_notice(" adding pmo / cgi-env '%s' = '%s'\n",
674 // mp_cgienv->name, mp_cgienv->value);
Andy Green0aa382f2016-07-06 10:48:41 +0800675 goto dostring;
Andy Greena5e73a12016-04-13 11:49:07 +0800676
Andy Green37098ae2016-04-08 13:25:34 +0800677 case LEJPVP_PROTOCOL_NAME_OPT:
678 /* this catches, eg,
679 * vhosts[].ws-protocols[].xxx-protocol.yyy-option
680 * ie, these are options attached to a protocol with { }
681 */
682 pvo = lwsws_align(a);
683 a->p += sizeof(*a->pvo);
684
Andy Green253942c2018-08-23 11:29:45 +0800685 n = lejp_get_wildcard(ctx, 1, a->p, lws_ptr_diff(a->end, a->p));
Andy Green37098ae2016-04-08 13:25:34 +0800686 /* ie, enable this protocol, no options yet */
687 pvo->next = a->pvo->options;
688 a->pvo->options = pvo;
689 pvo->name = a->p;
690 a->p += n;
691 pvo->value = a->p;
692 pvo->options = NULL;
Andy Green37098ae2016-04-08 13:25:34 +0800693 break;
Andy Green8ef14c02016-05-14 10:00:21 +0800694
695 case LEJPVP_MOUNT_EXTRA_MIMETYPES:
696 a->pvo_em = lwsws_align(a);
697 a->p += sizeof(*a->pvo_em);
698
Andy Green253942c2018-08-23 11:29:45 +0800699 n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
Andy Green8ef14c02016-05-14 10:00:21 +0800700 /* ie, enable this protocol, no options yet */
701 a->pvo_em->next = a->m.extra_mimetypes;
702 a->m.extra_mimetypes = a->pvo_em;
703 a->pvo_em->name = a->p;
Andy Green9bed6d62018-11-23 08:47:56 +0800704 lwsl_notice(" + extra-mimetypes %s -> %s\n", a->p, ctx->buf);
Andy Green8ef14c02016-05-14 10:00:21 +0800705 a->p += n;
706 a->pvo_em->value = a->p;
707 a->pvo_em->options = NULL;
708 break;
709
Andy Green7a2fc442016-05-19 15:28:31 +0800710 case LEJPVP_MOUNT_INTERPRET:
711 a->pvo_int = lwsws_align(a);
712 a->p += sizeof(*a->pvo_int);
713
Andy Green253942c2018-08-23 11:29:45 +0800714 n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
Andy Green7a2fc442016-05-19 15:28:31 +0800715 /* ie, enable this protocol, no options yet */
716 a->pvo_int->next = a->m.interpret;
717 a->m.interpret = a->pvo_int;
718 a->pvo_int->name = a->p;
719 lwsl_notice(" adding interpret %s -> %s\n", a->p,
720 ctx->buf);
721 a->p += n;
722 a->pvo_int->value = a->p;
723 a->pvo_int->options = NULL;
724 break;
725
Andy Greenfb8be052016-05-12 19:39:29 +0800726 case LEJPVP_ENABLE_CLIENT_SSL:
727 a->enable_client_ssl = arg_to_bool(ctx->buf);
728 return 0;
Andy Green126be3c2018-04-11 13:39:42 +0800729#if defined(LWS_WITH_TLS)
Joel Winarske390ba342017-02-20 20:53:58 -0800730 case LEJPVP_CLIENT_SSL_KEY:
731 a->info->client_ssl_private_key_filepath = a->p;
732 break;
733 case LEJPVP_CLIENT_SSL_CERT:
734 a->info->client_ssl_cert_filepath = a->p;
735 break;
736 case LEJPVP_CLIENT_SSL_CA:
737 a->info->client_ssl_ca_filepath = a->p;
738 break;
Anzeya903d732018-01-04 10:42:07 +0800739#endif
Andy Green37098ae2016-04-08 13:25:34 +0800740
Andy Green2dc7dde2016-06-03 21:19:40 +0800741 case LEJPVP_NOIPV6:
Andy Greenb3188772018-11-29 08:47:49 +0800742 set_reset_flag(&a->info->options, ctx->buf,
743 LWS_SERVER_OPTION_DISABLE_IPV6);
Andy Green2dc7dde2016-06-03 21:19:40 +0800744 return 0;
745
Andy Green7597ac32017-10-16 16:59:57 +0800746 case LEJPVP_FLAG_ONLYRAW:
Andy Greenb3188772018-11-29 08:47:49 +0800747 set_reset_flag(&a->info->options, ctx->buf,
748 LWS_SERVER_OPTION_ADOPT_APPLY_LISTEN_ACCEPT_CONFIG);
Andy Green7597ac32017-10-16 16:59:57 +0800749 return 0;
750
Andy Green011f9152016-06-04 09:01:28 +0800751 case LEJPVP_IPV6ONLY:
752 a->info->options |= LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY;
Andy Greenb3188772018-11-29 08:47:49 +0800753 set_reset_flag(&a->info->options, ctx->buf,
754 LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE);
Andy Green011f9152016-06-04 09:01:28 +0800755 return 0;
756
Andy Greenc2488dd2017-11-07 08:30:57 +0800757 case LEJPVP_FLAG_CLIENT_CERT_REQUIRED:
758 if (arg_to_bool(ctx->buf))
759 a->info->options |=
760 LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;
761 return 0;
762
Andy Greena5514d22017-11-02 06:22:44 +0800763 case LEJPVP_IGNORE_MISSING_CERT:
Andy Greenb3188772018-11-29 08:47:49 +0800764 set_reset_flag(&a->info->options, ctx->buf,
765 LWS_SERVER_OPTION_IGNORE_MISSING_CERT);
Andy Greena5514d22017-11-02 06:22:44 +0800766 return 0;
767
Andy Greenf6ae0ed2018-11-13 09:33:13 +0800768 case LEJPVP_FLAG_STRICT_HOST_CHECK:
Andy Greenb3188772018-11-29 08:47:49 +0800769 set_reset_flag(&a->info->options, ctx->buf,
770 LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK);
Andy Greenf6ae0ed2018-11-13 09:33:13 +0800771 return 0;
772
Andy Greenb4900792018-03-07 19:57:34 +0800773 case LEJPVP_ERROR_DOCUMENT_404:
774 a->info->error_document_404 = a->p;
775 break;
776
Andy Green1ec8ba82016-06-10 08:37:26 +0800777 case LEJPVP_SSL_OPTION_SET:
778 a->info->ssl_options_set |= atol(ctx->buf);
779 return 0;
780 case LEJPVP_SSL_OPTION_CLEAR:
781 a->info->ssl_options_clear |= atol(ctx->buf);
782 return 0;
783
Andy Green20fb5592018-10-26 09:44:58 +0800784 case LEJPVP_SSL_CLIENT_OPTION_SET:
785 a->info->ssl_client_options_set |= atol(ctx->buf);
786 return 0;
787 case LEJPVP_SSL_CLIENT_OPTION_CLEAR:
788 a->info->ssl_client_options_clear |= atol(ctx->buf);
789 return 0;
790
Andy Greenaa816e92018-04-12 15:56:38 +0800791 case LEJPVP_ALPN:
792 a->info->alpn = a->p;
793 break;
794
Andy Greenb3188772018-11-29 08:47:49 +0800795 case LEJPVP_LISTEN_ACCEPT_ROLE:
796 a->info->listen_accept_role = a->p;
797 break;
798 case LEJPVP_LISTEN_ACCEPT_PROTOCOL:
799 a->info->listen_accept_protocol = a->p;
800 break;
801
802 case LEJPVP_FLAG_APPLY_LISTEN_ACCEPT:
803 set_reset_flag(&a->info->options, ctx->buf,
804 LWS_SERVER_OPTION_ADOPT_APPLY_LISTEN_ACCEPT_CONFIG);
805 return 0;
806 case LEJPVP_FLAG_FALLBACK_LISTEN_ACCEPT:
Andy Green08b5ad92018-11-29 08:29:48 +0800807 lwsl_notice("vh %s: LEJPVP_FLAG_FALLBACK_LISTEN_ACCEPT: %s\n",
808 a->info->vhost_name, ctx->buf);
Andy Greenb3188772018-11-29 08:47:49 +0800809 set_reset_flag(&a->info->options, ctx->buf,
810 LWS_SERVER_OPTION_FALLBACK_TO_APPLY_LISTEN_ACCEPT_CONFIG);
811 return 0;
812 case LEJPVP_FLAG_ALLOW_NON_TLS:
813 set_reset_flag(&a->info->options, ctx->buf,
814 LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT);
815 return 0;
816 case LEJPVP_FLAG_REDIRECT_HTTP:
817 set_reset_flag(&a->info->options, ctx->buf,
818 LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS);
819 return 0;
820 case LEJPVP_FLAG_ALLOW_HTTP_ON_HTTPS:
821 set_reset_flag(&a->info->options, ctx->buf,
822 LWS_SERVER_OPTION_ALLOW_HTTP_ON_HTTPS_LISTENER);
823 return 0;
824
Andy Green3a31c472019-02-22 14:27:21 +0800825 case LEJPVP_FLAG_DISABLE_NO_PROTOCOL_WS_UPGRADES:
826 a->reject_ws_with_no_protocol = 1;
827 return 0;
828
Andy Greencd0c6962016-03-28 10:12:37 +0800829 default:
830 return 0;
831 }
832
Andy Green0aa382f2016-07-06 10:48:41 +0800833dostring:
834 p = ctx->buf;
Andy Green844b7792018-08-24 16:00:33 +0800835 p[LEJP_STRING_CHUNK] = '\0';
Andy Green0aa382f2016-07-06 10:48:41 +0800836 p1 = strstr(p, ESC_INSTALL_DATADIR);
837 if (p1) {
Andy Green253942c2018-08-23 11:29:45 +0800838 n = lws_ptr_diff(p1, p);
Andy Green0aa382f2016-07-06 10:48:41 +0800839 if (n > a->end - a->p)
Andy Green253942c2018-08-23 11:29:45 +0800840 n = lws_ptr_diff(a->end, a->p);
Andy Greenaae2c242018-03-12 09:28:26 +0800841 lws_strncpy(a->p, p, n + 1);
Andy Green0aa382f2016-07-06 10:48:41 +0800842 a->p += n;
Andy Green9bed6d62018-11-23 08:47:56 +0800843 a->p += lws_snprintf(a->p, a->end - a->p, "%s",
844 LWS_INSTALL_DATADIR);
Andy Green0aa382f2016-07-06 10:48:41 +0800845 p += n + strlen(ESC_INSTALL_DATADIR);
846 }
847
Andy Greena4967002016-09-15 02:22:57 +0800848 a->p += lws_snprintf(a->p, a->end - a->p, "%s", p);
Andy Green844b7792018-08-24 16:00:33 +0800849 if (reason == LEJPCB_VAL_STR_END)
850 *(a->p)++ = '\0';
Andy Greencd0c6962016-03-28 10:12:37 +0800851
852 return 0;
853}
854
855/*
856 * returns 0 = OK, 1 = can't open, 2 = parsing error
857 */
858
859static int
860lwsws_get_config(void *user, const char *f, const char * const *paths,
861 int count_paths, lejp_callback cb)
862{
863 unsigned char buf[128];
864 struct lejp_ctx ctx;
865 int n, m, fd;
866
Andy Greenf2f96852018-06-23 12:56:21 +0800867 fd = lws_open(f, O_RDONLY);
Andy Greencd0c6962016-03-28 10:12:37 +0800868 if (fd < 0) {
869 lwsl_err("Cannot open %s\n", f);
Andy Green92b0d8a2016-05-22 07:01:35 +0800870 return 2;
Andy Greencd0c6962016-03-28 10:12:37 +0800871 }
872 lwsl_info("%s: %s\n", __func__, f);
873 lejp_construct(&ctx, cb, user, paths, count_paths);
874
875 do {
876 n = read(fd, buf, sizeof(buf));
877 if (!n)
878 break;
879
Andy Green6e7b79b2016-04-09 09:32:01 +0800880 m = (int)(signed char)lejp_parse(&ctx, buf, n);
Andy Greencd0c6962016-03-28 10:12:37 +0800881 } while (m == LEJP_CONTINUE);
882
883 close(fd);
884 n = ctx.line;
885 lejp_destruct(&ctx);
886
887 if (m < 0) {
Andy Green4bd5b962016-06-18 06:36:37 +0800888 lwsl_err("%s(%u): parsing error %d: %s\n", f, n, m,
Andy Green6a884832019-03-12 07:54:27 +0800889 lejp_error_to_string(m));
Andy Greencd0c6962016-03-28 10:12:37 +0800890 return 2;
891 }
892
893 return 0;
894}
895
Andy Greenfc995df2017-09-28 11:29:03 +0800896#if defined(LWS_WITH_LIBUV) && UV_VERSION_MAJOR > 0
Andy Green0a183542016-04-09 07:22:40 +0800897
898static int
899lwsws_get_config_d(void *user, const char *d, const char * const *paths,
900 int count_paths, lejp_callback cb)
901{
902 uv_dirent_t dent;
903 uv_fs_t req;
904 char path[256];
Andy Greenbe9fb912016-12-16 07:37:43 +0800905 int ret = 0, ir;
Andy Green0a183542016-04-09 07:22:40 +0800906 uv_loop_t loop;
907
Andy Greenbe9fb912016-12-16 07:37:43 +0800908 ir = uv_loop_init(&loop);
909 if (ir) {
910 lwsl_err("%s: loop init failed %d\n", __func__, ir);
911 }
Andy Green0a183542016-04-09 07:22:40 +0800912
913 if (!uv_fs_scandir(&loop, &req, d, 0, NULL)) {
914 lwsl_err("Scandir on %s failed\n", d);
Andy Green92b0d8a2016-05-22 07:01:35 +0800915 return 2;
Andy Green0a183542016-04-09 07:22:40 +0800916 }
917
918 while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
Andy Greena4967002016-09-15 02:22:57 +0800919 lws_snprintf(path, sizeof(path) - 1, "%s/%s", d, dent.name);
Andy Green0a183542016-04-09 07:22:40 +0800920 ret = lwsws_get_config(user, path, paths, count_paths, cb);
921 if (ret)
922 goto bail;
923 }
924
925bail:
926 uv_fs_req_cleanup(&req);
Andy Green2d313bd2017-07-19 14:28:53 +0800927 while (uv_loop_close(&loop))
928 ;
Andy Green0a183542016-04-09 07:22:40 +0800929
930 return ret;
931}
932
933#else
934
Andy Greencd0c6962016-03-28 10:12:37 +0800935#ifndef _WIN32
936static int filter(const struct dirent *ent)
937{
938 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
939 return 0;
940
941 return 1;
942}
943#endif
944
945static int
946lwsws_get_config_d(void *user, const char *d, const char * const *paths,
947 int count_paths, lejp_callback cb)
948{
negativekelvin9b35bc12018-09-30 12:01:56 -0700949#if !defined(_WIN32) && !defined(LWS_WITH_ESP32)
Andy Greencd0c6962016-03-28 10:12:37 +0800950 struct dirent **namelist;
951 char path[256];
952 int n, i, ret = 0;
953
pblemel39e19c82019-01-11 16:48:53 +0800954 n = scandir((char *) d, &namelist, filter, alphasort);
Andy Greencd0c6962016-03-28 10:12:37 +0800955 if (n < 0) {
Andy Greence37ee92017-02-05 22:07:34 +0800956 lwsl_err("Scandir on %s failed\n", d);
Andy Green6f3f2df2017-10-12 07:03:44 +0800957 return 1;
Andy Greencd0c6962016-03-28 10:12:37 +0800958 }
959
960 for (i = 0; i < n; i++) {
Andy Green6f3f2df2017-10-12 07:03:44 +0800961 if (strchr(namelist[i]->d_name, '~'))
962 goto skip;
Andy Greena4967002016-09-15 02:22:57 +0800963 lws_snprintf(path, sizeof(path) - 1, "%s/%s", d,
Andy Greencd0c6962016-03-28 10:12:37 +0800964 namelist[i]->d_name);
965 ret = lwsws_get_config(user, path, paths, count_paths, cb);
966 if (ret) {
967 while (i++ < n)
968 free(namelist[i]);
969 goto bail;
970 }
Andy Green6f3f2df2017-10-12 07:03:44 +0800971skip:
Andy Greencd0c6962016-03-28 10:12:37 +0800972 free(namelist[i]);
973 }
974
975bail:
976 free(namelist);
977
978 return ret;
979#else
980 return 0;
981#endif
982}
983
Andy Green0a183542016-04-09 07:22:40 +0800984#endif
985
Andy Greencd0c6962016-03-28 10:12:37 +0800986int
987lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d,
988 char **cs, int *len)
989{
990 struct jpargs a;
Andy Greencae57ad2016-05-02 10:03:25 +0800991 const char * const *old = info->plugin_dirs;
Andy Green92b0d8a2016-05-22 07:01:35 +0800992 char dd[128];
Andy Greencae57ad2016-05-02 10:03:25 +0800993
994 memset(&a, 0, sizeof(a));
Andy Greencd0c6962016-03-28 10:12:37 +0800995
996 a.info = info;
997 a.p = *cs;
Andy Greena5e73a12016-04-13 11:49:07 +0800998 a.end = (a.p + *len) - 1;
Andy Greencd0c6962016-03-28 10:12:37 +0800999 a.valid = 0;
1000
Andy Greencae57ad2016-05-02 10:03:25 +08001001 lwsws_align(&a);
1002 info->plugin_dirs = (void *)a.p;
1003 a.plugin_dirs = (void *)a.p; /* writeable version */
1004 a.p += MAX_PLUGIN_DIRS * sizeof(void *);
1005
1006 /* copy any default paths */
1007
1008 while (old && *old) {
1009 a.plugin_dirs[a.count_plugin_dirs++] = *old;
1010 old++;
1011 }
1012
Andy Greena4967002016-09-15 02:22:57 +08001013 lws_snprintf(dd, sizeof(dd) - 1, "%s/conf", d);
Andy Green92b0d8a2016-05-22 07:01:35 +08001014 if (lwsws_get_config(&a, dd, paths_global,
Andy Greend461f462018-08-16 19:10:32 +08001015 LWS_ARRAY_SIZE(paths_global), lejp_globals_cb) > 1)
Andy Greencd0c6962016-03-28 10:12:37 +08001016 return 1;
Andy Greena4967002016-09-15 02:22:57 +08001017 lws_snprintf(dd, sizeof(dd) - 1, "%s/conf.d", d);
Andy Green92b0d8a2016-05-22 07:01:35 +08001018 if (lwsws_get_config_d(&a, dd, paths_global,
Andy Green9bed6d62018-11-23 08:47:56 +08001019 LWS_ARRAY_SIZE(paths_global),
1020 lejp_globals_cb) > 1)
Andy Greencd0c6962016-03-28 10:12:37 +08001021 return 1;
1022
Andy Greencae57ad2016-05-02 10:03:25 +08001023 a.plugin_dirs[a.count_plugin_dirs] = NULL;
1024
Andy Greencd0c6962016-03-28 10:12:37 +08001025 *cs = a.p;
Andy Green253942c2018-08-23 11:29:45 +08001026 *len = lws_ptr_diff(a.end, a.p);
Andy Greencd0c6962016-03-28 10:12:37 +08001027
1028 return 0;
1029}
1030
1031int
1032lwsws_get_config_vhosts(struct lws_context *context,
1033 struct lws_context_creation_info *info, const char *d,
1034 char **cs, int *len)
1035{
1036 struct jpargs a;
Andy Green92b0d8a2016-05-22 07:01:35 +08001037 char dd[128];
Andy Greencd0c6962016-03-28 10:12:37 +08001038
Andy Greencae57ad2016-05-02 10:03:25 +08001039 memset(&a, 0, sizeof(a));
1040
Andy Greencd0c6962016-03-28 10:12:37 +08001041 a.info = info;
1042 a.p = *cs;
1043 a.end = a.p + *len;
1044 a.valid = 0;
1045 a.context = context;
1046 a.protocols = info->protocols;
Andy Green00790992019-03-10 05:34:02 +08001047 a.pprotocols = info->pprotocols;
Andy Greencd0c6962016-03-28 10:12:37 +08001048 a.extensions = info->extensions;
1049
Andy Greena4967002016-09-15 02:22:57 +08001050 lws_snprintf(dd, sizeof(dd) - 1, "%s/conf", d);
Andy Green92b0d8a2016-05-22 07:01:35 +08001051 if (lwsws_get_config(&a, dd, paths_vhosts,
Andy Greend461f462018-08-16 19:10:32 +08001052 LWS_ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1)
Andy Greencd0c6962016-03-28 10:12:37 +08001053 return 1;
Andy Greena4967002016-09-15 02:22:57 +08001054 lws_snprintf(dd, sizeof(dd) - 1, "%s/conf.d", d);
Andy Green92b0d8a2016-05-22 07:01:35 +08001055 if (lwsws_get_config_d(&a, dd, paths_vhosts,
Andy Greend461f462018-08-16 19:10:32 +08001056 LWS_ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1)
Andy Greencd0c6962016-03-28 10:12:37 +08001057 return 1;
1058
1059 *cs = a.p;
Andy Green253942c2018-08-23 11:29:45 +08001060 *len = lws_ptr_diff(a.end, a.p);
Andy Greencd0c6962016-03-28 10:12:37 +08001061
Andy Green92b0d8a2016-05-22 07:01:35 +08001062 if (!a.any_vhosts) {
1063 lwsl_err("Need at least one vhost\n");
1064 return 1;
1065 }
1066
Andy Green7a77c0b2016-12-03 15:23:00 +08001067// lws_finalize_startup(context);
Andy Greencd0c6962016-03-28 10:12:37 +08001068
1069 return 0;
1070}