tGTK+ HTTP authentication dialog now called (almost) properly when needed - 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 aa38d66d5be2f4de64e3beb58c67937ebd7bcc93
 (DIR) parent a1952c3b817dae1e9e9835751e2fe5dfe3e1fed5
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Thu,  4 Oct 2001 19:13:32 +0000
       
       GTK+ HTTP authentication dialog now called (almost) properly when needed
       
       
       Diffstat:
         M src/gtk_client.c                    |     108 +++++++++++++++++++++++++++++++
         M src/network.c                       |      17 +++++++++++++++++
         M src/network.h                       |      15 +++++++++++++--
       
       3 files changed, 138 insertions(+), 2 deletions(-)
       ---
 (DIR) diff --git a/src/gtk_client.c b/src/gtk_client.c
       t@@ -95,6 +95,7 @@ static void NewGameDialog(void);
        static void StartGame(void);
        static void EndGame(void);
        static void UpdateMenus(void);
       +static gboolean AuthDialog(HttpConnection *conn,gchar *realm);
        
        #ifdef NETWORKING
        static void GetClientMessage(gpointer data,gint socket,
       t@@ -2074,6 +2075,7 @@ static void UpdateMetaServerList(GtkWidget *widget,
        
           if (OpenMetaHttpConnection(&widgets->MetaConn)) {
              metaserv=widgets->metaserv;
       +      SetHttpAuthFunc(widgets->MetaConn,AuthDialog);
              SetNetworkBufferCallBack(&widgets->MetaConn->NetBuf,
                                       MetaSocketStatus,(gpointer)widgets);
           } else {
       t@@ -3076,6 +3078,112 @@ void DisplaySpyReports(Player *Play) {
           gtk_widget_show_all(notebook);
        }
        
       +static void OKAuthDialog(GtkWidget *widget,GtkWidget *window) {
       +   GtkWidget *userentry,*passwdentry;
       +   gchar *username,*password;
       +   HttpConnection *conn;
       +   gboolean *retval;
       +
       +   userentry = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window),"username");
       +   passwdentry = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(window),
       +                                                  "password");
       +   retval = (gboolean *)gtk_object_get_data(GTK_OBJECT(window),"retval");
       +   conn = (HttpConnection *)gtk_object_get_data(GTK_OBJECT(window),"httpconn");
       +   g_assert(userentry && passwdentry && retval && conn);
       +
       +   *retval = TRUE;
       +
       +   username = gtk_editable_get_chars(GTK_EDITABLE(userentry),0,-1);
       +   password = gtk_editable_get_chars(GTK_EDITABLE(passwdentry),0,-1);
       +
       +   SetHttpAuthentication(conn,username,password);
       +   g_free(username); g_free(password);
       +
       +   gtk_widget_destroy(window);
       +}
       +
       +void DestroyAuthDialog(GtkWidget *widget,gpointer data) {
       +   gtk_main_quit();
       +}
       +
       +gboolean AuthDialog(HttpConnection *conn,gchar *realm) {
       +   GtkWidget *window,*button,*hsep,*vbox,*label,*entry,*table,*hbbox;
       +   gboolean retval=FALSE;
       +
       +   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),"retval",(gpointer)&retval);
       +   gtk_object_set_data(GTK_OBJECT(window),"httpconn",(gpointer)conn);
       +
       +   if (conn->proxyauth) {
       +      gtk_window_set_title(GTK_WINDOW(window),
       +/* Title of dialog for authenticating with a proxy server */
       +                           _("Proxy Authentication Required"));
       +   } else {
       +/* Title of dialog for authenticating with a web server */
       +      gtk_window_set_title(GTK_WINDOW(window),_("Authentication Required"));
       +   }
       +
       +   gtk_window_set_modal(GTK_WINDOW(window),TRUE);
       +   gtk_window_set_transient_for(GTK_WINDOW(window),
       +                                GTK_WINDOW(ClientData.window));
       +   gtk_container_set_border_width(GTK_CONTAINER(window),7);
       +
       +   vbox=gtk_vbox_new(FALSE,7);
       +
       +   table=gtk_table_new(3,3,FALSE);
       +   gtk_table_set_row_spacings(GTK_TABLE(table),10);
       +   gtk_table_set_col_spacings(GTK_TABLE(table),5);
       +
       +   label=gtk_label_new("Realm:");
       +   gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,0,1);
       +
       +   label=gtk_label_new(realm);
       +   gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,0,1);
       +
       +   label=gtk_label_new("User name:");
       +   gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,1,2);
       +
       +   entry=gtk_entry_new();
       +   gtk_object_set_data(GTK_OBJECT(window),"username",(gpointer)entry);
       +   gtk_table_attach_defaults(GTK_TABLE(table),entry,1,2,1,2);
       +
       +   label=gtk_label_new("Password:");
       +   gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,2,3);
       +
       +   entry=gtk_entry_new();
       +   gtk_object_set_data(GTK_OBJECT(window),"password",(gpointer)entry);
       +   gtk_entry_set_visibility(GTK_ENTRY(entry),FALSE);
       +   gtk_table_attach_defaults(GTK_TABLE(table),entry,1,2,2,3);
       +
       +   gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,0);
       +
       +   hsep=gtk_hseparator_new();
       +   gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0);
       +
       +   hbbox = gtk_hbutton_box_new();
       +
       +   button=gtk_button_new_with_label(_("OK"));
       +   gtk_signal_connect(GTK_OBJECT(button),"clicked",
       +                      GTK_SIGNAL_FUNC(OKAuthDialog),(gpointer)window);
       +   gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0);
       +
       +   button=gtk_button_new_with_label(_("Cancel"));
       +   gtk_signal_connect_object(GTK_OBJECT(button),"clicked",
       +                             GTK_SIGNAL_FUNC(gtk_widget_destroy),
       +                             (gpointer)window);
       +   gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0);
       +
       +   gtk_box_pack_start(GTK_BOX(vbox),hbbox,TRUE,TRUE,0);
       +
       +   gtk_container_add(GTK_CONTAINER(window),vbox);
       +   gtk_widget_show_all(window);
       +
       +   gtk_main();
       +   return retval;
       +}
       +
        #else
        
        #include <glib.h>
 (DIR) diff --git a/src/network.c b/src/network.c
       t@@ -512,6 +512,9 @@ void CloseHttpConnection(HttpConnection *conn) {
           g_free(conn->Body);
           g_free(conn->RedirHost);
           g_free(conn->RedirQuery);
       +   g_free(conn->realm);
       +   g_free(conn->user);
       +   g_free(conn->password);
           g_free(conn);
        }
        
       t@@ -519,6 +522,19 @@ gboolean IsHttpError(HttpConnection *conn) {
           return IsError(&conn->NetBuf.error);
        }
        
       +void SetHttpAuthentication(HttpConnection *conn,gchar *user,gchar *password) {
       +   g_assert(conn && user && password);
       +   g_free(conn->user);
       +   g_free(conn->password);
       +   conn->user = g_strdup(user);
       +   conn->password = g_strdup(password);
       +}
       +
       +void SetHttpAuthFunc(HttpConnection *conn,HCAuthFunc authfunc) {
       +   g_assert(conn && authfunc);
       +   conn->authfunc = authfunc;
       +}
       +
        static gboolean ParseHtmlLocation(gchar *uri,gchar **host,unsigned *port,
                                          gchar **query) {
          gchar *uris,*colon,*slash;
       t@@ -576,6 +592,7 @@ 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->authfunc)(conn,split[1]);
            }
          }
          g_strfreev(split);
 (DIR) diff --git a/src/network.h b/src/network.h
       t@@ -85,8 +85,12 @@ typedef enum {
           HS_CONNECTING, HS_READHEADERS, HS_READSEPARATOR, HS_READBODY
        } HttpStatus;
        
       +typedef struct _HttpConnection HttpConnection;
       +
       +typedef gboolean (*HCAuthFunc)(struct _HttpConnection *conn,gchar *realm);
       +
        /* A structure used to keep track of an HTTP connection */
       -typedef struct _HttpConnection {
       +struct _HttpConnection {
           gchar *HostName;       /* The machine on which the desired page resides */
           unsigned Port;         /* The port */
           gchar *Proxy;          /* If non-NULL, a web proxy to use */
       t@@ -98,11 +102,16 @@ typedef struct _HttpConnection {
           gchar *RedirHost;      /* if non-NULL, a hostname to redirect to */
           gchar *RedirQuery;     /* if non-NULL, the path to redirect to */
           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 */
       +   gchar *realm;          /* The realm for basic HTTP authentication */
       +   gchar *user;           /* The supplied username */
       +   gchar *password;       /* The supplied password */
           NetworkBuffer NetBuf;  /* The actual network connection itself */
           gint Tries;            /* Number of requests actually sent so far */
           gint StatusCode;       /* 0=no status yet, otherwise an HTTP status code */
           HttpStatus Status;
       -} HttpConnection;
       +};
        
        void InitNetworkBuffer(NetworkBuffer *NetBuf,char Terminator,char StripChar);
        void SetNetworkBufferCallBack(NetworkBuffer *NetBuf,NBCallBack CallBack,
       t@@ -132,6 +141,8 @@ gboolean OpenHttpConnection(HttpConnection **conn,gchar *HostName,
        void CloseHttpConnection(HttpConnection *conn);
        gboolean IsHttpError(HttpConnection *conn);
        gchar *ReadHttpResponse(HttpConnection *conn);
       +void SetHttpAuthentication(HttpConnection *conn,gchar *user,gchar *password);
       +void SetHttpAuthFunc(HttpConnection *conn,HCAuthFunc authfunc);
        gboolean HandleHttpCompletion(HttpConnection *conn);
        
        gboolean StartConnect(int *fd,gchar *RemoteHost,unsigned RemotePort,