Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
belle-sip
Commits
3cc6f3b7
Commit
3cc6f3b7
authored
Jul 09, 2012
by
jehan
Browse files
Better authenticatiion handling, thanks to
belle_sip_provider_add_authorization
parent
0ab402f0
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
419 additions
and
37 deletions
+419
-37
include/belle-sip/auth-info.h
include/belle-sip/auth-info.h
+39
-0
include/belle-sip/belle-sip.h
include/belle-sip/belle-sip.h
+1
-0
include/belle-sip/headers.h
include/belle-sip/headers.h
+10
-1
include/belle-sip/listener.h
include/belle-sip/listener.h
+20
-0
include/belle-sip/provider.h
include/belle-sip/provider.h
+10
-0
include/belle-sip/transaction.h
include/belle-sip/transaction.h
+4
-1
src/Makefile.am
src/Makefile.am
+1
-0
src/auth_event.c
src/auth_event.c
+44
-0
src/auth_helper.c
src/auth_helper.c
+1
-1
src/belle_sip_headers_impl.c
src/belle_sip_headers_impl.c
+18
-4
src/belle_sip_internal.h
src/belle_sip_internal.h
+10
-1
src/belle_sip_utils.c
src/belle_sip_utils.c
+2
-1
src/message.c
src/message.c
+2
-2
src/provider.c
src/provider.c
+172
-0
src/transaction.c
src/transaction.c
+1
-0
tester/belle_sip_message_tester.c
tester/belle_sip_message_tester.c
+2
-2
tester/belle_sip_register_tester.c
tester/belle_sip_register_tester.c
+60
-15
tester/belle_sip_tester.c
tester/belle_sip_tester.c
+22
-9
No files found.
include/belle-sip/auth-info.h
0 → 100644
View file @
3cc6f3b7
/*
belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef AUTH_INFO_H_
#define AUTH_INFO_H_
typedef
struct
belle_sip_auth_info
belle_sip_auth_info_t
;
const
char
*
belle_sip_auth_info_get_username
(
const
belle_sip_auth_info_t
info
);
void
belle_sip_auth_info_set_username
(
belle_sip_auth_info_t
info
,
const
char
*
value
);
const
char
*
belle_sip_auth_info_get_userid
(
const
belle_sip_auth_info_t
info
);
void
belle_sip_auth_info_set_userid
(
belle_sip_auth_info_t
info
,
const
char
*
value
);
const
char
*
belle_sip_auth_info_get_realm
(
const
belle_sip_auth_info_t
info
);
void
belle_sip_auth_info_set_realm
(
belle_sip_auth_info_t
info
,
const
char
*
value
);
const
char
*
belle_sip_auth_info_get_passwd
(
const
belle_sip_auth_info_t
info
);
void
belle_sip_auth_info_set_passwd
(
belle_sip_auth_info_t
info
,
const
char
*
value
);
const
char
*
belle_sip_auth_info_get_ha1
(
const
belle_sip_auth_info_t
info
);
void
belle_sip_auth_info_set_ha1
(
belle_sip_auth_info_t
info
,
const
char
*
value
);
#endif
/* AUTH_INFO_H_ */
include/belle-sip/belle-sip.h
View file @
3cc6f3b7
...
...
@@ -137,6 +137,7 @@ typedef struct _belle_sip_response belle_sip_response_t;
#include "belle-sip/utils.h"
#include "belle-sip/list.h"
#include "belle-sip/auth-info.h"
#include "belle-sip/listener.h"
#include "belle-sip/mainloop.h"
#include "belle-sip/uri.h"
...
...
include/belle-sip/headers.h
View file @
3cc6f3b7
...
...
@@ -194,6 +194,11 @@ belle_sip_header_via_t* belle_sip_header_via_create(const char *host, int port,
belle_sip_header_via_t
*
belle_sip_header_via_parse
(
const
char
*
via
)
;
const
char
*
belle_sip_header_via_get_branch
(
const
belle_sip_header_via_t
*
via
);
const
char
*
belle_sip_header_via_get_transport
(
const
belle_sip_header_via_t
*
via
);
/**
* Get lower case version of the transport
* @return the lower case version of the transport if from tcp,udp,tls or dtls else, return the value from #belle_sip_header_via_get_transport
*/
const
char
*
belle_sip_header_via_get_transport_lowercase
(
const
belle_sip_header_via_t
*
via
);
const
char
*
belle_sip_header_via_get_host
(
const
belle_sip_header_via_t
*
via
);
int
belle_sip_header_via_get_port
(
const
belle_sip_header_via_t
*
via
);
int
belle_sip_header_via_get_listening_port
(
const
belle_sip_header_via_t
*
via
);
...
...
@@ -226,7 +231,8 @@ belle_sip_header_call_id_t* belle_sip_header_call_id_new();
belle_sip_header_call_id_t
*
belle_sip_header_call_id_parse
(
const
char
*
call_id
)
;
const
char
*
belle_sip_header_call_id_get_call_id
(
const
belle_sip_header_call_id_t
*
call_id
);
void
belle_sip_header_call_id_set_call_id
(
belle_sip_header_call_id_t
*
via
,
const
char
*
call_id
);
void
belle_sip_header_call_id_set_call_id
(
belle_sip_header_call_id_t
*
call_id
,
const
char
*
id
);
unsigned
int
belle_sip_header_call_id_equals
(
const
belle_sip_header_call_id_t
*
a
,
const
belle_sip_header_call_id_t
*
b
);
#define BELLE_SIP_HEADER_CALL_ID(t) BELLE_SIP_CAST(t,belle_sip_header_call_id_t)
#define BELLE_SIP_CALL_ID "Call-ID"
/******************************
...
...
@@ -374,6 +380,7 @@ void belle_sip_header_authorization_set_uri(belle_sip_header_authorization_t* au
void
belle_sip_header_authorization_set_username
(
belle_sip_header_authorization_t
*
authorization
,
const
char
*
username
);
#define BELLE_SIP_HEADER_AUTHORIZATION(t) BELLE_SIP_CAST(t,belle_sip_header_authorization_t)
#define BELLE_SIP_AUTHORIZATION "Authorization"
/*******************************
* proxy_authorization inherit from Authorization
...
...
@@ -382,6 +389,7 @@ typedef struct _belle_sip_header_proxy_authorization belle_sip_header_proxy_auth
belle_sip_header_proxy_authorization_t
*
belle_sip_header_proxy_authorization_new
();
belle_sip_header_proxy_authorization_t
*
belle_sip_header_proxy_authorization_parse
(
const
char
*
proxy_authorization
);
#define BELLE_SIP_HEADER_PROXY_AUTHORIZATION(t) BELLE_SIP_CAST(t,belle_sip_header_proxy_authorization_t)
#define BELLE_SIP_PROXY_AUTHORIZATION "Proxy-Authorization"
/*******************************
* www_authenticate inherit from parameters
...
...
@@ -393,6 +401,7 @@ const char* belle_sip_header_www_authenticate_get_algorithm(const belle_sip_head
const
char
*
belle_sip_header_www_authenticate_get_nonce
(
const
belle_sip_header_www_authenticate_t
*
www_authenticate
);
const
char
*
belle_sip_header_www_authenticate_get_opaque
(
const
belle_sip_header_www_authenticate_t
*
www_authenticate
);
belle_sip_list_t
*
belle_sip_header_www_authenticate_get_qop
(
const
belle_sip_header_www_authenticate_t
*
www_authetication
);
const
char
*
belle_sip_header_www_authenticate_get_qop_first
(
const
belle_sip_header_www_authenticate_t
*
www_authetication
);
const
char
*
belle_sip_header_www_authenticate_get_realm
(
const
belle_sip_header_www_authenticate_t
*
www_authenticate
);
const
char
*
belle_sip_header_www_authenticate_get_scheme
(
const
belle_sip_header_www_authenticate_t
*
www_authenticate
);
const
char
*
belle_sip_header_www_authenticate_get_domain
(
const
belle_sip_header_www_authenticate_t
*
www_authenticate
);
...
...
include/belle-sip/listener.h
View file @
3cc6f3b7
...
...
@@ -26,6 +26,8 @@ typedef struct belle_sip_request_event belle_sip_request_event_t;
typedef
struct
belle_sip_response_event
belle_sip_response_event_t
;
typedef
struct
belle_sip_timeout_event
belle_sip_timeout_event_t
;
typedef
struct
belle_sip_transaction_terminated_event
belle_sip_transaction_terminated_event_t
;
typedef
struct
belle_sip_auth_event
belle_sip_auth_event_t
;
BELLE_SIP_DECLARE_INTERFACE_BEGIN
(
belle_sip_listener_t
)
void
(
*
process_dialog_terminated
)(
belle_sip_listener_t
*
user_ctx
,
const
belle_sip_dialog_terminated_event_t
*
event
);
...
...
@@ -34,6 +36,7 @@ BELLE_SIP_DECLARE_INTERFACE_BEGIN(belle_sip_listener_t)
void
(
*
process_response_event
)(
belle_sip_listener_t
*
user_ctx
,
const
belle_sip_response_event_t
*
event
);
void
(
*
process_timeout
)(
belle_sip_listener_t
*
user_ctx
,
const
belle_sip_timeout_event_t
*
event
);
void
(
*
process_transaction_terminated
)(
belle_sip_listener_t
*
user_ctx
,
const
belle_sip_transaction_terminated_event_t
*
event
);
void
(
*
process_auth_requested
)(
belle_sip_listener_t
*
user_ctx
,
belle_sip_auth_event_t
*
event
);
BELLE_SIP_DECLARE_INTERFACE_END
#define BELLE_SIP_LISTENER(obj) BELLE_SIP_INTERFACE_CAST(obj,belle_sip_listener_t)
...
...
@@ -47,6 +50,22 @@ belle_sip_request_t* belle_sip_request_event_get_request(const belle_sip_request
belle_sip_server_transaction_t
*
belle_sip_request_event_get_server_transaction
(
const
belle_sip_request_event_t
*
event
);
belle_sip_dialog_t
*
belle_sip_request_event_get_dialog
(
const
belle_sip_request_event_t
*
event
);
/*auth event*/
const
char
*
belle_sip_auth_event_get_username
(
const
belle_sip_auth_event_t
*
event
);
void
belle_sip_auth_event_set_username
(
belle_sip_auth_event_t
*
event
,
const
char
*
value
);
const
char
*
belle_sip_auth_event_get_userid
(
const
belle_sip_auth_event_t
*
event
);
void
belle_sip_auth_event_set_userid
(
belle_sip_auth_event_t
*
event
,
const
char
*
value
);
const
char
*
belle_sip_auth_event_get_realm
(
const
belle_sip_auth_event_t
*
event
);
void
belle_sip_auth_event_set_realm
(
belle_sip_auth_event_t
*
event
,
const
char
*
value
);
const
char
*
belle_sip_auth_event_get_passwd
(
const
belle_sip_auth_event_t
*
event
);
void
belle_sip_auth_event_set_passwd
(
belle_sip_auth_event_t
*
event
,
const
char
*
value
);
const
char
*
belle_sip_auth_event_get_ha1
(
const
belle_sip_auth_event_t
*
event
);
void
belle_sip_auth_event_set_ha1
(
belle_sip_auth_event_t
*
event
,
const
char
*
value
);
struct
belle_sip_listener_callbacks
{
void
(
*
process_dialog_terminated
)(
void
*
user_ctx
,
const
belle_sip_dialog_terminated_event_t
*
event
);
...
...
@@ -55,6 +74,7 @@ struct belle_sip_listener_callbacks{
void
(
*
process_response_event
)(
void
*
user_ctx
,
const
belle_sip_response_event_t
*
event
);
void
(
*
process_timeout
)(
void
*
user_ctx
,
const
belle_sip_timeout_event_t
*
event
);
void
(
*
process_transaction_terminated
)(
void
*
user_ctx
,
const
belle_sip_transaction_terminated_event_t
*
event
);
void
(
*
process_auth_requested
)(
void
*
user_ctx
,
belle_sip_auth_event_t
*
auth_event
);
};
typedef
struct
belle_sip_listener_callbacks
belle_sip_listener_callbacks_t
;
...
...
include/belle-sip/provider.h
View file @
3cc6f3b7
...
...
@@ -50,6 +50,16 @@ void belle_sip_provider_send_request(belle_sip_provider_t *p, belle_sip_request_
void
belle_sip_provider_send_response
(
belle_sip_provider_t
*
p
,
belle_sip_response_t
*
resp
);
/*
* Add auth info the the request if found
* @param p object
* @param request to be updated
* @param resp response to take authentication values from, might be NULL
* @returns 0 in case of success,
*
* */
int
belle_sip_provider_add_authorization
(
belle_sip_provider_t
*
p
,
belle_sip_request_t
*
request
,
belle_sip_response_t
*
resp
);
BELLE_SIP_END_DECLS
#define BELLE_SIP_PROVIDER(obj) BELLE_SIP_CAST(obj,belle_sip_provider_t)
...
...
include/belle-sip/transaction.h
View file @
3cc6f3b7
...
...
@@ -44,7 +44,10 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *
belle_sip_request_t
*
belle_sip_client_transaction_create_cancel
(
belle_sip_client_transaction_t
*
t
);
void
belle_sip_client_transaction_send_request
(
belle_sip_client_transaction_t
*
t
);
/**
* Create an authenticated request based on an existing terminated transaction
* */
belle_sip_request_t
*
belle_sip_client_create_authenticated_request
(
belle_sip_client_transaction_t
*
t
);
#define BELLE_SIP_TRANSACTION(t) BELLE_SIP_CAST(t,belle_sip_transaction_t)
#define BELLE_SIP_SERVER_TRANSACTION(t) BELLE_SIP_CAST(t,belle_sip_server_transaction_t)
...
...
src/Makefile.am
View file @
3cc6f3b7
...
...
@@ -51,6 +51,7 @@ libbellesip_la_SOURCES= \
nict.c
\
nist.c
\
dialog.c
\
auth_event.c
\
transports/udp_listeningpoint.c
\
transports/udp_channel.c
\
transports/stream_channel.c
\
...
...
src/auth_event.c
0 → 100644
View file @
3cc6f3b7
/*
auth_info.c belle-sip - SIP (RFC3261) library.
Copyright (C) 2010 Belledonne Communications SARL
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "belle-sip/auth-helper.h"
#include "belle_sip_internal.h"
GET_SET_STRING
(
belle_sip_auth_event
,
username
)
GET_SET_STRING
(
belle_sip_auth_event
,
userid
)
GET_SET_STRING
(
belle_sip_auth_event
,
realm
)
GET_SET_STRING
(
belle_sip_auth_event
,
passwd
)
GET_SET_STRING
(
belle_sip_auth_event
,
ha1
)
belle_sip_auth_event_t
*
belle_sip_auth_event_create
(
const
char
*
realm
,
const
char
*
username
)
{
belle_sip_auth_event_t
*
result
=
belle_sip_malloc
(
sizeof
(
belle_sip_auth_event_t
));
memset
(
result
,
0
,
sizeof
(
belle_sip_auth_event_t
));
belle_sip_auth_event_set_realm
(
result
,
realm
);
belle_sip_auth_event_set_username
(
result
,
username
);
return
result
;
}
void
belle_sip_auth_event_destroy
(
belle_sip_auth_event_t
*
event
)
{
DESTROY_STRING
(
event
,
username
);
DESTROY_STRING
(
event
,
userid
);
DESTROY_STRING
(
event
,
realm
);
DESTROY_STRING
(
event
,
passwd
);
DESTROY_STRING
(
event
,
ha1
);
belle_sip_free
(
event
);
}
src/auth_helper.c
View file @
3cc6f3b7
...
...
@@ -108,7 +108,7 @@ int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* a
if
(
auth_mode
)
{
CHECK_IS_PRESENT
(
authorization
,
authorization
,
nonce_count
)
if
(
!
belle_sip_header_authorization_get_cnonce
(
authorization
))
{
snprintf
(
cnonce
,
sizeof
(
cnonce
),
"%08x"
,(
short
)(
long
)
authorization
);
snprintf
(
cnonce
,
sizeof
(
cnonce
),
"%08x"
,(
short
)(
long
)
authorization
^
0x5555555
);
belle_sip_header_authorization_set_cnonce
(
authorization
,
cnonce
);
}
}
...
...
src/belle_sip_headers_impl.c
View file @
3cc6f3b7
...
...
@@ -510,7 +510,16 @@ int belle_sip_header_via_get_listening_port(const belle_sip_header_via_t *via){
if
(
ret
==-
1
)
ret
=
belle_sip_listening_point_get_well_known_port
(
via
->
protocol
);
return
ret
;
}
const
char
*
belle_sip_header_via_get_transport_lowercase
(
const
belle_sip_header_via_t
*
via
)
{
if
(
strcasecmp
(
"udp"
,
via
->
transport
)
==
0
)
return
"udp"
;
else
if
(
strcasecmp
(
"tcp"
,
via
->
transport
)
==
0
)
return
"tcp"
;
else
if
(
strcasecmp
(
"tls"
,
via
->
transport
)
==
0
)
return
"tls"
;
else
if
(
strcasecmp
(
"dtls"
,
via
->
transport
)
==
0
)
return
"dtls"
;
else
{
belle_sip_warning
(
"Cannot convert [%s] to lower case"
,
via
->
transport
);
return
via
->
transport
;
}
}
/**************************
* call_id header object inherits from object
****************************
...
...
@@ -533,7 +542,9 @@ int belle_sip_header_call_id_marshal(belle_sip_header_call_id_t* call_id, char*
current_offset
+=
snprintf
(
buff
+
current_offset
,
buff_size
-
current_offset
,
"%s"
,
call_id
->
call_id
);
return
current_offset
-
offset
;
}
unsigned
int
belle_sip_header_call_id_equals
(
const
belle_sip_header_call_id_t
*
a
,
const
belle_sip_header_call_id_t
*
b
)
{
return
strcasecmp
(
a
->
call_id
,
b
->
call_id
)
==
0
;
}
BELLE_SIP_NEW_HEADER
(
header_call_id
,
header
,
BELLE_SIP_CALL_ID
)
BELLE_SIP_PARSE
(
header_call_id
)
GET_SET_STRING
(
belle_sip_header_call_id
,
call_id
);
...
...
@@ -917,7 +928,7 @@ int belle_sip_header_authorization_marshal(belle_sip_header_authorization_t* aut
}
return
current_offset
-
offset
;
}
BELLE_SIP_NEW_HEADER
(
header_authorization
,
parameters
,
"Authorization"
)
BELLE_SIP_NEW_HEADER
(
header_authorization
,
parameters
,
BELLE_SIP_AUTHORIZATION
)
BELLE_SIP_PARSE
(
header_authorization
)
GET_SET_STRING
(
belle_sip_header_authorization
,
scheme
);
GET_SET_STRING
(
belle_sip_header_authorization
,
username
);
...
...
@@ -957,7 +968,7 @@ static void belle_sip_header_proxy_authorization_clone(belle_sip_header_proxy_au
int
belle_sip_header_proxy_authorization_marshal
(
belle_sip_header_proxy_authorization_t
*
proxy_authorization
,
char
*
buff
,
unsigned
int
offset
,
unsigned
int
buff_size
)
{
return
belle_sip_header_authorization_marshal
(
&
proxy_authorization
->
authorization
,
buff
,
offset
,
buff_size
);
}
BELLE_SIP_NEW_HEADER
(
header_proxy_authorization
,
header_authorization
,
"Proxy-Authorization"
)
BELLE_SIP_NEW_HEADER
(
header_proxy_authorization
,
header_authorization
,
BELLE_SIP_PROXY_AUTHORIZATION
)
BELLE_SIP_PARSE
(
header_proxy_authorization
)
/**************************
*WWW-Authenticate header object inherent from parameters
...
...
@@ -1033,6 +1044,9 @@ GET_SET_BOOL(belle_sip_header_www_authenticate,stale,is)
belle_sip_list_t
*
belle_sip_header_www_authenticate_get_qop
(
const
belle_sip_header_www_authenticate_t
*
www_authetication
)
{
return
www_authetication
->
qop
;
}
const
char
*
belle_sip_header_www_authenticate_get_qop_first
(
const
belle_sip_header_www_authenticate_t
*
www_authetication
)
{
return
www_authetication
->
qop
?
(
const
char
*
)
www_authetication
->
qop
->
data
:
NULL
;
}
/**************************
*Proxy-authenticate header object inherent from www_authenticate
...
...
src/belle_sip_internal.h
View file @
3cc6f3b7
...
...
@@ -508,6 +508,7 @@ struct belle_sip_provider{
belle_sip_list_t
*
client_transactions
;
belle_sip_list_t
*
server_transactions
;
belle_sip_list_t
*
dialogs
;
belle_sip_list_t
*
auth_contexts
;
};
belle_sip_provider_t
*
belle_sip_provider_new
(
belle_sip_stack_t
*
s
,
belle_sip_listening_point_t
*
lp
);
...
...
@@ -803,7 +804,15 @@ struct belle_sip_transaction_terminated_event{
int
is_server_transaction
;
};
struct
belle_sip_auth_event
{
char
*
username
;
char
*
userid
;
char
*
realm
;
char
*
passwd
;
char
*
ha1
;
};
belle_sip_auth_event_t
*
belle_sip_auth_event_create
(
const
char
*
realm
,
const
char
*
username
);
void
belle_sip_auth_event_destroy
(
belle_sip_auth_event_t
*
event
);
#ifdef __cplusplus
}
...
...
src/belle_sip_utils.c
View file @
3cc6f3b7
...
...
@@ -164,7 +164,8 @@ belle_sip_list_t* belle_sip_list_new(void *data){
belle_sip_list_t
*
belle_sip_list_append_link
(
belle_sip_list_t
*
elem
,
belle_sip_list_t
*
new_elem
){
belle_sip_list_t
*
it
=
elem
;
if
(
elem
==
NULL
)
return
new_elem
;
if
(
elem
==
NULL
)
return
new_elem
;
if
(
new_elem
==
NULL
)
return
elem
;
while
(
it
->
next
!=
NULL
)
it
=
belle_sip_list_next
(
it
);
it
->
next
=
new_elem
;
new_elem
->
prev
=
it
;
...
...
src/message.c
View file @
3cc6f3b7
...
...
@@ -297,7 +297,7 @@ belle_sip_uri_t* belle_sip_request_extract_origin(const belle_sip_request_t* req
belle_sip_uri_set_port
(
uri
,
belle_sip_header_via_get_port
(
via_header
));
}
if
(
belle_sip_header_via_get_transport
(
via_header
))
{
belle_sip_uri_set_transport_param
(
uri
,
belle_sip_header_via_get_transport
(
via_header
));
belle_sip_uri_set_transport_param
(
uri
,
belle_sip_header_via_get_transport
_lowercase
(
via_header
));
}
return
uri
;
}
...
...
@@ -515,7 +515,7 @@ void belle_sip_response_fill_for_dialog(belle_sip_response_t *obj, belle_sip_req
void
belle_sip_response_get_return_hop
(
belle_sip_response_t
*
msg
,
belle_sip_hop_t
*
hop
){
belle_sip_header_via_t
*
via
=
BELLE_SIP_HEADER_VIA
(
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
msg
),
"via"
));
const
char
*
host
;
hop
->
transport
=
belle_sip_strdup
(
belle_sip_header_via_get_transport
(
via
));
hop
->
transport
=
belle_sip_strdup
(
belle_sip_header_via_get_transport
_lowercase
(
via
));
host
=
belle_sip_header_via_get_received
(
via
);
if
(
host
==
NULL
)
host
=
belle_sip_header_via_get_host
(
via
);
...
...
src/provider.c
View file @
3cc6f3b7
...
...
@@ -19,12 +19,45 @@
#include "belle_sip_internal.h"
#include "listeningpoint_internal.h"
typedef
struct
authorization_context
{
belle_sip_header_call_id_t
*
callid
;
const
char
*
scheme
;
const
char
*
realm
;
const
char
*
nonce
;
const
char
*
qop
;
const
char
*
opaque
;
int
nonce_count
;
int
is_proxy
;
}
authorization_context_t
;
GET_SET_STRING
(
authorization_context
,
realm
)
GET_SET_STRING
(
authorization_context
,
nonce
)
GET_SET_STRING
(
authorization_context
,
qop
)
GET_SET_STRING
(
authorization_context
,
scheme
)
GET_SET_STRING
(
authorization_context
,
opaque
)
GET_SET_INT
(
authorization_context
,
nonce_count
,
int
)
static
authorization_context_t
*
belle_sip_authorization_create
(
belle_sip_header_call_id_t
*
call_id
)
{
authorization_context_t
*
result
=
malloc
(
sizeof
(
authorization_context_t
));
memset
(
result
,
0
,
sizeof
(
authorization_context_t
));
result
->
callid
=
call_id
;
belle_sip_object_ref
(
result
->
callid
);
return
result
;
}
static
void
belle_sip_authorization_destroy
(
authorization_context_t
*
object
)
{
DESTROY_STRING
(
object
,
scheme
);
DESTROY_STRING
(
object
,
realm
);
DESTROY_STRING
(
object
,
nonce
);
DESTROY_STRING
(
object
,
qop
);
belle_sip_object_unref
(
object
->
callid
);
belle_sip_free
(
object
);
}
static
void
belle_sip_provider_uninit
(
belle_sip_provider_t
*
p
){
belle_sip_list_free
(
p
->
listeners
);
belle_sip_list_free_with_data
(
p
->
lps
,
belle_sip_object_unref
);
belle_sip_list_free_with_data
(
p
->
client_transactions
,
belle_sip_object_unref
);
belle_sip_list_free_with_data
(
p
->
server_transactions
,
belle_sip_object_unref
);
belle_sip_list_free_with_data
(
p
->
auth_contexts
,(
void
(
*
)(
void
*
))
belle_sip_authorization_destroy
);
}
static
void
channel_state_changed
(
belle_sip_channel_listener_t
*
obj
,
belle_sip_channel_t
*
chan
,
belle_sip_channel_state_t
state
){
...
...
@@ -489,3 +522,142 @@ void belle_sip_provider_remove_server_transaction(belle_sip_provider_t *prov, be
prov
->
server_transactions
=
belle_sip_list_remove
(
prov
->
server_transactions
,
t
);
belle_sip_object_unref
(
t
);
}
static
void
authorization_context_fill_from_auth
(
authorization_context_t
*
auth_context
,
belle_sip_header_www_authenticate_t
*
authenticate
)
{
authorization_context_set_realm
(
auth_context
,
belle_sip_header_www_authenticate_get_realm
(
authenticate
));
if
(
auth_context
->
nonce
&&
strcmp
(
belle_sip_header_www_authenticate_get_nonce
(
authenticate
),
auth_context
->
nonce
)
!=
0
)
{
/*new nonce, resetting nounce_count*/
auth_context
->
nonce_count
=
0
;
}
authorization_context_set_nonce
(
auth_context
,
belle_sip_header_www_authenticate_get_nonce
(
authenticate
));
authorization_context_set_qop
(
auth_context
,
belle_sip_header_www_authenticate_get_qop_first
(
authenticate
));
authorization_context_set_scheme
(
auth_context
,
belle_sip_header_www_authenticate_get_scheme
(
authenticate
));
authorization_context_set_opaque
(
auth_context
,
belle_sip_header_www_authenticate_get_opaque
(
authenticate
));
if
(
belle_sip_object_is_instance_of
(
BELLE_SIP_OBJECT
(
authenticate
),
BELLE_SIP_TYPE_ID
(
belle_sip_header_proxy_authenticate_t
)))
{
auth_context
->
is_proxy
=
1
;
}
}
static
belle_sip_list_t
*
belle_sip_provider_get_auth_context_by_call_id
(
belle_sip_provider_t
*
p
,
belle_sip_header_call_id_t
*
call_id
)
{
belle_sip_list_t
*
auth_context_lst
=
NULL
;
belle_sip_list_t
*
result
=
NULL
;
authorization_context_t
*
auth_context
;
for
(
auth_context_lst
=
p
->
auth_contexts
;
auth_context_lst
!=
NULL
;
auth_context_lst
=
auth_context_lst
->
next
)
{
auth_context
=
(
authorization_context_t
*
)
auth_context_lst
->
data
;
if
(
belle_sip_header_call_id_equals
(
auth_context
->
callid
,
call_id
)
)
{
result
=
belle_sip_list_append
(
result
,
auth_context_lst
->
data
);
}
}
return
result
;
}
static
void
belle_sip_provider_update_or_create_auth_context
(
belle_sip_provider_t
*
p
,
belle_sip_header_call_id_t
*
call_id
,
belle_sip_header_www_authenticate_t
*
authenticate
)
{
belle_sip_list_t
*
auth_context_lst
=
belle_sip_provider_get_auth_context_by_call_id
(
p
,
call_id
);
authorization_context_t
*
auth_context
;
for
(;
auth_context_lst
!=
NULL
;
auth_context_lst
=
auth_context_lst
->
next
)
{
auth_context
=
(
authorization_context_t
*
)
auth_context_lst
->
data
;
if
(
strcmp
(
auth_context
->
realm
,
belle_sip_header_www_authenticate_get_realm
(
authenticate
))
==
0
)
{
authorization_context_fill_from_auth
(
auth_context
,
authenticate
);
if
(
auth_context_lst
)
belle_sip_free
(
auth_context_lst
);
return
;
/*only one realm is supposed to be found for now*/
}
}
/*no auth context found, creating one*/
auth_context
=
belle_sip_authorization_create
(
call_id
);
authorization_context_fill_from_auth
(
auth_context
,
authenticate
);
p
->
auth_contexts
=
belle_sip_list_append
(
p
->
auth_contexts
,
auth_context
);
if
(
auth_context_lst
)
belle_sip_free
(
auth_context_lst
);
return
;
}
int
belle_sip_provider_add_authorization
(
belle_sip_provider_t
*
p
,
belle_sip_request_t
*
request
,
belle_sip_response_t
*
resp
)
{
belle_sip_header_call_id_t
*
call_id
;
belle_sip_list_t
*
auth_context_lst
;
belle_sip_list_t
*
authenticate_lst
;
belle_sip_header_www_authenticate_t
*
authenticate
;
belle_sip_header_authorization_t
*
authorization
;
belle_sip_header_address_t
*
from
;
belle_sip_auth_event_t
*
auth_event
;
authorization_context_t
*
auth_context
;
belle_sip_uri_t
*
from_uri
;
const
char
*
ha1
;
char
computed_ha1
[
33
];
int
result
=
0
;
/*check params*/
if
(
!
p
||
!
request
)
{
belle_sip_error
(
"belle_sip_provider_add_authorization bad parameters"
);
return
-
1
;
}
/*get authenticates value from response*/
if
(
resp
)
{
call_id
=
belle_sip_message_get_header_by_type
(
BELLE_SIP_MESSAGE
(
resp
),
belle_sip_header_call_id_t
);
/*searching for authentication headers*/
authenticate_lst
=
belle_sip_list_copy
(
belle_sip_message_get_headers
(
BELLE_SIP_MESSAGE
(
resp
),
BELLE_SIP_WWW_AUTHENTICATE
));
/*search for proxy authenticate*/
authenticate_lst
=
belle_sip_list_append_link
(
authenticate_lst
,
belle_sip_list_copy
(
belle_sip_message_get_headers
(
BELLE_SIP_MESSAGE
(
resp
),
BELLE_SIP_PROXY_AUTHENTICATE
)));
/*update auth contexts with authenticate headers from response*/
for
(;
authenticate_lst
!=
NULL
;
authenticate_lst
=
authenticate_lst
->
next
)
{
authenticate
=
BELLE_SIP_HEADER_WWW_AUTHENTICATE
(
authenticate_lst
->
data
);
belle_sip_provider_update_or_create_auth_context
(
p
,
call_id
,
authenticate
);
}
}
/*put authorization header if passwd found*/
call_id
=
belle_sip_message_get_header_by_type
(
BELLE_SIP_MESSAGE
(
request
),
belle_sip_header_call_id_t
);
from
=
BELLE_SIP_HEADER_ADDRESS
(
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
request
),
BELLE_SIP_FROM
));
from_uri
=
belle_sip_header_address_get_uri
(
from
);
if
((
auth_context_lst
=
belle_sip_provider_get_auth_context_by_call_id
(
p
,
call_id
)))
{
/*we assume there no existing auth headers*/
for
(;
auth_context_lst
!=
NULL
;
auth_context_lst
=
auth_context_lst
->
next
)
{
/*clear auth info*/
auth_context
=
(
authorization_context_t
*
)
auth_context_lst
->
data
;
auth_event
=
belle_sip_auth_event_create
(
auth_context
->
realm
,
belle_sip_uri_get_user
(
from_uri
));
/*put data*/
/*call listener*/
BELLE_SIP_PROVIDER_INVOKE_LISTENERS
(
p
,
process_auth_requested
,
auth_event
);
if
(
auth_event
->
passwd
||
auth_event
->
ha1
)
{
if
(
!
auth_event
->
userid
)
{
/*if no userid, username = userid*/
belle_sip_auth_event_set_userid
(
auth_event
,(
const
char
*
)
auth_event
->
username
);
}
belle_sip_message
(
"Auth info found for [%s] realm [%s]"
,
auth_event
->
userid
,
auth_event
->
realm
);
if
(
auth_context
->
is_proxy
)
{
authorization
=
BELLE_SIP_HEADER_AUTHORIZATION
(
belle_sip_header_proxy_authorization_new
());
}
else
{
authorization
=
belle_sip_header_authorization_new
();
}
belle_sip_header_authorization_set_scheme
(
authorization
,
auth_context
->
scheme
);
belle_sip_header_authorization_set_realm
(
authorization
,
auth_context
->
realm
);
belle_sip_header_authorization_set_username
(
authorization
,
auth_event
->
userid
);
belle_sip_header_authorization_set_nonce
(
authorization
,
auth_context
->
nonce
);
belle_sip_header_authorization_set_qop
(
authorization
,
auth_context
->
qop
);
belle_sip_header_authorization_set_opaque
(
authorization
,
auth_context
->
opaque
);
belle_sip_header_authorization_set_uri
(
authorization
,
belle_sip_request_get_uri
(
request
)
/*belle_sip_uri_create(belle_sip_uri_get_user(belle_sip_request_get_uri(request))
,belle_sip_uri_get_host(belle_sip_request_get_uri(request)))*/
);
belle_sip_header_authorization_set_nonce_count
(
authorization
,
++
auth_context
->
nonce_count
);
if
(
auth_event
->
ha1
)
{
ha1
=
auth_event
->
ha1
;
}
else
{
belle_sip_auth_helper_compute_ha1
(
auth_event
->
userid
,
auth_context
->
realm
,
auth_event
->
passwd
,
computed_ha1
);
ha1
=
computed_ha1
;
}
if
(
belle_sip_auth_helper_fill_authorization
(
authorization
,
belle_sip_request_get_method
(
request
)
,
ha1
))
{
belle_sip_object_unref
(
authorization
);
}
else
belle_sip_message_add_header
(
BELLE_SIP_MESSAGE
(
request
),
BELLE_SIP_HEADER
(
authorization
));
result
=
1
;
}
else
{
belle_sip_message
(
"No auth info found for call id [%s]"
,
belle_sip_header_call_id_get_call_id
(
call_id
));
}
}
belle_sip_list_free
(
auth_context_lst
);
}
else
{
/*nothing to do*/
}
return
result
;
}
src/transaction.c
View file @
3cc6f3b7
...
...
@@ -345,3 +345,4 @@ belle_sip_dialog_t* belle_sip_transaction_get_dialog(const belle_sip_transactio
return
t
->
dialog
;
}
tester/belle_sip_message_tester.c
View file @
3cc6f3b7
...
...
@@ -225,7 +225,7 @@ static void test_extract_source() {
CU_ASSERT_PTR_NOT_NULL
(
source
);
CU_ASSERT_STRING_EQUAL
(
belle_sip_uri_get_host
(
source
),
"37.59.129.73"
);
CU_ASSERT_EQUAL
(
belle_sip_uri_get_port
(
source
),
0
);
CU_ASSERT_STRING_EQUAL
(
belle_sip_uri_get_transport_param
(
source
),
"
TCP
"
);
CU_ASSERT_STRING_EQUAL
(
belle_sip_uri_get_transport_param
(
source
),
"
tcp
"
);
belle_sip_object_unref
(
message
);
message
=
belle_sip_message_parse
(
invite_2
);
...
...
@@ -234,7 +234,7 @@ static void test_extract_source() {
CU_ASSERT_PTR_NOT_NULL
(
source
);
CU_ASSERT_STRING_EQUAL
(
belle_sip_uri_get_host
(
source
),
"81.56.113.2"
);
CU_ASSERT_EQUAL
(
belle_sip_uri_get_port
(
source
),
15060
);
CU_ASSERT_STRING_EQUAL
(
belle_sip_uri_get_transport_param
(
source
),
"
UDP
"
);
CU_ASSERT_STRING_EQUAL
(
belle_sip_uri_get_transport_param
(
source
),
"
udp
"
);
belle_sip_object_unref
(
message
);
}
...
...
tester/belle_sip_register_tester.c
View file @
3cc6f3b7
...
...
@@ -22,7 +22,9 @@
#include "pthread.h"
const
char
*
test_domain
=
"test.linphone.org"
;
const
char
*
auth_domain
=
"sip.linphone.org"
;
static
int
is_register_ok
;
static
int
number_of_challange
;
static
int
using_transaction
;
belle_sip_stack_t
*
stack
;
belle_sip_provider_t
*
prov
;
...
...
@@ -39,13 +41,31 @@ static void process_io_error(belle_sip_listener_t *obj, const belle_sip_io_error
static
void
process_request_event
(
belle_sip_listener_t
*
obj
,
const
belle_sip_request_event_t
*
event
){
belle_sip_message
(
"process_request_event"
);
}
belle_sip_request_t
*
authorized_request
;
static
void
process_response_event
(
belle_sip_listener_t
*
obj
,
const
belle_sip_response_event_t
*
event
){
belle_sip_message
(
"process_response_event"
);
int
status
;
belle_sip_request_t
*
request
;
CU_ASSERT_PTR_NOT_NULL_FATAL
(
belle_sip_response_event_get_response
(
event
));
CU_ASSERT_EQUAL
(
belle_sip_response_get_status_code
(
belle_sip_response_event_get_response
(
event
)),
200
);
is_register_ok
=
1
;
using_transaction
=
belle_sip_response_event_get_client_transaction
(
event
)
!=
NULL
;
belle_sip_main_loop_quit
(
belle_sip_stack_get_main_loop
(
stack
));
belle_sip_message
(
"process_response_event [%i] [%s]"
,
status
=
belle_sip_response_get_status_code
(
belle_sip_response_event_get_response
(
event
))
,
belle_sip_response_get_reason_phrase
(
belle_sip_response_event_get_response
(
event
)));
if
(
status
==
401
)
{
CU_ASSERT_NOT_EQUAL_FATAL
(
number_of_challange
,
2
);
CU_ASSERT_PTR_NOT_NULL_FATAL
(
belle_sip_response_event_get_client_transaction
(
event
));
/*require transaction mode*/
request
=
belle_sip_transaction_get_request
(
BELLE_SIP_TRANSACTION
(
belle_sip_response_event_get_client_transaction
(
event
)));
belle_sip_header_cseq_t
*
cseq
=
(
belle_sip_header_cseq_t
*
)
belle_sip_message_get_header
(
BELLE_SIP_MESSAGE
(
request
),
BELLE_SIP_CSEQ
);
belle_sip_header_cseq_set_seq_number
(
cseq
,
belle_sip_header_cseq_get_seq_number
(
cseq
)
+
1
);
CU_ASSERT_TRUE_FATAL
(
belle_sip_provider_add_authorization
(
prov
,
request
,
belle_sip_response_event_get_response
(
event
)));
belle_sip_client_transaction_t
*
t
=
belle_sip_provider_create_client_transaction
(
prov
,
request
);
belle_sip_client_transaction_send_request
(
t
);