tHTTP authentication tidied up; better error reporting for socket() and bind() … | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 62523aa3d60bd5a9ea19f35c4af2f8ce36b03f9d | |
parent d575d43a2095a190ad01076332009a6b08071aa7 | |
Author: Ben Webb <[email protected]> | |
Date: Fri, 12 Oct 2001 16:40:35 +0000 | |
HTTP authentication tidied up; better error reporting for socket() and bind() f… | |
Diffstat: | |
M src/gtk_client.c | 41 ++++++++++++-----------------… | |
M src/network.c | 94 +++++++++++++++++++++++++----… | |
M src/network.h | 2 ++ | |
3 files changed, 95 insertions(+), 42 deletions(-) | |
--- | |
diff --git a/src/gtk_client.c b/src/gtk_client.c | |
t@@ -2057,6 +2057,9 @@ static void HandleMetaSock(gpointer data,gint socket, | |
NBStatus oldstatus,newstatus; | |
gchar *text; | |
+g_print("HandleMetaSock: read %d, write %d\n", | |
+ condition&GDK_INPUT_READ, | |
+ condition&GDK_INPUT_WRITE); | |
widgets=(struct StartGameStruct *)data; | |
if (!widgets->MetaConn) return; | |
t@@ -3127,11 +3130,17 @@ void DisplaySpyReports(Player *Play) { | |
} | |
static void OKAuthDialog(GtkWidget *widget,GtkWidget *window) { | |
+ gtk_object_set_data(GTK_OBJECT(window),"authok",GINT_TO_POINTER(TRUE)); | |
+ gtk_widget_destroy(window); | |
+} | |
+ | |
+static void DestroyAuthDialog(GtkWidget *window,gpointer data) { | |
GtkWidget *userentry,*passwdentry; | |
- gchar *username,*password; | |
- gpointer proxy; | |
+ gchar *username=NULL,*password=NULL; | |
+ gpointer proxy,authok; | |
HttpConnection *conn; | |
+ authok = gtk_object_get_data(GTK_OBJECT(window),"authok"); | |
proxy = gtk_object_get_data(GTK_OBJECT(window),"proxy"); | |
userentry = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window),"username"); | |
passwdentry = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), | |
t@@ -3139,34 +3148,16 @@ static void OKAuthDialog(GtkWidget *widget,GtkWidget *… | |
conn = (HttpConnection *)gtk_object_get_data(GTK_OBJECT(window),"httpconn"); | |
g_assert(userentry && passwdentry && conn); | |
- username = gtk_editable_get_chars(GTK_EDITABLE(userentry),0,-1); | |
- password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry),0,-1); | |
- | |
- gtk_object_set_data(GTK_OBJECT(window),"authdone",GINT_TO_POINTER(TRUE)); | |
+ if (authok) { | |
+ username = gtk_editable_get_chars(GTK_EDITABLE(userentry),0,-1); | |
+ password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry),0,-1); | |
+ } | |
if (!SetHttpAuthentication(conn,GPOINTER_TO_INT(proxy),username,password)) { | |
g_print("FIXME: Connect error on setauth\n"); | |
} | |
- g_free(username); g_free(password); | |
- | |
- gtk_widget_destroy(window); | |
-} | |
- | |
-void DestroyAuthDialog(GtkWidget *widget,gpointer data) { | |
- HttpConnection *conn; | |
- gpointer authdone,proxy; | |
- | |
- authdone = gtk_object_get_data(GTK_OBJECT(widget),"authdone"); | |
- conn = (HttpConnection *)gtk_object_get_data(GTK_OBJECT(widget),"httpconn"); | |
- proxy = gtk_object_get_data(GTK_OBJECT(widget),"proxy"); | |
- if (authdone) { | |
- g_print("Auth already done, thanks\n"); | |
- } else { | |
- if (!SetHttpAuthentication(conn,GPOINTER_TO_INT(proxy),NULL,NULL)) { | |
- g_print("FIXME: Connect error on unsetauth\n"); | |
- } | |
- } | |
+ g_free(username); g_free(password); | |
} | |
void AuthDialog(HttpConnection *conn,gboolean proxy,gchar *realm) { | |
diff --git a/src/network.c b/src/network.c | |
t@@ -119,6 +119,14 @@ static gboolean FinishConnect(int fd,LastError *error); | |
static void NetBufCallBack(NetworkBuffer *NetBuf) { | |
if (NetBuf && NetBuf->CallBack) { | |
+g_print("status = %d, read = %d, write = %d\n", | |
+NetBuf->status, | |
+NetBuf->status!=NBS_PRECONNECT, | |
+ (NetBuf->status==NBS_CONNECTED && | |
+ NetBuf->WriteBuf.DataPresent) || | |
+ (NetBuf->status==NBS_SOCKSCONNECT && | |
+ NetBuf->negbuf.DataPresent) || | |
+ NetBuf->WaitConnect); | |
(*NetBuf->CallBack)(NetBuf,NetBuf->status!=NBS_PRECONNECT, | |
(NetBuf->status==NBS_CONNECTED && | |
NetBuf->WriteBuf.DataPresent) || | |
t@@ -710,6 +718,7 @@ gboolean ReadDataFromWire(NetworkBuffer *NetBuf) { | |
return FALSE; | |
} else { | |
CurrentPosition+=BytesRead; | |
+g_print("%d bytes read from wire\n",BytesRead); | |
conn->DataPresent=CurrentPosition; | |
} | |
} | |
t@@ -897,6 +906,7 @@ static gboolean WriteBufToWire(NetworkBuffer *NetBuf,ConnB… | |
} | |
#endif | |
} else { | |
+g_print("%d bytes written to wire\n",BytesSent); | |
CurrentPosition+=BytesSent; | |
} | |
} | |
t@@ -913,8 +923,10 @@ gboolean WriteDataToWire(NetworkBuffer *NetBuf) { | |
/* TRUE on success, or FALSE if the buffer's maximum length is */ | |
/* reached, or the remote end has closed the connection. */ | |
if (NetBuf->status==NBS_SOCKSCONNECT) { | |
+g_print("Writing negbuf\n"); | |
return WriteBufToWire(NetBuf,&NetBuf->negbuf); | |
} else { | |
+g_print("Writing WriteBuf\n"); | |
return WriteBufToWire(NetBuf,&NetBuf->WriteBuf); | |
} | |
} | |
t@@ -1090,6 +1102,25 @@ static gboolean ParseHtmlLocation(gchar *uri,gchar **ho… | |
return TRUE; | |
} | |
+static void StartHttpAuth(HttpConnection *conn,gboolean proxy,gchar *header) { | |
+ gchar *realm,**split; | |
+ | |
+ if (!conn->authfunc) return; | |
+ | |
+ split=g_strsplit(header," ",1); | |
+ | |
+ if (split[0] && split[1] && g_strcasecmp(split[0],"Basic")==0 && | |
+ g_strncasecmp(split[1],"realm=",6)==0 && strlen(split[1])>6) { | |
+ realm = &split[1][6]; | |
+ conn->waitinput=TRUE; | |
+ (*conn->authfunc)(conn,proxy,realm); | |
+ } else { | |
+ g_print("FIXME: Bad HTTP auth header\n"); | |
+ } | |
+ | |
+ g_strfreev(split); | |
+} | |
+ | |
static void ParseHtmlHeader(gchar *line,HttpConnection *conn) { | |
gchar **split,*host,*query; | |
unsigned port; | |
t@@ -1109,19 +1140,13 @@ static void ParseHtmlHeader(gchar *line,HttpConnection… | |
} 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->waitinput=TRUE; | |
- (*conn->authfunc)(conn,FALSE,split[1]); | |
- } | |
+ StartHttpAuth(conn,FALSE,split[1]); | |
/* Proxy-Authenticate is, strictly speaking, an HTTP/1.1 thing, but some | |
HTTP/1.0 proxies seem to support it anyway */ | |
} else if (g_strcasecmp(split[0],"Proxy-Authenticate:")==0 && | |
conn->StatusCode==407) { | |
g_print("FIXME: Proxy authentication %s required\n",split[1]); | |
- if (conn->authfunc) { | |
- conn->waitinput=TRUE; | |
- (*conn->authfunc)(conn,TRUE,split[1]); | |
- } | |
+ StartHttpAuth(conn,TRUE,split[1]); | |
} | |
} | |
g_strfreev(split); | |
t@@ -1204,10 +1229,52 @@ gboolean HandleHttpCompletion(HttpConnection *conn) { | |
SetNetworkBufferUserPasswdFunc(&conn->NetBuf,userpasswd); | |
return FALSE; | |
} | |
+ } else { | |
+ if (conn->StatusCode>=300) { | |
+ g_print("FIXME: Connection failed, code %d\n",conn->StatusCode); | |
+ } | |
} | |
return TRUE; | |
} | |
+int CreateTCPSocket(LastError *error) { | |
+ int fd; | |
+ | |
+ fd=socket(AF_INET,SOCK_STREAM,0); | |
+ | |
+ if (fd==SOCKET_ERROR && error) { | |
+#ifdef CYGWIN | |
+ SetError(error,ET_WINSOCK,WSAGetLastError()); | |
+#else | |
+ SetError(error,ET_ERRNO,errno); | |
+#endif | |
+ } | |
+ | |
+ return fd; | |
+} | |
+ | |
+gboolean BindTCPSocket(int sock,unsigned port,LastError *error) { | |
+ struct sockaddr_in bindaddr; | |
+ int retval; | |
+ | |
+ bindaddr.sin_family=AF_INET; | |
+ bindaddr.sin_port=htons(port); | |
+ bindaddr.sin_addr.s_addr=INADDR_ANY; | |
+ memset(bindaddr.sin_zero,0,sizeof(bindaddr.sin_zero)); | |
+ | |
+ retval = bind(sock,(struct sockaddr *)&bindaddr,sizeof(struct sockaddr)); | |
+ | |
+ if (retval==SOCKET_ERROR && error) { | |
+#ifdef CYGWIN | |
+ SetError(error,ET_WINSOCK,WSAGetLastError()); | |
+#else | |
+ SetError(error,ET_ERRNO,errno); | |
+#endif | |
+ } | |
+ | |
+ return (retval!=SOCKET_ERROR); | |
+} | |
+ | |
gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort, | |
gboolean NonBlocking,LastError *error) { | |
struct sockaddr_in ClientAddr; | |
t@@ -1216,15 +1283,8 @@ gboolean StartConnect(int *fd,gchar *RemoteHost,unsigne… | |
he = LookupHostname(RemoteHost,error); | |
if (!he) return FALSE; | |
- *fd=socket(AF_INET,SOCK_STREAM,0); | |
- if (*fd==SOCKET_ERROR) { | |
-#ifdef CYGWIN | |
- if (error) SetError(error,ET_WINSOCK,WSAGetLastError()); | |
-#else | |
- if (error) SetError(error,ET_ERRNO,errno); | |
-#endif | |
- return FALSE; | |
- } | |
+ *fd=CreateTCPSocket(error); | |
+ if (*fd==SOCKET_ERROR) return FALSE; | |
ClientAddr.sin_family=AF_INET; | |
ClientAddr.sin_port=htons(RemotePort); | |
diff --git a/src/network.h b/src/network.h | |
t@@ -191,6 +191,8 @@ gboolean SetHttpAuthentication(HttpConnection *conn,gboole… | |
void SetHttpAuthFunc(HttpConnection *conn,HCAuthFunc authfunc); | |
gboolean HandleHttpCompletion(HttpConnection *conn); | |
+int CreateTCPSocket(LastError *error); | |
+gboolean BindTCPSocket(int sock,unsigned port,LastError *error); | |
gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort, | |
gboolean NonBlocking,LastError *error); | |
void StartNetworking(void); |