Reuse previous nonce if outbound proxy realm is set to avoid reauthentication

parent 012dc476
......@@ -21,7 +21,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "linphonecore.h"
#include "private.h"
#include "lpconfig.h"
......@@ -143,7 +143,7 @@ void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, in
char key[50];
sprintf(key,"auth_info_%i",pos);
lp_config_clean_section(config,key);
if (obj==NULL || lp_config_get_int(config, "sip", "store_auth_info", 1) == 0){
return;
}
......@@ -176,12 +176,12 @@ LinphoneAuthInfo *linphone_auth_info_new_from_config_file(LpConfig * config, int
char key[50];
const char *username,*userid,*passwd,*ha1,*realm,*domain;
LinphoneAuthInfo *ret;
sprintf(key,"auth_info_%i",pos);
if (!lp_config_has_section(config,key)){
return NULL;
}
username=lp_config_get_string(config,key,"username",NULL);
userid=lp_config_get_string(config,key,"userid",NULL);
passwd=lp_config_get_string(config,key,"passwd",NULL);
......@@ -221,7 +221,7 @@ static int realm_match(const char *realm1, const char *realm2){
static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *username, const char *realm, const char *domain){
MSList *elem;
const LinphoneAuthInfo *ret=NULL;
for (elem=lc->auth_info;elem!=NULL;elem=elem->next) {
LinphoneAuthInfo *pinfo = (LinphoneAuthInfo*)elem->data;
if (username && pinfo->username && strcmp(username,pinfo->username)==0) {
......@@ -240,7 +240,7 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user
}
} else if (domain && pinfo->domain && strcmp(domain,pinfo->domain)==0) {
return pinfo;
} else if (!domain) {
} else if (!domain) {
return pinfo;
}
}
......@@ -249,7 +249,7 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user
}
/**
* Find authentication info matching realm, username, domain criterias.
* Find authentication info matching realm, username, domain criteria.
* First of all, (realm,username) pair are searched. If multiple results (which should not happen because realm are supposed to be unique), then domain is added to the search.
* @param lc the LinphoneCore
* @param realm the authentication 'realm' (optional)
......@@ -264,7 +264,7 @@ const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const cha
if (ai==NULL && domain){
ai=find_auth_info(lc,username,realm,domain);
}
}
}
if (ai == NULL && domain != NULL) {
ai=find_auth_info(lc,username,NULL,domain);
}
......@@ -292,8 +292,8 @@ LinphoneAuthInfo * linphone_core_create_auth_info(LinphoneCore *lc, const char *
/**
* Adds authentication information to the LinphoneCore.
*
* This information will be used during all SIP transacations that require authentication.
*
* This information will be used during all SIP transactions that require authentication.
**/
void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info){
LinphoneAuthInfo *ai;
......@@ -301,7 +301,7 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
MSList *l;
int restarted_op_count=0;
bool_t updating=FALSE;
if (info->ha1==NULL && info->passwd==NULL){
ms_error("linphone_core_add_auth_info(): info supplied with empty password or ha1.");
return;
......@@ -371,7 +371,6 @@ void linphone_core_remove_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *in
r=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username,info->domain);
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);
}
......
......@@ -137,7 +137,7 @@ void sal_process_authentication(SalOp *op) {
return;
}
if (belle_sip_provider_add_authorization(op->base.root->prov,new_request,response,from_uri,&auth_list)) {
if (belle_sip_provider_add_authorization(op->base.root->prov,new_request,response,from_uri,&auth_list,op->base.realm)) {
if (is_within_dialog) {
sal_op_send_request(op,new_request);
} else {
......
......@@ -137,7 +137,7 @@ static void add_initial_route_set(belle_sip_request_t *request, const MSList *li
continue;
}
}
route=belle_sip_header_route_create((belle_sip_header_address_t*)addr);
uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route);
belle_sip_uri_set_lr_param(uri,1);
......@@ -180,11 +180,11 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
belle_sip_header_p_preferred_identity_t* p_preferred_identity=belle_sip_header_p_preferred_identity_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(p_preferred_identity));
}
if (elem && strcmp(method,"REGISTER")!=0 && !op->base.root->no_initial_route){
add_initial_route_set(req,elem);
}
if (strcmp("REGISTER",method)!=0 && op->privacy!=SalPrivacyNone ){
belle_sip_header_privacy_t* privacy_header=belle_sip_header_privacy_new();
if (op->privacy&SalPrivacyCritical)
......@@ -332,7 +332,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION)
&& !belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION)) {
/*hmm just in case we already have authentication param in cache*/
belle_sip_provider_add_authorization(op->base.root->prov,request,NULL,NULL,NULL);
belle_sip_provider_add_authorization(op->base.root->prov,request,NULL,NULL,NULL,op->base.realm);
}
result = belle_sip_client_transaction_send_request_to(client_transaction,next_hop_uri/*might be null*/);
......@@ -608,7 +608,7 @@ int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int exp
belle_sip_object_unref(op->refresher);
}
if ((op->refresher = belle_sip_client_transaction_create_refresher(op->pending_client_trans))) {
/*since refresher acquires the transaction, we should remove our context from the transaction, because we won't be notified
/*since refresher acquires the transaction, we should remove our context from the transaction, because we won't be notified
* that it is terminated anymore.*/
sal_op_unref(op);/*loose the reference that was given to the transaction when creating it*/
/* Note that the refresher will replace our data with belle_sip_transaction_set_application_data().
......@@ -617,6 +617,7 @@ int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int exp
notify the user as a normal transaction*/
belle_sip_refresher_set_listener(op->refresher,listener,op);
belle_sip_refresher_set_retry_after(op->refresher,op->base.root->refresher_retry_after);
belle_sip_refresher_set_realm(op->refresher,op->base.realm);
belle_sip_refresher_enable_manual_mode(op->refresher,op->manual_refresher);
return 0;
} else {
......
......@@ -35,7 +35,7 @@ void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceMo
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_CONTENT_TYPE);
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_CONTENT_LENGTH);
belle_sip_message_set_body(BELLE_SIP_MESSAGE(notify),NULL,0);
if (content){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify)
,BELLE_SIP_HEADER(belle_sip_header_content_type_create("application","pidf+xml")));
......@@ -95,7 +95,7 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
int code = belle_sip_response_get_status_code(response);
belle_sip_header_expires_t* expires;
sal_op_set_error_info_from_response(op,response);
if (code>=300) {
......@@ -127,6 +127,7 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
if (expires>0){
op->refresher=belle_sip_client_transaction_create_refresher(client_transaction);
belle_sip_refresher_set_listener(op->refresher,presence_refresher_listener,op);
belle_sip_refresher_set_realm(op->refresher,op->base.realm);
}
}
break;
......@@ -164,7 +165,7 @@ static SalPresenceModel * process_presence_notification(SalOp *op, belle_sip_req
return NULL;
if (belle_sip_header_content_length_get_content_length(content_length) == 0)
return NULL;
if (body==NULL) return NULL;
op->base.root->callbacks.parse_presence_requested(op,
......@@ -181,7 +182,7 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req){
belle_sip_server_transaction_t* server_transaction=op->pending_server_trans;
belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t);
SalSubscribeStatus sub_state;
if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) {
SalPresenceModel *presence_model = NULL;
const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
......@@ -194,7 +195,7 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req){
presence_model = process_presence_notification(op, req);
if (presence_model != NULL || body==NULL) {
/* Presence notification body parsed successfully. */
resp = sal_op_create_response_from_request(op, req, 200); /*create first because the op may be destroyed by notify_presence */
op->base.root->callbacks.notify_presence(op, sub_state, presence_model, NULL);
} else if (body){
......@@ -214,7 +215,7 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t);
belle_sip_response_t* resp;
const char *method=belle_sip_request_get_method(req);
belle_sip_object_ref(server_transaction);
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
op->pending_server_trans=server_transaction;
......@@ -256,7 +257,7 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques
}
}
break;
default:
default:
ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state));
break;
}
......
......@@ -724,6 +724,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
from_str=linphone_address_as_string_uri_only(from);
sal_op_set_route(call->ping_op,sal_op_get_network_origin(op));
sal_op_set_user_pointer(call->ping_op,call);
sal_op_set_realm(call->ping_op,linphone_proxy_config_get_realm(linphone_core_lookup_known_proxy(call->core, to)));
sal_ping(call->ping_op,linphone_core_find_best_identity(lc,from),from_str);
ms_free(from_str);
}
......@@ -1313,7 +1314,7 @@ int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file){
* Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns.
* @param call a LinphoneCall
* @param file a path where to write the jpeg content.
* @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported).
* @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported).
**/
int linphone_call_take_preview_snapshot(LinphoneCall *call, const char *file){
#ifdef VIDEO_ENABLED
......
......@@ -2824,6 +2824,7 @@ void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *d
sal_op_set_to_address(op,dest);
sal_op_set_from(op,identity);
sal_op_set_sent_custom_header(op,headers);
sal_op_set_realm(op,linphone_proxy_config_get_realm(proxy));
if (with_contact && proxy && proxy->op){
const SalAddress *contact;
if ((contact=sal_op_get_contact_address(proxy->op))){
......
......@@ -917,6 +917,20 @@ LINPHONE_PUBLIC bool_t linphone_proxy_config_is_registered(const LinphoneProxyCo
**/
LINPHONE_PUBLIC const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg);
/**
* Get the realm of the given proxy config.
* @param[in] cfg #LinphoneProxyConfig object.
* @returns The realm of the proxy config.
**/
LINPHONE_PUBLIC const char *linphone_proxy_config_get_realm(const LinphoneProxyConfig *cfg);
/**
* Set the realm of the given proxy config.
* @param[in] cfg #LinphoneProxyConfig object.
* @param[in] realm New realm value.
* @returns The realm of the proxy config.
**/
LINPHONE_PUBLIC void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char * realm);
LINPHONE_PUBLIC const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *obj);
LINPHONE_PUBLIC const char *linphone_proxy_config_get_identity(const LinphoneProxyConfig *obj);
LINPHONE_PUBLIC bool_t linphone_proxy_config_publish_enabled(const LinphoneProxyConfig *obj);
......
......@@ -423,6 +423,7 @@ struct _LinphoneProxyConfig
char *reg_identity;
char *reg_route;
char *quality_reporting_collector;
char *domain;
char *realm;
char *contact_params;
char *contact_uri_params;
......
......@@ -94,6 +94,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob
const char *identity = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_identity", NULL) : NULL;
const char *proxy = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_proxy", NULL) : NULL;
const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL;
const char *realm = lc ? lp_config_get_default_string(lc->config, "proxy", "realm", NULL) : NULL;
const char *quality_reporting_collector = lc ? lp_config_get_default_string(lc->config, "proxy", "quality_reporting_collector", NULL) : NULL;
const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL;
const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL;
......@@ -108,6 +109,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob
obj->reg_identity = identity ? ms_strdup(identity) : NULL;
obj->reg_proxy = proxy ? ms_strdup(proxy) : NULL;
obj->reg_route = route ? ms_strdup(route) : NULL;
obj->realm = realm ? ms_strdup(realm) : NULL;
obj->quality_reporting_enabled = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0;
obj->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL;
obj->quality_reporting_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_interval", 0) : 0;
......@@ -150,6 +152,7 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
if (obj->reg_route!=NULL) ms_free(obj->reg_route);
if (obj->quality_reporting_collector!=NULL) ms_free(obj->quality_reporting_collector);
if (obj->ssctx!=NULL) sip_setup_context_free(obj->ssctx);
if (obj->domain!=NULL) ms_free(obj->domain);
if (obj->realm!=NULL) ms_free(obj->realm);
if (obj->type!=NULL) ms_free(obj->type);
if (obj->dial_prefix!=NULL) ms_free(obj->dial_prefix);
......@@ -228,10 +231,10 @@ int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *ide
obj->reg_identity=NULL;
}
obj->reg_identity=ms_strdup(identity);
if (obj->realm){
ms_free(obj->realm);
if (obj->domain){
ms_free(obj->domain);
}
obj->realm=ms_strdup(linphone_address_get_domain(addr));
obj->domain=ms_strdup(linphone_address_get_domain(addr));
linphone_address_destroy(addr);
return 0;
}
......@@ -240,7 +243,7 @@ int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *ide
}
const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){
return cfg->realm;
return cfg->domain;
}
/**
......@@ -310,7 +313,7 @@ void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){
/**
* Prevent a proxy config from refreshing its registration.
* This is useful to let registrations to expire naturally (or) when the application wants to keep control on when
* This is useful to let registrations to expire naturally (or) when the application wants to keep control on when
* refreshes are sent.
* However, linphone_core_set_network_reachable(lc,TRUE) will always request the proxy configs to refresh their registrations.
* The refreshing operations can be resumed with linphone_proxy_config_refresh_register().
......@@ -422,6 +425,7 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
linphone_address_destroy(contact);
}
sal_op_set_user_pointer(obj->op,obj);
sal_op_set_realm(obj->op, obj->realm);
if (sal_register(obj->op,proxy_string,obj->reg_identity,obj->expires)==0) {
linphone_proxy_config_set_state(obj,LinphoneRegistrationProgress,"Registration in progress");
} else {
......@@ -946,13 +950,16 @@ int linphone_proxy_config_done(LinphoneProxyConfig *obj)
return 0;
}
const char* linphone_proxy_config_get_realm(const LinphoneProxyConfig *cfg)
{
return cfg?cfg->realm:NULL;
}
void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm)
{
if (cfg->realm!=NULL) {
ms_free(cfg->realm);
cfg->realm=NULL;
}
if (realm!=NULL) cfg->realm=ms_strdup(realm);
cfg->realm=ms_strdup(realm);
}
int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePresenceModel *presence){
......@@ -964,6 +971,7 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese
sal_op_set_route(proxy->publish_op,proxy->reg_proxy);
sal_op_set_from(proxy->publish_op,linphone_proxy_config_get_identity(proxy));
sal_op_set_to(proxy->publish_op,linphone_proxy_config_get_identity(proxy));
sal_op_set_realm(proxy->publish_op,linphone_proxy_config_get_realm(proxy));
if (lp_config_get_int(proxy->lc->config,"sip","publish_msg_with_contact",0)){
SalAddress *addr=sal_address_new(linphone_proxy_config_get_identity(proxy));
sal_op_set_contact_address(proxy->publish_op,addr);
......@@ -1205,6 +1213,9 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
if (obj->reg_identity!=NULL){
lp_config_set_string(config,key,"reg_identity",obj->reg_identity);
}
if (obj->realm!=NULL){
lp_config_set_string(config,key,"realm",obj->realm);
}
if (obj->contact_params!=NULL){
lp_config_set_string(config,key,"contact_parameters",obj->contact_params);
}
......@@ -1259,10 +1270,10 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc
CONFIGURE_STRING_VALUE(cfg,config,key,server_addr,"reg_proxy")
CONFIGURE_STRING_VALUE(cfg,config,key,route,"reg_route")
CONFIGURE_BOOL_VALUE(cfg,config,key,quality_reporting,"quality_reporting_enabled")
CONFIGURE_STRING_VALUE(cfg,config,key,realm,"realm")
CONFIGURE_BOOL_VALUE(cfg,config,key,quality_reporting,"quality_reporting_enabled")
CONFIGURE_STRING_VALUE(cfg,config,key,quality_reporting_collector,"quality_reporting_collector")
CONFIGURE_INT_VALUE(cfg,config,key,quality_reporting_interval,"quality_reporting_interval")
CONFIGURE_STRING_VALUE(cfg,config,key,contact_parameters,"contact_parameters")
......
......@@ -386,6 +386,13 @@ void sal_op_add_route_address(SalOp *op, const SalAddress *address){
sal_op_set_route_address(op,address);
}
}
void sal_op_set_realm(SalOp *op, const char *realm){
SalOpBase* op_base = (SalOpBase*)op;
if (op_base->realm != NULL){
ms_free(op_base->realm);
}
op_base->realm = ms_strdup(realm);
}
void sal_op_set_from(SalOp *op, const char *from){
SET_PARAM(op,from);
}
......@@ -511,6 +518,10 @@ void __sal_op_free(SalOp *op){
ms_free(b->route);
b->route=NULL;
}
if (b->realm) {
ms_free(b->realm);
b->realm=NULL;
}
if (b->contact_address) {
sal_address_destroy(b->contact_address);
}
......
......@@ -285,6 +285,7 @@ typedef struct SalOpBase{
SalMediaDescription *remote_media;
void *user_pointer;
const char* call_id;
char* realm;
SalAddress* service_route; /*as defined by rfc3608, might be a list*/
SalCustomHeader *sent_custom_headers;
SalCustomHeader *recv_custom_headers;
......@@ -560,6 +561,7 @@ void sal_op_set_contact_address(SalOp *op, const SalAddress* address);
void sal_op_set_route(SalOp *op, const char *route);
void sal_op_set_route_address(SalOp *op, const SalAddress* address);
void sal_op_add_route_address(SalOp *op, const SalAddress* address);
void sal_op_set_realm(SalOp *op, const char *realm);
void sal_op_set_from(SalOp *op, const char *from);
void sal_op_set_from_address(SalOp *op, const SalAddress *from);
void sal_op_set_to(SalOp *op, const char *to);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment