]> sjero.net Git - linphone/blobdiff - coreapi/authentication.c
Aac-eld add missing header according to RFC3640 3.3.6
[linphone] / coreapi / authentication.c
index ee360ecfe0f966a86415f4f813a0771a87a04432..8ab1c21ffdb406ecba2ebc1f8e82f5a4677dc687 100644 (file)
  
 #include "linphonecore.h"
 #include "private.h"
-#include <eXosip2/eXosip.h>
-#include <osipparser2/osip_message.h>
 #include "lpconfig.h"
 
-extern LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid);
-
 /**
  * @addtogroup authentication
  * @{
@@ -51,10 +47,46 @@ LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *useri
        if (ha1!=NULL && (strlen(ha1)>0)) obj->ha1=ms_strdup(ha1);
        if (realm!=NULL && (strlen(realm)>0)) obj->realm=ms_strdup(realm);
        obj->works=FALSE;
-       obj->first_time=TRUE;
        return obj;
 }
 
+static LinphoneAuthInfo *linphone_auth_info_clone(const LinphoneAuthInfo *ai){
+       LinphoneAuthInfo *obj=ms_new0(LinphoneAuthInfo,1);
+       if (ai->username) obj->username=ms_strdup(ai->username);
+       if (ai->userid) obj->userid=ms_strdup(ai->userid);
+       if (ai->passwd) obj->passwd=ms_strdup(ai->passwd);
+       if (ai->ha1)    obj->ha1=ms_strdup(ai->ha1);
+       if (ai->realm)  obj->realm=ms_strdup(ai->realm);
+       obj->works=FALSE;
+       obj->usecount=0;
+       return obj;
+}
+
+/**
+ * Returns username.
+**/
+const char *linphone_auth_info_get_username(const LinphoneAuthInfo *i){
+       return i->username;
+}
+
+/**
+ * Returns password.
+**/
+const char *linphone_auth_info_get_passwd(const LinphoneAuthInfo *i){
+       return i->passwd;
+}
+
+const char *linphone_auth_info_get_userid(const LinphoneAuthInfo *i){
+       return i->userid;
+}
+
+const char *linphone_auth_info_get_realm(const LinphoneAuthInfo *i){
+       return i->realm;
+}
+const char *linphone_auth_info_get_ha1(const LinphoneAuthInfo *i){
+       return i->ha1;
+}
+
 /**
  * Sets the password.
 **/
@@ -88,6 +120,27 @@ void linphone_auth_info_set_userid(LinphoneAuthInfo *info, const char *userid){
        if (userid && strlen(userid)>0) info->userid=ms_strdup(userid);
 }
 
+/**
+ * Sets realm.
+**/
+void linphone_auth_info_set_realm(LinphoneAuthInfo *info, const char *realm){
+       if (info->realm){
+               ms_free(info->realm);
+               info->realm=NULL;
+       }
+       if (realm && strlen(realm)>0) info->realm=ms_strdup(realm);
+}
+/**
+ * Sets ha1.
+**/
+void linphone_auth_info_set_ha1(LinphoneAuthInfo *info, const char *ha1){
+       if (info->ha1){
+               ms_free(info->ha1);
+               info->ha1=NULL;
+       }
+       if (ha1 && strlen(ha1)>0) info->ha1=ms_strdup(ha1);
+}
+
 /**
  * Destroys a LinphoneAuthInfo object.
 **/
@@ -106,7 +159,7 @@ void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, in
        sprintf(key,"auth_info_%i",pos);
        lp_config_clean_section(config,key);
        
