1 /***************************************************************************
2 * authentication.c
3 *
4 * Fri Jul 16 12:08:34 2004
5 * Copyright 2004-2009 Simon MORLAT
6 * simon.morlat@linphone.org
7 ****************************************************************************/
8
9 /*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 */
24
25 #include "linphone/core.h"
26 #include "private.h"
27 #include "linphone/lpconfig.h"
28
29 static void _linphone_auth_info_uninit(LinphoneAuthInfo *obj);
30 static void _linphone_auth_info_copy(LinphoneAuthInfo *dst, const LinphoneAuthInfo *src);
31
32 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneAuthInfo);
33 BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAuthInfo);
34 BELLE_SIP_INSTANCIATE_VPTR(
35 LinphoneAuthInfo,
36 belle_sip_object_t,
37 _linphone_auth_info_uninit, // destroy
38 _linphone_auth_info_copy, // clone
39 NULL, // marshal
40 FALSE
41 );
42
linphone_auth_info_new(const char * username,const char * userid,const char * passwd,const char * ha1,const char * realm,const char * domain)43 LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm, const char *domain){
44 LinphoneAuthInfo *obj=belle_sip_object_new(LinphoneAuthInfo);
45 if (username!=NULL && (strlen(username)>0) ) obj->username=ms_strdup(username);
46 if (userid!=NULL && (strlen(userid)>0)) obj->userid=ms_strdup(userid);
47 if (passwd!=NULL && (strlen(passwd)>0)) obj->passwd=ms_strdup(passwd);
48 if (ha1!=NULL && (strlen(ha1)>0)) obj->ha1=ms_strdup(ha1);
49 if (realm!=NULL && (strlen(realm)>0)) obj->realm=ms_strdup(realm);
50 if (domain!=NULL && (strlen(domain)>0)) obj->domain=ms_strdup(domain);
51 return obj;
52 }
53
_linphone_auth_info_copy(LinphoneAuthInfo * dst,const LinphoneAuthInfo * src)54 static void _linphone_auth_info_copy(LinphoneAuthInfo *dst, const LinphoneAuthInfo *src) {
55 if (src->username) dst->username = ms_strdup(src->username);
56 if (src->userid) dst->userid = ms_strdup(src->userid);
57 if (src->passwd) dst->passwd = ms_strdup(src->passwd);
58 if (src->ha1) dst->ha1 = ms_strdup(src->ha1);
59 if (src->realm) dst->realm = ms_strdup(src->realm);
60 if (src->domain) dst->domain = ms_strdup(src->domain);
61 if (src->tls_cert) dst->tls_cert = ms_strdup(src->tls_cert);
62 if (src->tls_key) dst->tls_key = ms_strdup(src->tls_key);
63 if (src->tls_cert_path) dst->tls_cert_path = ms_strdup(src->tls_cert_path);
64 if (src->tls_key_path) dst->tls_key_path = ms_strdup(src->tls_key_path);
65 }
66
linphone_auth_info_clone(const LinphoneAuthInfo * ai)67 LinphoneAuthInfo *linphone_auth_info_clone(const LinphoneAuthInfo *ai){
68 return LINPHONE_AUTH_INFO(belle_sip_object_clone(BELLE_SIP_OBJECT(ai)));
69 }
70
linphone_auth_info_ref(LinphoneAuthInfo * obj)71 LinphoneAuthInfo *linphone_auth_info_ref(LinphoneAuthInfo *obj) {
72 return LINPHONE_AUTH_INFO(belle_sip_object_ref(obj));
73 }
74
linphone_auth_info_unref(LinphoneAuthInfo * obj)75 void linphone_auth_info_unref(LinphoneAuthInfo *obj) {
76 belle_sip_object_unref(obj);
77 }
78
linphone_auth_info_get_username(const LinphoneAuthInfo * i)79 const char *linphone_auth_info_get_username(const LinphoneAuthInfo *i) {
80 return i->username;
81 }
82
linphone_auth_info_get_passwd(const LinphoneAuthInfo * i)83 const char *linphone_auth_info_get_passwd(const LinphoneAuthInfo *i) {
84 return i->passwd;
85 }
86
linphone_auth_info_get_userid(const LinphoneAuthInfo * i)87 const char *linphone_auth_info_get_userid(const LinphoneAuthInfo *i) {
88 return i->userid;
89 }
90
linphone_auth_info_get_realm(const LinphoneAuthInfo * i)91 const char *linphone_auth_info_get_realm(const LinphoneAuthInfo *i) {
92 return i->realm;
93 }
94
linphone_auth_info_get_domain(const LinphoneAuthInfo * i)95 const char *linphone_auth_info_get_domain(const LinphoneAuthInfo *i) {
96 return i->domain;
97 }
98
linphone_auth_info_get_ha1(const LinphoneAuthInfo * i)99 const char *linphone_auth_info_get_ha1(const LinphoneAuthInfo *i) {
100 return i->ha1;
101 }
102
linphone_auth_info_get_tls_cert(const LinphoneAuthInfo * i)103 const char *linphone_auth_info_get_tls_cert(const LinphoneAuthInfo *i) {
104 return i->tls_cert;
105 }
106
linphone_auth_info_get_tls_key(const LinphoneAuthInfo * i)107 const char *linphone_auth_info_get_tls_key(const LinphoneAuthInfo *i) {
108 return i->tls_key;
109 }
110
linphone_auth_info_get_tls_cert_path(const LinphoneAuthInfo * i)111 const char *linphone_auth_info_get_tls_cert_path(const LinphoneAuthInfo *i) {
112 return i->tls_cert_path;
113 }
114
linphone_auth_info_get_tls_key_path(const LinphoneAuthInfo * i)115 const char *linphone_auth_info_get_tls_key_path(const LinphoneAuthInfo *i) {
116 return i->tls_key_path;
117 }
118
119
linphone_auth_info_set_passwd(LinphoneAuthInfo * info,const char * passwd)120 void linphone_auth_info_set_passwd(LinphoneAuthInfo *info, const char *passwd) {
121 if (info->passwd) {
122 ms_free(info->passwd);
123 info->passwd = NULL;
124 }
125 if (passwd && strlen(passwd) > 0) info->passwd = ms_strdup(passwd);
126 }
127
linphone_auth_info_set_username(LinphoneAuthInfo * info,const char * username)128 void linphone_auth_info_set_username(LinphoneAuthInfo *info, const char *username) {
129 if (info->username) {
130 ms_free(info->username);
131 info->username = NULL;
132 }
133 if (username && strlen(username) > 0) info->username = ms_strdup(username);
134 }
135
linphone_auth_info_set_userid(LinphoneAuthInfo * info,const char * userid)136 void linphone_auth_info_set_userid(LinphoneAuthInfo *info, const char *userid) {
137 if (info->userid) {
138 ms_free(info->userid);
139 info->userid = NULL;
140 }
141 if (userid && strlen(userid) > 0) info->userid = ms_strdup(userid);
142 }
143
linphone_auth_info_set_realm(LinphoneAuthInfo * info,const char * realm)144 void linphone_auth_info_set_realm(LinphoneAuthInfo *info, const char *realm) {
145 if (info->realm) {
146 ms_free(info->realm);
147 info->realm = NULL;
148 }
149 if (realm && strlen(realm) > 0) info->realm = ms_strdup(realm);
150 }
151
linphone_auth_info_set_domain(LinphoneAuthInfo * info,const char * domain)152 void linphone_auth_info_set_domain(LinphoneAuthInfo *info, const char *domain) {
153 if (info->domain) {
154 ms_free(info->domain);
155 info->domain = NULL;
156 }
157 if (domain && strlen(domain) > 0) info->domain = ms_strdup(domain);
158 }
159
linphone_auth_info_set_ha1(LinphoneAuthInfo * info,const char * ha1)160 void linphone_auth_info_set_ha1(LinphoneAuthInfo *info, const char *ha1) {
161 if (info->ha1) {
162 ms_free(info->ha1);
163 info->ha1 = NULL;
164 }
165 if (ha1 && strlen(ha1) > 0) info->ha1 = ms_strdup(ha1);
166 }
167
linphone_auth_info_set_tls_cert(LinphoneAuthInfo * info,const char * tls_cert)168 void linphone_auth_info_set_tls_cert(LinphoneAuthInfo *info, const char *tls_cert) {
169 if (info->tls_cert) {
170 ms_free(info->tls_cert);
171 info->tls_cert = NULL;
172 }
173 if (tls_cert && strlen(tls_cert) > 0) info->tls_cert = ms_strdup(tls_cert);
174 }
175
linphone_auth_info_set_tls_key(LinphoneAuthInfo * info,const char * tls_key)176 void linphone_auth_info_set_tls_key(LinphoneAuthInfo *info, const char *tls_key) {
177 if (info->tls_key) {
178 ms_free(info->tls_key);
179 info->tls_key = NULL;
180 }
181 if (tls_key && strlen(tls_key) > 0) info->tls_key = ms_strdup(tls_key);
182 }
183
linphone_auth_info_set_tls_cert_path(LinphoneAuthInfo * info,const char * tls_cert_path)184 void linphone_auth_info_set_tls_cert_path(LinphoneAuthInfo *info, const char *tls_cert_path) {
185 if (info->tls_cert_path) {
186 ms_free(info->tls_cert_path);
187 info->tls_cert_path = NULL;
188 }
189 if (tls_cert_path && strlen(tls_cert_path) > 0) info->tls_cert_path = ms_strdup(tls_cert_path);
190 }
191
linphone_auth_info_set_tls_key_path(LinphoneAuthInfo * info,const char * tls_key_path)192 void linphone_auth_info_set_tls_key_path(LinphoneAuthInfo *info, const char *tls_key_path) {
193 if (info->tls_key_path) {
194 ms_free(info->tls_key_path);
195 info->tls_key_path = NULL;
196 }
197 if (tls_key_path && strlen(tls_key_path) > 0) info->tls_key_path = ms_strdup(tls_key_path);
198 }
199
_linphone_auth_info_uninit(LinphoneAuthInfo * obj)200 static void _linphone_auth_info_uninit(LinphoneAuthInfo *obj) {
201 if (obj->username != NULL) ms_free(obj->username);
202 if (obj->userid != NULL) ms_free(obj->userid);
203 if (obj->passwd != NULL) ms_free(obj->passwd);
204 if (obj->ha1 != NULL) ms_free(obj->ha1);
205 if (obj->realm != NULL) ms_free(obj->realm);
206 if (obj->domain != NULL) ms_free(obj->domain);
207 if (obj->tls_cert != NULL) ms_free(obj->tls_cert);
208 if (obj->tls_key != NULL) ms_free(obj->tls_key);
209 if (obj->tls_cert_path != NULL) ms_free(obj->tls_cert_path);
210 if (obj->tls_key_path != NULL) ms_free(obj->tls_key_path);
211 }
212
213 /**
214 * Destroys a LinphoneAuthInfo object.
215 **/
linphone_auth_info_destroy(LinphoneAuthInfo * obj)216 void linphone_auth_info_destroy(LinphoneAuthInfo *obj){
217 belle_sip_object_unref(obj);
218 }
219
linphone_auth_info_write_config(LpConfig * config,LinphoneAuthInfo * obj,int pos)220 void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, int pos) {
221 char key[50];
222 bool_t store_ha1_passwd = lp_config_get_int(config, "sip", "store_ha1_passwd", 1);
223
224 sprintf(key, "auth_info_%i", pos);
225 lp_config_clean_section(config, key);
226
227 if (obj == NULL || lp_config_get_int(config, "sip", "store_auth_info", 1) == 0) {
228 return;
229 }
230 if (!obj->ha1 && obj->realm && obj->passwd && (obj->username || obj->userid) && store_ha1_passwd) {
231 /*compute ha1 to avoid storing clear text password*/
232 obj->ha1 = ms_malloc(33);
233 sal_auth_compute_ha1(obj->userid ? obj->userid : obj->username, obj->realm, obj->passwd, obj->ha1);
234 }
235 if (obj->username != NULL) {
236 lp_config_set_string(config, key, "username", obj->username);
237 }
238 if (obj->userid != NULL) {
239 lp_config_set_string(config, key, "userid", obj->userid);
240 }
241 if (obj->ha1 != NULL) {
242 lp_config_set_string(config, key, "ha1", obj->ha1);
243 }
244 if (obj->passwd != NULL) {
245 if (store_ha1_passwd && obj->ha1) {
246 /*if we have our ha1 and store_ha1_passwd set to TRUE, then drop the clear text password for security*/
247 linphone_auth_info_set_passwd(obj, NULL);
248 } else {
249 /*we store clear text password only if store_ha1_passwd is FALSE AND we have an ha1 to store. Otherwise, passwd would simply be removed, which might bring major auth issue*/
250 lp_config_set_string(config, key, "passwd", obj->passwd);
251 }
252 }
253 if (obj->realm != NULL) {
254 lp_config_set_string(config, key, "realm", obj->realm);
255 }
256 if (obj->domain != NULL) {
257 lp_config_set_string(config, key, "domain", obj->domain);
258 }
259 if (obj->tls_cert_path != NULL) {
260 lp_config_set_string(config, key, "client_cert_chain", obj->tls_cert_path);
261 }
262 if (obj->tls_key_path != NULL) {
263 lp_config_set_string(config, key, "client_cert_key", obj->tls_key_path);
264 }
265 }
266
linphone_auth_info_new_from_config_file(LpConfig * config,int pos)267 LinphoneAuthInfo *linphone_auth_info_new_from_config_file(LpConfig * config, int pos)
268 {
269 char key[50];
270 const char *username,*userid,*passwd,*ha1,*realm,*domain,*tls_cert_path,*tls_key_path;
271 LinphoneAuthInfo *ret;
272
273 sprintf(key, "auth_info_%i", pos);
274 if (!lp_config_has_section(config, key)) {
275 return NULL;
276 }
277
278 username = lp_config_get_string(config, key, "username", NULL);
279 userid = lp_config_get_string(config, key, "userid", NULL);
280 passwd = lp_config_get_string(config, key, "passwd", NULL);
281 ha1 = lp_config_get_string(config, key, "ha1", NULL);
282 realm = lp_config_get_string(config, key, "realm", NULL);
283 domain = lp_config_get_string(config, key, "domain", NULL);
284 tls_cert_path = lp_config_get_string(config, key, "client_cert_chain", NULL);
285 tls_key_path = lp_config_get_string(config, key, "client_cert_key", NULL);
286 ret = linphone_auth_info_new(username, userid, passwd, ha1, realm, domain);
287 linphone_auth_info_set_tls_cert_path(ret, tls_cert_path);
288 linphone_auth_info_set_tls_key_path(ret, tls_key_path);
289 return ret;
290 }
291
remove_quotes(char * input)292 static char * remove_quotes(char * input){
293 char *tmp;
294 if (*input=='"') input++;
295 tmp=strchr(input,'"');
296 if (tmp) *tmp='\0';
297 return input;
298 }
299
realm_match(const char * realm1,const char * realm2)300 static bool_t realm_match(const char *realm1, const char *realm2){
301 if (realm1==NULL && realm2==NULL) return TRUE;
302 if (realm1!=NULL && realm2!=NULL){
303 if (strcmp(realm1,realm2)==0) return TRUE;
304 else{
305 char tmp1[128];
306 char tmp2[128];
307 char *p1,*p2;
308 strncpy(tmp1,realm1,sizeof(tmp1)-1);
309 strncpy(tmp2,realm2,sizeof(tmp2)-1);
310 p1=remove_quotes(tmp1);
311 p2=remove_quotes(tmp2);
312 return strcmp(p1,p2)==0;
313 }
314 }
315 return FALSE;
316 }
317
find_auth_info(LinphoneCore * lc,const char * username,const char * realm,const char * domain,bool_t ignore_realm)318 static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *username, const char *realm, const char *domain, bool_t ignore_realm){
319 bctbx_list_t *elem;
320 const LinphoneAuthInfo *ret=NULL;
321
322 for (elem=lc->auth_info;elem!=NULL;elem=elem->next) {
323 LinphoneAuthInfo *pinfo = (LinphoneAuthInfo*)elem->data;
324 if (username && pinfo->username && strcmp(username,pinfo->username)==0) {
325 if (realm && domain){
326 if (pinfo->realm && realm_match(realm,pinfo->realm)
327 && pinfo->domain && strcmp(domain,pinfo->domain)==0) {
328 return pinfo;
329 }
330 } else if (realm) {
331 if (pinfo->realm && realm_match(realm,pinfo->realm)) {
332 if (ret!=NULL) {
333 ms_warning("Non unique realm found for %s",username);
334 return NULL;
335 }
336 ret=pinfo;
337 }
338 } else if (domain && pinfo->domain && strcmp(domain,pinfo->domain)==0 && (pinfo->ha1==NULL || ignore_realm)) {
339 return pinfo;
340 } else if (!domain && (pinfo->ha1==NULL || ignore_realm)) {
341 return pinfo;
342 }
343 }
344 }
345 return ret;
346 }
347
_linphone_core_find_tls_auth_info(LinphoneCore * lc)348 const LinphoneAuthInfo *_linphone_core_find_tls_auth_info(LinphoneCore *lc) {
349 bctbx_list_t *elem;
350 for (elem=lc->auth_info;elem!=NULL;elem=elem->next) {
351 LinphoneAuthInfo *pinfo = (LinphoneAuthInfo*)elem->data;
352 if (pinfo->tls_cert && pinfo->tls_key) {
353 return pinfo;
354 } else if (pinfo->tls_cert_path && pinfo->tls_key_path) {
355 return pinfo;
356 }
357 }
358 return NULL;
359 }
360
_linphone_core_find_auth_info(LinphoneCore * lc,const char * realm,const char * username,const char * domain,bool_t ignore_realm)361 const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain, bool_t ignore_realm){
362 const LinphoneAuthInfo *ai=NULL;
363 if (realm){
364 ai=find_auth_info(lc,username,realm,NULL, FALSE);
365 if (ai==NULL && domain){
366 ai=find_auth_info(lc,username,realm,domain, FALSE);
367 }
368 }
369 if (ai == NULL && domain != NULL) {
370 ai=find_auth_info(lc,username,NULL,domain, ignore_realm);
371 }
372 if (ai==NULL){
373 ai=find_auth_info(lc,username,NULL,NULL, ignore_realm);
374 }
375 if (ai) ms_message("linphone_core_find_auth_info(): returning auth info username=%s, realm=%s", ai->username ? ai->username : "", ai->realm ? ai->realm : "");
376 return ai;
377 }
378
linphone_core_find_auth_info(LinphoneCore * lc,const char * realm,const char * username,const char * domain)379 const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain){
380 return _linphone_core_find_auth_info(lc, realm, username, domain, TRUE);
381 }
382
383 /*the auth info is expected to be in the core's list*/
linphone_core_write_auth_info(LinphoneCore * lc,LinphoneAuthInfo * ai)384 void linphone_core_write_auth_info(LinphoneCore *lc, LinphoneAuthInfo *ai){
385 int i;
386 bctbx_list_t *elem = lc->auth_info;
387
388 if (!lc->sip_conf.save_auth_info) return;
389
390 for (i=0; elem != NULL; elem = elem->next, i++){
391 if (ai == elem->data){
392 linphone_auth_info_write_config(lc->config, ai, i);
393 }
394 }
395 }
396
write_auth_infos(LinphoneCore * lc)397 static void write_auth_infos(LinphoneCore *lc){
398 bctbx_list_t *elem;
399 int i;
400
401 if (!linphone_core_ready(lc)) return;
402 if (!lc->sip_conf.save_auth_info) return;
403 for(elem=lc->auth_info,i=0;elem!=NULL;elem=bctbx_list_next(elem),i++){
404 LinphoneAuthInfo *ai=(LinphoneAuthInfo*)(elem->data);
405 linphone_auth_info_write_config(lc->config,ai,i);
406 }
407 linphone_auth_info_write_config(lc->config,NULL,i); /* mark the end */
408 }
409
linphone_core_create_auth_info(LinphoneCore * lc,const char * username,const char * userid,const char * passwd,const char * ha1,const char * realm,const char * domain)410 LinphoneAuthInfo * linphone_core_create_auth_info(LinphoneCore *lc, const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm, const char *domain) {
411 return linphone_auth_info_new(username, userid, passwd, ha1, realm, domain);
412 }
413
linphone_core_add_auth_info(LinphoneCore * lc,const LinphoneAuthInfo * info)414 void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info){
415 LinphoneAuthInfo *ai;
416 bctbx_list_t *elem;
417 bctbx_list_t *l;
418 int restarted_op_count=0;
419 bool_t updating=FALSE;
420
421 if (info->tls_key == NULL && info->tls_key_path == NULL
422 && info->ha1==NULL && info->passwd==NULL){
423 ms_error("linphone_core_add_auth_info(): info supplied with empty password, ha1 or TLS client/key");
424 return;
425 }
426 /* find if we are attempting to modify an existing auth info */
427 ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username,info->domain);
428 if (ai!=NULL && ai->domain && info->domain && strcmp(ai->domain, info->domain)==0){
429 lc->auth_info=bctbx_list_remove(lc->auth_info,ai);
430 linphone_auth_info_unref(ai);
431 updating=TRUE;
432 }
433 lc->auth_info=bctbx_list_append(lc->auth_info,linphone_auth_info_clone(info));
434
435 /* retry pending authentication operations */
436 for(l=elem=sal_get_pending_auths(lc->sal);elem!=NULL;elem=elem->next){
437 SalOp *op=(SalOp*)elem->data;
438 LinphoneAuthInfo *ai;
439 const SalAuthInfo *req_sai=sal_op_get_auth_requested(op);
440 ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,req_sai->realm,req_sai->username,req_sai->domain, FALSE);
441 if (ai){
442 SalAuthInfo sai;
443 bctbx_list_t* proxy;
444 sai.username=ai->username;
445 sai.userid=ai->userid;
446 sai.realm=ai->realm;
447 sai.password=ai->passwd;
448 sai.ha1=ai->ha1;
449 if (ai->tls_cert && ai->tls_key) {
450 sal_certificates_chain_parse(&sai, ai->tls_cert, SAL_CERTIFICATE_RAW_FORMAT_PEM);
451 sal_signing_key_parse(&sai, ai->tls_key, "");
452 } else if (ai->tls_cert_path && ai->tls_key_path) {
453 sal_certificates_chain_parse_file(&sai, ai->tls_cert_path, SAL_CERTIFICATE_RAW_FORMAT_PEM);
454 sal_signing_key_parse_file(&sai, ai->tls_key_path, "");
455 }
456 /*proxy case*/
457 for (proxy=(bctbx_list_t*)linphone_core_get_proxy_config_list(lc);proxy!=NULL;proxy=proxy->next) {
458 if (proxy->data == sal_op_get_user_pointer(op)) {
459 linphone_proxy_config_set_state((LinphoneProxyConfig*)(proxy->data),LinphoneRegistrationProgress,"Authentication...");
460 break;
461 }
462 }
463 sal_op_authenticate(op,&sai);
464 restarted_op_count++;
465 }
466 }
467 if (l){
468 ms_message("linphone_core_add_auth_info(): restarted [%i] operation(s) after %s auth info for\n"
469 "\tusername: [%s]\n"
470 "\trealm [%s]\n"
471 "\tdomain [%s]\n",
472 restarted_op_count,
473 updating ? "updating" : "adding",
474 info->username ? info->username : "",
475 info->realm ? info->realm : "",
476 info->domain ? info->domain : "");
477 }
478 bctbx_list_free(l);
479 write_auth_infos(lc);
480 }
481
linphone_core_abort_authentication(LinphoneCore * lc,LinphoneAuthInfo * info)482 void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *info){
483 }
484
linphone_core_remove_auth_info(LinphoneCore * lc,const LinphoneAuthInfo * info)485 void linphone_core_remove_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info){
486 LinphoneAuthInfo *r;
487 r=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username,info->domain);
488 if (r){
489 lc->auth_info=bctbx_list_remove(lc->auth_info,r);
490 linphone_auth_info_unref(r);
491 write_auth_infos(lc);
492 }
493 }
494
linphone_core_get_auth_info_list(const LinphoneCore * lc)495 const bctbx_list_t *linphone_core_get_auth_info_list(const LinphoneCore *lc){
496 return lc->auth_info;
497 }
498
linphone_core_clear_all_auth_info(LinphoneCore * lc)499 void linphone_core_clear_all_auth_info(LinphoneCore *lc){
500 bctbx_list_t *elem;
501 int i;
502 for(i=0,elem=lc->auth_info;elem!=NULL;elem=bctbx_list_next(elem),i++){
503 LinphoneAuthInfo *info=(LinphoneAuthInfo*)elem->data;
504 linphone_auth_info_unref(info);
505 linphone_auth_info_write_config(lc->config,NULL,i);
506 }
507 bctbx_list_free(lc->auth_info);
508 lc->auth_info=NULL;
509 }
510