From 5965554dbb41504b250c14f78c8b464ec5c2b9e7 Mon Sep 17 00:00:00 2001 From: Karl Heyes Date: Tue, 29 Nov 2005 03:06:03 +0000 Subject: [PATCH] update for authentication header via libcurl. allows for http://user:pass@host.. else the param specified user/pass. In the case of listener_add/remove use the client provided user/pass if no others are specified. svn path=/icecast/trunk/icecast/; revision=10498 --- src/auth_url.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/src/auth_url.c b/src/auth_url.c index 6a81c429..c592485c 100644 --- a/src/auth_url.c +++ b/src/auth_url.c @@ -86,6 +86,7 @@ typedef struct { int auth_header_len; char *timelimit_header; int timelimit_header_len; + char *userpwd; CURL *handle; char errormsg [CURL_ERROR_SIZE]; } auth_url; @@ -106,10 +107,19 @@ static void auth_url_clear(auth_t *self) free (url->stream_end); free (url->auth_header); free (url->timelimit_header); + free (url->userpwd); free (url); } +/* make sure that prompting at the console does not occur */ +static int my_getpass(void *client, char *prompt, char *buffer, int buflen) +{ + buffer[0] = '\0'; + return 0; +} + + static int handle_returned_header (void *ptr, size_t size, size_t nmemb, void *stream) { auth_client *auth_user = stream; @@ -159,8 +169,10 @@ static auth_result url_remove_client (auth_client *auth_user) char *username, *password, *mount, *server; ice_config_t *config; int port; - char post [4096]; + char *userpwd = NULL, post [4096]; + if (url->removeurl == NULL) + return AUTH_OK; config = config_get_config (); server = util_url_escape (config->hostname); port = config->port; @@ -192,6 +204,29 @@ static auth_result url_remove_client (auth_client *auth_user) free (username); free (password); + if (strchr (url->removeurl, '@') == NULL) + { + if (url->userpwd) + curl_easy_setopt (url->handle, CURLOPT_USERPWD, url->userpwd); + else + { + /* auth'd requests may not have a user/pass, but may use query args */ + if (client->username && client->password) + { + int len = strlen (client->username) + strlen (client->password) + 2; + userpwd = malloc (len); + snprintf (userpwd, len, "%s:%s", client->username, client->password); + curl_easy_setopt (url->handle, CURLOPT_USERPWD, userpwd); + } + else + curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); + } + } + else + { + /* url has user/pass but libcurl may need to clear any existing settings */ + curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); + } curl_easy_setopt (url->handle, CURLOPT_URL, url->removeurl); curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post); curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user); @@ -199,6 +234,8 @@ static auth_result url_remove_client (auth_client *auth_user) if (curl_easy_perform (url->handle)) WARN2 ("auth to server %s failed with %s", url->removeurl, url->errormsg); + free (userpwd); + return AUTH_OK; } @@ -212,7 +249,7 @@ static auth_result url_add_client (auth_client *auth_user) char *agent, *user_agent, *username, *password; char *mount, *ipaddr, *server; ice_config_t *config; - char post [4096]; + char *userpwd = NULL, post [4096]; if (url->addurl == NULL) return AUTH_OK; @@ -253,6 +290,29 @@ static auth_result url_add_client (auth_client *auth_user) free (password); free (ipaddr); + if (strchr (url->addurl, '@') == NULL) + { + if (url->userpwd) + curl_easy_setopt (url->handle, CURLOPT_USERPWD, url->userpwd); + else + { + /* auth'd requests may not have a user/pass, but may use query args */ + if (client->username && client->password) + { + int len = strlen (client->username) + strlen (client->password) + 2; + userpwd = malloc (len); + snprintf (userpwd, len, "%s:%s", client->username, client->password); + curl_easy_setopt (url->handle, CURLOPT_USERPWD, userpwd); + } + else + curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); + } + } + else + { + /* url has user/pass but libcurl may need to clear any existing settings */ + curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); + } curl_easy_setopt (url->handle, CURLOPT_URL, url->addurl); curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post); curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user); @@ -260,6 +320,8 @@ static auth_result url_add_client (auth_client *auth_user) res = curl_easy_perform (url->handle); + free (userpwd); + if (res) { WARN2 ("auth to server %s failed with %s", url->addurl, url->errormsg); @@ -306,6 +368,15 @@ static void url_stream_start (auth_client *auth_user) free (server); free (mount); + if (strchr (url->stream_start, '@') == NULL) + { + if (url->userpwd) + curl_easy_setopt (url->handle, CURLOPT_USERPWD, url->userpwd); + else + curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); + } + else + curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); curl_easy_setopt (url->handle, CURLOPT_URL, stream_start_url); curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post); curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user); @@ -349,7 +420,16 @@ static void url_stream_end (auth_client *auth_user) free (server); free (mount); - curl_easy_setopt (url->handle, CURLOPT_URL, stream_end_url); + if (strchr (url->stream_end, '@') == NULL) + { + if (url->userpwd) + curl_easy_setopt (url->handle, CURLOPT_USERPWD, url->userpwd); + else + curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); + } + else + curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); + curl_easy_setopt (url->handle, CURLOPT_URL, url->stream_end); curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post); curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user); @@ -438,8 +518,16 @@ int auth_get_url_auth (auth_t *authenticator, config_options_t *options) curl_easy_setopt (url_info->handle, CURLOPT_WRITEDATA, url_info->handle); curl_easy_setopt (url_info->handle, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt (url_info->handle, CURLOPT_TIMEOUT, 15L); + curl_easy_setopt (url_info->handle, CURLOPT_PASSWDFUNCTION, my_getpass); curl_easy_setopt (url_info->handle, CURLOPT_ERRORBUFFER, &url_info->errormsg[0]); + if (url_info->username && url_info->password) + { + int len = strlen (url_info->username) + strlen (url_info->password) + 2; + url_info->userpwd = malloc (len); + snprintf (url_info->userpwd, len, "%s:%s", url_info->username, url_info->password); + } + authenticator->state = url_info; INFO0("URL based authentication setup"); return 0;