diff options
Diffstat (limited to 'protocols/jabber/sasl.c')
-rw-r--r-- | protocols/jabber/sasl.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/protocols/jabber/sasl.c b/protocols/jabber/sasl.c index adcc0f1a..45d52593 100644 --- a/protocols/jabber/sasl.c +++ b/protocols/jabber/sasl.c @@ -54,7 +54,7 @@ xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data) struct xt_node *c, *reply; char *s; int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_fb = 0; - int want_oauth = FALSE; + int want_oauth = FALSE, want_hipchat = FALSE; GString *mechs; if (!sasl_supported(ic)) { @@ -74,6 +74,7 @@ xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data) } want_oauth = set_getbool(&ic->acc->set, "oauth"); + want_hipchat = (jd->flags & JFLAG_HIPCHAT); mechs = g_string_new(""); c = node->children; @@ -110,7 +111,11 @@ xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data) g_string_free(mechs, TRUE); reply = xt_new_node("auth", NULL, NULL); - xt_add_attr(reply, "xmlns", XMLNS_SASL); + if (!want_hipchat) { + xt_add_attr(reply, "xmlns", XMLNS_SASL); + } else { + xt_add_attr(reply, "xmlns", XMLNS_HIPCHAT); + } if (sup_gtalk && want_oauth) { int len; @@ -142,15 +147,33 @@ xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data) /* The rest will be done later, when we receive a <challenge/>. */ } else if (sup_plain) { int len; + GString *gs; + char *username; - xt_add_attr(reply, "mechanism", "PLAIN"); + if (!want_hipchat) { + xt_add_attr(reply, "mechanism", "PLAIN"); + username = jd->username; + } else { + username = jd->me; + } + + /* set an arbitrary initial size to avoid reallocations */ + gs = g_string_sized_new(128); /* With SASL PLAIN in XMPP, the text should be b64(\0user\0pass) */ - len = strlen(jd->username) + strlen(ic->acc->pass) + 2; - s = g_malloc(len + 1); - s[0] = 0; - strcpy(s + 1, jd->username); - strcpy(s + 2 + strlen(jd->username), ic->acc->pass); + g_string_append_c(gs, '\0'); + g_string_append(gs, username); + g_string_append_c(gs, '\0'); + g_string_append(gs, ic->acc->pass); + if (want_hipchat) { + /* Hipchat's variation adds \0resource at the end */ + g_string_append_c(gs, '\0'); + g_string_append(gs, set_getstr(&ic->acc->set, "resource")); + } + + len = gs->len; + s = g_string_free(gs, FALSE); + reply->text = base64_encode((unsigned char *) s, len); reply->text_len = strlen(reply->text); g_free(s); @@ -396,6 +419,10 @@ xt_status sasl_pkt_result(struct xt_node *node, gpointer data) if (strcmp(node->name, "success") == 0) { imcb_log(ic, "Authentication finished"); jd->flags |= JFLAG_AUTHENTICATED | JFLAG_STREAM_RESTART; + + if (jd->flags & JFLAG_HIPCHAT) { + return hipchat_handle_success(ic, node); + } } else if (strcmp(node->name, "failure") == 0) { imcb_error(ic, "Authentication failure"); imc_logout(ic, FALSE); |