Commit 203de12a authored by Kai Vehmanen's avatar Kai Vehmanen
Browse files

Refactored the nua_glib authentication interface.

darcs-hash:20060530161835-7659e-499009c684d16d0fa30d6a726e5083e4e7c8a97a.gz
parent 62eb0562
...@@ -8,7 +8,6 @@ Changes since last release ...@@ -8,7 +8,6 @@ Changes since last release
<changes since last written in freshmeat.net "Changes:" style; <changes since last written in freshmeat.net "Changes:" style;
and in less than 10 lines /> and in less than 10 lines />
API/ABI changes and versioning API/ABI changes and versioning
------------------------------ ------------------------------
...@@ -18,10 +17,19 @@ API/ABI changes and versioning ...@@ -18,10 +17,19 @@ API/ABI changes and versioning
other important information to developers; other important information to developers;
- and should be updated _continuously_! /> - and should be updated _continuously_! />
- nua_glib.h: renamed glib property 'stun' to 'stun-server', [libsofia-sip-ua]
removed property 'bind-address' (same as 'contact').
- Added sip_route_reverse_as() and sip_route_fixdup_as(). - Added sip_route_reverse_as() and sip_route_fixdup_as().
[libsofia-sip-ua-glib]
- nua_glib: Changes in object properties.
- renamed 'stun' to 'stun-server'
- renamed 'bind-address' to 'contact'
- added 'proxy' and 'registrar' URI properties
- nua_glib.h: Refactored the nua_glib authentication API.
- added 'auth-required' signal
- added 'password' property, removed 'authinfo' property.
- added nua_glib_auth_add() and nua_glib_auth_clear
Contributors to this release Contributors to this release
---------------------------- ----------------------------
......
...@@ -88,11 +88,11 @@ static guint signals[LAST_SIGNAL] = {0}; ...@@ -88,11 +88,11 @@ static guint signals[LAST_SIGNAL] = {0};
enum enum
{ {
PROP_CONTACT = 1, PROP_ADDRESS = 1,
PROP_ADDRESS, PROP_PASSWORD,
PROP_CONTACT,
PROP_PROXY, PROP_PROXY,
PROP_REGISTRAR, PROP_REGISTRAR,
PROP_AUTHINFO,
PROP_STUN_SERVER, PROP_STUN_SERVER,
LAST_PROPERTY LAST_PROPERTY
}; };
...@@ -105,6 +105,7 @@ void final_shutdown(NuaGlib *self) ...@@ -105,6 +105,7 @@ void final_shutdown(NuaGlib *self)
static GObjectClass *parent_class=NULL; static GObjectClass *parent_class=NULL;
static int sof_init(NuaGlibPrivate *priv, const char *contact); static int sof_init(NuaGlibPrivate *priv, const char *contact);
static void priv_submit_authlist(NuaGlibOp *op);
static GObject * static GObject *
nua_glib_constructor (GType type, nua_glib_constructor (GType type,
...@@ -189,7 +190,6 @@ nua_glib_init(NuaGlib *self) ...@@ -189,7 +190,6 @@ nua_glib_init(NuaGlib *self)
/* initialize sofia su OS abstraction layer */ /* initialize sofia su OS abstraction layer */
su_init(); su_init();
su_home_init(self->priv->home); su_home_init(self->priv->home);
self->priv->authinfo = g_strdup("");
} }
static void static void
...@@ -200,7 +200,6 @@ nua_glib_dispose(GObject *obj) ...@@ -200,7 +200,6 @@ nua_glib_dispose(GObject *obj)
if (self->priv->init) if (self->priv->init)
{ {
g_free((gpointer)self->priv->contact); g_free((gpointer)self->priv->contact);
g_free((gpointer)self->priv->authinfo);
nua_shutdown(self->priv->nua); nua_shutdown(self->priv->nua);
...@@ -241,10 +240,6 @@ void nua_glib_set_property(GObject *object, ...@@ -241,10 +240,6 @@ void nua_glib_set_property(GObject *object,
(s)->priv->x = g_value_dup_string (value) (s)->priv->x = g_value_dup_string (value)
switch (property_id) { switch (property_id) {
case PROP_CONTACT: {
STORE_PARAM(self, contact);
break;
}
case PROP_ADDRESS: { case PROP_ADDRESS: {
if (self->priv->nua) if (self->priv->nua)
{ {
...@@ -259,6 +254,14 @@ void nua_glib_set_property(GObject *object, ...@@ -259,6 +254,14 @@ void nua_glib_set_property(GObject *object,
} }
break; break;
} }
case PROP_PASSWORD: {
STORE_PARAM(self, password);
break;
}
case PROP_CONTACT: {
STORE_PARAM(self, contact);
break;
}
case PROP_PROXY: { case PROP_PROXY: {
STORE_PARAM(self, proxy); STORE_PARAM(self, proxy);
if (self->priv->nua) if (self->priv->nua)
...@@ -279,10 +282,6 @@ void nua_glib_set_property(GObject *object, ...@@ -279,10 +282,6 @@ void nua_glib_set_property(GObject *object,
} }
break; break;
} }
case PROP_AUTHINFO: {
STORE_PARAM(self, authinfo);
break;
}
case PROP_STUN_SERVER: { case PROP_STUN_SERVER: {
STORE_PARAM(self, stun_server); STORE_PARAM(self, stun_server);
break; break;
...@@ -303,14 +302,18 @@ nua_glib_get_property (GObject *object, ...@@ -303,14 +302,18 @@ nua_glib_get_property (GObject *object,
NuaGlib *self = (NuaGlib *) object; NuaGlib *self = (NuaGlib *) object;
switch (property_id) { switch (property_id) {
case PROP_CONTACT: {
g_value_set_string (value, self->priv->contact);
break;
}
case PROP_ADDRESS: { case PROP_ADDRESS: {
g_value_set_string (value, self->priv->address); g_value_set_string (value, self->priv->address);
break; break;
} }
case PROP_PASSWORD: {
g_value_set_string (value, self->priv->password);
break;
}
case PROP_CONTACT: {
g_value_set_string (value, self->priv->contact);
break;
}
case PROP_PROXY: { case PROP_PROXY: {
g_value_set_string (value, self->priv->proxy); g_value_set_string (value, self->priv->proxy);
break; break;
...@@ -319,8 +322,8 @@ nua_glib_get_property (GObject *object, ...@@ -319,8 +322,8 @@ nua_glib_get_property (GObject *object,
g_value_set_string (value, self->priv->registrar); g_value_set_string (value, self->priv->registrar);
break; break;
} }
case PROP_AUTHINFO: { case PROP_STUN_SERVER: {
g_value_set_string (value, self->priv->authinfo); g_value_set_string (value, self->priv->stun_server);
break; break;
} }
default: default:
...@@ -344,15 +347,6 @@ nua_glib_class_init (NuaGlibClass *nua_glib_class) ...@@ -344,15 +347,6 @@ nua_glib_class_init (NuaGlibClass *nua_glib_class)
gobject_class->set_property = nua_glib_set_property; gobject_class->set_property = nua_glib_set_property;
gobject_class->get_property = nua_glib_get_property; gobject_class->get_property = nua_glib_get_property;
param_spec = g_param_spec_string("contact",
"NuaGlib construction property",
"local bind interface (e.g. 'sip:0.0.0.0:*') [optional]",
NULL, /*default value*/
G_PARAM_READWRITE );
g_object_class_install_property (gobject_class,
PROP_CONTACT,
param_spec);
param_spec = g_param_spec_string("address", param_spec = g_param_spec_string("address",
"NuaGlib construction property", "NuaGlib construction property",
"The address-of-record for this UA (e.g. 'sip:first.surname@myprovider.com')", "The address-of-record for this UA (e.g. 'sip:first.surname@myprovider.com')",
...@@ -362,34 +356,41 @@ nua_glib_class_init (NuaGlibClass *nua_glib_class) ...@@ -362,34 +356,41 @@ nua_glib_class_init (NuaGlibClass *nua_glib_class)
PROP_ADDRESS, PROP_ADDRESS,
param_spec); param_spec);
param_spec = g_param_spec_string("proxy", param_spec = g_param_spec_string("password",
"NuaGlib construction property", "NuaGlib construction property",
"SIP outgoing proxy URI (e.g. 'sip:sipproxy.myprovider.com') [optional]", "SIP account password",
NULL, /*default value*/ NULL, /*default value*/
G_PARAM_READWRITE ); G_PARAM_READWRITE);
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_PROXY, PROP_PASSWORD,
param_spec); param_spec);
param_spec = g_param_spec_string("registrar", param_spec = g_param_spec_string("contact",
"NuaGlib construction property", "NuaGlib construction property",
"SIP registrar URI (e.g. 'sip:sip.myprovider.com') [optional]", "local bind interface (e.g. 'sip:0.0.0.0:*') [optional]",
NULL, /*default value*/ NULL, /*default value*/
G_PARAM_READWRITE ); G_PARAM_READWRITE );
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_REGISTRAR, PROP_CONTACT,
param_spec); param_spec);
param_spec = g_param_spec_string("authinfo", param_spec = g_param_spec_string("proxy",
"NuaGlib construction property", "NuaGlib construction property",
"Authorization information for SIP network. Syntax:" "SIP outgoing proxy URI (e.g. 'sip:sipproxy.myprovider.com') [optional]",
"scheme:\"realm\":user:password (e.g. 'digest:myprovider.com:foo:bar') [optional]",
NULL, /*default value*/ NULL, /*default value*/
G_PARAM_READWRITE ); G_PARAM_READWRITE );
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_AUTHINFO, PROP_PROXY,
param_spec); param_spec);
param_spec = g_param_spec_string("registrar",
"NuaGlib construction property",
"SIP registrar URI (e.g. 'sip:sip.myprovider.com') [optional]",
NULL, /*default value*/
G_PARAM_READWRITE );
g_object_class_install_property (gobject_class,
PROP_REGISTRAR,
param_spec);
param_spec = g_param_spec_string("stun-server", param_spec = g_param_spec_string("stun-server",
"NuaGlib construction property", "NuaGlib construction property",
...@@ -1173,6 +1174,9 @@ nua_glib_op_destroy(NuaGlib *self, NuaGlibOp *op) ...@@ -1173,6 +1174,9 @@ nua_glib_op_destroy(NuaGlib *self, NuaGlibOp *op)
if (*prev) if (*prev)
*prev = op->op_next, op->op_next = NULL; *prev = op->op_next, op->op_next = NULL;
if (op->op_authlist)
nua_glib_auth_clear(self, op);
if (op->op_handle) if (op->op_handle)
nua_handle_destroy(op->op_handle), op->op_handle = NULL; nua_handle_destroy(op->op_handle), op->op_handle = NULL;
...@@ -1194,91 +1198,17 @@ oper_assign(NuaGlibOp *op, sip_method_t method, char const *name) ...@@ -1194,91 +1198,17 @@ oper_assign(NuaGlibOp *op, sip_method_t method, char const *name)
method == sip_method_publish; method == sip_method_publish;
} }
#if 0 /**
/** Find call operation */ * Handles authentication challenge for operation 'op'.
static NuaGlibOp * */
oper_find_call(NuaGlib *self)
{
NuaGlibOp *op;
for (op = self->priv->operations; op; op = op->op_next)
if (op->op_callstate)
break;
return op;
}
/** Find call operation */
static NuaGlibOp *
oper_find_call_in_progress(NuaGlib *self)
{
NuaGlibOp *op;
for (op = self->priv->operations; op; op = op->op_next)
if (op->op_callstate & opc_sent) /* opc_sent bit is on? */
break;
return op;
}
static NuaGlibOp *
oper_find_call_embryonic(NuaGlib *self)
{
NuaGlibOp *op;
for (op = self->priv->operations; op; op = op->op_next)
if (op->op_callstate == 0 && op->op_method == sip_method_invite)
break;
return op;
}
/** Find unanswered call */
static NuaGlibOp *
oper_find_unanswered(NuaGlib *self)
{
NuaGlibOp *op;
for (op = self->priv->operations; op; op = op->op_next)
if (op->op_callstate == opc_recv)
break;
return op;
}
/** Find operation by method */
NuaGlibOp *oper_find_by_method(NuaGlib *self, sip_method_t method)
{
NuaGlibOp *op;
for (op = self->priv->operations; op; op = op->op_next)
if (op->op_method == method && op->op_persistent)
break;
return op;
}
/** Find register operation */
NuaGlibOp *oper_find_register(NuaGlib *self)
{
NuaGlibOp *op;
for (op = self->priv->operations; op; op = op->op_next)
if (op->op_method == sip_method_register && op->op_persistent)
break;
return op;
}
#endif
/** Set operation to be authenticated */
static void static void
oper_set_auth (NuaGlib *self, NuaGlibOp *op, sip_t const *sip, tagi_t *tags) oper_set_auth (NuaGlib *self, NuaGlibOp *op, sip_t const *sip, tagi_t *tags)
{ {
sip_www_authenticate_t const *wa = sip->sip_www_authenticate; sip_www_authenticate_t const *wa = sip->sip_www_authenticate;
sip_proxy_authenticate_t const *pa = sip->sip_proxy_authenticate; sip_proxy_authenticate_t const *pa = sip->sip_proxy_authenticate;
sip_from_t const *sipfrom = sip->sip_from;
const char *realm = NULL;
enter; enter;
tl_gets(tags, tl_gets(tags,
...@@ -1286,9 +1216,18 @@ oper_set_auth (NuaGlib *self, NuaGlibOp *op, sip_t const *sip, tagi_t *tags) ...@@ -1286,9 +1216,18 @@ oper_set_auth (NuaGlib *self, NuaGlibOp *op, sip_t const *sip, tagi_t *tags)
SIPTAG_PROXY_AUTHENTICATE_REF(pa), SIPTAG_PROXY_AUTHENTICATE_REF(pa),
TAG_NULL()); TAG_NULL());
printf("%s: %s was unauthorized\n", self->priv->name, op->op_method_name); SU_DEBUG_3(("%s: %s was unauthorized\n", self->priv->name, op->op_method_name));
if (wa) sl_header_print(stdout, "Server auth: %s\n", (sip_header_t *)wa);
if (pa) sl_header_print(stdout, "Proxy auth: %s\n", (sip_header_t *)pa); if (wa) {
sl_header_print(stdout, "Server auth: %s\n", (sip_header_t *)wa);
realm = msg_params_find(wa->au_params, "realm=");
nua_glib_auth_add(self, op, wa->au_scheme, realm, sipfrom->a_url->url_user, self->priv->password);
}
if (pa) {
sl_header_print(stdout, "Proxy auth: %s\n", (sip_header_t *)pa);
realm = msg_params_find(pa->au_params, "realm=");
nua_glib_auth_add(self, op, pa->au_scheme, realm, sipfrom->a_url->url_user, self->priv->password);
}
if (op->op_tried_auth) if (op->op_tried_auth)
{ {
...@@ -1299,7 +1238,7 @@ oper_set_auth (NuaGlib *self, NuaGlibOp *op, sip_t const *sip, tagi_t *tags) ...@@ -1299,7 +1238,7 @@ oper_set_auth (NuaGlib *self, NuaGlibOp *op, sip_t const *sip, tagi_t *tags)
return; return;
} }
nua_authenticate(op->op_handle, NUTAG_AUTH(self->priv->authinfo), TAG_END()); priv_submit_authlist(op);
op->op_tried_auth =1; op->op_tried_auth =1;
} }
...@@ -2509,3 +2448,76 @@ sof_r_get_params (int status, char const *phrase, ...@@ -2509,3 +2448,76 @@ sof_r_get_params (int status, char const *phrase,
} }
} }
/**
* Submit all authentication credentials stored for
* operation handle 'op'
*/
static void priv_submit_authlist(NuaGlibOp *op)
{
GSList *i = op->op_authlist;
while(i) {
GString *tmp = (GString*)i->data;
if (tmp && tmp->str) {
g_assert(tmp->len > 0);
g_debug("submitting authitem (op=%p): %s.\n", op, tmp->str);
nua_authenticate(op->op_handle, NUTAG_AUTH(tmp->str), TAG_END());
}
i = g_slist_next(i);
}
}
/**
* nua_glib_auth_add:
* @op: operation to which the auth credentials are added
* @method: auth method (RFC2617)
* @method: auth realm (RFC2617)
* @method: auth username (RFC2617)
* @method: auth passwrod (RFC2617)
*
* Attach new authentication credentials to operation 'op'.
*
* @see nua_glib_auth_clear()
*/
void nua_glib_auth_add(NuaGlib *self, NuaGlibOp *op, const char *method, const char *realm, const char *user, const char *password)
{
GString *tmp = g_string_new(NULL);
/* XXX: we should prune the auth-cred database in case scheme, realm
and username match */
if (realm[0] == '"')
g_string_printf(tmp, "%s:%s:%s:%s",
method, realm, user, password);
else
g_string_printf(tmp, "%s:\"%s\":%s:%s",
method, realm, user, password);
op->op_authlist = g_slist_append(op->op_authlist, tmp);
op->op_tried_auth = 0;
priv_submit_authlist(op);
}
/**
* nua_glib_auth_clear:
* @op: operation to which the auth credentials are added
*
* Clears the authentication credentials for operation 'op'.
*
* @see nua_glib_auth_add()
*/
void nua_glib_auth_clear(NuaGlib *self, NuaGlibOp *op)
{
GSList *i = op->op_authlist;
while(i) {
GString *tmp = (GString*)i->data;
g_string_free(tmp, TRUE);
i = g_slist_next(i);
}
g_slist_free(op->op_authlist), op->op_authlist = NULL;
op->op_tried_auth = 0;
}
...@@ -7,4 +7,5 @@ VOID:POINTER,POINTER ...@@ -7,4 +7,5 @@ VOID:POINTER,POINTER
VOID:POINTER,STRING,STRING,STRING,POINTER VOID:POINTER,STRING,STRING,STRING,POINTER
VOID:POINTER,STRING,STRING,STRING,STRING VOID:POINTER,STRING,STRING,STRING,STRING
VOID:POINTER,STRING,STRING,STRING VOID:POINTER,STRING,STRING,STRING
VOID:POINTER,STRING,STRING
VOID:INT,STRING VOID:INT,STRING
...@@ -107,7 +107,9 @@ struct _NuaGlibOp { ...@@ -107,7 +107,9 @@ struct _NuaGlibOp {
unsigned op_referred : 1; unsigned op_referred : 1;
unsigned :0; unsigned :0;
gpointer data; GSList *op_authlist;
gpointer data;
}; };
...@@ -121,11 +123,11 @@ struct _NuaGlibPrivate { ...@@ -121,11 +123,11 @@ struct _NuaGlibPrivate {
unsigned init : 1; /**< True if class is inited */ unsigned init : 1; /**< True if class is inited */
gchar *address; /**< our SIP address (address-of-record) */ gchar *address; /**< our SIP address (address-of-record) */
gchar *password; /**< SIP account password */
gchar *contact; /**< contact URI (local address) */ gchar *contact; /**< contact URI (local address) */
gchar *proxy; /**< outgoing proxy URI (optional, otherwise from DNS) */ gchar *proxy; /**< outgoing proxy URI (optional, otherwise from DNS) */
gchar *registrar; /**< registrar URI (optional, otherwise from DNS) */ gchar *registrar; /**< registrar URI (optional, otherwise from DNS) */
gchar *stun_server; /**< STUN server URI (optional, otherwise from DNS) */ gchar *stun_server; /**< STUN server URI (optional, otherwise from DNS) */
gchar *authinfo; /**< authorization info used by this UA*/
nua_t *nua; /**< Pointer to NUA object */ nua_t *nua; /**< Pointer to NUA object */
NuaGlibOp *operations; /**< Remote destinations */ NuaGlibOp *operations; /**< Remote destinations */
......
...@@ -84,7 +84,6 @@ typedef enum { ...@@ -84,7 +84,6 @@ typedef enum {
| NUA_GLIB_MEDIA_RECVONLY | NUA_GLIB_MEDIA_RECVONLY
} NuaGlibMediaActive; } NuaGlibMediaActive;
NuaGlibOp * nua_glib_invite (NuaGlib *self, const char *destination, const char *local_sdp); NuaGlibOp * nua_glib_invite (NuaGlib *self, const char *destination, const char *local_sdp);
void nua_glib_answer (NuaGlib *self, NuaGlibOp *op, int status, const char *phrase, const char *sdp); void nua_glib_answer (NuaGlib *self, NuaGlibOp *op, int status, const char *phrase, const char *sdp);
...@@ -131,6 +130,10 @@ NuaGlibOp* nua_glib_unpublish_direct (NuaGlib *self); ...@@ -131,6 +130,10 @@ NuaGlibOp* nua_glib_unpublish_direct (NuaGlib *self);
void nua_glib_redirect(NuaGlib *self, NuaGlibOp *op, const char *contact); void nua_glib_redirect(NuaGlib *self, NuaGlibOp *op, const char *contact);
void nua_glib_auth_add(NuaGlib *self, NuaGlibOp *op, const char *method, const char *realm, const char *user, const char *password);
void nua_glib_auth_clear(NuaGlib *self, NuaGlibOp *op);
/*helper functions*/ /*helper functions*/
gpointer nua_glib_op_get_data(NuaGlibOp *op); gpointer nua_glib_op_get_data(NuaGlibOp *op);
......
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