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
25static char **
26map (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 **/
149void
150gsasl_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 **/
175void
176gsasl_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 **/
217const char *
218gsasl_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 **/
254const char *
255gsasl_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