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