1 | /* property.c --- Callback property handling. |
2 | * Copyright (C) 2004-2012 Simon Josefsson |
3 | * |
4 | * This file is part of GNU SASL Library. |
5 | * |
6 | * GNU SASL Library is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU Lesser General Public License |
8 | * as published by the Free Software Foundation; either version 2.1 of |
9 | * the License, or (at your option) any later version. |
10 | * |
11 | * GNU SASL Library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * License License along with GNU SASL Library; if not, write to the |
18 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | * Boston, MA 02110-1301, USA. |
20 | * |
21 | */ |
22 | |
23 | #include "internal.h" |
24 | |
25 | static char ** |
26 | map (Gsasl_session * sctx, Gsasl_property prop) |
27 | { |
28 | char **p = NULL; |
29 | |
30 | if (!sctx) |
31 | return NULL; |
32 | |
33 | switch (prop) |
34 | { |
35 | case GSASL_ANONYMOUS_TOKEN: |
36 | p = &sctx->anonymous_token; |
37 | break; |
38 | |
39 | case GSASL_SERVICE: |
40 | p = &sctx->service; |
41 | break; |
42 | |
43 | case GSASL_HOSTNAME: |
44 | p = &sctx->hostname; |
45 | break; |
46 | |
47 | case GSASL_AUTHID: |
48 | p = &sctx->authid; |
49 | break; |
50 | |
51 | case GSASL_AUTHZID: |
52 | p = &sctx->authzid; |
53 | break; |
54 | |
55 | case GSASL_PASSWORD: |
56 | p = &sctx->password; |
57 | break; |
58 | |
59 | case GSASL_PASSCODE: |
60 | p = &sctx->passcode; |
61 | break; |
62 | |
63 | case GSASL_PIN: |
64 | p = &sctx->pin; |
65 | break; |
66 | |
67 | case GSASL_SUGGESTED_PIN: |
68 | p = &sctx->suggestedpin; |
69 | break; |
70 | |
71 | case GSASL_GSSAPI_DISPLAY_NAME: |
72 | p = &sctx->gssapi_display_name; |
73 | break; |
74 | |
75 | case GSASL_REALM: |
76 | p = &sctx->realm; |
77 | break; |
78 | |
79 | case GSASL_DIGEST_MD5_HASHED_PASSWORD: |
80 | p = &sctx->digest_md5_hashed_password; |
81 | break; |
82 | |
83 | case GSASL_QOPS: |
84 | p = &sctx->qops; |
85 | break; |
86 | |
87 | case GSASL_QOP: |
88 | p = &sctx->qop; |
89 | break; |
90 | |
91 | case GSASL_SCRAM_ITER: |
92 | p = &sctx->scram_iter; |
93 | break; |
94 | |
95 | case GSASL_SCRAM_SALT: |
96 | p = &sctx->scram_salt; |
97 | break; |
98 | |
99 | case GSASL_SCRAM_SALTED_PASSWORD: |
100 | p = &sctx->scram_salted_password; |
101 | break; |
102 | |
103 | case GSASL_CB_TLS_UNIQUE: |
104 | p = &sctx->cb_tls_unique; |
105 | break; |
106 | |
107 | case GSASL_SAML20_IDP_IDENTIFIER: |
108 | p = &sctx->saml20_idp_identifier; |
109 | break; |
110 | |
111 | case GSASL_SAML20_REDIRECT_URL: |
112 | p = &sctx->saml20_redirect_url; |
113 | break; |
114 | |
115 | case GSASL_OPENID20_REDIRECT_URL: |
116 | p = &sctx->openid20_redirect_url; |
117 | break; |
118 | |
119 | case GSASL_OPENID20_OUTCOME_DATA: |
120 | p = &sctx->openid20_outcome_data; |
121 | break; |
122 | |
123 | /* If you add anything here, remember to change change |
124 | gsasl_finish() in xfinish.c and Gsasl_session in |
125 | internal.h. */ |
126 | |
127 | default: |
128 | break; |
129 | } |
130 | |
131 | return p; |
132 | } |
133 | |
134 | /** |
135 | * gsasl_property_set: |
136 | * @sctx: session handle. |
137 | * @prop: enumerated value of Gsasl_property type, indicating the |
138 | * type of data in @data. |
139 | * @data: zero terminated character string to store. |
140 | * |
141 | * Make a copy of @data and store it in the session handle for the |
142 | * indicated property @prop. |
143 | * |
144 | * You can immediately deallocate @data after calling this function, |
145 | * without affecting the data stored in the session handle. |
146 | * |
147 | * Since: 0.2.0 |
148 | **/ |
149 | void |
150 | gsasl_property_set (Gsasl_session * sctx, Gsasl_property prop, |
151 | const char *data) |
152 | { |
153 | gsasl_property_set_raw (sctx, prop, data, data ? strlen (data) : 0); |
154 | } |
155 | |
156 | /** |
157 | * gsasl_property_set_raw: |
158 | * @sctx: session handle. |
159 | * @prop: enumerated value of Gsasl_property type, indicating the |
160 | * type of data in @data. |
161 | * @data: character string to store. |
162 | * @len: length of character string to store. |
163 | * |
164 | * Make a copy of @len sized @data and store a zero terminated version |
165 | * of it in the session handle for the indicated property @prop. |
166 | * |
167 | * You can immediately deallocate @data after calling this function, |
168 | * without affecting the data stored in the session handle. |
169 | * |
170 | * Except for the length indicator, this function is identical to |
171 | * gsasl_property_set. |
172 | * |
173 | * Since: 0.2.0 |
174 | **/ |
175 | void |
176 | gsasl_property_set_raw (Gsasl_session * sctx, Gsasl_property prop, |
177 | const char *data, size_t len) |
178 | { |
179 | char **p = map (sctx, prop); |
180 | |
181 | if (p) |
182 | { |
183 | free (*p); |
184 | if (data) |
185 | { |
186 | *p = malloc (len + 1); |
187 | if (*p) |
188 | { |
189 | memcpy (*p, data, len); |
190 | (*p)[len] = '\0'; |
191 | } |
192 | } |
193 | else |
194 | *p = NULL; |
195 | } |
196 | } |
197 | |
198 | /** |
199 | * gsasl_property_fast: |
200 | * @sctx: session handle. |
201 | * @prop: enumerated value of Gsasl_property type, indicating the |
202 | * type of data in @data. |
203 | * |
204 | * Retrieve the data stored in the session handle for given property |
205 | * @prop. |
206 | * |
207 | * The pointer is to live data, and must not be deallocated or |
208 | * modified in any way. |
209 | * |
210 | * This function will not invoke the application callback. |
211 | * |
212 | * Return value: Return property value, if known, or NULL if no value |
213 | * known. |
214 | * |
215 | * Since: 0.2.0 |
216 | **/ |
217 | const char * |
218 | gsasl_property_fast (Gsasl_session * sctx, Gsasl_property prop) |
219 | { |
220 | char **p = map (sctx, prop); |
221 | |
222 | if (p) |
223 | return *p; |
224 | |
225 | return NULL; |
226 | } |
227 | |
228 | /** |
229 | * gsasl_property_get: |
230 | * @sctx: session handle. |
231 | * @prop: enumerated value of Gsasl_property type, indicating the |
232 | * type of data in @data. |
233 | * |
234 | * Retrieve the data stored in the session handle for given property |
235 | * @prop, possibly invoking the application callback to get the value. |
236 | * |
237 | * The pointer is to live data, and must not be deallocated or |
238 | * modified in any way. |
239 | * |
240 | * This function will invoke the application callback, using |
241 | * gsasl_callback(), when a property value is not known. |
242 | * |
243 | * If no value is known, and no callback is specified or if the |
244 | * callback fail to return data, and if any obsolete callback |
245 | * functions has been set by the application, this function will try |
246 | * to call these obsolete callbacks, and store the returned data as |
247 | * the corresponding property. This behaviour of this function will |
248 | * be removed when the obsolete callback interfaces are removed. |
249 | * |
250 | * Return value: Return data for property, or NULL if no value known. |
251 | * |
252 | * Since: 0.2.0 |
253 | **/ |
254 | const char * |
255 | gsasl_property_get (Gsasl_session * sctx, Gsasl_property prop) |
256 | { |
257 | const char *p = gsasl_property_fast (sctx, prop); |
258 | |
259 | if (!p) |
260 | { |
261 | gsasl_callback (NULL, sctx, prop); |
262 | p = gsasl_property_fast (sctx, prop); |
263 | } |
264 | |
265 | #ifndef GSASL_NO_OBSOLETE |
266 | if (!p) |
267 | p = _gsasl_obsolete_property_map (sctx, prop); |
268 | #endif |
269 | |
270 | return p; |
271 | } |
272 | |