- Timestamp:
- 2016-08-30T20:40:19Z (8 years ago)
- Branches:
- master
- Children:
- 15c4cd4, a33ee0f
- Parents:
- 2dc394c
- Location:
- protocols/jabber
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/jabber/jabber.c
r2dc394c r67ea361 82 82 s->flags |= SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK; 83 83 84 set_add(&acc->set, "oauth", "false", set_eval_oauth, acc); 85 84 86 if (strcmp(acc->prpl->name, "hipchat") == 0) { 85 87 set_setstr(&acc->set, "server", "chat.hipchat.com"); 86 88 } else { 87 set_add(&acc->set, "oauth", "false", set_eval_oauth, acc);88 89 89 /* this reuses set_eval_oauth, which clears the password */ 90 90 set_add(&acc->set, "anonymous", "false", set_eval_oauth, acc); … … 397 397 if (g_strcasecmp(who, JABBER_OAUTH_HANDLE) == 0 && 398 398 !(jd->flags & OPT_LOGGED_IN) && jd->fd == -1) { 399 if (sasl_oauth2_get_refresh_token(ic, message)) { 399 400 if (jd->flags & JFLAG_HIPCHAT) { 401 sasl_oauth2_got_token(ic, message, NULL, NULL); 402 return 1; 403 } else if (sasl_oauth2_get_refresh_token(ic, message)) { 400 404 return 1; 401 405 } else { -
protocols/jabber/jabber.h
r2dc394c r67ea361 340 340 int sasl_oauth2_get_refresh_token(struct im_connection *ic, const char *msg); 341 341 int sasl_oauth2_refresh(struct im_connection *ic, const char *refresh_token); 342 void sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token, const char *error); 342 343 343 344 extern const struct oauth2_service oauth2_service_google; -
protocols/jabber/sasl.c
r2dc394c r67ea361 39 39 }; 40 40 41 /* """"""""""""""""""""""""""""""oauth"""""""""""""""""""""""""""""" */ 42 #define HIPCHAT_SO_CALLED_OAUTH_URL "https://hipchat.com/account/api" 43 41 44 xt_status sasl_pkt_mechanisms(struct xt_node *node, gpointer data) 42 45 { … … 45 48 struct xt_node *c, *reply; 46 49 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; 48 51 int want_oauth = FALSE, want_hipchat = FALSE, want_anonymous = FALSE; 49 52 GString *mechs; … … 80 83 } else if (c->text && g_strcasecmp(c->text, "X-OAUTH2") == 0) { 81 84 sup_gtalk = 1; 85 } else if (c->text && g_strcasecmp(c->text, "X-HIPCHAT-OAUTH2") == 0) { 86 sup_hipchat_oauth = 1; 82 87 } 83 88 … … 90 95 91 96 if (!want_oauth && !sup_plain && !sup_digest) { 92 if (sup_gtalk ) {97 if (sup_gtalk || sup_hipchat_oauth) { 93 98 imcb_error(ic, "This server requires OAuth " 94 99 "(supported schemes:%s)", mechs->str); … … 110 115 } 111 116 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); 126 144 reply->text_len = strlen(reply->text); 127 g_free(s); 145 g_string_free(gs, TRUE); 146 128 147 } else if (want_oauth) { 129 148 imcb_error(ic, "OAuth requested, but not supported by server"); … … 149 168 /* The rest will be done later, when we receive a <challenge/>. */ 150 169 } else if (sup_plain) { 151 int len;152 170 GString *gs; 153 171 char *username; … … 174 192 } 175 193 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); 180 195 reply->text_len = strlen(reply->text); 181 g_ free(s);196 g_string_free(gs, TRUE); 182 197 } 183 198 … … 428 443 { 429 444 struct jabber_data *jd = ic->proto_data; 430 char *msg, *url;431 445 432 446 imcb_log(ic, "Starting OAuth authentication"); … … 434 448 /* Temporary contact, just used to receive the OAuth response. */ 435 449 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 } 439 465 imcb_buddy_msg(ic, JABBER_OAUTH_HANDLE, "Respond to this message with the returned " 440 466 "authorization token.", 0, 0); 441 467 442 g_free(msg);443 g_free(url);444 468 } 445 469 … … 453 477 return FALSE; 454 478 } 455 456 static void sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token,457 const char *error);458 479 459 480 int sasl_oauth2_get_refresh_token(struct im_connection *ic, const char *msg) … … 486 507 } 487 508 488 staticvoid sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token, const char *error)509 void sasl_oauth2_got_token(gpointer data, const char *access_token, const char *refresh_token, const char *error) 489 510 { 490 511 struct im_connection *ic = data;
Note: See TracChangeset
for help on using the changeset viewer.