233 lines
6.3 KiB
C
233 lines
6.3 KiB
C
/*
|
|
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
|
|
*
|
|
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
|
*
|
|
* NetSurf is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* NetSurf is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "utils/log.h"
|
|
#include "utils/nsurl.h"
|
|
#include "content/urldb.h"
|
|
|
|
#include "gtk/resources.h"
|
|
#include "gtk/login.h"
|
|
|
|
/** login window session data */
|
|
struct session_401 {
|
|
nsurl *url; /**< URL being fetched */
|
|
lwc_string *host; /**< Host for user display */
|
|
char *realm; /**< Authentication realm */
|
|
nserror (*cb)(bool proceed, void *pw); /**< Continuation callback */
|
|
void *cbpw; /**< Continuation data */
|
|
GtkBuilder *x; /**< Our builder windows */
|
|
GtkWindow *wnd; /**< The login window itself */
|
|
GtkEntry *user; /**< Widget with username */
|
|
GtkEntry *pass; /**< Widget with password */
|
|
};
|
|
|
|
/**
|
|
* Destroy login window and free all associated resources
|
|
*
|
|
* \param session The login window session to destroy.
|
|
*/
|
|
static void destroy_login_window(struct session_401 *session)
|
|
{
|
|
nsurl_unref(session->url);
|
|
lwc_string_unref(session->host);
|
|
free(session->realm);
|
|
gtk_widget_destroy(GTK_WIDGET(session->wnd));
|
|
g_object_unref(G_OBJECT(session->x));
|
|
free(session);
|
|
}
|
|
|
|
|
|
/**
|
|
* process next signal in entry widgets.
|
|
*
|
|
* \param w current widget
|
|
* \param data next widget
|
|
*/
|
|
static void nsgtk_login_next(GtkWidget *w, gpointer data)
|
|
{
|
|
gtk_widget_grab_focus(GTK_WIDGET(data));
|
|
}
|
|
|
|
|
|
/**
|
|
* handler called when navigation is continued
|
|
*
|
|
* \param w current widget
|
|
* \param data login window session
|
|
*/
|
|
static void nsgtk_login_ok_clicked(GtkButton *w, gpointer data)
|
|
{
|
|
/* close the window and destroy it, having continued the fetch
|
|
* assoicated with it.
|
|
*/
|
|
|
|
struct session_401 *session = (struct session_401 *)data;
|
|
const gchar *user = gtk_entry_get_text(session->user);
|
|
const gchar *pass = gtk_entry_get_text(session->pass);
|
|
char *auth;
|
|
|
|
auth = malloc(strlen(user) + strlen(pass) + 2);
|
|
sprintf(auth, "%s:%s", user, pass);
|
|
urldb_set_auth_details(session->url, session->realm, auth);
|
|
free(auth);
|
|
|
|
session->cb(true, session->cbpw);
|
|
|
|
destroy_login_window(session);
|
|
}
|
|
|
|
|
|
/**
|
|
* handler called when navigation is cancelled
|
|
*
|
|
* \param w widget
|
|
* \param data login window session
|
|
*/
|
|
static void nsgtk_login_cancel_clicked(GtkButton *w, gpointer data)
|
|
{
|
|
struct session_401 *session = (struct session_401 *) data;
|
|
|
|
session->cb(false, session->cbpw);
|
|
|
|
/* close and destroy the window */
|
|
destroy_login_window(session);
|
|
}
|
|
|
|
|
|
/**
|
|
* create a new instance of the login window
|
|
*
|
|
* creates login window and handles to all the widgets we're
|
|
* interested in.
|
|
*
|
|
* \param url The url causing the login.
|
|
* \param host the host being logged into
|
|
* \param realm realmm the login relates to
|
|
* \param cb callback when complete
|
|
* \param cbpw data to pass to callback
|
|
* \return NSERROR_OK on sucessful window creation or error code on faliure.
|
|
*/
|
|
static nserror
|
|
create_login_window(nsurl *url,
|
|
lwc_string *host,
|
|
const char *realm,
|
|
nserror (*cb)(bool proceed, void *pw),
|
|
void *cbpw)
|
|
{
|
|
struct session_401 *session;
|
|
GtkWindow *wnd;
|
|
GtkLabel *lhost, *lrealm;
|
|
GtkEntry *euser, *epass;
|
|
GtkButton *bok, *bcan;
|
|
GtkBuilder* builder;
|
|
nserror res;
|
|
|
|
session = calloc(1, sizeof(struct session_401));
|
|
if (session == NULL) {
|
|
return NSERROR_NOMEM;
|
|
}
|
|
|
|
res = nsgtk_builder_new_from_resname("login", &builder);
|
|
if (res != NSERROR_OK) {
|
|
free(session);
|
|
return res;
|
|
}
|
|
|
|
gtk_builder_connect_signals(builder, NULL);
|
|
|
|
wnd = GTK_WINDOW(gtk_builder_get_object(builder, "wndLogin"));
|
|
lhost = GTK_LABEL(gtk_builder_get_object(builder, "labelLoginHost"));
|
|
lrealm = GTK_LABEL(gtk_builder_get_object(builder, "labelLoginRealm"));
|
|
euser = GTK_ENTRY(gtk_builder_get_object(builder, "entryLoginUser"));
|
|
epass = GTK_ENTRY(gtk_builder_get_object(builder, "entryLoginPass"));
|
|
bok = GTK_BUTTON(gtk_builder_get_object(builder, "buttonLoginOK"));
|
|
bcan = GTK_BUTTON(gtk_builder_get_object(builder, "buttonLoginCan"));
|
|
|
|
/* create and fill in our session structure */
|
|
session->url = nsurl_ref(url);
|
|
session->host = lwc_string_ref(host);
|
|
session->realm = strdup(realm ? realm : "Secure Area");
|
|
session->cb = cb;
|
|
session->cbpw = cbpw;
|
|
session->x = builder;
|
|
session->wnd = wnd;
|
|
session->user = euser;
|
|
session->pass = epass;
|
|
|
|
/* fill in our new login window */
|
|
|
|
gtk_label_set_text(GTK_LABEL(lhost), lwc_string_data(host));
|
|
gtk_label_set_text(lrealm, realm);
|
|
gtk_entry_set_text(euser, "");
|
|
gtk_entry_set_text(epass, "");
|
|
|
|
/* attach signal handlers to the Login and Cancel buttons in our new
|
|
* window to call functions in this file to process the login
|
|
*/
|
|
g_signal_connect(G_OBJECT(bok), "clicked",
|
|
G_CALLBACK(nsgtk_login_ok_clicked), (gpointer)session);
|
|
g_signal_connect(G_OBJECT(bcan), "clicked",
|
|
G_CALLBACK(nsgtk_login_cancel_clicked),
|
|
(gpointer)session);
|
|
|
|
/* attach signal handlers to the entry boxes such that pressing
|
|
* enter in one progresses the focus onto the next widget.
|
|
*/
|
|
|
|
g_signal_connect(G_OBJECT(euser), "activate",
|
|
G_CALLBACK(nsgtk_login_next), (gpointer)epass);
|
|
g_signal_connect(G_OBJECT(epass), "activate",
|
|
G_CALLBACK(nsgtk_login_next), (gpointer)bok);
|
|
|
|
/* make sure the username entry box currently has the focus */
|
|
gtk_widget_grab_focus(GTK_WIDGET(euser));
|
|
|
|
/* finally, show the window */
|
|
gtk_widget_show(GTK_WIDGET(wnd));
|
|
|
|
return NSERROR_OK;
|
|
}
|
|
|
|
|
|
/* exported function documented in gtk/login.h */
|
|
void gui_401login_open(nsurl *url,
|
|
const char *realm,
|
|
nserror (*cb)(bool proceed, void *pw),
|
|
void *cbpw)
|
|
{
|
|
lwc_string *host;
|
|
nserror res;
|
|
|
|
host = nsurl_get_component(url, NSURL_HOST);
|
|
assert(host != NULL);
|
|
|
|
res = create_login_window(url, host, realm, cb, cbpw);
|
|
if (res != NSERROR_OK) {
|
|
LOG("Login init failed");
|
|
|
|
/* creating login failed so cancel navigation */
|
|
cb(false, cbpw);
|
|
}
|
|
|
|
lwc_string_unref(host);
|
|
}
|