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-headers.h" |
---|
16 | #include "soup-message.h" |
---|
17 | #include "soup-misc.h" |
---|
18 | #include "soup-uri.h" |
---|
19 | |
---|
20 | static void construct (SoupAuth *auth, const char *header); |
---|
21 | static GSList *get_protection_space (SoupAuth *auth, const SoupUri *source_uri); |
---|
22 | static const char *get_realm (SoupAuth *auth); |
---|
23 | static void authenticate (SoupAuth *auth, const char *username, const char *password); |
---|
24 | static gboolean is_authenticated (SoupAuth *auth); |
---|
25 | static char *get_authorization (SoupAuth *auth, SoupMessage *msg); |
---|
26 | |
---|
27 | struct SoupAuthBasicPrivate { |
---|
28 | char *realm, *token; |
---|
29 | }; |
---|
30 | |
---|
31 | #define PARENT_TYPE SOUP_TYPE_AUTH |
---|
32 | static SoupAuthClass *parent_class; |
---|
33 | |
---|
34 | static void |
---|
35 | init (GObject *object) |
---|
36 | { |
---|
37 | SoupAuthBasic *basic = SOUP_AUTH_BASIC (object); |
---|
38 | |
---|
39 | basic->priv = g_new0 (SoupAuthBasicPrivate, 1); |
---|
40 | } |
---|
41 | |
---|
42 | static void |
---|
43 | finalize (GObject *object) |
---|
44 | { |
---|
45 | SoupAuthBasic *basic = SOUP_AUTH_BASIC (object); |
---|
46 | |
---|
47 | g_free (basic->priv->realm); |
---|
48 | g_free (basic->priv->token); |
---|
49 | g_free (basic->priv); |
---|
50 | |
---|
51 | G_OBJECT_CLASS (parent_class)->finalize (object); |
---|
52 | } |
---|
53 | |
---|
54 | static void |
---|
55 | class_init (GObjectClass *object_class) |
---|
56 | { |
---|
57 | SoupAuthClass *auth_class = SOUP_AUTH_CLASS (object_class); |
---|
58 | |
---|
59 | parent_class = g_type_class_ref (PARENT_TYPE); |
---|
60 | |
---|
61 | auth_class->scheme_name = "Basic"; |
---|
62 | |
---|
63 | auth_class->construct = construct; |
---|
64 | auth_class->get_protection_space = get_protection_space; |
---|
65 | auth_class->get_realm = get_realm; |
---|
66 | auth_class->authenticate = authenticate; |
---|
67 | auth_class->is_authenticated = is_authenticated; |
---|
68 | auth_class->get_authorization = get_authorization; |
---|
69 | |
---|
70 | object_class->finalize = finalize; |
---|
71 | } |
---|
72 | |
---|
73 | SOUP_MAKE_TYPE (soup_auth_basic, SoupAuthBasic, class_init, init, PARENT_TYPE) |
---|
74 | |
---|
75 | |
---|
76 | static void |
---|
77 | construct (SoupAuth *auth, const char *header) |
---|
78 | { |
---|
79 | SoupAuthBasic *basic = SOUP_AUTH_BASIC (auth); |
---|
80 | GHashTable *tokens; |
---|
81 | |
---|
82 | header += sizeof ("Basic"); |
---|
83 | |
---|
84 | tokens = soup_header_param_parse_list (header); |
---|
85 | if (!tokens) |
---|
86 | return; |
---|
87 | |
---|
88 | basic->priv->realm = soup_header_param_copy_token (tokens, "realm"); |
---|
89 | soup_header_param_destroy_hash (tokens); |
---|
90 | } |
---|
91 | |
---|
92 | static GSList * |
---|
93 | get_protection_space (SoupAuth *auth, const SoupUri *source_uri) |
---|
94 | { |
---|
95 | char *space, *p; |
---|
96 | |
---|
97 | space = g_strdup (source_uri->path); |
---|
98 | |
---|
99 | /* Strip query and filename component */ |
---|
100 | p = strrchr (space, '/'); |
---|
101 | if (p && p != space && p[1]) |
---|
102 | *p = '\0'; |
---|
103 | |
---|
104 | return g_slist_prepend (NULL, space); |
---|
105 | } |
---|
106 | |
---|
107 | static const char * |
---|
108 | get_realm (SoupAuth *auth) |
---|
109 | { |
---|
110 | SoupAuthBasic *basic = SOUP_AUTH_BASIC (auth); |
---|
111 | |
---|
112 | return basic->priv->realm; |
---|
113 | } |
---|
114 | |
---|
115 | static void |
---|
116 | authenticate (SoupAuth *auth, const char *username, const char *password) |
---|
117 | { |
---|
118 | SoupAuthBasic *basic = SOUP_AUTH_BASIC (auth); |
---|
119 | char *user_pass; |
---|
120 | int len; |
---|
121 | |
---|
122 | g_return_if_fail (username != NULL); |
---|
123 | g_return_if_fail (password != NULL); |
---|
124 | |
---|
125 | user_pass = g_strdup_printf ("%s:%s", username, password); |
---|
126 | len = strlen (user_pass); |
---|
127 | |
---|
128 | basic->priv->token = soup_base64_encode (user_pass, len); |
---|
129 | |
---|
130 | memset (user_pass, 0, len); |
---|
131 | g_free (user_pass); |
---|
132 | } |
---|
133 | |
---|
134 | static gboolean |
---|
135 | is_authenticated (SoupAuth *auth) |
---|
136 | { |
---|
137 | SoupAuthBasic *basic = SOUP_AUTH_BASIC (auth); |
---|
138 | |
---|
139 | return basic->priv->token != NULL; |
---|
140 | } |
---|
141 | |
---|
142 | static char * |
---|
143 | get_authorization (SoupAuth *auth, SoupMessage *msg) |
---|
144 | { |
---|
145 | SoupAuthBasic *basic = SOUP_AUTH_BASIC (auth); |
---|
146 | |
---|
147 | return g_strdup_printf ("Basic %s", basic->priv->token); |
---|
148 | } |
---|