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