sample: net: http: Add Basic auth support to server sample

Basic auth support was missing from HTTP server sample.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2017-05-18 12:32:05 +03:00
commit 11aee50eef
3 changed files with 99 additions and 1 deletions

View file

@ -217,6 +217,27 @@ and this is the HTML message that wget will save:
<body><h1><center>404 Not Found</center></h1></body>
</html>
To test the HTTP Basic Authentication functionality, use the
following command:
.. code-block:: console
wget 192.168.1.120/auth -O index.html --user=zephyr --password=0123456789
the :file:`index.html` file will contain the following information:
.. code-block:: html
<html>
<head>
<title>Zephyr HTTP Server</title>
</head>
<body>
<h1><center>Zephyr HTTP server</center></h1>
<h2><center>user: zephyr, password: 0123456789</center></h2>
</body>
</html>
HTTPS Server
============
@ -274,4 +295,3 @@ Known Issues and Limitations
- Currently, this sample application only generates HTTP responses in
chunk transfer mode.
- Basic authentication is not yet implemented.

View file

@ -30,4 +30,12 @@
#define ZEPHYR_PORT 8080
#endif
#define HTTP_AUTH_URL "/auth"
#define HTTP_AUTH_TYPE "Basic"
/* HTTP Basic Auth, see https://tools.ietf.org/html/rfc7617 */
#define HTTP_AUTH_REALM "Zephyr"
#define HTTP_AUTH_USERNAME "zephyr"
#define HTTP_AUTH_PASSWORD "0123456789"
#endif

View file

@ -17,6 +17,11 @@
#include <zephyr.h>
#include <stdio.h>
/* For Basic auth, we need base64 decoder which can be found
* in mbedtls library.
*/
#include <mbedtls/base64.h>
#include <net/net_context.h>
#include <net/http.h>
@ -77,6 +82,10 @@ void panic(const char *msg)
"Transfer-Encoding: chunked\r\n" \
"\r\n"
#define HTTP_401_STATUS_US "HTTP/1.1 401 Unauthorized status\r\n" \
"WWW-Authenticate: Basic realm=" \
"\""HTTP_AUTH_REALM"\"\r\n\r\n"
#define HTML_HEADER "<html><head>" \
"<title>Zephyr HTTP Server</title>" \
"</head><body><h1>" \
@ -167,6 +176,65 @@ static int http_response_soft_404(struct http_server_ctx *ctx)
HTML_FOOTER);
}
static int http_response_auth(struct http_server_ctx *ctx)
{
return http_response(ctx, HTTP_STATUS_200_OK, HTML_HEADER
"<h2><center>user: "HTTP_AUTH_USERNAME
", password: "HTTP_AUTH_PASSWORD
"</center></h2>" HTML_FOOTER);
}
int http_response_401(struct http_server_ctx *ctx, s32_t timeout)
{
return http_response_wait(ctx, HTTP_401_STATUS_US, NULL, timeout);
}
static int http_basic_auth(struct http_server_ctx *ctx)
{
const char auth_str[] = HTTP_CRLF "Authorization: Basic ";
char *ptr;
ptr = strstr(ctx->req.field_values[0].key, auth_str);
if (ptr) {
char output[sizeof(HTTP_AUTH_USERNAME) +
sizeof(":") +
sizeof(HTTP_AUTH_PASSWORD)];
size_t olen, ilen, alen;
char *end, *colon;
int ret;
memset(output, 0, sizeof(output));
end = strstr(ptr + 2, HTTP_CRLF);
if (!end) {
return http_response_401(ctx, K_NO_WAIT);
}
alen = sizeof(auth_str) - 1;
ilen = end - (ptr + alen);
ret = mbedtls_base64_decode(output, sizeof(output) - 1,
&olen, ptr + alen, ilen);
if (ret) {
return http_response_401(ctx, K_NO_WAIT);
}
colon = memchr(output, ':', olen);
if (colon && colon > output && colon < (output + olen) &&
memcmp(output, HTTP_AUTH_USERNAME, colon - output) == 0 &&
memcmp(colon + 1, HTTP_AUTH_PASSWORD,
output + olen - colon) == 0) {
return http_response_auth(ctx);
}
return http_response_401(ctx, K_NO_WAIT);
}
/* Wait 2 secs for the reply with proper credentials */
return http_response_401(ctx, K_SECONDS(2));
}
#if defined(CONFIG_HTTPS)
/* Load the certificates and private RSA key. */
@ -271,6 +339,8 @@ void main(void)
#endif
http_server_add_default(&http_urls, http_response_soft_404);
http_server_add_url(&http_urls, HTTP_AUTH_URL, HTTP_URL_STANDARD,
http_basic_auth);
http_server_add_url(&http_urls, "/headers", HTTP_URL_STANDARD,
http_response_header_fields);
http_server_add_url(&http_urls, "/index.html", HTTP_URL_STANDARD,