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