Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • protocols/jabber/sasl.c

    r9b02bab r67ea361  
    3939};
    4040
     41/* """"""""""""""""""""""""""""""oauth"""""""""""""""""""""""""""""" */
     42#define HIPCHAT_SO_CALLED_OAUTH_URL "https://hipchat.com/account/api"
     43
    4144xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data)
    4245{
     
    4548        struct xt_node *c, *reply;
    4649        char *s;
    47         int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_anonymous = 0;
     50        int sup_plain = 0, sup_digest = 0, sup_gtalk = 0, sup_anonymous = 0, sup_hipchat_oauth = 0;
    4851        int want_oauth = FALSE, want_hipchat = FALSE, want_anonymous = FALSE;
    4952        GString *mechs;
     
    8083                } else if (c->text && g_strcasecmp(c->text, "X-OAUTH2") == 0) {
    8184                        sup_gtalk = 1;
     85                } else if (c->text && g_strcasecmp(c->text, "X-HIPCHAT-OAUTH2") == 0) {
     86                        sup_hipchat_oauth = 1;
    8287                }
    8388
     
    9095
    9196        if (!want_oauth && !sup_plain && !sup_digest) {
    92                 if (!sup_gtalk) {
     97                if (sup_gtalk || sup_hipchat_oauth) {
    9398                        imcb_error(ic, "This server requires OAuth "
    9499                                   "(supported schemes:%s)", mechs->str);
     
    110115        }
    111116
    112         if (sup_gtalk && want_oauth) {
    113                 int len;
    114 
    115                 /* X-OAUTH2 is, not *the* standard OAuth2 SASL/XMPP implementation.
    116                    It's currently used by GTalk and vaguely documented on
    117                    http://code.google.com/apis/cloudprint/docs/rawxmpp.html . */
    118                 xt_add_attr(reply, "mechanism", "X-OAUTH2");
    119 
    120                 len = strlen(jd->username) + strlen(jd->oauth2_access_token) + 2;
    121                 s = g_malloc(len + 1);
    122                 s[0] = 0;
    123                 strcpy(s + 1, jd->username);
    124                 strcpy(s + 2 + strlen(jd->username), jd->oauth2_access_token);
    125                 reply->text = base64_encode((unsigned char *) s, len);
     117        if ((sup_gtalk || sup_hipchat_oauth) && want_oauth) {
     118                GString *gs;
     119
     120                gs = g_string_sized_new(128);
     121
     122                g_string_append_c(gs, '\0');
     123
     124                if (sup_gtalk) {
     125                        /* X-OAUTH2 is not *the* standard OAuth2 SASL/XMPP implementation.
     126                           It's currently used by GTalk and vaguely documented on
     127                           http://code.google.com/apis/cloudprint/docs/rawxmpp.html */
     128                        xt_add_attr(reply, "mechanism", "X-OAUTH2");
     129
     130                        g_string_append(gs, jd->username);
     131                        g_string_append_c(gs, '\0');
     132                        g_string_append(gs, jd->oauth2_access_token);
     133                } else if (sup_hipchat_oauth) {
     134                        /* Hipchat's variant, not standard either, is documented here:
     135                           https://docs.atlassian.com/hipchat.xmpp/latest/xmpp/auth.html */
     136                        xt_add_attr(reply, "mechanism", "oauth2");
     137
     138                        g_string_append(gs, jd->oauth2_access_token);
     139                        g_string_append_c(gs, '\0');
     140                        g_string_append(gs, set_getstr(&ic->acc->set, "resource"));
     141                }
     142
     143                reply->text = base64_encode((unsigned char *) gs->str, gs->len);
    126144                reply->text_len = strlen(reply->text);
    127                 g_free(s);
     145                g_string_free(gs, TRUE);
     146
    128147        } else if (want_oauth) {
    129148                imcb_error(ic, "OAuth requested, but not supported by server");
     
    149168                /* The rest will be done later, when we receive a <challenge/>. */
    150169        } else if (sup_plain) {
    151                 int len;
    152170                GString *gs;
    153171                char *username;
     
    174192                }
    175193
    176                 len = gs->len;
    177                 s = g_string_free(gs, FALSE);
    178 
    179                 reply->text = base64_encode((unsigned char *) s, len);
     194                reply->text = base64_encode((unsigned char *) gs->str, gs->len);
    180195                reply->text_len = strlen(reply->text);
    181                 g_free(s);
     196                g_string_free(gs, TRUE);
    182197        }
    183198
     
    428443{
    429444        struct jabber_data *jd = ic->proto_data;
    430         char *msg, *url;
    431445
    432446        imcb_log(ic, "Starting OAuth authentication");
     
    434448        /* Temporary contact, just used to receive the OAuth response. */
    435449        imcb_add_buddy(ic, JABBER_OAUTH_HANDLE, NULL);
    436         url = oauth2_url(jd->oauth2_service);
    437         msg = g_strdup_printf("Open this URL in your browser to authenticate: %s", url);
    438         imcb_buddy_msg(ic, JABBER_OAUTH_HANDLE, msg, 0, 0);
     450
     451        if (jd->flags & JFLAG_HIPCHAT) {
     452                imcb_buddy_msg(ic, JABBER_OAUTH_HANDLE,
     453                        "Open this URL and generate a token with 'View Group' and 'Send Message' scopes: "
     454                        HIPCHAT_SO_CALLED_OAUTH_URL, 0, 0);
     455        } else {
     456                char *msg, *url;
     457
     458                url = oauth2_url(jd->oauth2_service);
     459                msg = g_strdup_printf("Open this URL in your browser to authenticate: %s", url);
     460                imcb_buddy_msg(ic, JABBER_OAUTH_HANDLE, msg, 0, 0);
     461
     462                g_free(msg);
     463                g_free(url);
     464        }
    439465        imcb_buddy_msg(ic, JABBER_OAUTH_HANDLE, "Respond to this message with the returned "
    440466                       "authorization token.", 0, 0);
    441467
    442         g_free(msg);
    443         g_free(url);
    444468}
    445469
     
    453477        return FALSE;
    454478}
    455 
    456 static void sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token,
    457                                   const char *error);
    458479
    459480int sasl_oauth2_get_refresh_token(struct im_connection *ic, const char *msg)
     
    486507}
    487508
    488 static void sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token, const char *error)
     509void sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token, const char *error)
    489510{
    490511        struct im_connection *ic = data;
Note: See TracChangeset for help on using the changeset viewer.