• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-auth-basic.c: HTTP Basic Authentication
4  *
5  * Copyright (C) 2001-2003, Ximian, Inc.
6  */
7 
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11 
12 #include <string.h>
13 
14 #include "soup-auth-basic.h"
15 #include "soup.h"
16 
17 typedef struct {
18 	char *token;
19 } SoupAuthBasicPrivate;
20 
21 /**
22  * SOUP_TYPE_AUTH_BASIC:
23  *
24  * A #GType corresponding to HTTP "Basic" authentication.
25  * #SoupSessions support this by default; if you want to disable
26  * support for it, call soup_session_remove_feature_by_type(),
27  * passing %SOUP_TYPE_AUTH_BASIC.
28  *
29  * Since: 2.34
30  */
31 
G_DEFINE_TYPE_WITH_PRIVATE(SoupAuthBasic,soup_auth_basic,SOUP_TYPE_AUTH)32 G_DEFINE_TYPE_WITH_PRIVATE (SoupAuthBasic, soup_auth_basic, SOUP_TYPE_AUTH)
33 
34 static void
35 soup_auth_basic_init (SoupAuthBasic *basic)
36 {
37 }
38 
39 static void
soup_auth_basic_finalize(GObject * object)40 soup_auth_basic_finalize (GObject *object)
41 {
42 	SoupAuthBasicPrivate *priv = soup_auth_basic_get_instance_private (SOUP_AUTH_BASIC (object));
43 
44 	g_free (priv->token);
45 
46 	G_OBJECT_CLASS (soup_auth_basic_parent_class)->finalize (object);
47 }
48 
49 static gboolean
soup_auth_basic_update(SoupAuth * auth,SoupMessage * msg,GHashTable * auth_params)50 soup_auth_basic_update (SoupAuth *auth, SoupMessage *msg,
51 			GHashTable *auth_params)
52 {
53 	SoupAuthBasicPrivate *priv = soup_auth_basic_get_instance_private (SOUP_AUTH_BASIC (auth));
54 
55 	/* If we're updating a pre-existing auth, the
56 	 * username/password must be bad now, so forget it.
57 	 * Other than that, there's nothing to do here.
58 	 */
59 	if (priv->token) {
60 		memset (priv->token, 0, strlen (priv->token));
61 		g_free (priv->token);
62 		priv->token = NULL;
63 	}
64 
65 	return TRUE;
66 }
67 
68 static GSList *
soup_auth_basic_get_protection_space(SoupAuth * auth,SoupURI * source_uri)69 soup_auth_basic_get_protection_space (SoupAuth *auth, SoupURI *source_uri)
70 {
71 	char *space, *p;
72 
73 	space = g_strdup (source_uri->path);
74 
75 	/* Strip filename component */
76 	p = strrchr (space, '/');
77 	if (p == space && p[1])
78 		p[1] = '\0';
79 	else if (p && p[1])
80 		*p = '\0';
81 
82 	return g_slist_prepend (NULL, space);
83 }
84 
85 static void
soup_auth_basic_authenticate(SoupAuth * auth,const char * username,const char * password)86 soup_auth_basic_authenticate (SoupAuth *auth, const char *username,
87 			      const char *password)
88 {
89 	SoupAuthBasicPrivate *priv = soup_auth_basic_get_instance_private (SOUP_AUTH_BASIC (auth));
90 	char *user_pass, *user_pass_latin1;
91 	int len;
92 
93 	user_pass = g_strdup_printf ("%s:%s", username, password);
94 	user_pass_latin1 = g_convert (user_pass, -1, "ISO-8859-1", "UTF-8",
95 				      NULL, NULL, NULL);
96 	if (user_pass_latin1) {
97 		memset (user_pass, 0, strlen (user_pass));
98 		g_free (user_pass);
99 		user_pass = user_pass_latin1;
100 	}
101 	len = strlen (user_pass);
102 
103 	if (priv->token) {
104 		memset (priv->token, 0, strlen (priv->token));
105 		g_free (priv->token);
106 	}
107 	priv->token = g_base64_encode ((guchar *)user_pass, len);
108 
109 	memset (user_pass, 0, len);
110 	g_free (user_pass);
111 }
112 
113 static gboolean
soup_auth_basic_is_authenticated(SoupAuth * auth)114 soup_auth_basic_is_authenticated (SoupAuth *auth)
115 {
116 	SoupAuthBasicPrivate *priv = soup_auth_basic_get_instance_private (SOUP_AUTH_BASIC (auth));
117 
118 	return priv->token != NULL;
119 }
120 
121 static char *
soup_auth_basic_get_authorization(SoupAuth * auth,SoupMessage * msg)122 soup_auth_basic_get_authorization (SoupAuth *auth, SoupMessage *msg)
123 {
124 	SoupAuthBasicPrivate *priv = soup_auth_basic_get_instance_private (SOUP_AUTH_BASIC (auth));
125 
126 	return g_strdup_printf ("Basic %s", priv->token);
127 }
128 
129 static void
soup_auth_basic_class_init(SoupAuthBasicClass * auth_basic_class)130 soup_auth_basic_class_init (SoupAuthBasicClass *auth_basic_class)
131 {
132 	SoupAuthClass *auth_class = SOUP_AUTH_CLASS (auth_basic_class);
133 	GObjectClass *object_class = G_OBJECT_CLASS (auth_basic_class);
134 
135 	auth_class->scheme_name = "Basic";
136 	auth_class->strength = 1;
137 
138 	auth_class->update = soup_auth_basic_update;
139 	auth_class->get_protection_space = soup_auth_basic_get_protection_space;
140 	auth_class->authenticate = soup_auth_basic_authenticate;
141 	auth_class->is_authenticated = soup_auth_basic_is_authenticated;
142 	auth_class->get_authorization = soup_auth_basic_get_authorization;
143 
144 	object_class->finalize = soup_auth_basic_finalize;
145 }
146