diff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c index 19e57b83..0b86a808 100644 --- a/lib/roles/http/server/server.c +++ b/lib/roles/http/server/server.c @@ -696,7 +696,7 @@ lws_find_string_in_file(const char *filename, const char *string, int stringlen) fd = open(filename, O_RDONLY); if (fd < 0) { lwsl_err("can't open auth file: %s\n", filename); - return 1; + return 0; } while (1) { @@ -1097,7 +1097,7 @@ lws_http_action(struct lws *wsi) return lws_unauthorised_basic_auth(wsi); } - lwsl_notice("basic auth accepted\n"); + lwsl_info("basic auth accepted\n"); /* accept the auth */ } diff --git a/minimal-examples/http-server/README.md b/minimal-examples/http-server/README.md index 1ecfeebe..84ef807d 100644 --- a/minimal-examples/http-server/README.md +++ b/minimal-examples/http-server/README.md @@ -1,5 +1,6 @@ |Example|Demonstrates| ---|--- +minimal-http-server-basicauth|Shows how to protect a mount using a password file and basic auth minimal-http-server-dynamic|Serves both static and dynamically generated http content minimal-http-server-form-get|Process a GET form minimal-http-server-form-post-file|Process a multipart POST form with file transfer diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/CMakeLists.txt b/minimal-examples/http-server/minimal-http-server-basicauth/CMakeLists.txt new file mode 100644 index 00000000..edf29d0a --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-basicauth/CMakeLists.txt @@ -0,0 +1,76 @@ +cmake_minimum_required(VERSION 2.8) +include(CheckCSourceCompiles) + +set(SAMP lws-minimal-http-server-basicauth) +set(SRCS minimal-http-server-basicauth.c) + +# If we are being built as part of lws, confirm current build config supports +# reqconfig, else skip building ourselves. +# +# If we are being built externally, confirm installed lws was configured to +# support reqconfig, else error out with a helpful message about the problem. +# +MACRO(require_lws_config reqconfig _val result) + + if (DEFINED ${reqconfig}) + if (${reqconfig}) + set (rq 1) + else() + set (rq 0) + endif() + else() + set(rq 0) + endif() + + if (${_val} EQUAL ${rq}) + set(SAME 1) + else() + set(SAME 0) + endif() + + if (LWS_WITH_MINIMAL_EXAMPLES AND NOT ${SAME}) + if (${_val}) + message("${SAMP}: skipping as lws being built without ${reqconfig}") + else() + message("${SAMP}: skipping as lws built with ${reqconfig}") + endif() + set(${result} 0) + else() + if (LWS_WITH_MINIMAL_EXAMPLES) + set(MET ${SAME}) + else() + CHECK_C_SOURCE_COMPILES("#include \nint main(void) {\n#if defined(${reqconfig})\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_${reqconfig}) + if (NOT DEFINED HAS_${reqconfig} OR NOT HAS_${reqconfig}) + set(HAS_${reqconfig} 0) + else() + set(HAS_${reqconfig} 1) + endif() + if ((HAS_${reqconfig} AND ${_val}) OR (NOT HAS_${reqconfig} AND NOT ${_val})) + set(MET 1) + else() + set(MET 0) + endif() + endif() + if (NOT MET) + if (${_val}) + message(FATAL_ERROR "This project requires lws must have been configured with ${reqconfig}") + else() + message(FATAL_ERROR "Lws configuration of ${reqconfig} is incompatible with this project") + endif() + endif() + endif() +ENDMACRO() + +set(requirements 1) +require_lws_config(LWS_WITHOUT_SERVER 0 requirements) + +if (requirements) + add_executable(${SAMP} ${SRCS}) + + if (websockets_shared) + target_link_libraries(${SAMP} websockets_shared) + add_dependencies(${SAMP} websockets_shared) + else() + target_link_libraries(${SAMP} websockets) + endif() +endif() diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/README.md b/minimal-examples/http-server/minimal-http-server-basicauth/README.md new file mode 100644 index 00000000..0b386132 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-basicauth/README.md @@ -0,0 +1,29 @@ +# lws minimal http server basic auth + +This demonstrates how to protect a mount using a password +file outside of the mount itself. + +The demo has two mounts, a normal one at / and one protected +by basic auth at /secret. + +The file at ./ba-passwords contains valid user:password +combinations. + +## build + +``` + $ cmake . && make +``` + +## usage + +``` + $ ./lws-minimal-http-server-basic-auth +[2018/04/19 08:40:05:1333] USER: LWS minimal http server basic auth | visit http://localhost:7681 +[2018/04/19 08:40:05:1333] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 off +``` + +Visit http://localhost:7681, and follow the link there to the secret area. + +Give your browser "user" and "password" as the credentials. + diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/ba-passwords b/minimal-examples/http-server/minimal-http-server-basicauth/ba-passwords new file mode 100644 index 00000000..28b9bb2a --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-basicauth/ba-passwords @@ -0,0 +1 @@ +user:password diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/minimal-http-server-basicauth.c b/minimal-examples/http-server/minimal-http-server-basicauth/minimal-http-server-basicauth.c new file mode 100644 index 00000000..843a48b6 --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-basicauth/minimal-http-server-basicauth.c @@ -0,0 +1,111 @@ +/* + * lws-minimal-http-server-basicauth + * + * Copyright (C) 2018 Andy Green + * + * This file is made available under the Creative Commons CC0 1.0 + * Universal Public Domain Dedication. + * + * This demonstrates a minimal http server with a second mount that + * is protected using a password file and basic auth. + * + * To keep it simple, it serves the static stuff from the subdirectory + * "./mount-origin" of the directory it was started in. + * + * You can change that by changing mount.origin below. + */ + +#include +#include +#include +#include + +static int interrupted; + +/* override the default mount for /secret in the URL space */ + +static const struct lws_http_mount mount_secret = { + /* .mount_next */ NULL, /* linked-list "next" */ + /* .mountpoint */ "/secret", /* mountpoint URL */ + /* .origin */ "./mount-secret-origin", + /* .def */ "index.html", + /* .protocol */ NULL, + /* .cgienv */ NULL, + /* .extra_mimetypes */ NULL, + /* .interpret */ NULL, + /* .cgi_timeout */ 0, + /* .cache_max_age */ 0, + /* .auth_mask */ 0, + /* .cache_reusable */ 0, + /* .cache_revalidate */ 0, + /* .cache_intermediaries */ 0, + /* .origin_protocol */ LWSMPRO_FILE, /* dynamic */ + /* .mountpoint_len */ 7, /* char count */ + /* .basic_auth_login_file */ "./ba-passwords", +}; + +/* default mount serves the URL space from ./mount-origin */ + +static const struct lws_http_mount mount = { + /* .mount_next */ &mount_secret, /* linked-list "next" */ + /* .mountpoint */ "/", /* mountpoint URL */ + /* .origin */ "./mount-origin", /* serve from dir */ + /* .def */ "index.html", /* default filename */ + /* .protocol */ NULL, + /* .cgienv */ NULL, + /* .extra_mimetypes */ NULL, + /* .interpret */ NULL, + /* .cgi_timeout */ 0, + /* .cache_max_age */ 0, + /* .auth_mask */ 0, + /* .cache_reusable */ 0, + /* .cache_revalidate */ 0, + /* .cache_intermediaries */ 0, + /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */ + /* .mountpoint_len */ 1, /* char count */ + /* .basic_auth_login_file */ NULL, +}; + +void sigint_handler(int sig) +{ + interrupted = 1; +} + +int main(int argc, const char **argv) +{ + struct lws_context_creation_info info; + struct lws_context *context; + const char *p; + int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE + /* for LLL_ verbosity above NOTICE to be built into lws, + * lws must have been configured and built with + * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */ + /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */ + /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */ + /* | LLL_DEBUG */; + + signal(SIGINT, sigint_handler); + + if ((p = lws_cmdline_option(argc, argv, "-d"))) + logs = atoi(p); + + lws_set_log_level(logs, NULL); + lwsl_user("LWS minimal http server basic auth | visit http://localhost:7681\n"); + + memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ + info.port = 7681; + info.mounts = &mount; + + context = lws_create_context(&info); + if (!context) { + lwsl_err("lws init failed\n"); + return 1; + } + + while (n >= 0 && !interrupted) + n = lws_service(context, 1000); + + lws_context_destroy(context); + + return 0; +} diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/404.html b/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/404.html new file mode 100644 index 00000000..1f7ae66e --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/404.html @@ -0,0 +1,9 @@ + + + +
+

