dovecot-2.2: lib-http: server: Added support for authentication.
dovecot at dovecot.org
dovecot at dovecot.org
Wed Sep 10 10:45:14 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/5ab0ab678497
changeset: 17772:5ab0ab678497
user: Stephan Bosch <stephan at rename-it.nl>
date: Wed Sep 10 13:39:37 2014 +0300
description:
lib-http: server: Added support for authentication.
diffstat:
src/lib-http/http-server-private.h | 1 +
src/lib-http/http-server-request.c | 59 +++++++++++++++++++++++++++++++++++-
src/lib-http/http-server-response.c | 30 ++++++++++++++++++-
src/lib-http/http-server.h | 26 ++++++++++++++++
4 files changed, 112 insertions(+), 4 deletions(-)
diffs (213 lines):
diff -r 2121057f994b -r 5ab0ab678497 src/lib-http/http-server-private.h
--- a/src/lib-http/http-server-private.h Wed Sep 10 13:39:37 2014 +0300
+++ b/src/lib-http/http-server-private.h Wed Sep 10 13:39:37 2014 +0300
@@ -47,6 +47,7 @@
string_t *headers;
time_t date;
+ ARRAY_TYPE(http_auth_challenge) auth_challenges;
struct istream *payload_input;
uoff_t payload_size, payload_offset;
diff -r 2121057f994b -r 5ab0ab678497 src/lib-http/http-server-request.c
--- a/src/lib-http/http-server-request.c Wed Sep 10 13:39:37 2014 +0300
+++ b/src/lib-http/http-server-request.c Wed Sep 10 13:39:37 2014 +0300
@@ -111,6 +111,22 @@
return req->response;
}
+int http_server_request_get_auth(struct http_server_request *req,
+ struct http_auth_credentials *credentials)
+{
+ const char *auth;
+
+ auth = http_request_header_get(&req->req, "Authorization");
+ if (auth == NULL)
+ return 0;
+
+ if (http_auth_parse_credentials
+ ((const unsigned char *)auth, strlen(auth), credentials) < 0)
+ return -1;
+
+ return 1;
+}
+
bool http_server_request_is_finished(struct http_server_request *req)
{
return req->response != NULL ||
@@ -197,9 +213,9 @@
http_server_connection_send_responses(conn);
}
-static void
-http_server_request_fail_full(struct http_server_request *req,
- unsigned int status, const char *reason, bool close)
+static struct http_server_response *
+http_server_request_create_fail_response(struct http_server_request *req,
+ unsigned int status, const char *reason)
{
struct http_server_response *resp;
@@ -211,6 +227,18 @@
reason = t_strconcat(reason, "\r\n", NULL);
http_server_response_set_payload_data
(resp, (const unsigned char *)reason, strlen(reason));
+
+ return resp;
+}
+
+static void
+http_server_request_fail_full(struct http_server_request *req,
+ unsigned int status, const char *reason, bool close)
+{
+ struct http_server_response *resp;
+
+ req->failed = TRUE;
+ resp = http_server_request_create_fail_response(req, status, reason);
if (close)
http_server_response_submit_close(resp);
else
@@ -229,3 +257,28 @@
{
http_server_request_fail_full(req, status, reason, TRUE);
}
+
+void http_server_request_fail_auth(struct http_server_request *req,
+ const char *reason, const struct http_auth_challenge *chlng)
+{
+ struct http_server_response *resp;
+
+ req->failed = TRUE;
+
+ if (reason == NULL)
+ reason = "Unauthenticated";
+
+ resp = http_server_request_create_fail_response(req, 401, reason);
+ http_server_response_add_auth(resp, chlng);
+ http_server_response_submit(resp);
+}
+
+void http_server_request_fail_auth_basic(struct http_server_request *req,
+ const char *reason, const char *realm)
+{
+ struct http_auth_challenge chlng;
+
+ http_auth_basic_challenge_init(&chlng, realm);
+ http_server_request_fail_auth(req, reason, &chlng);
+}
+
diff -r 2121057f994b -r 5ab0ab678497 src/lib-http/http-server-response.c
--- a/src/lib-http/http-server-response.c Wed Sep 10 13:39:37 2014 +0300
+++ b/src/lib-http/http-server-response.c Wed Sep 10 13:39:37 2014 +0300
@@ -2,6 +2,7 @@
#include "lib.h"
#include "str.h"
+#include "array.h"
#include "istream.h"
#include "ostream.h"
#include "http-date.h"
@@ -137,6 +138,29 @@
i_stream_unref(&input);
}
+void http_server_response_add_auth(
+ struct http_server_response *resp,
+ const struct http_auth_challenge *chlng)
+{
+ struct http_auth_challenge *new;
+ pool_t pool = resp->request->pool;
+
+ if (!array_is_created(&resp->auth_challenges))
+ p_array_init(&resp->auth_challenges, pool, 4);
+
+ new = array_append_space(&resp->auth_challenges);
+ http_auth_challenge_copy(pool, new, chlng);
+}
+
+void http_server_response_add_auth_basic(
+ struct http_server_response *resp, const char *realm)
+{
+ struct http_auth_challenge chlng;
+
+ http_auth_basic_challenge_init(&chlng, realm);
+ http_server_response_add_auth(resp, &chlng);
+}
+
static void http_server_response_do_submit(struct http_server_response *resp,
bool close)
{
@@ -284,6 +308,11 @@
str_append(rtext, http_date_create(resp->date));
str_append(rtext, "\r\n");
}
+ if (array_is_created(&resp->auth_challenges)) {
+ str_append(rtext, "WWW-Authenticate: ");
+ http_auth_create_challenges(rtext, &resp->auth_challenges);
+ str_append(rtext, "\r\n");
+ }
if (resp->payload_chunked) {
if (http_server_request_version_equals(req, 1, 0)) {
/* cannot use Transfer-Encoding */
@@ -382,4 +411,3 @@
} T_END;
return ret;
}
-
diff -r 2121057f994b -r 5ab0ab678497 src/lib-http/http-server.h
--- a/src/lib-http/http-server.h Wed Sep 10 13:39:37 2014 +0300
+++ b/src/lib-http/http-server.h Wed Sep 10 13:39:37 2014 +0300
@@ -1,6 +1,7 @@
#ifndef HTTP_SERVER_H
#define HTTP_SERVER_H
+#include "http-auth.h"
#include "http-request.h"
struct istream;
@@ -90,6 +91,12 @@
or because the request was aborted. */
bool http_server_request_is_finished(struct http_server_request *req);
+/* Get the authentication credentials provided in this request. Returns 0 if
+ the Authorization header is absent, returns -1 when that header cannot be
+ parsed, and returns 1 otherwise */
+int http_server_request_get_auth(struct http_server_request *req,
+ struct http_auth_credentials *credentials);
+
/* Send a failure response to the request with given status/reason. */
void http_server_request_fail(struct http_server_request *req,
unsigned int status, const char *reason);
@@ -97,6 +104,18 @@
and close the connection. */
void http_server_request_fail_close(struct http_server_request *req,
unsigned int status, const char *reason);
+/* Send an authentication failure response to the request with given reason.
+ The provided challenge is set in the WWW-Authenticate header of the
+ response. */
+void http_server_request_fail_auth(struct http_server_request *req,
+ const char *reason, const struct http_auth_challenge *chlng)
+ ATTR_NULL(2);
+/* Send a authentication failure response to the request with given reason.
+ The provided realm is used to construct an Basic challenge in the
+ WWW-Authenticate header of the response. */
+void http_server_request_fail_auth_basic(struct http_server_request *req,
+ const char *reason, const char *realm)
+ ATTR_NULL(2);
/* Call the specified callback when HTTP request is destroyed. This happens
after one of the following:
@@ -131,6 +150,13 @@
struct istream *input);
void http_server_response_set_payload_data(struct http_server_response *resp,
const unsigned char *data, size_t size);
+
+void http_server_response_add_auth(
+ struct http_server_response *resp,
+ const struct http_auth_challenge *chlng);
+void http_server_response_add_auth_basic(
+ struct http_server_response *resp, const char *realm);
+
void http_server_response_submit(struct http_server_response *resp);
/* Submit response and close the connection. */
void http_server_response_submit_close(struct http_server_response *resp);
More information about the dovecot-cvs
mailing list