-       if (obj==NULL){
+       if (obj==NULL || lp_config_get_int(config, "sip", "store_auth_info", 1) == 0){
                return;
        }               
        if (obj->username!=NULL){
@@ -180,7 +233,7 @@ static int realm_match(const char *realm1, const char *realm2){
 /**
  * Retrieves a LinphoneAuthInfo previously entered into the LinphoneCore.
 **/
-LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username)
+const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username)
 {
        MSList *elem;
        LinphoneAuthInfo *ret=NULL,*candidate=NULL;
@@ -212,19 +265,16 @@ LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *rea
        return ret;
 }
 
-static void refresh_exosip_auth_info(LinphoneCore *lc){
+static void write_auth_infos(LinphoneCore *lc){
        MSList *elem;
-       eXosip_lock();
-       eXosip_clear_authentication_info();
-       for (elem=lc->auth_info;elem!=NULL;elem=ms_list_next(elem)){
-               LinphoneAuthInfo *info=(LinphoneAuthInfo*)elem->data;
-               char *userid;
-               if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
-               else userid=info->userid;
-               eXosip_add_authentication_info(info->username,userid,
-                               info->passwd,info->ha1,info->realm);
+       int i;
+
+       if (!linphone_core_ready(lc)) return;
+       for(elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){
+               LinphoneAuthInfo *ai=(LinphoneAuthInfo*)(elem->data);
+               linphone_auth_info_write_config(lc->config,ai,i);
        }
-       eXosip_unlock();
+       linphone_auth_info_write_config(lc->config,NULL,i); /* mark the end */
 }
 
 /**
@@ -232,27 +282,38 @@ static void refresh_exosip_auth_info(LinphoneCore *lc){
  * 
  * This information will be used during all SIP transacations that require authentication.
 **/
-void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info)
+void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
 {
-       MSList *elem;
        LinphoneAuthInfo *ai;
+       MSList *elem;
+       MSList *l;
        
        /* find if we are attempting to modify an existing auth info */
-       ai=linphone_core_find_auth_info(lc,info->realm,info->username);
+       ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username);
        if (ai!=NULL){
-               elem=ms_list_find(lc->auth_info,ai);
-               if (elem==NULL){
-                       ms_error("AuthInfo list corruption ?");
-                       return;
+               lc->auth_info=ms_list_remove(lc->auth_info,ai);
+               linphone_auth_info_destroy(ai);
+       }
+       lc->auth_info=ms_list_append(lc->auth_info,linphone_auth_info_clone(info));
+       /* retry pending authentication operations */
+       for(l=elem=sal_get_pending_auths(lc->sal);elem!=NULL;elem=elem->next){
+               const char *username,*realm;
+               SalOp *op=(SalOp*)elem->data;
+               LinphoneAuthInfo *ai;
+               sal_op_get_auth_requested(op,&realm,&username);
+               ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,realm,username);
+               if (ai){
+                       SalAuthInfo sai;
+                       sai.username=ai->username;
+                       sai.userid=ai->userid;
+                       sai.realm=ai->realm;
+                       sai.password=ai->passwd;
+                       sal_op_authenticate(op,&sai);
+                       ai->usecount++;
                }
-               linphone_auth_info_destroy((LinphoneAuthInfo*)elem->data);
-               elem->data=(void *)info;
-       }else {
-               lc->auth_info=ms_list_append(lc->auth_info,(void *)info);
        }
-       refresh_exosip_auth_info(lc);
-       /* if the user was prompted, re-allow automatic_action */
-       if (lc->automatic_action>0) lc->automatic_action--;
+       ms_list_free(l);
+       write_auth_infos(lc);
 }
 
 
@@ -261,29 +322,20 @@ void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info)
  * from the auth_info_requested callback of LinphoneCoreVTable.
 **/
 void linphone_core_abort_authentication(LinphoneCore *lc,  LinphoneAuthInfo *info){
-       if (lc->automatic_action>0) lc->automatic_action--;
 }
 
 /**
  * Removes an authentication information object.
 **/
