tHTTP and SOCKS authentication improved; now also works for servers and AI players - 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 bc1834ece535f81b294b3e9167728116ef3d4bf7
(DIR) parent d6e0ec90931c5375b3157cfbb9e4bb42c8cf13f6
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Tue, 16 Oct 2001 16:44:30 +0000
HTTP and SOCKS authentication improved; now also works for servers and AI players
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(-)
---
(DIR) 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 metaserver.
<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 available.
<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>
(DIR) diff --git a/src/AIPlayer.c b/src/AIPlayer.c
t@@ -110,6 +110,12 @@ static void DisplayConnectStatus(NetworkBuffer *netbuf,NBStatus oldstatus,
}
}
+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:
(DIR) diff --git a/src/curses_client.c b/src/curses_client.c
t@@ -231,7 +231,7 @@ static gboolean SelectServerFromMetaServer(Player *Play,GString *errstr) {
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,GString *errstr) {
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,GString *errstr) {
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 proxyauth,
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) {
(DIR) 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 METASERVER *src) {
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
(DIR) 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
(DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c
t@@ -107,9 +107,10 @@ static void MetaSocksAuthDialog(NetworkBuffer *netbuf,gpointer data);
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,gboolean Write) {
(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 Read,gboolean Write) {
(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,gpointer data) {
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,gpointer data) {
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 data) {
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 data) {
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,gpointer data) {
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"));
(DIR) 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,NBCallBack CallBack,
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,gchar *RemoteHost,
/* 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 *user,
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 ReadReady,
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 *NetBuf,gboolean ReadReady,
*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,gboolean ReadReady,
} 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,gboolean ReadReady,
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,gboolean proxy,
*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 *conn) {
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;
(DIR) 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 *HostName,
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);
(DIR) diff --git a/src/serverside.c b/src/serverside.c
t@@ -135,7 +135,7 @@ static gboolean HighScoreWrite(FILE *fp,struct HISCORE *MultiScore,
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,gboolean Write) {
}
}
-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 Read,gboolean Write) {
(Write ? GDK_INPUT_WRITE : 0),
GuiHandleMeta,NetBuf->CallBackData);
}
+ if (CallNow) GuiHandleMeta(NetBuf->CallBackData,NetBuf->fd,0);
}
static void GuiNewConnect(gpointer data,gint socket,