tFunctional HTTP authentication for GTK+ client - vaccinewars - be a doctor and… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 04aa8fc36d982da2256c181c63a833ca0cd5c52a | |
parent 88feb29ac0e7cbce3c3f4f1a9aaaaa84fb1e1d7f | |
Author: Ben Webb <[email protected]> | |
Date: Fri, 5 Oct 2001 17:03:34 +0000 | |
Functional HTTP authentication for GTK+ client | |
Diffstat: | |
M src/network.c | 75 +++++++++++++++++++++++++++--… | |
M src/network.h | 3 +++ | |
2 files changed, 69 insertions(+), 9 deletions(-) | |
--- | |
diff --git a/src/network.c b/src/network.c | |
t@@ -435,10 +435,12 @@ gboolean WriteDataToWire(NetworkBuffer *NetBuf) { | |
static void SendHttpRequest(HttpConnection *conn) { | |
GString *text; | |
+ char *userpasswd; | |
conn->Tries++; | |
conn->StatusCode=0; | |
conn->Status=HS_CONNECTING; | |
+ conn->authsupplied=FALSE; | |
text=g_string_new(""); | |
t@@ -448,6 +450,14 @@ static void SendHttpRequest(HttpConnection *conn) { | |
if (conn->Headers) QueueMessageForSend(&conn->NetBuf,conn->Headers); | |
+ if (conn->user && conn->password) { | |
+ userpasswd = g_strdup_printf("%s:%s",conn->user,conn->password); | |
+ g_string_assign(text,"Authorization: Basic "); | |
+ AddB64Enc(text,userpasswd); | |
+ g_free(userpasswd); | |
+ QueueMessageForSend(&conn->NetBuf,text->str); | |
+ } | |
+ | |
g_string_sprintf(text,"User-Agent: dopewars/%s",VERSION); | |
QueueMessageForSend(&conn->NetBuf,text->str); | |
t@@ -592,7 +602,7 @@ static void ParseHtmlHeader(gchar *line,HttpConnection *co… | |
} else if (g_strcasecmp(split[0],"WWW-Authenticate:")==0 && | |
conn->StatusCode==401) { | |
g_print("FIXME: Authentication %s required\n",split[1]); | |
- if (conn->authfunc) (*conn->authfunc)(conn,split[1]); | |
+ if (conn->authfunc) conn->authsupplied=(*conn->authfunc)(conn,split[1]); | |
} | |
} | |
g_strfreev(split); | |
t@@ -628,22 +638,31 @@ gchar *ReadHttpResponse(HttpConnection *conn) { | |
gboolean HandleHttpCompletion(HttpConnection *conn) { | |
NBCallBack CallBack; | |
gpointer CallBackData; | |
+ gboolean retry=FALSE; | |
+ | |
+ if (conn->Tries>=5) { | |
+ g_print("FIXME: Number of tries exceeded\n"); | |
+ return TRUE; | |
+ } | |
+ | |
if (conn->RedirHost) { | |
g_print("Following redirect to %s\n",conn->RedirHost); | |
- CallBack=conn->NetBuf.CallBack; | |
- CallBackData=conn->NetBuf.CallBackData; | |
- ShutdownNetworkBuffer(&conn->NetBuf); | |
g_free(conn->HostName); g_free(conn->Query); | |
conn->HostName = conn->RedirHost; | |
conn->Query = conn->RedirQuery; | |
conn->Port = conn->RedirPort; | |
conn->RedirHost = conn->RedirQuery = NULL; | |
+ retry = TRUE; | |
+ } | |
+ if (conn->authsupplied && conn->user && conn->password) { | |
+ g_print("Trying again with authentication\n"); | |
+ retry = TRUE; | |
+ } | |
- if (conn->Tries>=5) { | |
- g_print("FIXME: Number of tries exceeded\n"); | |
- return TRUE; | |
- } | |
- | |
+ if (retry) { | |
+ CallBack=conn->NetBuf.CallBack; | |
+ CallBackData=conn->NetBuf.CallBackData; | |
+ ShutdownNetworkBuffer(&conn->NetBuf); | |
if (StartHttpConnect(conn)) { | |
SendHttpRequest(conn); | |
SetNetworkBufferCallBack(&conn->NetBuf,CallBack,CallBackData); | |
t@@ -729,4 +748,42 @@ gboolean FinishConnect(int fd,LastError *error) { | |
#endif /* CYGWIN */ | |
} | |
+static void AddB64char(GString *str,int c) { | |
+ if (c<0) return; | |
+ else if (c<26) g_string_append_c(str,c+'A'); | |
+ else if (c<52) g_string_append_c(str,c-26+'a'); | |
+ else if (c<62) g_string_append_c(str,c-52+'0'); | |
+ else if (c==62) g_string_append_c(str,'+'); | |
+ else g_string_append_c(str,'/'); | |
+} | |
+ | |
+void AddB64Enc(GString *str,gchar *unenc) { | |
+/* Adds the plain text string "unenc" to the end of the GString "str", */ | |
+/* using the Base64 encoding scheme. */ | |
+ guint i; | |
+ long value=0; | |
+ if (!unenc || !str) return; | |
+ for (i=0;i<strlen(unenc);i++) { | |
+ value <<= 8; | |
+ value |= (unsigned char)unenc[i]; | |
+ if (i % 3 == 2) { | |
+ AddB64char(str,(value>>18)&0x3F); | |
+ AddB64char(str,(value>>12)&0x3F); | |
+ AddB64char(str,(value>>6)&0x3F); | |
+ AddB64char(str,value&0x3F); | |
+ value=0; | |
+ } | |
+ } | |
+ if (i % 3 == 1) { | |
+ AddB64char(str,(value>>2)&0x3F); | |
+ AddB64char(str,(value<<4)&0x3F); | |
+ g_string_append(str,"=="); | |
+ } else if (i % 3 == 2) { | |
+ AddB64char(str,(value>>10)&0x3F); | |
+ AddB64char(str,(value>>4)&0x3F); | |
+ AddB64char(str,(value<<2)&0x3F); | |
+ g_string_append_c(str,'='); | |
+ } | |
+} | |
+ | |
#endif /* NETWORKING */ | |
diff --git a/src/network.h b/src/network.h | |
t@@ -104,6 +104,7 @@ struct _HttpConnection { | |
unsigned RedirPort; /* The port on the host to redirect to */ | |
HCAuthFunc authfunc; /* Callback function for authentication */ | |
gboolean proxyauth; /* TRUE if the authentication is with a proxy */ | |
+ gboolean authsupplied; /* TRUE if the request should be retried with auth */ | |
gchar *realm; /* The realm for basic HTTP authentication */ | |
gchar *user; /* The supplied username */ | |
gchar *password; /* The supplied password */ | |
t@@ -160,6 +161,8 @@ void SetReuse(int sock); | |
void SetBlocking(int sock,gboolean blocking); | |
#endif | |
+void AddB64Enc(GString *str,gchar *unenc); | |
+ | |
#endif /* NETWORKING */ | |
#endif /* __NETWORK_H__ */ |