-void linphone_core_remove_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info){
-       int len=ms_list_size(lc->auth_info);
-       int newlen;
-       int i;
-       MSList *elem;
-       lc->auth_info=ms_list_remove(lc->auth_info,info);
-       newlen=ms_list_size(lc->auth_info);
-       /*printf("len=%i newlen=%i\n",len,newlen);*/
-       linphone_auth_info_destroy(info);
-       for (i=0;i<len;i++){
-               linphone_auth_info_write_config(lc->config,NULL,i);
+void linphone_core_remove_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info){
+       LinphoneAuthInfo *r;
+       r=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username);
+       if (r){
+               lc->auth_info=ms_list_remove(lc->auth_info,r);
+               /*printf("len=%i newlen=%i\n",len,newlen);*/
+               linphone_auth_info_destroy(r);
+               write_auth_infos(lc);
        }
-       for (elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){
-               linphone_auth_info_write_config(lc->config,(LinphoneAuthInfo*)elem->data,i);
-       }
-       refresh_exosip_auth_info(lc);
-       
 }
 
 /**
@@ -299,9 +351,6 @@ const MSList *linphone_core_get_auth_info_list(const LinphoneCore *lc){
 void linphone_core_clear_all_auth_info(LinphoneCore *lc){
        MSList *elem;
        int i;
-       eXosip_lock();
-       eXosip_clear_authentication_info();
-       eXosip_unlock();
        for(i=0,elem=lc->auth_info;elem!=NULL;elem=ms_list_next(elem),i++){
                LinphoneAuthInfo *info=(LinphoneAuthInfo*)elem->data;
                linphone_auth_info_destroy(info);
@@ -311,84 +360,6 @@ void linphone_core_clear_all_auth_info(LinphoneCore *lc){
        lc->auth_info=NULL;
 }
 
-void linphone_authentication_ok(LinphoneCore *lc, eXosip_event_t *ev){
-       char *prx_realm=NULL,*www_realm=NULL;
-       osip_proxy_authorization_t *prx_auth;
-       osip_authorization_t *www_auth;
-       osip_message_t *msg=ev->request;
-       char *username;
-       LinphoneAuthInfo *as=NULL;
-
-       username=osip_uri_get_username(msg->from->url);
-       osip_message_get_proxy_authorization(msg,0,&prx_auth);
-       osip_message_get_authorization(msg,0,&www_auth);
-       if (prx_auth!=NULL)
-               prx_realm=osip_proxy_authorization_get_realm(prx_auth);
-       if (www_auth!=NULL)
-               www_realm=osip_authorization_get_realm(www_auth);
-       
-       if (prx_realm==NULL && www_realm==NULL){
-               ms_message("No authentication info in the request, ignoring");
-               return;
-       }
-       /* see if we already have this auth information , not to ask it everytime to the user */
-       if (prx_realm!=NULL)
-               as=linphone_core_find_auth_info(lc,prx_realm,username);
-       if (www_realm!=NULL) 
-               as=linphone_core_find_auth_info(lc,www_realm,username);
-       if (as){
-               ms_message("Authentication for user=%s realm=%s is working.",username,prx_realm ? prx_realm : www_realm);
-               as->works=TRUE;
-       }
-}
-
-
-void linphone_core_find_or_ask_for_auth_info(LinphoneCore *lc,const char *username,const char* realm, int tid)
-{
-       LinphoneAuthInfo *as=linphone_core_find_auth_info(lc,realm,username);
-       if ( as==NULL || (as!=NULL && as->works==FALSE && as->first_time==FALSE)){
-               if (lc->vtable.auth_info_requested!=NULL){
-                       lc->vtable.auth_info_requested(lc,realm,username);
-                       lc->automatic_action++;/*suspends eXosip_automatic_action until the user supplies a password */
-               }
-       }
-       if (as) as->first_time=FALSE;
-}
-
-void linphone_process_authentication(LinphoneCore *lc, eXosip_event_t *ev)
-{
-       char *prx_realm=NULL,*www_realm=NULL;
-       osip_proxy_authenticate_t *prx_auth;
-       osip_www_authenticate_t *www_auth;
-       osip_message_t *resp=ev->response;
-       char *username;
-
-       /*
-       if (strcmp(ev->request->sip_method,"REGISTER")==0) {
-               gstate_new_state(lc, GSTATE_REG_FAILED, "Authentication required");
-       }
-       */
-
-       username=osip_uri_get_username(resp->from->url);
-       prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
-       www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
-       if (prx_auth!=NULL)
-               prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
-       if (www_auth!=NULL)
-               www_realm=osip_www_authenticate_get_realm(www_auth);
-       
-       if (prx_realm==NULL && www_realm==NULL){
-               ms_warning("No realm in the server response.");
-               return;
-       }
-       /* see if we already have this auth information , not to ask it everytime to the user */
-       if (prx_realm!=NULL) 
-               linphone_core_find_or_ask_for_auth_info(lc,username,prx_realm,ev->tid);
-       if (www_realm!=NULL) 
-               linphone_core_find_or_ask_for_auth_info(lc,username,www_realm,ev->tid);
-}
-
-
 /**
  * @}
 **/