From ce6ebaef9712ef2f5d4cd6a717f13906f70364b7 Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Thu, 23 Apr 2009 20:36:35 +0000 Subject: Support HTTP digest authentication for the http manager interface. (closes issue #10961) Reported by: ys Patches: digest_auth_r148468_v5.diff uploaded by ys (license 281) SVN branch http://svn.digium.com/svn/asterisk/team/group/manager_http_auth Tested by: ys, twilson, tilghman Review: http://reviewboard.digium.com/r/223/ Reviewed by: tilghman,russellb,mmichelson git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190349 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/http.h | 117 +++++++++++++++++++++++++++++++++++++---------- include/asterisk/utils.h | 30 +++++++++++- 2 files changed, 123 insertions(+), 24 deletions(-) (limited to 'include/asterisk') diff --git a/include/asterisk/http.h b/include/asterisk/http.h index 25de13352..688febfeb 100644 --- a/include/asterisk/http.h +++ b/include/asterisk/http.h @@ -52,27 +52,40 @@ * be run earlier in the startup process so modules have it available. */ - -/*! \brief HTTP Callbacks take the socket - - \note The method and the path as arguments and should - return the content, allocated with malloc(). Status should be changed to reflect - the status of the request if it isn't 200 and title may be set to a malloc()'d string - to an appropriate title for non-200 responses. Content length may also be specified. -\verbatim - The return value may include additional headers at the front and MUST include a blank - line with \r\n to provide separation between user headers and content (even if no - content is specified) -\endverbatim -*/ - +/*! \brief HTTP Request methods known by Asterisk */ enum ast_http_method { + AST_HTTP_UNKNOWN = -1, /*!< Unknown response */ AST_HTTP_GET = 0, AST_HTTP_POST, + AST_HTTP_HEAD, + AST_HTTP_PUT, /*!< Not supported in Asterisk */ }; + struct ast_http_uri; -typedef struct ast_str *(*ast_http_callback)(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *params, struct ast_variable *headers, int *status, char **title, int *contentlength); +/*! \brief HTTP Callbacks + * + * \note The callback function receives server instance, uri, http method, + * get method (if present in URI), and http headers as arguments and should + * use the ast_http_send() function for sending content allocated with ast_str + * and/or content from an opened file descriptor. + * + * Status and status text should be sent as arguments to the ast_http_send() + * function to reflect the status of the request (200 or 304, for example). + * Content length is calculated by ast_http_send() automatically. + * + * Static content may be indicated to the ast_http_send() function, to indicate + * that it may be cached. + * + * \verbatim + * The return value may include additional headers at the front and MUST + * include a blank line with \r\n to provide separation between user headers + * and content (even if no content is specified) + * \endverbatim + * + * For an error response, the ast_http_error() function may be used. +*/ +typedef int (*ast_http_callback)(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers); /*! \brief Definition of a URI handler */ struct ast_http_uri { @@ -81,12 +94,6 @@ struct ast_http_uri { const char *uri; ast_http_callback callback; unsigned int has_subtree:1; - /*! This handler serves static content */ - unsigned int static_content:1; - /*! This handler accepts GET requests */ - unsigned int supports_get:1; - /*! This handler accepts POST requests */ - unsigned int supports_post:1; /*! Structure is malloc'd */ unsigned int mallocd:1; /*! Data structure is malloc'd */ @@ -97,6 +104,9 @@ struct ast_http_uri { const char *key; }; +/*! \brief Get cookie from Request headers */ +struct ast_variable *ast_http_get_cookies(struct ast_variable *headers); + /*! \brief Register a URI handler */ int ast_http_uri_link(struct ast_http_uri *urihandler); @@ -106,8 +116,58 @@ void ast_http_uri_unlink(struct ast_http_uri *urihandler); /*! \brief Unregister all handlers with matching key */ void ast_http_uri_unlink_all_with_key(const char *key); -/*! \brief Return an ast_str malloc()'d string containing an HTTP error message */ -struct ast_str *ast_http_error(int status, const char *title, const char *extra_header, const char *text); +/*!\brief Return http method name string + * \since 1.6.3 + */ +const char *ast_get_http_method(enum ast_http_method method) attribute_pure; + +/*!\brief Return mime type based on extension + * \param ftype filename extension + * \return String containing associated MIME type + * \since 1.6.3 + */ +const char *ast_http_ftype2mtype(const char *ftype) attribute_pure; + +/*!\brief Return manager id, if exist, from request headers + * \param headers List of HTTP headers + * \return 32-bit associated manager session identifier + * \since 1.6.3 + */ +uint32_t ast_http_manid_from_vars(struct ast_variable *headers) attribute_pure; + +/*! \brief Generic function for sending http/1.1 response. + * \param ser TCP/TLS session object + * \param method GET/POST/HEAD + * \param status_code HTTP response code (200/401/403/404/500) + * \param status_title English equivalent to the status_code parameter + * \param http_header An ast_str object containing all headers + * \param out An ast_str object containing the body of the response + * \param fd If out is NULL, a file descriptor where the body of the response is held (otherwise -1) + * \param static_content Zero if the content is dynamically generated and should not be cached; nonzero otherwise + * + * \note Function determines the HTTP response header from status_code, + * status_header, and http_header. + * + * Extra HTTP headers MUST be present only in the http_header argument. The + * argument "out" should contain only content of the response (no headers!). + * + * HTTP content can be constructed from the argument "out", if it is not NULL; + * otherwise, the function will read content from FD. + * + * This function calculates the content-length http header itself. + * + * Both the http_header and out arguments will be freed by this function; + * however, if FD is open, it will remain open. + * + * \since 1.6.3 + */ +void ast_http_send(struct ast_tcptls_session_instance *ser, enum ast_http_method method, int status_code, const char *status_title, struct ast_str *http_header, struct ast_str *out, const int fd, unsigned int static_content); + +/*!\brief Send http "401 Unauthorized" response and close socket */ +void ast_http_auth(struct ast_tcptls_session_instance *ser, const char *realm, const unsigned long nonce, const unsigned long opaque, int stale, const char *text); + +/*!\brief Send HTTP error message and close socket */ +void ast_http_error(struct ast_tcptls_session_instance *ser, int status, const char *title, const char *text); /*! * \brief Return the current prefix @@ -117,4 +177,15 @@ struct ast_str *ast_http_error(int status, const char *title, const char *extra_ */ void ast_http_prefix(char *buf, int len); + +/*!\brief Get post variables from client Request Entity-Body, if content type is application/x-www-form-urlencoded. + * \param ser TCP/TLS session object + * \param headers List of HTTP headers + * \return List of variables within the POST body + * \note Since returned list is malloc'd, list should be free'd by the calling function + * \since 1.6.3 + */ +struct ast_variable *ast_http_get_post_vars(struct ast_tcptls_session_instance *ser, struct ast_variable *headers); + + #endif /* _ASTERISK_SRV_H */ diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index cb150ae4e..aac5a4651 100644 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -32,8 +32,9 @@ #include "asterisk/time.h" #include "asterisk/logger.h" #include "asterisk/localtime.h" +#include "asterisk/stringfields.h" -/*! +/*! \note \verbatim Note: It is very important to use only unsigned variables to hold @@ -646,6 +647,33 @@ int ast_mkdir(const char *path, int mode); #define ARRAY_LEN(a) (sizeof(a) / sizeof(0[a])) + +/* Definition for Digest authorization */ +struct ast_http_digest { + AST_DECLARE_STRING_FIELDS( + AST_STRING_FIELD(username); + AST_STRING_FIELD(nonce); + AST_STRING_FIELD(uri); + AST_STRING_FIELD(realm); + AST_STRING_FIELD(domain); + AST_STRING_FIELD(response); + AST_STRING_FIELD(cnonce); + AST_STRING_FIELD(opaque); + AST_STRING_FIELD(nc); + ); + int qop; /* Flag set to 1, if we send/recv qop="quth" */ +}; + +/*! + *\brief Parse digest authorization header. + *\return Returns -1 if we have no auth or something wrong with digest. + *\note This function may be used for Digest request and responce header. + * request arg is set to nonzero, if we parse Digest Request. + * pedantic arg can be set to nonzero if we need to do addition Digest check. + */ +int ast_parse_digest(const char *digest, struct ast_http_digest *d, int request, int pedantic); + + #ifdef AST_DEVMODE #define ast_assert(a) _ast_assert(a, # a, __FILE__, __LINE__, __PRETTY_FUNCTION__) static void force_inline _ast_assert(int condition, const char *condition_str, -- cgit v1.2.3