NetSurf
login.c
Go to the documentation of this file.
1 /*
2  * Copyright 2006 Rob Kendrick <rjek@rjek.com>
3  *
4  * This file is part of NetSurf, http://www.netsurf-browser.org/
5  *
6  * NetSurf is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * NetSurf is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <stdlib.h>
20 #include <string.h>
21 #include <gtk/gtk.h>
22 
23 #include "utils/log.h"
24 #include "utils/nsurl.h"
25 #include "utils/messages.h"
26 #include "netsurf/url_db.h"
27 
28 #include "gtk/resources.h"
29 #include "gtk/login.h"
30 
31 /** login window session data */
32 struct session_401 {
33  nserror (*cb)(const char *username,
34  const char *password,
35  void *pw); /**< Continuation callback */
36  void *cbpw; /**< Continuation data */
37  GtkBuilder *x; /**< Our builder windows */
38  GtkWindow *wnd; /**< The login window itself */
39  GtkEntry *user; /**< Widget with username */
40  GtkEntry *pass; /**< Widget with password */
41 };
42 
43 /**
44  * Destroy login window and free all associated resources
45  *
46  * \param session The login window session to destroy.
47  */
48 static void destroy_login_window(struct session_401 *session)
49 {
50  gtk_widget_destroy(GTK_WIDGET(session->wnd));
51  g_object_unref(G_OBJECT(session->x));
52  free(session);
53 }
54 
55 
56 /**
57  * process next signal in entry widgets.
58  *
59  * \param w current widget
60  * \param data next widget
61  */
62 static void nsgtk_login_next(GtkWidget *w, gpointer data)
63 {
64  gtk_widget_grab_focus(GTK_WIDGET(data));
65 }
66 
67 
68 /**
69  * handler called when navigation is continued
70  *
71  * \param w current widget
72  * \param data login window session
73  */
74 static void nsgtk_login_ok_clicked(GtkButton *w, gpointer data)
75 {
76  /* close the window and destroy it, having continued the fetch
77  * assoicated with it.
78  */
79 
80  struct session_401 *session = (struct session_401 *)data;
81  const gchar *user;
82  const gchar *pass;
83 
84  user = gtk_entry_get_text(session->user);
85  pass = gtk_entry_get_text(session->pass);
86 
87  session->cb(user, pass, session->cbpw);
88 
89  destroy_login_window(session);
90 }
91 
92 
93 /**
94  * handler called when navigation is cancelled
95  *
96  * \param w widget
97  * \param data login window session
98  */
99 static void nsgtk_login_cancel_clicked(GtkButton *w, gpointer data)
100 {
101  struct session_401 *session = (struct session_401 *) data;
102 
103  session->cb(NULL, NULL, session->cbpw);
104 
105  /* close and destroy the window */
106  destroy_login_window(session);
107 }
108 
109 
110 /**
111  * generate the description of the login request
112  */
113 static nserror
115  const char *realm,
116  const char *username,
117  const char *password,
118  char **out_str)
119 {
120  char *url_s;
121  size_t url_l;
122  nserror res;
123  char *str = NULL;
124  int slen;
125  const char *key;
126 
127  res = nsurl_get(url, NSURL_SCHEME | NSURL_HOST, &url_s, &url_l);
128  if (res != NSERROR_OK) {
129  return res;
130  }
131 
132  if ((*username == 0) && (*password == 0)) {
133  key = "LoginDescription";
134  } else {
135  key = "LoginAgain";
136  }
137 
138  str = messages_get_buff(key, url_s, realm);
139  NSLOG(netsurf, INFO,
140  "key:%s url:%s realm:%s str:%s", key, url_s, realm, str);
141 
142  if ((str != NULL) && (strcmp(key, str) != 0)) {
143  *out_str = str;
144  } else {
145  /* no message so fallback */
146  const char *fmt = "The site %s is requesting your username and password. The realm is \"%s\"";
147  slen = snprintf(str, 0, fmt, url_s, realm) + 1;
148  str = malloc(slen);
149  if (str == NULL) {
150  res = NSERROR_NOMEM;
151  } else {
152  snprintf(str, slen, fmt, url_s, realm);
153  *out_str = str;
154  }
155  }
156 
157  free(url_s);
158 
159  return res;
160 }
161 
162 
163 /**
164  * create a new instance of the login window
165  *
166  * creates login window and handles to all the widgets we're
167  * interested in.
168  *
169  * \param url The url causing the login.
170  * \param host the host being logged into
171  * \param realm realmm the login relates to
172  * \param cb callback when complete
173  * \param cbpw data to pass to callback
174  * \return NSERROR_OK on sucessful window creation or error code on faliure.
175  */
176 static nserror
178  lwc_string *host,
179  const char *realm,
180  const char *username,
181  const char *password,
182  nserror (*cb)(const char *username,
183  const char *password,
184  void *pw),
185  void *cbpw)
186 {
187  nserror res;
188  struct session_401 *session;
189  GtkWindow *wnd;
190  GtkLabel *ldesc;
191  GtkEntry *euser, *epass;
192  GtkButton *bok, *bcan;
193  GtkBuilder *builder;
194  char *description = NULL;
195 
196  session = calloc(1, sizeof(struct session_401));
197  if (session == NULL) {
198  return NSERROR_NOMEM;
199  }
200 
201  res = nsgtk_builder_new_from_resname("login", &builder);
202  if (res != NSERROR_OK) {
203  free(session);
204  return res;
205  }
206 
207  gtk_builder_connect_signals(builder, NULL);
208 
209  wnd = GTK_WINDOW(gtk_builder_get_object(builder, "LoginDialog"));
210  ldesc = GTK_LABEL(gtk_builder_get_object(builder, "LoginDescription"));
211  euser = GTK_ENTRY(gtk_builder_get_object(builder, "LoginUsername"));
212  epass = GTK_ENTRY(gtk_builder_get_object(builder, "LoginPassword"));
213  bok = GTK_BUTTON(gtk_builder_get_object(builder, "LoginOK"));
214  bcan = GTK_BUTTON(gtk_builder_get_object(builder, "LoginCancel"));
215 
216  /* create and fill in our session structure */
217  session->cb = cb;
218  session->cbpw = cbpw;
219  session->x = builder;
220  session->wnd = wnd;
221  session->user = euser;
222  session->pass = epass;
223 
224  /* fill in our new login window */
225  res = get_login_description(url, realm, username, password, &description);
226  if (res == NSERROR_OK) {
227  gtk_label_set_text(GTK_LABEL(ldesc), description);
228  free(description);
229  }
230  gtk_entry_set_text(euser, username);
231  gtk_entry_set_text(epass, password);
232 
233  /* attach signal handlers to the Login and Cancel buttons in our new
234  * window to call functions in this file to process the login
235  */
236  g_signal_connect(G_OBJECT(bok), "clicked",
237  G_CALLBACK(nsgtk_login_ok_clicked), (gpointer)session);
238  g_signal_connect(G_OBJECT(bcan), "clicked",
239  G_CALLBACK(nsgtk_login_cancel_clicked),
240  (gpointer)session);
241 
242  /* attach signal handlers to the entry boxes such that pressing
243  * enter in one progresses the focus onto the next widget.
244  */
245  g_signal_connect(G_OBJECT(euser), "activate",
246  G_CALLBACK(nsgtk_login_next), (gpointer)epass);
247  g_signal_connect(G_OBJECT(epass), "activate",
248  G_CALLBACK(nsgtk_login_next), (gpointer)bok);
249 
250  /* make sure the username entry box currently has the focus */
251  gtk_widget_grab_focus(GTK_WIDGET(euser));
252 
253  /* finally, show the window */
254  gtk_widget_show(GTK_WIDGET(wnd));
255 
256  return NSERROR_OK;
257 }
258 
259 
260 /* exported function documented in gtk/login.h */
261 nserror
263  const char *realm,
264  const char *username,
265  const char *password,
266  nserror (*cb)(const char *username,
267  const char *password,
268  void *pw),
269  void *cbpw)
270 {
271  lwc_string *host;
272  nserror res;
273 
274  host = nsurl_get_component(url, NSURL_HOST);
275  assert(host != NULL);
276 
277  res = create_login_window(url, host, realm, username, password,
278  cb, cbpw);
279  if (res != NSERROR_OK) {
280  NSLOG(netsurf, INFO, "Login init failed");
281 
282  return res;
283  }
284 
285  lwc_string_unref(host);
286 
287  return NSERROR_OK;
288 }
Interface to gtk builtin resource handling.
char * realm
Authentication realm.
Definition: 401login.c:56
static nserror get_login_description(struct nsurl *url, const char *realm, const char *username, const char *password, char **out_str)
generate the description of the login request
Definition: login.c:114
Interface to utility string handling.
GtkEntry * user
Widget with username.
Definition: login.c:39
Localised message support (interface).
lwc_string * host
Host for user display.
Definition: 401login.c:55
void * cbpw
Continuation data.
Definition: login.c:36
Memory exhaustion.
Definition: errors.h:32
nserror gui_401login_open(nsurl *url, const char *realm, const char *username, const char *password, nserror(*cb)(const char *username, const char *password, void *pw), void *cbpw)
login window request.
Definition: login.c:96
GtkBuilder * x
Our builder windows.
Definition: login.c:37
nserror nsurl_get(const nsurl *url, nsurl_component parts, char **url_s, size_t *url_l)
Get URL (section) as a string, from a NetSurf URL object.
static void nsgtk_login_next(GtkWidget *w, gpointer data)
process next signal in entry widgets.
Definition: login.c:62
nserror
Enumeration of error codes.
Definition: errors.h:29
static void nsgtk_login_cancel_clicked(GtkButton *w, gpointer data)
handler called when navigation is cancelled
Definition: login.c:99
Login interfaces.
No error.
Definition: errors.h:30
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:115
nsurl * url
URL being fetched.
Definition: 401login.c:58
static nserror create_login_window(nsurl *url, lwc_string *host, const char *realm, const char *username, const char *password, nserror(*cb)(const char *username, const char *password, void *pw), void *cbpw)
create a new instance of the login window
Definition: login.c:177
lwc_string * nsurl_get_component(const nsurl *url, nsurl_component part)
Get part of a URL as a lwc_string, from a NetSurf URL object.
Unified URL information database public interface.
nserror(* cb)(const char *username, const char *password, void *pw)
Continuation callback.
Definition: login.c:33
GtkWindow * wnd
The login window itself.
Definition: login.c:38
char * messages_get_buff(const char *key,...)
Formatted message from a key in the global message hash.
Definition: messages.c:161
nserror nsgtk_builder_new_from_resname(const char *resname, GtkBuilder **builder_out)
Create gtk builder object for the named ui resource.
Definition: resources.c:522
static void destroy_login_window(struct session_401 *session)
Destroy login window and free all associated resources.
Definition: login.c:48
GtkEntry * pass
Widget with password.
Definition: login.c:40
NetSurf URL handling (interface).
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
login window session data
Definition: login.c:32
static void nsgtk_login_ok_clicked(GtkButton *w, gpointer data)
handler called when navigation is continued
Definition: login.c:74