404

+ Sorry, that file doesn't exist. + + + diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/favicon.ico b/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/favicon.ico new file mode 100644 index 00000000..c0cc2e3d Binary files /dev/null and b/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/favicon.ico differ diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/index.html b/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/index.html new file mode 100644 index 00000000..5813719e --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/index.html @@ -0,0 +1,22 @@ + + + +
+ + Hello from the minimal http server basic auth example. +

+ This is a static page served from ./mount-origin/index.html. +

+ Stuff down /secret in the URL space is protected by Basic Auth.
+ Your browser will ask for a username / password combination, and
+ lws will check it against ./ba-passwords, which contains a list of
+ "username:password" one per line.
+
+ The example content for ba-passwords is literally "user:password".
+ Click on the link into the protected area of the URL space below
+ and give your browser the credentials "user" and "password". +

+ /secret + + + diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/libwebsockets.org-logo.png b/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/libwebsockets.org-logo.png new file mode 100644 index 00000000..2060a10c Binary files /dev/null and b/minimal-examples/http-server/minimal-http-server-basicauth/mount-origin/libwebsockets.org-logo.png differ diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/mount-secret-origin/index.html b/minimal-examples/http-server/minimal-http-server-basicauth/mount-secret-origin/index.html new file mode 100644 index 00000000..ba2d3e6e --- /dev/null +++ b/minimal-examples/http-server/minimal-http-server-basicauth/mount-secret-origin/index.html @@ -0,0 +1,9 @@ + + + +
+ + This is the big secret protected by basic auth. + + + diff --git a/minimal-examples/http-server/minimal-http-server-basicauth/mount-secret-origin/libwebsockets.org-logo.png b/minimal-examples/http-server/minimal-http-server-basicauth/mount-secret-origin/libwebsockets.org-logo.png new file mode 100644 index 00000000..2060a10c Binary files /dev/null and b/minimal-examples/http-server/minimal-http-server-basicauth/mount-secret-origin/libwebsockets.org-logo.png differ