tHTTP and SOCKS authentication improved; now also works for servers and AI play… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit bc1834ece535f81b294b3e9167728116ef3d4bf7 | |
parent d6e0ec90931c5375b3157cfbb9e4bb42c8cf13f6 | |
Author: Ben Webb <[email protected]> | |
Date: Tue, 16 Oct 2001 16:44:30 +0000 | |
HTTP and SOCKS authentication improved; now also works for servers and AI playe… | |
Diffstat: | |
M doc/configfile.html | 32 +++++++++++++++++++++++++++++… | |
M src/AIPlayer.c | 19 ++++++++++++++----- | |
M src/curses_client.c | 48 +++++++++++++++--------------… | |
M src/dopewars.c | 33 +++++++++++++++++++++++++++--… | |
M src/dopewars.h | 1 + | |
M src/gtk_client.c | 56 +++++++++--------------------… | |
M src/network.c | 49 ++++++++++++++++-------------… | |
M src/network.h | 27 ++++++++++++++------------- | |
M src/serverside.c | 43 +++++++++++++++++++++++++++++… | |
9 files changed, 193 insertions(+), 115 deletions(-) | |
--- | |
diff --git a/doc/configfile.html b/doc/configfile.html | |
t@@ -120,6 +120,16 @@ be <i>"socks"</i>. | |
<dd>Uses SOCKS version <i>4</i>. Version 5 is also supported; SOCKS5 servers | |
support username/password authentication, unlike SOCKS4. | |
+<dt><b>Socks.Auth.User=<i>""</i></b></a> | |
+<dd>If using SOCKS5 with user/password authentication, with the server or AI | |
+player (which can both run unattended) then setting this variable to something | |
+other than "" will enable them to authenticate themselves with the SOCKS | |
+server, provided Socks.Auth.Password is also set. (The game clients prompt | |
+the user for a username and password on each connect instead.) | |
+ | |
+<dt><b>Socks.Auth.Password=<i>""</i></b></a> | |
+<dd>The corresponding password for Socks.Auth.User, above. | |
+ | |
<dt><a name="HiScoreFile"><b>HiScoreFile=<i>"/var/lib/dopewars.sco"</i></b></a> | |
<dd>Tells the dopewars server (or the client, if running in single-player | |
mode, not connected to a server) to use the file <i>/var/lib/dopewars.sco</i> | |
t@@ -152,7 +162,7 @@ This setting, if set to TRUE, can be overridden by the -S | |
about connecting to the dopewars metaserver via. a proxy web server. | |
<dt><b>MetaServer.Port=<i>80</i></b> | |
-<dd>Instructs dopewarsclient that the metaserver can be found on TCP port | |
+<dd>Instructs dopewars that the metaserver can be found on TCP port | |
<i>80</i>. This is the standard HTTP port for Web access. (You shouldn't need | |
to change this, even if you connect via. a proxy.) | |
t@@ -195,6 +205,24 @@ hostname (see MetaServer.LocalName above) with the metase… | |
<dd>Even if "Socks.Active" is TRUE, do not use SOCKS for metaserver | |
communication - connect directly to the metaserver or proxy. | |
+<dt><b>MetaServer.Auth.User=<i>""</i></b></a> | |
+<dd>If the metaserver webpage is on a restricted access server (i.e. it | |
+requires HTTP Basic authentication), and you wish to connect with the server | |
+or AI player (which can both run unattended) then setting this variable to | |
+something other than "" will enable them to authenticate themselves, | |
+provided MetaServer.Auth.Password is also set. (The game clients prompt | |
+the user for a username and password on each connect instead.) | |
+ | |
+<dt><b>MetaServer.Auth.Password=<i>""</i></b></a> | |
+<dd>The corresponding password for MetaServer.Auth.User, above. | |
+ | |
+<dt><b>MetaServer.Proxy.User=<i>""</i></b></a> | |
+<dd>In a similar way to MetaServer.Auth.User, above, this enables a dopewars | |
+server or AI player to authenticate itself with a web proxy. | |
+ | |
+<dt><b>MetaServer.Proxy.Password=<i>""</i></b></a> | |
+<dd>The corresponding password for MetaServer.Proxy.User, above. | |
+ | |
</dl> | |
<h2><a name="places">Basic configuration: places in the game</a></h2> | |
t@@ -542,6 +570,6 @@ any drugs, and clients will display this information if av… | |
<ul> | |
<li><a href="index.html">Main index</a> | |
</ul> | |
-<p>Last update: <b>23-09-2001</b></p> | |
+<p>Last update: <b>16-10-2001</b></p> | |
</body> | |
</html> | |
diff --git a/src/AIPlayer.c b/src/AIPlayer.c | |
t@@ -110,6 +110,12 @@ static void DisplayConnectStatus(NetworkBuffer *netbuf,NB… | |
} | |
} | |
+static void NetBufAuth(NetworkBuffer *netbuf,gpointer data) { | |
+ g_print(_("Using Socks.Auth.User and Socks.Auth.Password " | |
+ "for SOCKS5 authentication\n")); | |
+ SendSocks5UserPasswd(netbuf,Socks.authuser,Socks.authpassword); | |
+} | |
+ | |
void AIPlayerLoop() { | |
/* Main loop for AI players. Connects to server, plays game, */ | |
/* and then disconnects. */ | |
t@@ -138,10 +144,13 @@ void AIPlayerLoop() { | |
if (!StartNetworkBufferConnect(netbuf,ServerName,Port)) { | |
AIConnectFailed(netbuf); return; | |
- } else if (netbuf->status==NBS_CONNECTED) { | |
- AIStartGame(AIPlay); | |
} else { | |
- DisplayConnectStatus(netbuf,oldstatus,oldsocks); | |
+ SetNetworkBufferUserPasswdFunc(netbuf,NetBufAuth,NULL); | |
+ if (netbuf->status==NBS_CONNECTED) { | |
+ AIStartGame(AIPlay); | |
+ } else { | |
+ DisplayConnectStatus(netbuf,oldstatus,oldsocks); | |
+ } | |
} | |
while (1) { | |
t@@ -301,12 +310,12 @@ int HandleAIMessage(char *Message,Player *AIPlay) { | |
} | |
break; | |
case C_SUBWAYFLASH: | |
+ dpg_print(_("Jetting to %tde with %P cash and %P debt\n"), | |
+ Location[(int)AIPlay->IsAt].Name,AIPlay->Cash,AIPlay->Debt); | |
/* Use bselect rather than sleep, as this is portable to Win32 */ | |
tv.tv_sec=AITurnPause; | |
tv.tv_usec=0; | |
bselect(0,NULL,NULL,NULL,&tv); | |
- dpg_print(_("Jetting to %tde with %P cash and %P debt\n"), | |
- Location[(int)AIPlay->IsAt].Name,AIPlay->Cash,AIPlay->Debt); | |
if (brandom(0,100)<10) AISendRandomMessage(AIPlay); | |
break; | |
case C_UPDATE: | |
diff --git a/src/curses_client.c b/src/curses_client.c | |
t@@ -231,7 +231,7 @@ static gboolean SelectServerFromMetaServer(Player *Play,GS… | |
gint index; | |
fd_set readfds,writefds; | |
int maxsock; | |
- gboolean DoneOK,authOK; | |
+ gboolean DoneOK; | |
HttpConnection *MetaConn; | |
attrset(TextAttr); | |
t@@ -240,8 +240,8 @@ static gboolean SelectServerFromMetaServer(Player *Play,GS… | |
refresh(); | |
if (OpenMetaHttpConnection(&MetaConn)) { | |
- SetHttpAuthFunc(MetaConn,HttpAuthFunc,&authOK); | |
- SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf,SocksAuthFunc,&authOK); | |
+ SetHttpAuthFunc(MetaConn,HttpAuthFunc,NULL); | |
+ SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf,SocksAuthFunc,NULL); | |
} else { | |
g_string_assign_error(errstr,MetaConn->NetBuf.error); | |
CloseHttpConnection(MetaConn); | |
t@@ -266,11 +266,10 @@ static gboolean SelectServerFromMetaServer(Player *Play,… | |
if (c=='\f') wrefresh(curscr); | |
#endif | |
} | |
- authOK=TRUE; /* Gets set to FALSE if authentication fails */ | |
if (RespondToSelect(&MetaConn->NetBuf,&readfds,&writefds,NULL,&DoneOK)) { | |
while (HandleWaitingMetaServerData(MetaConn,&ServerList,&DoneOK)) {} | |
} | |
- if ((!DoneOK || !authOK) && HandleHttpCompletion(MetaConn)) { | |
+ if (!DoneOK && HandleHttpCompletion(MetaConn)) { | |
if (IsHttpError(MetaConn)) { | |
g_string_assign_error(errstr,MetaConn->NetBuf.error); | |
CloseHttpConnection(MetaConn); | |
t@@ -381,10 +380,7 @@ static void DisplayConnectStatus(NetworkBuffer *netbuf, | |
void HttpAuthFunc(HttpConnection *conn,gboolean proxyauth, | |
gchar *realm,gpointer data) { | |
- gchar *text,*user,*password; | |
- gboolean *authOK; | |
- | |
- authOK = (gboolean *)data; | |
+ gchar *text,*user,*password=NULL; | |
attrset(TextAttr); | |
clear_bottom(); | |
t@@ -395,29 +391,32 @@ void HttpAuthFunc(HttpConnection *conn,gboolean proxyaut… | |
text = g_strdup_printf(_("Authentication required for realm %s"),realm); | |
} | |
mvaddstr(17,1,text); | |
+ mvaddstr(18,1,_("(Enter a blank username to cancel)")); | |
g_free(text); | |
- user=nice_input(_("User name: "),18,1,FALSE,NULL,'\0'); | |
- password=nice_input(_("Password: "),19,1,FALSE,NULL,'*'); | |
+ user=nice_input(_("User name: "),19,1,FALSE,NULL,'\0'); | |
+ if (user && user[0]) { | |
+ password=nice_input(_("Password: "),20,1,FALSE,NULL,'*'); | |
+ } | |
- *authOK = SetHttpAuthentication(conn,proxyauth,user,password); | |
+ SetHttpAuthentication(conn,proxyauth,user,password); | |
g_free(user); g_free(password); | |
} | |
void SocksAuthFunc(NetworkBuffer *netbuf,gpointer data) { | |
- gchar *user,*password; | |
- gboolean *authOK; | |
- | |
- authOK = (gboolean *)data; | |
+ gchar *user,*password=NULL; | |
attrset(TextAttr); | |
clear_bottom(); | |
- mvaddstr(17,1,_("SOCKS authentication required")); | |
+ mvaddstr(17,1, | |
+ _("SOCKS authentication required (enter a blank username to cancel)")); | |
user=nice_input(_("User name: "),18,1,FALSE,NULL,'\0'); | |
- password=nice_input(_("Password: "),19,1,FALSE,NULL,'*'); | |
+ if (user && user[0]) { | |
+ password=nice_input(_("Password: "),19,1,FALSE,NULL,'*'); | |
+ } | |
- *authOK = SendSocks5UserPasswd(netbuf,user,password); | |
+ SendSocks5UserPasswd(netbuf,user,password); | |
g_free(user); g_free(password); | |
} | |
t@@ -425,7 +424,7 @@ static gboolean DoConnect(Player *Play,GString *errstr) { | |
NetworkBuffer *netbuf; | |
fd_set readfds,writefds; | |
int maxsock,c; | |
- gboolean doneOK=TRUE,authOK=TRUE; | |
+ gboolean doneOK=TRUE; | |
NBStatus oldstatus; | |
NBSocksStatus oldsocks; | |
t@@ -436,7 +435,7 @@ static gboolean DoConnect(Player *Play,GString *errstr) { | |
if (!StartNetworkBufferConnect(netbuf,ServerName,Port)) { | |
doneOK=FALSE; | |
} else { | |
- SetNetworkBufferUserPasswdFunc(netbuf,SocksAuthFunc,&authOK); | |
+ SetNetworkBufferUserPasswdFunc(netbuf,SocksAuthFunc,NULL); | |
if (netbuf->status!=NBS_CONNECTED) { | |
DisplayConnectStatus(netbuf,oldstatus,oldsocks); | |
do { | |
t@@ -456,16 +455,15 @@ static gboolean DoConnect(Player *Play,GString *errstr) { | |
} | |
oldstatus = netbuf->status; | |
oldsocks = netbuf->sockstat; | |
- authOK=TRUE; | |
RespondToSelect(netbuf,&readfds,&writefds,NULL,&doneOK); | |
if (netbuf->status==NBS_CONNECTED) break; | |
DisplayConnectStatus(netbuf,oldstatus,oldsocks); | |
- } while (doneOK && authOK); | |
+ } while (doneOK); | |
} | |
} | |
- if (!doneOK || !authOK) g_string_assign_error(errstr,netbuf->error); | |
- return (doneOK && authOK); | |
+ if (!doneOK) g_string_assign_error(errstr,netbuf->error); | |
+ return doneOK; | |
} | |
static gboolean ConnectToServer(Player *Play) { | |
diff --git a/src/dopewars.c b/src/dopewars.c | |
t@@ -160,14 +160,14 @@ struct BITCH Bitch = { | |
#ifdef NETWORKING | |
struct METASERVER MetaServer = { FALSE,NULL,0,NULL,0,NULL,NULL,NULL, | |
- NULL,FALSE }; | |
+ NULL,FALSE,NULL,NULL,NULL,NULL }; | |
struct METASERVER DefaultMetaServer = { | |
TRUE,"dopewars.sourceforge.net",80,"",8080,"/metaserver.php", | |
- "","","dopewars server", FALSE | |
+ "","","dopewars server", FALSE, "", "", "", "" | |
}; | |
-SocksServer Socks = { NULL,0,0,FALSE,NULL }; | |
+SocksServer Socks = { NULL,0,0,FALSE,NULL,NULL,NULL }; | |
gboolean UseSocks; | |
#endif | |
t@@ -209,6 +209,12 @@ struct GLOBALS Globals[] = { | |
{ &Socks.version,NULL,NULL,NULL,NULL,"Socks.Version", | |
N_("The version of the SOCKS protocol to use (4 or 5)"), | |
NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,NULL,&Socks.authuser,NULL,"Socks.Auth.User", | |
+ N_("Username for SOCKS5 authentication"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,NULL,&Socks.authpassword,NULL,"Socks.Auth.Password", | |
+ N_("Password for SOCKS5 authentication"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
{ NULL,&MetaServer.Active,NULL,NULL,NULL,"MetaServer.Active", | |
N_("TRUE if server should report to a metaserver"), | |
NULL,NULL,0,"",NULL,NULL }, | |
t@@ -238,6 +244,19 @@ struct GLOBALS Globals[] = { | |
{ NULL,&MetaServer.UseSocks,NULL,NULL,NULL,"MetaServer.UseSocks", | |
N_("If TRUE, use SOCKS for metaserver communication"), | |
NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,NULL,&MetaServer.authuser,NULL,"MetaServer.Auth.User", | |
+ N_("Username for HTTP Basic authentication"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,NULL,&MetaServer.authpassword,NULL,"MetaServer.Auth.Password", | |
+ N_("Password for HTTP Basic authentication"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,NULL,&MetaServer.proxyuser,NULL,"MetaServer.Proxy.User", | |
+ N_("Username for HTTP Basic proxy authentication"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,NULL,&MetaServer.proxypassword,NULL, | |
+ "MetaServer.Proxy.Password", | |
+ N_("Password for HTTP Basic proxy authentication"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
#endif | |
{ NULL,NULL,NULL,&Pager,NULL,"Pager", | |
N_("Program used to display multi-page output"),NULL,NULL,0,"",NULL,NULL … | |
t@@ -1264,6 +1283,10 @@ void CopyMetaServer(struct METASERVER *dest,struct META… | |
AssignName(&dest->LocalName,src->LocalName); | |
AssignName(&dest->Password,src->Password); | |
AssignName(&dest->Comment,src->Comment); | |
+ AssignName(&dest->authuser,src->authuser); | |
+ AssignName(&dest->authpassword,src->authpassword); | |
+ AssignName(&dest->proxyuser,src->proxyuser); | |
+ AssignName(&dest->proxypassword,src->proxypassword); | |
} | |
#endif | |
t@@ -1726,8 +1749,10 @@ void SetupParameters() { | |
AssignName(&Socks.name,"socks"); | |
Socks.port = 1080; | |
Socks.version = 4; | |
- Socks.user = NULL; | |
+ Socks.user = g_strdup(""); | |
Socks.numuid = FALSE; | |
+ Socks.authuser = g_strdup(""); | |
+ Socks.authpassword = g_strdup(""); | |
UseSocks = FALSE; | |
#endif | |
diff --git a/src/dopewars.h b/src/dopewars.h | |
t@@ -86,6 +86,7 @@ struct METASERVER { | |
unsigned ProxyPort; | |
gchar *Path,*LocalName,*Password,*Comment; | |
gboolean UseSocks; | |
+ gchar *authuser,*authpassword,*proxyuser,*proxypassword; | |
}; | |
#endif | |
diff --git a/src/gtk_client.c b/src/gtk_client.c | |
t@@ -107,9 +107,10 @@ static void MetaSocksAuthDialog(NetworkBuffer *netbuf,gpo… | |
static void SocksAuthDialog(NetworkBuffer *netbuf,gpointer data); | |
static void GetClientMessage(gpointer data,gint socket, | |
GdkInputCondition condition); | |
-static void SocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write); | |
+static void SocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write, | |
+ gboolean CallNow); | |
static void MetaSocketStatus(NetworkBuffer *NetBuf,gboolean Read, | |
- gboolean Write); | |
+ gboolean Write,gboolean CallNow); | |
static void FinishServerConnect(struct StartGameStruct *widgets, | |
gboolean ConnectOK); | |
t@@ -330,7 +331,8 @@ void GetClientMessage(gpointer data,gint socket, | |
} | |
} | |
-void SocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write) { | |
+void SocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write, | |
+ gboolean CallNow) { | |
if (NetBuf->InputTag) gdk_input_remove(NetBuf->InputTag); | |
NetBuf->InputTag=0; | |
if (Read || Write) { | |
t@@ -339,6 +341,7 @@ void SocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboo… | |
(Write ? GDK_INPUT_WRITE : 0), | |
GetClientMessage,NetBuf->CallBackData); | |
} | |
+ if (CallNow) GetClientMessage(NetBuf->CallBackData,NetBuf->fd,0); | |
} | |
#endif /* NETWORKING */ | |
t@@ -2030,7 +2033,7 @@ static void DoConnect(struct StartGameStruct *widgets) { | |
oldsocks = NetBuf->sockstat; | |
if (StartNetworkBufferConnect(NetBuf,ServerName,Port)) { | |
DisplayConnectStatus(widgets,FALSE,oldstatus,oldsocks); | |
- SetNetworkBufferUserPasswdFunc(NetBuf,SocksAuthDialog,(gpointer)widgets); | |
+ SetNetworkBufferUserPasswdFunc(NetBuf,SocksAuthDialog,NULL); | |
SetNetworkBufferCallBack(NetBuf,SocketStatus,(gpointer)widgets); | |
} else { | |
ConnectError(widgets,FALSE); | |
t@@ -2175,7 +2178,8 @@ static void HandleMetaSock(gpointer data,gint socket, | |
} | |
} | |
-void MetaSocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write) { | |
+void MetaSocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write, | |
+ gboolean CallNow) { | |
if (NetBuf->InputTag) gdk_input_remove(NetBuf->InputTag); | |
NetBuf->InputTag=0; | |
if (Read || Write) { | |
t@@ -2184,6 +2188,7 @@ void MetaSocketStatus(NetworkBuffer *NetBuf,gboolean Rea… | |
(Write ? GDK_INPUT_WRITE : 0), | |
HandleMetaSock,NetBuf->CallBackData); | |
} | |
+ if (CallNow) HandleMetaSock(NetBuf->CallBackData,NetBuf->fd,0); | |
} | |
static void UpdateMetaServerList(GtkWidget *widget, | |
t@@ -2206,9 +2211,9 @@ static void UpdateMetaServerList(GtkWidget *widget, | |
if (OpenMetaHttpConnection(&widgets->MetaConn)) { | |
metaserv=widgets->metaserv; | |
- SetHttpAuthFunc(widgets->MetaConn,AuthDialog,(gpointer)widgets); | |
+ SetHttpAuthFunc(widgets->MetaConn,AuthDialog,NULL); | |
SetNetworkBufferUserPasswdFunc(&widgets->MetaConn->NetBuf, | |
- MetaSocksAuthDialog,(gpointer)widgets); | |
+ MetaSocksAuthDialog,NULL); | |
SetNetworkBufferCallBack(&widgets->MetaConn->NetBuf, | |
MetaSocketStatus,(gpointer)widgets); | |
} else { | |
t@@ -3226,34 +3231,22 @@ static void DestroyAuthDialog(GtkWidget *window,gpoint… | |
GtkWidget *userentry,*passwdentry; | |
gchar *username=NULL,*password=NULL; | |
gpointer proxy,authok; | |
- struct StartGameStruct *widgets; | |
HttpConnection *conn; | |
- NBStatus oldstatus; | |
- NBSocksStatus oldsocks; | |
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), | |
"password"); | |
- widgets = (struct StartGameStruct *)gtk_object_get_data(GTK_OBJECT(window), | |
- "widgets"); | |
conn = (HttpConnection *)gtk_object_get_data(GTK_OBJECT(window),"httpconn"); | |
- g_assert(userentry && passwdentry && conn && widgets); | |
+ g_assert(userentry && passwdentry && conn); | |
if (authok) { | |
username = gtk_editable_get_chars(GTK_EDITABLE(userentry),0,-1); | |
password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry),0,-1); | |
} | |
- oldstatus = widgets->MetaConn->NetBuf.status; | |
- oldsocks = widgets->MetaConn->NetBuf.sockstat; | |
- | |
- if (!SetHttpAuthentication(conn,GPOINTER_TO_INT(proxy),username,password)) { | |
- MetaDone(widgets); | |
- } else { | |
- DisplayConnectStatus(widgets,TRUE,oldstatus,oldsocks); | |
- } | |
+ SetHttpAuthentication(conn,GPOINTER_TO_INT(proxy),username,password); | |
g_free(username); g_free(password); | |
} | |
t@@ -3261,16 +3254,12 @@ static void DestroyAuthDialog(GtkWidget *window,gpoint… | |
void AuthDialog(HttpConnection *conn,gboolean proxy,gchar *realm, | |
gpointer data) { | |
GtkWidget *window,*button,*hsep,*vbox,*label,*entry,*table,*hbbox; | |
- struct StartGameStruct *widgets; | |
- | |
- widgets = (struct StartGameStruct *)data; | |
window=gtk_window_new(GTK_WINDOW_DIALOG); | |
gtk_signal_connect(GTK_OBJECT(window),"destroy", | |
GTK_SIGNAL_FUNC(DestroyAuthDialog),NULL); | |
gtk_object_set_data(GTK_OBJECT(window),"proxy",GINT_TO_POINTER(proxy)); | |
gtk_object_set_data(GTK_OBJECT(window),"httpconn",(gpointer)conn); | |
- gtk_object_set_data(GTK_OBJECT(window),"widgets",(gpointer)widgets); | |
if (proxy) { | |
gtk_window_set_title(GTK_WINDOW(window), | |
t@@ -3352,9 +3341,6 @@ static void DestroySocksAuth(GtkWidget *window,gpointer … | |
gchar *username=NULL,*password=NULL; | |
gpointer authok,meta; | |
NetworkBuffer *netbuf; | |
- struct StartGameStruct *widgets; | |
- NBStatus oldstatus; | |
- NBSocksStatus oldsocks; | |
authok = gtk_object_get_data(GTK_OBJECT(window),"authok"); | |
meta = gtk_object_get_data(GTK_OBJECT(window),"meta"); | |
t@@ -3362,8 +3348,6 @@ static void DestroySocksAuth(GtkWidget *window,gpointer … | |
passwdentry = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window), | |
"password"); | |
netbuf = (NetworkBuffer *)gtk_object_get_data(GTK_OBJECT(window),"netbuf"); | |
- widgets = (struct StartGameStruct *)gtk_object_get_data(GTK_OBJECT(window), | |
- "widgets"); | |
g_assert(userentry && passwdentry && netbuf); | |
t@@ -3372,29 +3356,19 @@ static void DestroySocksAuth(GtkWidget *window,gpointe… | |
password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry),0,-1); | |
} | |
- oldstatus = netbuf->status; | |
- oldsocks = netbuf->sockstat; | |
- if (!SendSocks5UserPasswd(netbuf,username,password)) { | |
- if (meta) MetaDone(widgets); else ConnectError(widgets,FALSE); | |
- } else { | |
- DisplayConnectStatus(widgets,GPOINTER_TO_INT(meta),oldstatus,oldsocks); | |
- } | |
+ SendSocks5UserPasswd(netbuf,username,password); | |
g_free(username); g_free(password); | |
} | |
static void RealSocksAuthDialog(NetworkBuffer *netbuf,gboolean meta, | |
gpointer data) { | |
GtkWidget *window,*button,*hsep,*vbox,*label,*entry,*table,*hbbox; | |
- struct StartGameStruct *widgets; | |
- | |
- widgets = (struct StartGameStruct *)data; | |
window=gtk_window_new(GTK_WINDOW_DIALOG); | |
gtk_signal_connect(GTK_OBJECT(window),"destroy", | |
GTK_SIGNAL_FUNC(DestroySocksAuth),NULL); | |
gtk_object_set_data(GTK_OBJECT(window),"netbuf",(gpointer)netbuf); | |
gtk_object_set_data(GTK_OBJECT(window),"meta",GINT_TO_POINTER(meta)); | |
- gtk_object_set_data(GTK_OBJECT(window),"widgets",(gpointer)widgets); | |
/* Title of dialog for authenticating with a SOCKS server */ | |
gtk_window_set_title(GTK_WINDOW(window),_("SOCKS Authentication Required")); | |
diff --git a/src/network.c b/src/network.c | |
t@@ -125,20 +125,20 @@ void SetBlocking(int sock,gboolean blocking) { | |
static gboolean FinishConnect(int fd,LastError **error); | |
-static void NetBufCallBack(NetworkBuffer *NetBuf) { | |
+static void NetBufCallBack(NetworkBuffer *NetBuf,gboolean CallNow) { | |
if (NetBuf && NetBuf->CallBack) { | |
(*NetBuf->CallBack)(NetBuf,NetBuf->status!=NBS_PRECONNECT, | |
(NetBuf->status==NBS_CONNECTED && | |
NetBuf->WriteBuf.DataPresent) || | |
(NetBuf->status==NBS_SOCKSCONNECT && | |
NetBuf->negbuf.DataPresent) || | |
- NetBuf->WaitConnect); | |
+ NetBuf->WaitConnect,CallNow); | |
} | |
} | |
static void NetBufCallBackStop(NetworkBuffer *NetBuf) { | |
if (NetBuf && NetBuf->CallBack) { | |
- (*NetBuf->CallBack)(NetBuf,FALSE,FALSE); | |
+ (*NetBuf->CallBack)(NetBuf,FALSE,FALSE,FALSE); | |
} | |
} | |
t@@ -181,7 +181,7 @@ void SetNetworkBufferCallBack(NetworkBuffer *NetBuf,NBCall… | |
NetBufCallBackStop(NetBuf); | |
NetBuf->CallBack=CallBack; | |
NetBuf->CallBackData=CallBackData; | |
- NetBufCallBack(NetBuf); | |
+ NetBufCallBack(NetBuf,FALSE); | |
} | |
void SetNetworkBufferUserPasswdFunc(NetworkBuffer *NetBuf, | |
t@@ -238,7 +238,7 @@ gboolean StartNetworkBufferConnect(NetworkBuffer *NetBuf,g… | |
/* Notify the owner if necessary to check for the connection completing | |
and/or for data to be writeable */ | |
- NetBufCallBack(NetBuf); | |
+ NetBufCallBack(NetBuf,FALSE); | |
return TRUE; | |
} else { | |
t@@ -401,22 +401,23 @@ static gboolean Socks5UserPasswd(NetworkBuffer *NetBuf) { | |
} | |
} | |
-gboolean SendSocks5UserPasswd(NetworkBuffer *NetBuf,gchar *user, | |
- gchar *password) { | |
+void SendSocks5UserPasswd(NetworkBuffer *NetBuf,gchar *user,gchar *password) { | |
gchar *addpt; | |
guint addlen; | |
ConnBuf *conn; | |
if (!user || !password || !user[0] || !password[0]) { | |
SetError(&NetBuf->error,&ETSocks,SEC_USERCANCEL,NULL); | |
- return FALSE; | |
+ NetBufCallBack(NetBuf,TRUE); | |
+ return; | |
} | |
conn=&NetBuf->negbuf; | |
addlen = 3 + strlen(user) + strlen(password); | |
addpt = ExpandWriteBuffer(conn,addlen,&NetBuf->error); | |
if (!addpt || strlen(user)>255 || strlen(password)>255) { | |
SetError(&NetBuf->error,ET_CUSTOM,E_FULLBUF,NULL); | |
- return FALSE; | |
+ NetBufCallBack(NetBuf,TRUE); | |
+ return; | |
} | |
addpt[0] = 1; /* Subnegotiation version code */ | |
addpt[1] = strlen(user); | |
t@@ -425,8 +426,6 @@ gboolean SendSocks5UserPasswd(NetworkBuffer *NetBuf,gchar … | |
strcpy(&addpt[3+strlen(user)],password); | |
CommitWriteBuffer(NetBuf,conn,addpt,addlen); | |
- | |
- return TRUE; | |
} | |
static gboolean Socks5Connect(NetworkBuffer *NetBuf) { | |
t@@ -520,7 +519,7 @@ static gboolean HandleSocksReply(NetworkBuffer *NetBuf) { | |
else g_print("FQDN\n");*/ | |
NetBuf->status = NBS_CONNECTED; | |
g_free(data); | |
- NetBufCallBack(NetBuf); /* status has changed */ | |
+ NetBufCallBack(NetBuf,FALSE); /* status has changed */ | |
} | |
} | |
} | |
t@@ -535,7 +534,7 @@ static gboolean HandleSocksReply(NetworkBuffer *NetBuf) { | |
} else { | |
if (data[1]==90) { | |
NetBuf->status = NBS_CONNECTED; | |
- NetBufCallBack(NetBuf); /* status has changed */ | |
+ NetBufCallBack(NetBuf,FALSE); /* status has changed */ | |
retval=TRUE; | |
} else if (data[1]>=SEC_REJECT && data[1]<=SEC_IDMISMATCH) { | |
SetError(&NetBuf->error,&ETSocks,data[1],NULL); | |
t@@ -561,7 +560,7 @@ static gboolean DoNetworkBufferStuff(NetworkBuffer *NetBuf… | |
gboolean retval; | |
*ReadOK=*WriteOK=*ErrorOK=TRUE; | |
- if (ErrorReady) *ErrorOK=FALSE; | |
+ if (ErrorReady || NetBuf->error) *ErrorOK=FALSE; | |
else if (NetBuf->WaitConnect) { | |
if (WriteReady) { | |
retval=FinishConnect(NetBuf->fd,&NetBuf->error); | |
t@@ -587,7 +586,10 @@ static gboolean DoNetworkBufferStuff(NetworkBuffer *NetBu… | |
*ReadOK=ReadDataFromWire(NetBuf); | |
if (NetBuf->ReadBuf.DataPresent>0 && | |
NetBuf->status==NBS_SOCKSCONNECT) { | |
- if (!HandleSocksReply(NetBuf)) *ErrorOK=FALSE; | |
+ if (!HandleSocksReply(NetBuf) | |
+ || NetBuf->error) { /* From SendSocks5UserPasswd, possibly */ | |
+ *ErrorOK=FALSE; | |
+ } | |
} | |
if (NetBuf->ReadBuf.DataPresent>0 && | |
NetBuf->status!=NBS_SOCKSCONNECT) { | |
t@@ -605,7 +607,7 @@ static gboolean DoNetworkBufferStuff(NetworkBuffer *NetBuf… | |
} else if (ConnectDone) { | |
/* If we just connected, then no need to listen for write-ready status | |
any more */ | |
- NetBufCallBack(NetBuf); | |
+ NetBufCallBack(NetBuf,FALSE); | |
} else if (WriteReady && | |
((NetBuf->status==NBS_CONNECTED && | |
NetBuf->WriteBuf.DataPresent==0) || | |
t@@ -613,7 +615,7 @@ static gboolean DoNetworkBufferStuff(NetworkBuffer *NetBuf… | |
NetBuf->negbuf.DataPresent==0))) { | |
/* If we wrote out everything, then tell the owner so that the socket no | |
longer needs to be checked for write-ready status */ | |
- NetBufCallBack(NetBuf); | |
+ NetBufCallBack(NetBuf,FALSE); | |
} | |
return DataWaiting; | |
t@@ -787,7 +789,7 @@ void CommitWriteBuffer(NetworkBuffer *NetBuf,ConnBuf *conn, | |
/* If the buffer was empty before, we may need to tell the owner to check | |
the socket for write-ready status */ | |
- if (NetBuf && addpt==conn->Data) NetBufCallBack(NetBuf); | |
+ if (NetBuf && addpt==conn->Data) NetBufCallBack(NetBuf,FALSE); | |
} | |
void QueueMessageForSend(NetworkBuffer *NetBuf,gchar *data) { | |
t@@ -1065,8 +1067,8 @@ void CloseHttpConnection(HttpConnection *conn) { | |
g_free(conn); | |
} | |
-gboolean SetHttpAuthentication(HttpConnection *conn,gboolean proxy, | |
- gchar *user,gchar *password) { | |
+void SetHttpAuthentication(HttpConnection *conn,gboolean proxy, | |
+ gchar *user,gchar *password) { | |
gchar **ptuser,**ptpassword; | |
g_assert(conn); | |
if (proxy) { | |
t@@ -1082,8 +1084,9 @@ gboolean SetHttpAuthentication(HttpConnection *conn,gboo… | |
*ptuser = *ptpassword = NULL; | |
} | |
conn->waitinput=FALSE; | |
- if (conn->Status==HS_WAITCOMPLETE) return !HandleHttpCompletion(conn); | |
- else return TRUE; | |
+ if (conn->Status==HS_WAITCOMPLETE) { | |
+ NetBufCallBack(&conn->NetBuf,TRUE); | |
+ } | |
} | |
void SetHttpAuthFunc(HttpConnection *conn,HCAuthFunc authfunc,gpointer data) { | |
t@@ -1158,7 +1161,7 @@ static void ParseHtmlHeader(gchar *line,HttpConnection *… | |
if (g_strcasecmp(split[0],"Location:")==0 && | |
(conn->StatusCode==HEC_MOVETEMP || conn->StatusCode==HEC_MOVEPERM)) { | |
if (ParseHtmlLocation(split[1],&host,&port,&query)) { | |
- g_print("Redirect to %s:%u%s\n",host,port,query); | |
+ g_print("FIXME: Redirect to %s:%u%s\n",host,port,query); | |
g_free(conn->RedirHost); g_free(conn->RedirQuery); | |
conn->RedirHost=host; conn->RedirQuery=query; | |
conn->RedirPort=port; | |
diff --git a/src/network.h b/src/network.h | |
t@@ -63,22 +63,25 @@ typedef struct _ConnBuf { | |
typedef struct _NetworkBuffer NetworkBuffer; | |
-typedef void (*NBCallBack)(NetworkBuffer *NetBuf,gboolean Read,gboolean Write); | |
+typedef void (*NBCallBack)(NetworkBuffer *NetBuf,gboolean Read,gboolean Write, | |
+ gboolean CallNow); | |
typedef void (*NBUserPasswd)(NetworkBuffer *NetBuf,gpointer data); | |
/* Information about a SOCKS server */ | |
typedef struct _SocksServer { | |
- gchar *name; /* hostname */ | |
- unsigned port; /* port number */ | |
- int version; /* desired protocol version (usually 4 or 5) */ | |
- gboolean numuid; /* if TRUE, send numeric user IDs rather than names */ | |
- char *user; /* if not blank, override the username with this */ | |
+ gchar *name; /* hostname */ | |
+ unsigned port; /* port number */ | |
+ int version; /* desired protocol version (usually 4 or 5) */ | |
+ gboolean numuid; /* if TRUE, send numeric user IDs rather than names */ | |
+ char *user; /* if not blank, override the username with this */ | |
+ gchar *authuser; /* if set, the username for SOCKS5 auth */ | |
+ gchar *authpassword; /* if set, the password for SOCKS5 auth */ | |
} SocksServer; | |
/* The status of a network buffer */ | |
typedef enum { | |
- NBS_PRECONNECT, /* Socket is not connected */ | |
+ NBS_PRECONNECT, /* Socket is not yet connected */ | |
NBS_SOCKSCONNECT, /* A CONNECT request is being sent to a SOCKS server */ | |
NBS_CONNECTED /* Socket is connected */ | |
} NBStatus; | |
t@@ -94,8 +97,7 @@ typedef enum { | |
struct _NetworkBuffer { | |
int fd; /* File descriptor of the socket */ | |
gint InputTag; /* Identifier for gdk_input routines */ | |
- NBCallBack CallBack; /* Function called when the socket read- or | |
- write-able status changes */ | |
+ NBCallBack CallBack; /* Function called when the socket status changes … | |
gpointer CallBackData; /* Data accessible to the callback function */ | |
char Terminator; /* Character that separates messages */ | |
char StripChar; /* Char that should be removed from messages */ | |
t@@ -179,8 +181,7 @@ gboolean WriteDataToWire(NetworkBuffer *NetBuf); | |
void QueueMessageForSend(NetworkBuffer *NetBuf,gchar *data); | |
gint CountWaitingMessages(NetworkBuffer *NetBuf); | |
gchar *GetWaitingMessage(NetworkBuffer *NetBuf); | |
-gboolean SendSocks5UserPasswd(NetworkBuffer *NetBuf,gchar *user, | |
- gchar *password); | |
+void SendSocks5UserPasswd(NetworkBuffer *NetBuf,gchar *user,gchar *password); | |
gchar *GetWaitingData(NetworkBuffer *NetBuf,int numbytes); | |
gchar *PeekWaitingData(NetworkBuffer *NetBuf,int numbytes); | |
gchar *ExpandWriteBuffer(ConnBuf *conn,int numbytes,LastError **error); | |
t@@ -194,8 +195,8 @@ gboolean OpenHttpConnection(HttpConnection **conn,gchar *H… | |
gchar *Headers,gchar *Body); | |
void CloseHttpConnection(HttpConnection *conn); | |
gchar *ReadHttpResponse(HttpConnection *conn); | |
-gboolean SetHttpAuthentication(HttpConnection *conn,gboolean proxy, | |
- gchar *user,gchar *password); | |
+void SetHttpAuthentication(HttpConnection *conn,gboolean proxy, | |
+ gchar *user,gchar *password); | |
void SetHttpAuthFunc(HttpConnection *conn,HCAuthFunc authfunc,gpointer data); | |
gboolean HandleHttpCompletion(HttpConnection *conn); | |
gboolean IsHttpError(HttpConnection *conn); | |
diff --git a/src/serverside.c b/src/serverside.c | |
t@@ -135,7 +135,7 @@ static gboolean HighScoreWrite(FILE *fp,struct HISCORE *Mu… | |
static void GuiHandleMeta(gpointer data,gint socket, | |
GdkInputCondition condition); | |
static void MetaSocketStatus(NetworkBuffer *NetBuf, | |
- gboolean Read,gboolean Write); | |
+ gboolean Read,gboolean Write,gboolean CallNow); | |
#endif | |
#ifdef NETWORKING | |
t@@ -149,6 +149,37 @@ static gboolean MetaConnectError(HttpConnection *conn) { | |
g_string_free(errstr,TRUE); | |
return TRUE; | |
} | |
+ | |
+static void ServerHttpAuth(HttpConnection *conn,gboolean proxyauth, | |
+ gchar *realm,gpointer data) { | |
+ gchar *user=NULL,*password=NULL; | |
+ if (proxyauth) { | |
+ if (MetaServer.proxyuser[0] && MetaServer.proxypassword[0]) { | |
+ user = MetaServer.proxyuser; password = MetaServer.proxypassword; | |
+ dopelog(3,_("Using MetaServer.Proxy.User and MetaServer.Proxy.Password " | |
+ "for HTTP proxy authentication")); | |
+ } else { | |
+ dopelog(0,_("Unable to authenticate with HTTP proxy; please set " | |
+ "MetaServer.Proxy.User and MetaServer.Proxy.Password variables")… | |
+ } | |
+ } else { | |
+ if (MetaServer.authuser[0] && MetaServer.authpassword[0]) { | |
+ user = MetaServer.authuser; password = MetaServer.authpassword; | |
+ dopelog(3,_("Using MetaServer.Auth.User and MetaServer.Auth.Password " | |
+ "for HTTP authentication")); | |
+ } else { | |
+ dopelog(0,_("Unable to authenticate with HTTP server; please set " | |
+ "MetaServer.Auth.User and MetaServer.Auth.Password variables")); | |
+ } | |
+ } | |
+ SetHttpAuthentication(conn,proxyauth,user,password); | |
+} | |
+ | |
+static void ServerNetBufAuth(NetworkBuffer *netbuf,gpointer data) { | |
+ dopelog(3,_("Using Socks.Auth.User and Socks.Auth.Password " | |
+ "for SOCKS5 authentication")); | |
+ SendSocks5UserPasswd(netbuf,Socks.authuser,Socks.authpassword); | |
+} | |
#endif | |
void RegisterWithMetaServer(gboolean Up,gboolean SendData, | |
t@@ -234,6 +265,12 @@ void RegisterWithMetaServer(gboolean Up,gboolean SendData, | |
CloseHttpConnection(MetaConn); MetaConn=NULL; | |
return; | |
} | |
+ SetHttpAuthFunc(MetaConn,ServerHttpAuth,NULL); | |
+ | |
+ if (Socks.authuser && Socks.authuser[0] && | |
+ Socks.authpassword && Socks.authpassword[0]) { | |
+ SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf,ServerNetBufAuth,NULL); | |
+ } | |
#ifdef GUI_SERVER | |
SetNetworkBufferCallBack(&MetaConn->NetBuf,MetaSocketStatus,NULL); | |
#endif | |
t@@ -1083,7 +1120,8 @@ void SocketStatus(NetworkBuffer *NetBuf,gboolean Read,gb… | |
} | |
} | |
-void MetaSocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write) { | |
+void MetaSocketStatus(NetworkBuffer *NetBuf,gboolean Read,gboolean Write, | |
+ gboolean CallNow) { | |
if (NetBuf->InputTag) gdk_input_remove(NetBuf->InputTag); | |
NetBuf->InputTag=0; | |
if (Read || Write) { | |
t@@ -1092,6 +1130,7 @@ void MetaSocketStatus(NetworkBuffer *NetBuf,gboolean Rea… | |
(Write ? GDK_INPUT_WRITE : 0), | |
GuiHandleMeta,NetBuf->CallBackData); | |
} | |
+ if (CallNow) GuiHandleMeta(NetBuf->CallBackData,NetBuf->fd,0); | |
} | |
static void GuiNewConnect(gpointer data,gint socket, |