130{
131 int i;
132 size_t auth_object_count;
133 pjsip_www_authenticate_hdr *auth_hdr =
NULL;
134 pj_status_t res = PJ_SUCCESS;
135 pjsip_hdr_e search_type;
136 size_t cred_count;
137 pjsip_cred_info *creds_array;
138
139
140
141
142
143
144
145
146
147
148
149
150 AST_VECTOR(cred_info, pjsip_cred_info) auth_creds;
151
153 if (search_type == PJSIP_H_OTHER) {
154
155
156
157
158
159 return PJ_ENOTSUP;
160 }
161
163 if (auth_object_count == 0) {
164
165 return PJ_EINVAL;
166 }
167
168
169
170
171
172
173
174
175
176
177
179 return PJ_ENOMEM;
180 }
181
182
183
184
185
186
187 while ((auth_hdr = pjsip_msg_find_hdr(
challenge->msg_info.msg,
188 search_type, auth_hdr ? auth_hdr->next :
NULL))) {
189 int exact_match_index = -1;
190 int wildcard_match_index = -1;
191 int match_index = 0;
192 pjsip_cred_info auth_cred;
194
195 memset(&auth_cred, 0, sizeof(auth_cred));
196
197
198
199
200
201
202
203
204
205
206
207
208
210 ast_debug(3,
"Skipping header with realm '%.*s' and unsupported '%.*s' algorithm \n",
211 (int)auth_hdr->challenge.digest.realm.slen, auth_hdr->challenge.digest.realm.ptr,
212 (int)auth_hdr->challenge.digest.algorithm.slen, auth_hdr->challenge.digest.algorithm.ptr);
213 continue;
214 }
215
216
217
218
219
220
221
222 if (*realms) {
224 (int)auth_hdr->challenge.digest.realm.slen, auth_hdr->challenge.digest.realm.ptr);
225 }
226
227 ast_debug(3,
"Searching auths to find matching ones for header with realm '%.*s' and algorithm '%.*s'\n",
228 (int)auth_hdr->challenge.digest.realm.slen, auth_hdr->challenge.digest.realm.ptr,
229 (int)auth_hdr->challenge.digest.algorithm.slen, auth_hdr->challenge.digest.algorithm.ptr);
230
231
232
233
234
235
236
237
238
239
240 for (i = 0; i < auth_object_count; ++i) {
242
243
244
245
246
247
248
249
250 if (pj_stricmp2(&auth_hdr->challenge.digest.realm, auth->
realm) == 0) {
253 exact_match_index = i;
254
255
256
257
258 break;
259 }
260
261
262
263
264
265
266
267
268
269 if (wildcard_match_index < 0
272 (int)auth_hdr->challenge.digest.realm.slen, auth_hdr->challenge.digest.realm.ptr);
273 wildcard_match_index = i;
274 }
275 }
276
277 if (exact_match_index < 0 && wildcard_match_index < 0) {
278
279
280
281
282 ast_debug(3,
"No auth matching realm or no wildcard found for realm '%.*s'\n",
283 (int)auth_hdr->challenge.digest.realm.slen, auth_hdr->challenge.digest.realm.ptr);
284 continue;
285 }
286
287 if (exact_match_index >= 0) {
288
289
290
291 match_index = exact_match_index;
294 (int)auth_hdr->challenge.digest.realm.slen, auth_hdr->challenge.digest.realm.ptr);
295 } else {
296
297
298
299 match_index = wildcard_match_index;
302 (int)auth_hdr->challenge.digest.realm.slen, auth_hdr->challenge.digest.realm.ptr);
303 }
304
305
306
307
308
309 auth_cred.realm = auth_hdr->challenge.common.realm;
310 pj_cstr(&auth_cred.username, auth->
auth_user);
311 pj_cstr(&auth_cred.scheme, "digest");
312 switch (auth->
type) {
314 pj_cstr(&auth_cred.data, auth->
auth_pass);
315 auth_cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
316 break;
318 pj_cstr(&auth_cred.data, auth->
md5_creds);
319 auth_cred.data_type = PJSIP_CRED_DATA_DIGEST;
320 break;
322
323 break;
326 "Trying to set artificial outbound auth credentials shouldn't happen.\n");
327 continue;
328 }
329
330
331
332
333
334
335
336
337
338
339
340
341
342
344 if (res != PJ_SUCCESS) {
345 res = PJ_ENOMEM;
347 }
348 }
349
351
352
353
354
355
356
358 }
359
361
362 res = PJSIP_ENOCREDENTIAL;
364 }
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
383
384 res = pjsip_auth_clt_set_credentials(auth_sess, cred_count, creds_array);
386 if (res == PJ_SUCCESS) {
387 ast_debug(3,
"Set %zu credentials in auth session\n", cred_count);
388 } else {
389 ast_log(
LOG_ERROR,
"Failed to set %zu credentials in auth session\n", cred_count);
390 }
391
394 return res;
395}
#define ast_debug(level,...)
Log a DEBUG message.
@ AST_SIP_AUTH_TYPE_GOOGLE_OAUTH
@ AST_SIP_AUTH_TYPE_ARTIFICIAL
@ AST_SIP_AUTH_TYPE_USER_PASS
static int is_digest_algorithm_supported(pjsip_www_authenticate_hdr *auth_hdr)
static pjsip_hdr_e get_auth_search_type(pjsip_rx_data *challenge)
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
const ast_string_field md5_creds
const ast_string_field realm
const ast_string_field auth_user
const ast_string_field auth_pass
enum ast_sip_auth_type type
#define AST_VECTOR_STEAL_ELEMENTS(vec)
Steal the elements from a vector and reinitialize.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
#define AST_VECTOR(name, type)
Define a vector structure.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.