From 7c072503be1da7568c62e89d13708cff1972a591 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 18:11:05 -0700 Subject: [PATCH 1/3] Some experimental commands to use auth when downloading from HTTP sources --- src/d_clisrv.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/d_netfil.c | 33 ++++++++++++++++++++++ src/d_netfil.h | 11 ++++++++ 3 files changed, 118 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 652ffbcb..66477bbe 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3200,6 +3200,76 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) } } +#ifdef HAVE_CURL +/** Add a login for HTTP downloads. If the + * user/password is missing, remove it. + * + * \sa Command_list_http_logins + */ +static void Command_set_http_login (void) +{ + HTTP_login *login; + HTTP_login **prev_next; + + if (COM_Argc() < 2) + { + CONS_Printf( + "set_http_login [user:password]: Set or remove a login to " + "authenticate HTTP downloads.\n" + ); + return; + } + + login = CURLGetLogin(COM_Argv(1), &prev_next); + + if (COM_Argc() == 2) + { + if (login) + { + (*prev_next) = login->next; + CONS_Printf("Login for '%s' removed.\n", login->url); + Z_Free(login); + } + } + else + { + if (login) + Z_Free(login->auth); + else + { + login = ZZ_Alloc(sizeof *login); + login->url = Z_StrDup(COM_Argv(1)); + } + + login->auth = Z_StrDup(COM_Argv(2)); + + login->next = curl_logins; + curl_logins = login; + } +} + +/** List logins for HTTP downloads. + * + * \sa Command_set_http_login + */ +static void Command_list_http_logins (void) +{ + HTTP_login *login; + + for ( + login = curl_logins; + login; + login = login->next + ){ + CONS_Printf( + "'%s' -> '%s'\n", + login->url, + login->auth + ); + } +} +#endif/*HAVE_CURL*/ + static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}}; consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3241,6 +3311,10 @@ void D_ClientServerInit(void) COM_AddCommand("reloadbans", Command_ReloadBan); COM_AddCommand("connect", Command_connect); COM_AddCommand("nodes", Command_Nodes); +#ifdef HAVE_CURL + COM_AddCommand("set_http_login", Command_set_http_login); + COM_AddCommand("list_http_logins", Command_list_http_logins); +#endif #ifdef PACKETDROP COM_AddCommand("drop", Command_Drop); COM_AddCommand("droprate", Command_Droprate); diff --git a/src/d_netfil.c b/src/d_netfil.c index 3dc9da68..006f775b 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1062,6 +1062,9 @@ int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ul void CURLPrepareFile(const char* url, int dfilenum) { + HTTP_login *login; + char *final_url; + #ifdef PARANOIA if (M_CheckParm("-nodownload")) I_Error("Attempted to download files in -nodownload mode"); @@ -1090,6 +1093,13 @@ void CURLPrepareFile(const char* url, int dfilenum) curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. + // Authenticate if the user so wishes + curl_easy_getinfo(http_handle, CURLINFO_EFFECTIVE_URL, &final_url); + login = CURLGetLogin(final_url, NULL); + + if (login) + curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + // Follow a redirect request, if sent by the server. curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L); @@ -1189,4 +1199,27 @@ void CURLGetFile(void) curl_global_cleanup(); } } + +HTTP_login * +CURLGetLogin (const char *url, HTTP_login ***return_prev_next) +{ + HTTP_login * login; + HTTP_login ** prev_next; + + for ( + prev_next = &curl_logins; + ( login = (*prev_next)); + prev_next = &login->next + ){ + if (strcmp(login->url, url) == 0) + { + if (return_prev_next) + (*return_prev_next) = prev_next; + + return login; + } + } + + return NULL; +} #endif diff --git a/src/d_netfil.h b/src/d_netfil.h index f37df371..ef414b88 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -58,6 +58,16 @@ extern INT32 lastfilenum; extern boolean curl_failedwebdownload; extern boolean curl_running; extern INT32 curl_transfers; + +typedef struct HTTP_login HTTP_login; + +struct HTTP_login +{ + char * url; + char * auth; + HTTP_login * next; +} +*curl_logins; #endif UINT8 *PutFileNeeded(UINT16 firstfile); @@ -93,6 +103,7 @@ size_t nameonlylength(const char *s); #ifdef HAVE_CURL void CURLPrepareFile(const char* url, int dfilenum); void CURLGetFile(void); +HTTP_login * CURLGetLogin (const char *url, HTTP_login ***return_prev_next); #endif #endif // __D_NETFIL__ From 64e27f369845d2cc60dd501df02b7f48036df6dd Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 15 May 2020 19:04:03 -0700 Subject: [PATCH 2/3] I forgot extern, now I am the clown --- src/d_netfil.c | 1 + src/d_netfil.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 006f775b..446f3814 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -124,6 +124,7 @@ static UINT32 curl_origfilesize; static UINT32 curl_origtotalfilesize; static char *curl_realname = NULL; fileneeded_t *curl_curfile = NULL; +HTTP_login *curl_logins; #endif /** Fills a serverinfo packet with information about wad files loaded. diff --git a/src/d_netfil.h b/src/d_netfil.h index ef414b88..913a2119 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -61,7 +61,7 @@ extern INT32 curl_transfers; typedef struct HTTP_login HTTP_login; -struct HTTP_login +extern struct HTTP_login { char * url; char * auth; From 2d4202ac09dcd29f5794fee49d7732ff12742620 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 16 May 2020 21:03:37 -0700 Subject: [PATCH 3/3] Whoops I used the url to the file instead of the http_source --- src/d_netfil.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netfil.c b/src/d_netfil.c index 446f3814..d2a6fe55 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -1064,7 +1064,6 @@ int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ul void CURLPrepareFile(const char* url, int dfilenum) { HTTP_login *login; - char *final_url; #ifdef PARANOIA if (M_CheckParm("-nodownload")) @@ -1095,11 +1094,12 @@ void CURLPrepareFile(const char* url, int dfilenum) curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents. // Authenticate if the user so wishes - curl_easy_getinfo(http_handle, CURLINFO_EFFECTIVE_URL, &final_url); - login = CURLGetLogin(final_url, NULL); + login = CURLGetLogin(url, NULL); if (login) + { curl_easy_setopt(http_handle, CURLOPT_USERPWD, login->auth); + } // Follow a redirect request, if sent by the server. curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L);