lejp-conf.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /*
  2. * libwebsockets web server application
  3. *
  4. * Copyright (C) 2010-2018 Andy Green <[email protected]>
  5. *
  6. * 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.
  10. *
  11. * 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.
  15. *
  16. * 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
  20. */
  21. #include "core/private.h"
  22. #ifndef _WIN32
  23. /* this is needed for Travis CI */
  24. #include <dirent.h>
  25. #endif
  26. #define ESC_INSTALL_DATADIR "_lws_ddir_"
  27. static const char * const paths_global[] = {
  28. "global.uid",
  29. "global.gid",
  30. "global.count-threads",
  31. "global.init-ssl",
  32. "global.server-string",
  33. "global.plugin-dir",
  34. "global.ws-pingpong-secs",
  35. "global.timeout-secs",
  36. "global.reject-service-keywords[].*",
  37. "global.reject-service-keywords[]",
  38. "global.default-alpn",
  39. };
  40. enum lejp_global_paths {
  41. LEJPGP_UID,
  42. LEJPGP_GID,
  43. LEJPGP_COUNT_THREADS,
  44. LWJPGP_INIT_SSL,
  45. LEJPGP_SERVER_STRING,
  46. LEJPGP_PLUGIN_DIR,
  47. LWJPGP_PINGPONG_SECS,
  48. LWJPGP_TIMEOUT_SECS,
  49. LWJPGP_REJECT_SERVICE_KEYWORDS_NAME,
  50. LWJPGP_REJECT_SERVICE_KEYWORDS,
  51. LWJPGP_DEFAULT_ALPN,
  52. };
  53. static const char * const paths_vhosts[] = {
  54. "vhosts[]",
  55. "vhosts[].mounts[]",
  56. "vhosts[].name",
  57. "vhosts[].port",
  58. "vhosts[].interface",
  59. "vhosts[].unix-socket",
  60. "vhosts[].sts",
  61. "vhosts[].host-ssl-key",
  62. "vhosts[].host-ssl-cert",
  63. "vhosts[].host-ssl-ca",
  64. "vhosts[].access-log",
  65. "vhosts[].mounts[].mountpoint",
  66. "vhosts[].mounts[].origin",
  67. "vhosts[].mounts[].protocol",
  68. "vhosts[].mounts[].default",
  69. "vhosts[].mounts[].auth-mask",
  70. "vhosts[].mounts[].cgi-timeout",
  71. "vhosts[].mounts[].cgi-env[].*",
  72. "vhosts[].mounts[].cache-max-age",
  73. "vhosts[].mounts[].cache-reuse",
  74. "vhosts[].mounts[].cache-revalidate",
  75. "vhosts[].mounts[].basic-auth",
  76. "vhosts[].mounts[].cache-intermediaries",
  77. "vhosts[].mounts[].extra-mimetypes.*",
  78. "vhosts[].mounts[].interpret.*",
  79. "vhosts[].ws-protocols[].*.*",
  80. "vhosts[].ws-protocols[].*",
  81. "vhosts[].ws-protocols[]",
  82. "vhosts[].keepalive_timeout",
  83. "vhosts[].enable-client-ssl",
  84. "vhosts[].ciphers",
  85. "vhosts[].ecdh-curve",
  86. "vhosts[].noipv6",
  87. "vhosts[].ipv6only",
  88. "vhosts[].ssl-option-set",
  89. "vhosts[].ssl-option-clear",
  90. "vhosts[].mounts[].pmo[].*",
  91. "vhosts[].headers[].*",
  92. "vhosts[].headers[]",
  93. "vhosts[].client-ssl-key",
  94. "vhosts[].client-ssl-cert",
  95. "vhosts[].client-ssl-ca",
  96. "vhosts[].client-ssl-ciphers",
  97. "vhosts[].onlyraw",
  98. "vhosts[].client-cert-required",
  99. "vhosts[].ignore-missing-cert",
  100. "vhosts[].error-document-404",
  101. "vhosts[].alpn",
  102. "vhosts[].ssl-client-option-set",
  103. "vhosts[].ssl-client-option-clear",
  104. "vhosts[].tls13-ciphers",
  105. "vhosts[].client-tls13-ciphers",
  106. "vhosts[].strict-host-check",
  107. };
  108. enum lejp_vhost_paths {
  109. LEJPVP,
  110. LEJPVP_MOUNTS,
  111. LEJPVP_NAME,
  112. LEJPVP_PORT,
  113. LEJPVP_INTERFACE,
  114. LEJPVP_UNIXSKT,
  115. LEJPVP_STS,
  116. LEJPVP_HOST_SSL_KEY,
  117. LEJPVP_HOST_SSL_CERT,
  118. LEJPVP_HOST_SSL_CA,
  119. LEJPVP_ACCESS_LOG,
  120. LEJPVP_MOUNTPOINT,
  121. LEJPVP_ORIGIN,
  122. LEJPVP_MOUNT_PROTOCOL,
  123. LEJPVP_DEFAULT,
  124. LEJPVP_DEFAULT_AUTH_MASK,
  125. LEJPVP_CGI_TIMEOUT,
  126. LEJPVP_CGI_ENV,
  127. LEJPVP_MOUNT_CACHE_MAX_AGE,
  128. LEJPVP_MOUNT_CACHE_REUSE,
  129. LEJPVP_MOUNT_CACHE_REVALIDATE,
  130. LEJPVP_MOUNT_BASIC_AUTH,
  131. LEJPVP_MOUNT_CACHE_INTERMEDIARIES,
  132. LEJPVP_MOUNT_EXTRA_MIMETYPES,
  133. LEJPVP_MOUNT_INTERPRET,
  134. LEJPVP_PROTOCOL_NAME_OPT,
  135. LEJPVP_PROTOCOL_NAME,
  136. LEJPVP_PROTOCOL,
  137. LEJPVP_KEEPALIVE_TIMEOUT,
  138. LEJPVP_ENABLE_CLIENT_SSL,
  139. LEJPVP_CIPHERS,
  140. LEJPVP_ECDH_CURVE,
  141. LEJPVP_NOIPV6,
  142. LEJPVP_IPV6ONLY,
  143. LEJPVP_SSL_OPTION_SET,
  144. LEJPVP_SSL_OPTION_CLEAR,
  145. LEJPVP_PMO,
  146. LEJPVP_HEADERS_NAME,
  147. LEJPVP_HEADERS,
  148. LEJPVP_CLIENT_SSL_KEY,
  149. LEJPVP_CLIENT_SSL_CERT,
  150. LEJPVP_CLIENT_SSL_CA,
  151. LEJPVP_CLIENT_CIPHERS,
  152. LEJPVP_FLAG_ONLYRAW,
  153. LEJPVP_FLAG_CLIENT_CERT_REQUIRED,
  154. LEJPVP_IGNORE_MISSING_CERT,
  155. LEJPVP_ERROR_DOCUMENT_404,
  156. LEJPVP_ALPN,
  157. LEJPVP_SSL_CLIENT_OPTION_SET,
  158. LEJPVP_SSL_CLIENT_OPTION_CLEAR,
  159. LEJPVP_TLS13_CIPHERS,
  160. LEJPVP_CLIENT_TLS13_CIPHERS,
  161. LEJPVP_FLAG_STRICT_HOST_CHECK,
  162. };
  163. static const char * const parser_errs[] = {
  164. "",
  165. "",
  166. "No opening '{'",
  167. "Expected closing '}'",
  168. "Expected '\"'",
  169. "String underrun",
  170. "Illegal unescaped control char",
  171. "Illegal escape format",
  172. "Illegal hex number",
  173. "Expected ':'",
  174. "Illegal value start",
  175. "Digit required after decimal point",
  176. "Bad number format",
  177. "Bad exponent format",
  178. "Unknown token",
  179. "Too many ']'",
  180. "Mismatched ']'",
  181. "Expected ']'",
  182. "JSON nesting limit exceeded",
  183. "Nesting tracking used up",
  184. "Number too long",
  185. "Comma or block end expected",
  186. "Unknown",
  187. "Parser callback errored (see earlier error)",
  188. };
  189. #define MAX_PLUGIN_DIRS 10
  190. struct jpargs {
  191. struct lws_context_creation_info *info;
  192. struct lws_context *context;
  193. const struct lws_protocols *protocols;
  194. const struct lws_extension *extensions;
  195. char *p, *end, valid;
  196. struct lws_http_mount *head, *last;
  197. struct lws_protocol_vhost_options *pvo;
  198. struct lws_protocol_vhost_options *pvo_em;
  199. struct lws_protocol_vhost_options *pvo_int;
  200. struct lws_http_mount m;
  201. const char **plugin_dirs;
  202. int count_plugin_dirs;
  203. unsigned int enable_client_ssl:1;
  204. unsigned int fresh_mount:1;
  205. unsigned int any_vhosts:1;
  206. unsigned int chunk:1;
  207. };
  208. static void *
  209. lwsws_align(struct jpargs *a)
  210. {
  211. if ((lws_intptr_t)(a->p) & 15)
  212. a->p += 16 - ((lws_intptr_t)(a->p) & 15);
  213. a->chunk = 0;
  214. return a->p;
  215. }
  216. static int
  217. arg_to_bool(const char *s)
  218. {
  219. static const char * const on[] = { "on", "yes", "true" };
  220. int n = atoi(s);
  221. if (n)
  222. return 1;
  223. for (n = 0; n < (int)LWS_ARRAY_SIZE(on); n++)
  224. if (!strcasecmp(s, on[n]))
  225. return 1;
  226. return 0;
  227. }
  228. static signed char
  229. lejp_globals_cb(struct lejp_ctx *ctx, char reason)
  230. {
  231. struct jpargs *a = (struct jpargs *)ctx->user;
  232. struct lws_protocol_vhost_options *rej;
  233. int n;
  234. /* we only match on the prepared path strings */
  235. if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match)
  236. return 0;
  237. /* this catches, eg, vhosts[].headers[].xxx */
  238. if (reason == LEJPCB_VAL_STR_END &&
  239. ctx->path_match == LWJPGP_REJECT_SERVICE_KEYWORDS_NAME + 1) {
  240. rej = lwsws_align(a);
  241. a->p += sizeof(*rej);
  242. n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
  243. rej->next = a->info->reject_service_keywords;
  244. a->info->reject_service_keywords = rej;
  245. rej->name = a->p;
  246. lwsl_notice(" adding rej %s=%s\n", a->p, ctx->buf);
  247. a->p += n - 1;
  248. *(a->p++) = '\0';
  249. rej->value = a->p;
  250. rej->options = NULL;
  251. goto dostring;
  252. }
  253. switch (ctx->path_match - 1) {
  254. case LEJPGP_UID:
  255. a->info->uid = atoi(ctx->buf);
  256. return 0;
  257. case LEJPGP_GID:
  258. a->info->gid = atoi(ctx->buf);
  259. return 0;
  260. case LEJPGP_COUNT_THREADS:
  261. a->info->count_threads = atoi(ctx->buf);
  262. return 0;
  263. case LWJPGP_INIT_SSL:
  264. if (arg_to_bool(ctx->buf))
  265. a->info->options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
  266. return 0;
  267. case LEJPGP_SERVER_STRING:
  268. a->info->server_string = a->p;
  269. break;
  270. case LEJPGP_PLUGIN_DIR:
  271. if (a->count_plugin_dirs == MAX_PLUGIN_DIRS - 1) {
  272. lwsl_err("Too many plugin dirs\n");
  273. return -1;
  274. }
  275. a->plugin_dirs[a->count_plugin_dirs++] = a->p;
  276. break;
  277. case LWJPGP_PINGPONG_SECS:
  278. a->info->ws_ping_pong_interval = atoi(ctx->buf);
  279. return 0;
  280. case LWJPGP_TIMEOUT_SECS:
  281. a->info->timeout_secs = atoi(ctx->buf);
  282. return 0;
  283. case LWJPGP_DEFAULT_ALPN:
  284. a->info->alpn = a->p;
  285. break;
  286. default:
  287. return 0;
  288. }
  289. dostring:
  290. a->p += lws_snprintf(a->p, a->end - a->p, "%s", ctx->buf);
  291. *(a->p)++ = '\0';
  292. return 0;
  293. }
  294. static signed char
  295. lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
  296. {
  297. struct jpargs *a = (struct jpargs *)ctx->user;
  298. struct lws_protocol_vhost_options *pvo, *mp_cgienv, *headers;
  299. struct lws_http_mount *m;
  300. char *p, *p1;
  301. int n;
  302. #if 0
  303. lwsl_notice(" %d: %s (%d)\n", reason, ctx->path, ctx->path_match);
  304. for (n = 0; n < ctx->wildcount; n++)
  305. lwsl_notice(" %d\n", ctx->wild[n]);
  306. #endif
  307. if (reason == LEJPCB_OBJECT_START && ctx->path_match == LEJPVP + 1) {
  308. uint32_t i[4];
  309. const char *ss;
  310. /* set the defaults for this vhost */
  311. a->valid = 1;
  312. a->head = NULL;
  313. a->last = NULL;
  314. i[0] = a->info->count_threads;
  315. i[1] = a->info->options & (
  316. LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME |
  317. LWS_SERVER_OPTION_LIBUV |
  318. LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT |
  319. LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
  320. LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN |
  321. LWS_SERVER_OPTION_LIBEVENT |
  322. LWS_SERVER_OPTION_LIBEV
  323. );
  324. ss = a->info->server_string;
  325. i[2] = a->info->ws_ping_pong_interval;
  326. i[3] = a->info->timeout_secs;
  327. memset(a->info, 0, sizeof(*a->info));
  328. a->info->count_threads = i[0];
  329. a->info->options = i[1];
  330. a->info->server_string = ss;
  331. a->info->ws_ping_pong_interval = i[2];
  332. a->info->timeout_secs = i[3];
  333. a->info->protocols = a->protocols;
  334. a->info->extensions = a->extensions;
  335. #if defined(LWS_WITH_TLS)
  336. a->info->client_ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
  337. "ECDHE-RSA-AES256-GCM-SHA384:"
  338. "DHE-RSA-AES256-GCM-SHA384:"
  339. "ECDHE-RSA-AES256-SHA384:"
  340. "HIGH:!aNULL:!eNULL:!EXPORT:"
  341. "!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:"
  342. "!SHA1:!DHE-RSA-AES128-GCM-SHA256:"
  343. "!DHE-RSA-AES128-SHA256:"
  344. "!AES128-GCM-SHA256:"
  345. "!AES128-SHA256:"
  346. "!DHE-RSA-AES256-SHA256:"
  347. "!AES256-GCM-SHA384:"
  348. "!AES256-SHA256";
  349. #endif
  350. a->info->ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
  351. "ECDHE-RSA-AES256-GCM-SHA384:"
  352. "DHE-RSA-AES256-GCM-SHA384:"
  353. "ECDHE-RSA-AES256-SHA384:"
  354. "HIGH:!aNULL:!eNULL:!EXPORT:"
  355. "!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:"
  356. "!SHA1:!DHE-RSA-AES128-GCM-SHA256:"
  357. "!DHE-RSA-AES128-SHA256:"
  358. "!AES128-GCM-SHA256:"
  359. "!AES128-SHA256:"
  360. "!DHE-RSA-AES256-SHA256:"
  361. "!AES256-GCM-SHA384:"
  362. "!AES256-SHA256";
  363. a->info->keepalive_timeout = 5;
  364. }
  365. if (reason == LEJPCB_OBJECT_START &&
  366. ctx->path_match == LEJPVP_MOUNTS + 1) {
  367. a->fresh_mount = 1;
  368. memset(&a->m, 0, sizeof(a->m));
  369. }
  370. /* this catches, eg, vhosts[].ws-protocols[].xxx-protocol */
  371. if (reason == LEJPCB_OBJECT_START &&
  372. ctx->path_match == LEJPVP_PROTOCOL_NAME + 1) {
  373. a->pvo = lwsws_align(a);
  374. a->p += sizeof(*a->pvo);
  375. n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
  376. /* ie, enable this protocol, no options yet */
  377. a->pvo->next = a->info->pvo;
  378. a->info->pvo = a->pvo;
  379. a->pvo->name = a->p;
  380. lwsl_info(" adding protocol %s\n", a->p);
  381. a->p += n;
  382. a->pvo->value = a->p;
  383. a->pvo->options = NULL;
  384. goto dostring;
  385. }
  386. /* this catches, eg, vhosts[].headers[].xxx */
  387. if ((reason == LEJPCB_VAL_STR_END || reason == LEJPCB_VAL_STR_CHUNK) &&
  388. ctx->path_match == LEJPVP_HEADERS_NAME + 1) {
  389. if (!a->chunk) {
  390. headers = lwsws_align(a);
  391. a->p += sizeof(*headers);
  392. n = lejp_get_wildcard(ctx, 0, a->p,
  393. lws_ptr_diff(a->end, a->p));
  394. /* ie, add this header */
  395. headers->next = a->info->headers;
  396. a->info->headers = headers;
  397. headers->name = a->p;
  398. lwsl_notice(" adding header %s=%s\n", a->p, ctx->buf);
  399. a->p += n - 1;
  400. *(a->p++) = ':';
  401. if (a->p < a->end)
  402. *(a->p++) = '\0';
  403. else
  404. *(a->p - 1) = '\0';
  405. headers->value = a->p;
  406. headers->options = NULL;
  407. }
  408. a->chunk = reason == LEJPCB_VAL_STR_CHUNK;
  409. goto dostring;
  410. }
  411. if (reason == LEJPCB_OBJECT_END &&
  412. (ctx->path_match == LEJPVP + 1 || !ctx->path[0]) &&
  413. a->valid) {
  414. struct lws_vhost *vhost;
  415. //lwsl_notice("%s\n", ctx->path);
  416. if (!a->info->port &&
  417. !(a->info->options & LWS_SERVER_OPTION_UNIX_SOCK)) {
  418. lwsl_err("Port required (eg, 443)\n");
  419. return 1;
  420. }
  421. a->valid = 0;
  422. a->info->mounts = a->head;
  423. vhost = lws_create_vhost(a->context, a->info);
  424. if (!vhost) {
  425. lwsl_err("Failed to create vhost %s\n",
  426. a->info->vhost_name);
  427. return 1;
  428. }
  429. a->any_vhosts = 1;
  430. #if defined(LWS_WITH_TLS)
  431. if (a->enable_client_ssl) {
  432. const char *cert_filepath =
  433. a->info->client_ssl_cert_filepath;
  434. const char *private_key_filepath =
  435. a->info->client_ssl_private_key_filepath;
  436. const char *ca_filepath =
  437. a->info->client_ssl_ca_filepath;
  438. const char *cipher_list =
  439. a->info->client_ssl_cipher_list;
  440. memset(a->info, 0, sizeof(*a->info));
  441. a->info->client_ssl_cert_filepath = cert_filepath;
  442. a->info->client_ssl_private_key_filepath =
  443. private_key_filepath;
  444. a->info->client_ssl_ca_filepath = ca_filepath;
  445. a->info->client_ssl_cipher_list = cipher_list;
  446. a->info->options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
  447. lws_init_vhost_client_ssl(a->info, vhost);
  448. }
  449. #endif
  450. return 0;
  451. }
  452. if (reason == LEJPCB_OBJECT_END &&
  453. ctx->path_match == LEJPVP_MOUNTS + 1) {
  454. static const char * const mount_protocols[] = {
  455. "http://",
  456. "https://",
  457. "file://",
  458. "cgi://",
  459. ">http://",
  460. ">https://",
  461. "callback://",
  462. "gzip://",
  463. };
  464. if (!a->fresh_mount)
  465. return 0;
  466. if (!a->m.mountpoint || !a->m.origin) {
  467. lwsl_err("mountpoint and origin required\n");
  468. return 1;
  469. }
  470. lwsl_debug("adding mount %s\n", a->m.mountpoint);
  471. m = lwsws_align(a);
  472. memcpy(m, &a->m, sizeof(*m));
  473. if (a->last)
  474. a->last->mount_next = m;
  475. for (n = 0; n < (int)LWS_ARRAY_SIZE(mount_protocols); n++)
  476. if (!strncmp(a->m.origin, mount_protocols[n],
  477. strlen(mount_protocols[n]))) {
  478. lwsl_info("----%s\n", a->m.origin);
  479. m->origin_protocol = n;
  480. m->origin = a->m.origin +
  481. strlen(mount_protocols[n]);
  482. break;
  483. }
  484. if (n == (int)LWS_ARRAY_SIZE(mount_protocols)) {
  485. lwsl_err("unsupported protocol:// %s\n", a->m.origin);
  486. return 1;
  487. }
  488. a->p += sizeof(*m);
  489. if (!a->head)
  490. a->head = m;
  491. a->last = m;
  492. a->fresh_mount = 0;
  493. }
  494. /* we only match on the prepared path strings */
  495. if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match)
  496. return 0;
  497. switch (ctx->path_match - 1) {
  498. case LEJPVP_NAME:
  499. a->info->vhost_name = a->p;
  500. break;
  501. case LEJPVP_PORT:
  502. a->info->port = atoi(ctx->buf);
  503. return 0;
  504. case LEJPVP_INTERFACE:
  505. a->info->iface = a->p;
  506. break;
  507. case LEJPVP_UNIXSKT:
  508. if (arg_to_bool(ctx->buf))
  509. a->info->options |= LWS_SERVER_OPTION_UNIX_SOCK;
  510. else
  511. a->info->options &= ~(LWS_SERVER_OPTION_UNIX_SOCK);
  512. return 0;
  513. case LEJPVP_STS:
  514. if (arg_to_bool(ctx->buf))
  515. a->info->options |= LWS_SERVER_OPTION_STS;
  516. else
  517. a->info->options &= ~(LWS_SERVER_OPTION_STS);
  518. return 0;
  519. case LEJPVP_HOST_SSL_KEY:
  520. a->info->ssl_private_key_filepath = a->p;
  521. break;
  522. case LEJPVP_HOST_SSL_CERT:
  523. a->info->ssl_cert_filepath = a->p;
  524. break;
  525. case LEJPVP_HOST_SSL_CA:
  526. a->info->ssl_ca_filepath = a->p;
  527. break;
  528. case LEJPVP_ACCESS_LOG:
  529. a->info->log_filepath = a->p;
  530. break;
  531. case LEJPVP_MOUNTPOINT:
  532. a->m.mountpoint = a->p;
  533. a->m.mountpoint_len = (unsigned char)strlen(ctx->buf);
  534. break;
  535. case LEJPVP_ORIGIN:
  536. if (!strncmp(ctx->buf, "callback://", 11))
  537. a->m.protocol = a->p + 11;
  538. if (!a->m.origin)
  539. a->m.origin = a->p;
  540. break;
  541. case LEJPVP_DEFAULT:
  542. a->m.def = a->p;
  543. break;
  544. case LEJPVP_DEFAULT_AUTH_MASK:
  545. a->m.auth_mask = atoi(ctx->buf);
  546. return 0;
  547. case LEJPVP_MOUNT_CACHE_MAX_AGE:
  548. a->m.cache_max_age = atoi(ctx->buf);
  549. return 0;
  550. case LEJPVP_MOUNT_CACHE_REUSE:
  551. a->m.cache_reusable = arg_to_bool(ctx->buf);
  552. return 0;
  553. case LEJPVP_MOUNT_CACHE_REVALIDATE:
  554. a->m.cache_revalidate = arg_to_bool(ctx->buf);
  555. return 0;
  556. case LEJPVP_MOUNT_CACHE_INTERMEDIARIES:
  557. a->m.cache_intermediaries = arg_to_bool(ctx->buf);;
  558. return 0;
  559. case LEJPVP_MOUNT_BASIC_AUTH:
  560. a->m.basic_auth_login_file = a->p;
  561. break;
  562. case LEJPVP_CGI_TIMEOUT:
  563. a->m.cgi_timeout = atoi(ctx->buf);
  564. return 0;
  565. case LEJPVP_KEEPALIVE_TIMEOUT:
  566. a->info->keepalive_timeout = atoi(ctx->buf);
  567. return 0;
  568. #if defined(LWS_WITH_TLS)
  569. case LEJPVP_CLIENT_CIPHERS:
  570. a->info->client_ssl_cipher_list = a->p;
  571. break;
  572. #endif
  573. case LEJPVP_CIPHERS:
  574. a->info->ssl_cipher_list = a->p;
  575. break;
  576. case LEJPVP_TLS13_CIPHERS:
  577. a->info->tls1_3_plus_cipher_list = a->p;
  578. break;
  579. case LEJPVP_CLIENT_TLS13_CIPHERS:
  580. a->info->client_tls_1_3_plus_cipher_list = a->p;
  581. break;
  582. case LEJPVP_ECDH_CURVE:
  583. a->info->ecdh_curve = a->p;
  584. break;
  585. case LEJPVP_PMO:
  586. case LEJPVP_CGI_ENV:
  587. mp_cgienv = lwsws_align(a);
  588. a->p += sizeof(*a->m.cgienv);
  589. mp_cgienv->next = a->m.cgienv;
  590. a->m.cgienv = mp_cgienv;
  591. n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
  592. mp_cgienv->name = a->p;
  593. a->p += n;
  594. mp_cgienv->value = a->p;
  595. mp_cgienv->options = NULL;
  596. //lwsl_notice(" adding pmo / cgi-env '%s' = '%s'\n",
  597. // mp_cgienv->name, mp_cgienv->value);
  598. goto dostring;
  599. case LEJPVP_PROTOCOL_NAME_OPT:
  600. /* this catches, eg,
  601. * vhosts[].ws-protocols[].xxx-protocol.yyy-option
  602. * ie, these are options attached to a protocol with { }
  603. */
  604. pvo = lwsws_align(a);
  605. a->p += sizeof(*a->pvo);
  606. n = lejp_get_wildcard(ctx, 1, a->p, lws_ptr_diff(a->end, a->p));
  607. /* ie, enable this protocol, no options yet */
  608. pvo->next = a->pvo->options;
  609. a->pvo->options = pvo;
  610. pvo->name = a->p;
  611. a->p += n;
  612. pvo->value = a->p;
  613. pvo->options = NULL;
  614. break;
  615. case LEJPVP_MOUNT_EXTRA_MIMETYPES:
  616. a->pvo_em = lwsws_align(a);
  617. a->p += sizeof(*a->pvo_em);
  618. n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
  619. /* ie, enable this protocol, no options yet */
  620. a->pvo_em->next = a->m.extra_mimetypes;
  621. a->m.extra_mimetypes = a->pvo_em;
  622. a->pvo_em->name = a->p;
  623. lwsl_notice(" + extra-mimetypes %s -> %s\n", a->p, ctx->buf);
  624. a->p += n;
  625. a->pvo_em->value = a->p;
  626. a->pvo_em->options = NULL;
  627. break;
  628. case LEJPVP_MOUNT_INTERPRET:
  629. a->pvo_int = lwsws_align(a);
  630. a->p += sizeof(*a->pvo_int);
  631. n = lejp_get_wildcard(ctx, 0, a->p, lws_ptr_diff(a->end, a->p));
  632. /* ie, enable this protocol, no options yet */
  633. a->pvo_int->next = a->m.interpret;
  634. a->m.interpret = a->pvo_int;
  635. a->pvo_int->name = a->p;
  636. lwsl_notice(" adding interpret %s -> %s\n", a->p,
  637. ctx->buf);
  638. a->p += n;
  639. a->pvo_int->value = a->p;
  640. a->pvo_int->options = NULL;
  641. break;
  642. case LEJPVP_ENABLE_CLIENT_SSL:
  643. a->enable_client_ssl = arg_to_bool(ctx->buf);
  644. return 0;
  645. #if defined(LWS_WITH_TLS)
  646. case LEJPVP_CLIENT_SSL_KEY:
  647. a->info->client_ssl_private_key_filepath = a->p;
  648. break;
  649. case LEJPVP_CLIENT_SSL_CERT:
  650. a->info->client_ssl_cert_filepath = a->p;
  651. break;
  652. case LEJPVP_CLIENT_SSL_CA:
  653. a->info->client_ssl_ca_filepath = a->p;
  654. break;
  655. #endif
  656. case LEJPVP_NOIPV6:
  657. if (arg_to_bool(ctx->buf))
  658. a->info->options |= LWS_SERVER_OPTION_DISABLE_IPV6;
  659. else
  660. a->info->options &= ~(LWS_SERVER_OPTION_DISABLE_IPV6);
  661. return 0;
  662. case LEJPVP_FLAG_ONLYRAW:
  663. if (arg_to_bool(ctx->buf))
  664. a->info->options |= LWS_SERVER_OPTION_ONLY_RAW;
  665. else
  666. a->info->options &= ~(LWS_SERVER_OPTION_ONLY_RAW);
  667. return 0;
  668. case LEJPVP_IPV6ONLY:
  669. a->info->options |= LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY;
  670. if (arg_to_bool(ctx->buf))
  671. a->info->options |= LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE;
  672. else
  673. a->info->options &= ~(LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE);
  674. return 0;
  675. case LEJPVP_FLAG_CLIENT_CERT_REQUIRED:
  676. if (arg_to_bool(ctx->buf))
  677. a->info->options |=
  678. LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT;
  679. return 0;
  680. case LEJPVP_IGNORE_MISSING_CERT:
  681. if (arg_to_bool(ctx->buf))
  682. a->info->options |= LWS_SERVER_OPTION_IGNORE_MISSING_CERT;
  683. else
  684. a->info->options &= ~(LWS_SERVER_OPTION_IGNORE_MISSING_CERT);
  685. return 0;
  686. case LEJPVP_FLAG_STRICT_HOST_CHECK:
  687. if (arg_to_bool(ctx->buf))
  688. a->info->options |=
  689. LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK;
  690. else
  691. a->info->options &=
  692. ~(LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK);
  693. return 0;
  694. case LEJPVP_ERROR_DOCUMENT_404:
  695. a->info->error_document_404 = a->p;
  696. break;
  697. case LEJPVP_SSL_OPTION_SET:
  698. a->info->ssl_options_set |= atol(ctx->buf);
  699. return 0;
  700. case LEJPVP_SSL_OPTION_CLEAR:
  701. a->info->ssl_options_clear |= atol(ctx->buf);
  702. return 0;
  703. case LEJPVP_SSL_CLIENT_OPTION_SET:
  704. a->info->ssl_client_options_set |= atol(ctx->buf);
  705. return 0;
  706. case LEJPVP_SSL_CLIENT_OPTION_CLEAR:
  707. a->info->ssl_client_options_clear |= atol(ctx->buf);
  708. return 0;
  709. case LEJPVP_ALPN:
  710. a->info->alpn = a->p;
  711. break;
  712. default:
  713. return 0;
  714. }
  715. dostring:
  716. p = ctx->buf;
  717. p[LEJP_STRING_CHUNK] = '\0';
  718. p1 = strstr(p, ESC_INSTALL_DATADIR);
  719. if (p1) {
  720. n = lws_ptr_diff(p1, p);
  721. if (n > a->end - a->p)
  722. n = lws_ptr_diff(a->end, a->p);
  723. lws_strncpy(a->p, p, n + 1);
  724. a->p += n;
  725. a->p += lws_snprintf(a->p, a->end - a->p, "%s",
  726. LWS_INSTALL_DATADIR);
  727. p += n + strlen(ESC_INSTALL_DATADIR);
  728. }
  729. a->p += lws_snprintf(a->p, a->end - a->p, "%s", p);
  730. if (reason == LEJPCB_VAL_STR_END)
  731. *(a->p)++ = '\0';
  732. return 0;
  733. }
  734. /*
  735. * returns 0 = OK, 1 = can't open, 2 = parsing error
  736. */
  737. static int
  738. lwsws_get_config(void *user, const char *f, const char * const *paths,
  739. int count_paths, lejp_callback cb)
  740. {
  741. unsigned char buf[128];
  742. struct lejp_ctx ctx;
  743. int n, m, fd;
  744. fd = lws_open(f, O_RDONLY);
  745. if (fd < 0) {
  746. lwsl_err("Cannot open %s\n", f);
  747. return 2;
  748. }
  749. lwsl_info("%s: %s\n", __func__, f);
  750. lejp_construct(&ctx, cb, user, paths, count_paths);
  751. do {
  752. n = read(fd, buf, sizeof(buf));
  753. if (!n)
  754. break;
  755. m = (int)(signed char)lejp_parse(&ctx, buf, n);
  756. } while (m == LEJP_CONTINUE);
  757. close(fd);
  758. n = ctx.line;
  759. lejp_destruct(&ctx);
  760. if (m < 0) {
  761. lwsl_err("%s(%u): parsing error %d: %s\n", f, n, m,
  762. parser_errs[-m]);
  763. return 2;
  764. }
  765. return 0;
  766. }
  767. #if defined(LWS_WITH_LIBUV) && UV_VERSION_MAJOR > 0
  768. static int
  769. lwsws_get_config_d(void *user, const char *d, const char * const *paths,
  770. int count_paths, lejp_callback cb)
  771. {
  772. uv_dirent_t dent;
  773. uv_fs_t req;
  774. char path[256];
  775. int ret = 0, ir;
  776. uv_loop_t loop;
  777. ir = uv_loop_init(&loop);
  778. if (ir) {
  779. lwsl_err("%s: loop init failed %d\n", __func__, ir);
  780. }
  781. if (!uv_fs_scandir(&loop, &req, d, 0, NULL)) {
  782. lwsl_err("Scandir on %s failed\n", d);
  783. return 2;
  784. }
  785. while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
  786. lws_snprintf(path, sizeof(path) - 1, "%s/%s", d, dent.name);
  787. ret = lwsws_get_config(user, path, paths, count_paths, cb);
  788. if (ret)
  789. goto bail;
  790. }
  791. bail:
  792. uv_fs_req_cleanup(&req);
  793. while (uv_loop_close(&loop))
  794. ;
  795. return ret;
  796. }
  797. #else
  798. #ifndef _WIN32
  799. static int filter(const struct dirent *ent)
  800. {
  801. if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
  802. return 0;
  803. return 1;
  804. }
  805. #endif
  806. static int
  807. lwsws_get_config_d(void *user, const char *d, const char * const *paths,
  808. int count_paths, lejp_callback cb)
  809. {
  810. #if !defined(_WIN32) && !defined(LWS_WITH_ESP32)
  811. struct dirent **namelist;
  812. char path[256];
  813. int n, i, ret = 0;
  814. n = scandir(d, &namelist, filter, alphasort);
  815. if (n < 0) {
  816. lwsl_err("Scandir on %s failed\n", d);
  817. return 1;
  818. }
  819. for (i = 0; i < n; i++) {
  820. if (strchr(namelist[i]->d_name, '~'))
  821. goto skip;
  822. lws_snprintf(path, sizeof(path) - 1, "%s/%s", d,
  823. namelist[i]->d_name);
  824. ret = lwsws_get_config(user, path, paths, count_paths, cb);
  825. if (ret) {
  826. while (i++ < n)
  827. free(namelist[i]);
  828. goto bail;
  829. }
  830. skip:
  831. free(namelist[i]);
  832. }
  833. bail:
  834. free(namelist);
  835. return ret;
  836. #else
  837. return 0;
  838. #endif
  839. }
  840. #endif
  841. int
  842. lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d,
  843. char **cs, int *len)
  844. {
  845. struct jpargs a;
  846. const char * const *old = info->plugin_dirs;
  847. char dd[128];
  848. memset(&a, 0, sizeof(a));
  849. a.info = info;
  850. a.p = *cs;
  851. a.end = (a.p + *len) - 1;
  852. a.valid = 0;
  853. lwsws_align(&a);
  854. info->plugin_dirs = (void *)a.p;
  855. a.plugin_dirs = (void *)a.p; /* writeable version */
  856. a.p += MAX_PLUGIN_DIRS * sizeof(void *);
  857. /* copy any default paths */
  858. while (old && *old) {
  859. a.plugin_dirs[a.count_plugin_dirs++] = *old;
  860. old++;
  861. }
  862. lws_snprintf(dd, sizeof(dd) - 1, "%s/conf", d);
  863. if (lwsws_get_config(&a, dd, paths_global,
  864. LWS_ARRAY_SIZE(paths_global), lejp_globals_cb) > 1)
  865. return 1;
  866. lws_snprintf(dd, sizeof(dd) - 1, "%s/conf.d", d);
  867. if (lwsws_get_config_d(&a, dd, paths_global,
  868. LWS_ARRAY_SIZE(paths_global),
  869. lejp_globals_cb) > 1)
  870. return 1;
  871. a.plugin_dirs[a.count_plugin_dirs] = NULL;
  872. *cs = a.p;
  873. *len = lws_ptr_diff(a.end, a.p);
  874. return 0;
  875. }
  876. int
  877. lwsws_get_config_vhosts(struct lws_context *context,
  878. struct lws_context_creation_info *info, const char *d,
  879. char **cs, int *len)
  880. {
  881. struct jpargs a;
  882. char dd[128];
  883. memset(&a, 0, sizeof(a));
  884. a.info = info;
  885. a.p = *cs;
  886. a.end = a.p + *len;
  887. a.valid = 0;
  888. a.context = context;
  889. a.protocols = info->protocols;
  890. a.extensions = info->extensions;
  891. lws_snprintf(dd, sizeof(dd) - 1, "%s/conf", d);
  892. if (lwsws_get_config(&a, dd, paths_vhosts,
  893. LWS_ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1)
  894. return 1;
  895. lws_snprintf(dd, sizeof(dd) - 1, "%s/conf.d", d);
  896. if (lwsws_get_config_d(&a, dd, paths_vhosts,
  897. LWS_ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1)
  898. return 1;
  899. *cs = a.p;
  900. *len = lws_ptr_diff(a.end, a.p);
  901. if (!a.any_vhosts) {
  902. lwsl_err("Need at least one vhost\n");
  903. return 1;
  904. }
  905. // lws_finalize_startup(context);
  906. return 0;
  907. }