mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-23 05:40:52 +00:00
Use SASL DIGEST-MD5 authentication over unsecured network connections only.
This authentication mechanism is implemented under the iksemel API, which makes use of GnuTLS, whereas we use OpenSSL. Note : there's ongoing dicsussion at the SASL IETF WG in order to deprecate SASL DIGEST-MD5, see http://ietfreport.isoc.org/ids-wg-sasl.html. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@96499 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -65,7 +65,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-- Forward declarations */
|
/*-- Forward declarations */
|
||||||
static int aji_highest_bit(int number);
|
|
||||||
static void aji_buddy_destroy(struct aji_buddy *obj);
|
static void aji_buddy_destroy(struct aji_buddy *obj);
|
||||||
static void aji_client_destroy(struct aji_client *obj);
|
static void aji_client_destroy(struct aji_client *obj);
|
||||||
static int aji_send_exec(struct ast_channel *chan, void *data);
|
static int aji_send_exec(struct ast_channel *chan, void *data);
|
||||||
@@ -297,23 +296,6 @@ static int gtalk_yuck(iks *node)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Detects the highest bit in a number.
|
|
||||||
* \param number Number you want to have evaluated.
|
|
||||||
* \return the highest power of 2 that can go into the number.
|
|
||||||
*/
|
|
||||||
static int aji_highest_bit(int number)
|
|
||||||
{
|
|
||||||
int x = sizeof(number) * 8 - 1;
|
|
||||||
if (!number)
|
|
||||||
return 0;
|
|
||||||
for (; x > 0; x--) {
|
|
||||||
if (number & (1 << x))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return (1 << x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Setup the authentication struct
|
* \brief Setup the authentication struct
|
||||||
* \param id iksid
|
* \param id iksid
|
||||||
@@ -783,10 +765,6 @@ static void aji_log_hook(void *data, const char *xmpp, size_t size, int is_incom
|
|||||||
* \param username
|
* \param username
|
||||||
* \param pass password.
|
* \param pass password.
|
||||||
*
|
*
|
||||||
* If SASL authentication type is MD5, we simply call iks_start_sasl().
|
|
||||||
* If type is PLAIN, we compute the authentication string by ourselves,
|
|
||||||
* because it looks like Google's jabber server does not accept the value
|
|
||||||
* computed with iks_start_sasl().
|
|
||||||
* \return IKS_OK on success, IKSNET_NOTSUPP on failure.
|
* \return IKS_OK on success, IKSNET_NOTSUPP on failure.
|
||||||
*/
|
*/
|
||||||
static int aji_start_sasl(struct aji_client *client, enum ikssasltype type, char *username, char *pass)
|
static int aji_start_sasl(struct aji_client *client, enum ikssasltype type, char *username, char *pass)
|
||||||
@@ -796,8 +774,15 @@ static int aji_start_sasl(struct aji_client *client, enum ikssasltype type, char
|
|||||||
char *s;
|
char *s;
|
||||||
char *base64;
|
char *base64;
|
||||||
|
|
||||||
if (type == IKS_STREAM_SASL_MD5)
|
/* trigger SASL DIGEST-MD5 only over an unsecured connection.
|
||||||
return iks_start_sasl(client->p, IKS_SASL_DIGEST_MD5, username, pass);
|
iks_start_sasl is an iksemel API function and relies on GnuTLS,
|
||||||
|
whereas we use OpenSSL */
|
||||||
|
if ((type & IKS_STREAM_SASL_MD5) && !aji_is_secure(client))
|
||||||
|
return iks_start_sasl(client->p, IKS_SASL_DIGEST_MD5, username, pass);
|
||||||
|
if (!(type & IKS_STREAM_SASL_PLAIN)) {
|
||||||
|
ast_log(LOG_ERROR, "Server does not support SASL PLAIN authentication\n");
|
||||||
|
return IKS_NET_NOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
x = iks_new("auth");
|
x = iks_new("auth");
|
||||||
if (!x) {
|
if (!x) {
|
||||||
@@ -811,7 +796,12 @@ static int aji_start_sasl(struct aji_client *client, enum ikssasltype type, char
|
|||||||
base64 = alloca((len + 2) * 4 / 3);
|
base64 = alloca((len + 2) * 4 / 3);
|
||||||
iks_insert_attrib(x, "mechanism", "PLAIN");
|
iks_insert_attrib(x, "mechanism", "PLAIN");
|
||||||
snprintf(s, len, "%c%s%c%s", 0, username, 0, pass);
|
snprintf(s, len, "%c%s%c%s", 0, username, 0, pass);
|
||||||
ast_base64encode(base64, (const unsigned char *) s, len, (len + 2) * 4 / 3);
|
|
||||||
|
/* exclude the NULL training byte from the base64 encoding operation
|
||||||
|
as some XMPP servers will refuse it.
|
||||||
|
The format for authentication is [authzid]\0authcid\0password
|
||||||
|
not [authzid]\0authcid\0password\0 */
|
||||||
|
ast_base64encode(base64, (const unsigned char *) s, len - 1, (len + 2) * 4 / 3);
|
||||||
iks_insert_cdata(x, base64, 0);
|
iks_insert_cdata(x, base64, 0);
|
||||||
ast_aji_send(client, x);
|
ast_aji_send(client, x);
|
||||||
iks_delete(x);
|
iks_delete(x);
|
||||||
@@ -916,7 +906,7 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|||||||
ast_log(LOG_ERROR, "Malformed Jabber ID : %s (domain missing?)\n", client->jid->full);
|
ast_log(LOG_ERROR, "Malformed Jabber ID : %s (domain missing?)\n", client->jid->full);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
features = aji_highest_bit(features);
|
|
||||||
ret = aji_start_sasl(client, features, client->jid->user, client->password);
|
ret = aji_start_sasl(client, features, client->jid->user, client->password);
|
||||||
if (ret != IKS_OK) {
|
if (ret != IKS_OK) {
|
||||||
ASTOBJ_UNREF(client, aji_client_destroy);
|
ASTOBJ_UNREF(client, aji_client_destroy);
|
||||||
|
Reference in New Issue
Block a user