tHTTP authentication tidied up; better error reporting for socket() and bind() failures - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 62523aa3d60bd5a9ea19f35c4af2f8ce36b03f9d
(DIR) parent d575d43a2095a190ad01076332009a6b08071aa7
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Fri, 12 Oct 2001 16:40:35 +0000
HTTP authentication tidied up; better error reporting for socket() and bind() failures
Diffstat:
M src/gtk_client.c | 41 ++++++++++++-------------------
M src/network.c | 94 +++++++++++++++++++++++++------
M src/network.h | 2 ++
3 files changed, 95 insertions(+), 42 deletions(-)
---
(DIR) 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 *window) {
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) {
(DIR) 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,ConnBuf *conn) {
}
#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 **host,unsigned *port,
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 *conn) {
} 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,unsigned RemotePort,
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);
(DIR) diff --git a/src/network.h b/src/network.h
t@@ -191,6 +191,8 @@ gboolean SetHttpAuthentication(HttpConnection *conn,gboolean proxy,
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);