From 7125cb3775a0e384c0f2fc08fd56df9582199502 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 24 Aug 2008 19:01:05 +0100 Subject: Added SET_INVALID, which set evaluators should now return instead of NULL when the given value is not accepted. This to allow certain variables actually be set to NULL (server, for example). This should fully close #444. --- protocols/jabber/jabber.c | 2 +- protocols/jabber/jabber_util.c | 4 ++-- protocols/nogaim.c | 12 ++++-------- 3 files changed, 7 insertions(+), 11 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index c9c1d0a0..ac8638cf 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -69,7 +69,7 @@ static void jabber_init( account_t *acc ) s = set_add( &acc->set, "resource_select", "priority", NULL, acc ); s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); - s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY; + s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK; s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc ); s->flags |= ACC_SET_OFFLINE_ONLY; diff --git a/protocols/jabber/jabber_util.c b/protocols/jabber/jabber_util.c index 1bee5009..19a73b6a 100644 --- a/protocols/jabber/jabber_util.c +++ b/protocols/jabber/jabber_util.c @@ -36,10 +36,10 @@ char *set_eval_priority( set_t *set, char *value ) { /* Priority is a signed 8-bit integer, according to RFC 3921. */ if( i < -128 || i > 127 ) - return NULL; + return SET_INVALID; } else - return NULL; + return SET_INVALID; /* Only run this stuff if the account is online ATM, and if the setting seems to be acceptable. */ diff --git a/protocols/nogaim.c b/protocols/nogaim.c index b6f8d6e4..6a267adf 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -927,14 +927,10 @@ char *set_eval_away_devoice( set_t *set, char *value ) irc_t *irc = set->data; int st; - if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) - st = 1; - else if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) - st = 0; - else if( sscanf( value, "%d", &st ) != 1 ) - return( NULL ); + if( !is_bool( value ) ) + return SET_INVALID; - st = st != 0; + st = bool2int( value ); /* Horror.... */ @@ -978,7 +974,7 @@ char *set_eval_away_devoice( set_t *set, char *value ) irc->channel, pm, v, list ); } - return( set_eval_bool( set, value ) ); + return value; } -- cgit v1.2.3 From 3611717156f4c9ebfdf829319840d49e59b827ce Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 31 Aug 2008 16:00:35 +0100 Subject: Added auto_join code. --- protocols/nogaim.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 6a267adf..20d2f3f1 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -248,6 +248,8 @@ static gboolean send_keepalive( gpointer d, gint fd, b_input_condition cond ) void imcb_connected( struct im_connection *ic ) { + irc_t *irc = ic->irc; + struct chat *c; user_t *u; /* MSN servers sometimes redirect you to a different server and do @@ -270,6 +272,15 @@ void imcb_connected( struct im_connection *ic ) /* Apparently we're connected successfully, so reset the exponential backoff timer. */ ic->acc->auto_reconnect_delay = 0; + + for( c = irc->chatrooms; c; c = c->next ) + { + if( c->acc != ic->acc ) + continue; + + if( set_getbool( &c->set, "auto_join" ) ) + chat_join( irc, c ); + } } gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond ) -- cgit v1.2.3 From 2bebe15b447b84fd5705a021f73db609c336fd73 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 28 Sep 2008 01:18:21 +0100 Subject: Fixed one crash bug in Yahoo! chatroom invitation handling. --- protocols/yahoo/yahoo.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 8d9e95d8..fa36de39 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -789,9 +789,22 @@ int ext_yahoo_connect(const char *host, int port) static void byahoo_accept_conf( void *data ) { struct byahoo_conf_invitation *inv = data; + struct groupchat *b; + + for( b = inv->ic->groupchats; b; b = b->next ) + if( b == inv->c ) + break; + + if( b != NULL ) + { + yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name ); + imcb_chat_add_buddy( inv->c, inv->ic->acc->user ); + } + else + { + imcb_log( inv->ic, "Duplicate/corrupted invitation to `%s'.", inv->name ); + } - yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name ); - imcb_chat_add_buddy( inv->c, inv->ic->acc->user ); g_free( inv->name ); g_free( inv ); } -- cgit v1.2.3 From 94acdd0d7beaa659a5f6b26673c5dea5dbcc4496 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 28 Sep 2008 12:18:19 +0100 Subject: Restored support for password-protected chatrooms (for now only by accepting a password in the IRC JOIN command). --- protocols/jabber/conference.c | 2 +- protocols/jabber/jabber.c | 2 +- protocols/jabber/jabber.h | 2 +- protocols/nogaim.c | 4 ++-- protocols/nogaim.h | 4 ++-- protocols/oscar/oscar.c | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index 79fdd053..ce2c0b86 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -25,7 +25,7 @@ static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); -struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password ) +struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password ) { struct jabber_chat *jc; struct xt_node *node; diff --git a/protocols/jabber/jabber.c b/protocols/jabber/jabber.c index ac8638cf..b8e88c26 100644 --- a/protocols/jabber/jabber.c +++ b/protocols/jabber/jabber.c @@ -424,7 +424,7 @@ static void jabber_remove_buddy( struct im_connection *ic, char *who, char *grou presence_send_request( ic, who, "unsubscribe" ); } -static struct groupchat *jabber_chat_join_( struct im_connection *ic, char *room, char *nick, char *password ) +static struct groupchat *jabber_chat_join_( struct im_connection *ic, const char *room, const char *nick, const char *password ) { if( strchr( room, '@' ) == NULL ) imcb_error( ic, "Invalid room name: %s", room ); diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index 904bf0c4..ee453144 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -239,7 +239,7 @@ xt_status sasl_pkt_result( struct xt_node *node, gpointer data ); gboolean sasl_supported( struct im_connection *ic ); /* conference.c */ -struct groupchat *jabber_chat_join( struct im_connection *ic, char *room, char *nick, char *password ); +struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password ); struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name ); void jabber_chat_free( struct groupchat *c ); int jabber_chat_msg( struct groupchat *ic, char *message, int flags ); diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 20d2f3f1..bec80c25 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -279,7 +279,7 @@ void imcb_connected( struct im_connection *ic ) continue; if( set_getbool( &c->set, "auto_join" ) ) - chat_join( irc, c ); + chat_join( irc, c, NULL ); } } @@ -709,7 +709,7 @@ void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ) } } -struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle ) +struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ) { struct groupchat *c; diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 9fe843b5..d828de4c 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -208,7 +208,7 @@ struct prpl { * your protocol does not support publicly named group chats, then do * not implement this. */ struct groupchat * - (* chat_join) (struct im_connection *, char *room, char *nick, char *password); + (* chat_join) (struct im_connection *, const char *room, const char *nick, const char *password); /* Change the topic, if supported. Note that BitlBee expects the IM server to confirm the topic change with a regular topic change event. If it doesn't do that, you have to fake it to make it @@ -289,7 +289,7 @@ G_MODULE_EXPORT void imcb_chat_invited( struct im_connection *ic, char *handle, * - After you have a groupchat pointer, you should add the handles, finally * the user her/himself. At that point the group chat will be visible to the * user, too. */ -G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, char *handle ); +G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ); G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, char *handle ); /* To remove a handle from a group chat. Reason can be NULL. */ G_MODULE_EXPORT void imcb_chat_remove_buddy( struct groupchat *b, char *handle, char *reason ); diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 36e03166..8be04259 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -2580,7 +2580,7 @@ void oscar_chat_leave(struct groupchat *c) oscar_chat_kill(c->ic, c->data); } -struct groupchat *oscar_chat_join(struct im_connection * ic, char * room, char * nick, char * password ) +struct groupchat *oscar_chat_join(struct im_connection * ic, const char * room, const char * nick, const char * password ) { struct oscar_data * od = (struct oscar_data *)ic->proto_data; aim_conn_t * cur; -- cgit v1.2.3 From b2c062d609becdffc8c8542f68e260ab7b36dbcd Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 28 Sep 2008 12:21:55 +0100 Subject: Adding the password to the right part of the stanza so joining password-protected rooms *really* works. --- protocols/jabber/conference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index ce2c0b86..480006bd 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -35,9 +35,9 @@ struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, roomjid = g_strdup_printf( "%s/%s", room, nick ); node = xt_new_node( "x", NULL, NULL ); xt_add_attr( node, "xmlns", XMLNS_MUC ); - node = jabber_make_packet( "presence", NULL, roomjid, node ); if( password ) xt_add_child( node, xt_new_node( "password", password, NULL ) ); + node = jabber_make_packet( "presence", NULL, roomjid, node ); jabber_cache_add( ic, node, jabber_chat_join_failed ); if( !jabber_write_packet( ic, node ) ) -- cgit v1.2.3 From c0c43fba49da3d14097f2c7cf3569a829b84125a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 Dec 2008 10:31:49 +0000 Subject: Fixed ic->away leaking memory. This var is only used by OSCAR and should maybe be killed. Also fixed some completely broken indentation in those functions. --- protocols/nogaim.c | 3 +++ protocols/nogaim.h | 2 +- protocols/oscar/oscar.c | 37 +++++++++++++++++-------------------- protocols/yahoo/yahoo.c | 13 +++++++------ 4 files changed, 28 insertions(+), 27 deletions(-) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index bec80c25..fd445324 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -320,6 +320,9 @@ void imc_logout( struct im_connection *ic, int allow_reconnect ) ic->acc->prpl->logout( ic ); b_event_remove( ic->inpa ); + g_free( ic->away ); + ic->away = NULL; + u = irc->users; while( u ) { diff --git a/protocols/nogaim.h b/protocols/nogaim.h index d828de4c..ddfff07e 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -238,7 +238,7 @@ G_MODULE_EXPORT void register_protocol( struct prpl * ); /* You will need this function in prpl->login() to get an im_connection from * the account_t parameter. */ G_MODULE_EXPORT struct im_connection *imcb_new( account_t *acc ); -G_MODULE_EXPORT void imcb_free( struct im_connection *ic ); +G_MODULE_EXPORT void imc_free( struct im_connection *ic ); /* Once you're connected, you should call this function, so that the user will * see the success. */ G_MODULE_EXPORT void imcb_connected( struct im_connection *ic ); diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 8be04259..4142c046 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -1938,8 +1938,7 @@ static void oscar_set_away_aim(struct im_connection *ic, struct oscar_data *od, aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL); - if (ic->away) - g_free(ic->away); + g_free(ic->away); ic->away = NULL; if (!message) { @@ -1959,55 +1958,53 @@ static void oscar_set_away_aim(struct im_connection *ic, struct oscar_data *od, static void oscar_set_away_icq(struct im_connection *ic, struct oscar_data *od, const char *state, const char *message) { - const char *msg = NULL; + const char *msg = NULL; gboolean no_message = FALSE; /* clean old states */ - if (ic->away) { - g_free(ic->away); - ic->away = NULL; - } + g_free(ic->away); + ic->away = NULL; od->sess->aim_icq_state = 0; /* if no message, then use an empty message */ - if (message) { - msg = message; - } else { - msg = ""; + if (message) { + msg = message; + } else { + msg = ""; no_message = TRUE; - } + } if (!g_strcasecmp(state, "Online")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL); } else if (!g_strcasecmp(state, "Away")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY); - ic->away = g_strdup(msg); + ic->away = g_strdup(msg); od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY; } else if (!g_strcasecmp(state, "Do Not Disturb")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY); - ic->away = g_strdup(msg); + ic->away = g_strdup(msg); od->sess->aim_icq_state = AIM_MTYPE_AUTODND; } else if (!g_strcasecmp(state, "Not Available")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY); - ic->away = g_strdup(msg); + ic->away = g_strdup(msg); od->sess->aim_icq_state = AIM_MTYPE_AUTONA; } else if (!g_strcasecmp(state, "Occupied")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY); - ic->away = g_strdup(msg); + ic->away = g_strdup(msg); od->sess->aim_icq_state = AIM_MTYPE_AUTOBUSY; } else if (!g_strcasecmp(state, "Free For Chat")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_CHAT); - ic->away = g_strdup(msg); + ic->away = g_strdup(msg); od->sess->aim_icq_state = AIM_MTYPE_AUTOFFC; } else if (!g_strcasecmp(state, "Invisible")) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_INVISIBLE); - ic->away = g_strdup(msg); + ic->away = g_strdup(msg); } else if (!g_strcasecmp(state, GAIM_AWAY_CUSTOM)) { if (no_message) { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL); } else { aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY); - ic->away = g_strdup(msg); + ic->away = g_strdup(msg); od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY; } } @@ -2019,7 +2016,7 @@ static void oscar_set_away(struct im_connection *ic, char *state, char *message) { struct oscar_data *od = (struct oscar_data *)ic->proto_data; - oscar_set_away_aim(ic, od, state, message); + oscar_set_away_aim(ic, od, state, message); if (od->icq) oscar_set_away_icq(ic, od, state, message); diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index fa36de39..3e844c55 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -196,13 +196,14 @@ static int byahoo_send_typing( struct im_connection *ic, char *who, int typing ) static void byahoo_set_away( struct im_connection *ic, char *state, char *msg ) { struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data; + char *away; - ic->away = NULL; + away = NULL; if( state && msg && g_strcasecmp( state, msg ) != 0 ) { yd->current_status = YAHOO_STATUS_CUSTOM; - ic->away = ""; + away = ""; } else if( state ) { @@ -211,11 +212,11 @@ static void byahoo_set_away( struct im_connection *ic, char *state, char *msg ) away state. */ msg = NULL; - ic->away = ""; + away = ""; if( g_strcasecmp( state, "Available" ) == 0 ) { yd->current_status = YAHOO_STATUS_AVAILABLE; - ic->away = NULL; + away = NULL; } else if( g_strcasecmp( state, "Be Right Back" ) == 0 ) yd->current_status = YAHOO_STATUS_BRB; @@ -241,13 +242,13 @@ static void byahoo_set_away( struct im_connection *ic, char *state, char *msg ) { yd->current_status = YAHOO_STATUS_AVAILABLE; - ic->away = NULL; + away = NULL; } } else yd->current_status = YAHOO_STATUS_AVAILABLE; - yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL ? 2 : 0 ); + yahoo_set_away( yd->y2_id, yd->current_status, msg, away != NULL ? 2 : 0 ); } static GList *byahoo_away_states( struct im_connection *ic ) -- cgit v1.2.3 From 71d45c298e0757b5f92f0302b987e368ee75891a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 Dec 2008 13:39:02 +0000 Subject: Dropping warnings about unknown JIDs since they're spammy (mostly show up when the user logs in from mulitple locations) and the irc->debug setting shouldn't be read from inside the IM modules. --- protocols/jabber/presence.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/presence.c b/protocols/jabber/presence.c index 6fc360b7..939bc888 100644 --- a/protocols/jabber/presence.c +++ b/protocols/jabber/presence.c @@ -48,8 +48,9 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data ) { if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) ) { - if( set_getbool( &ic->irc->set, "debug" ) ) - imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from ); + /* + imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from ); + */ return XT_HANDLED; } @@ -105,8 +106,9 @@ xt_status jabber_pkt_presence( struct xt_node *node, gpointer data ) { if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL ) { - if( set_getbool( &ic->irc->set, "debug" ) ) - imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from ); + /* + imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from ); + */ return XT_HANDLED; } -- cgit v1.2.3 From 54699524eda49bb287d5998e443deefd81fce8fc Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 14 Dec 2008 15:04:48 +0000 Subject: Detect disconnects caused by concurrent logins or rate limiting, and disable auto-reconnect in those cases to prevent loops. --- protocols/oscar/oscar.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/oscar/oscar.c b/protocols/oscar/oscar.c index 4142c046..1118c26d 100644 --- a/protocols/oscar/oscar.c +++ b/protocols/oscar/oscar.c @@ -90,7 +90,7 @@ struct oscar_data { GSList *oscar_chats; - gboolean killme; + gboolean killme, no_reconnect; gboolean icq; GSList *evilhack; @@ -180,6 +180,7 @@ static struct chat_connection *find_oscar_chat_by_conn(struct im_connection *ic, static int gaim_parse_auth_resp (aim_session_t *, aim_frame_t *, ...); static int gaim_parse_login (aim_session_t *, aim_frame_t *, ...); +static int gaim_parse_logout (aim_session_t *, aim_frame_t *, ...); static int gaim_handle_redirect (aim_session_t *, aim_frame_t *, ...); static int gaim_parse_oncoming (aim_session_t *, aim_frame_t *, ...); static int gaim_parse_offgoing (aim_session_t *, aim_frame_t *, ...); @@ -293,7 +294,7 @@ static gboolean oscar_callback(gpointer data, gint source, if (aim_get_command(odata->sess, conn) >= 0) { aim_rxdispatch(odata->sess); if (odata->killme) - imc_logout(ic, TRUE); + imc_logout(ic, !odata->no_reconnect); } else { if ((conn->type == AIM_CONN_TYPE_BOS) || !(aim_getconn_type(odata->sess, AIM_CONN_TYPE_BOS))) { @@ -519,6 +520,7 @@ static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { break; case 0x18: /* connecting too frequently */ + od->no_reconnect = TRUE; imcb_error(ic, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); break; case 0x1c: @@ -571,6 +573,7 @@ static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_SRVACK, gaim_ssi_parseack, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parseaiminfo, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parsemtn, 0); + aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_parse_logout, 0); ((struct oscar_data *)ic->proto_data)->conn = bosconn; for (i = 0; i < (int)strlen(info->bosip); i++) { @@ -750,6 +753,30 @@ static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) { return 1; } +static int gaim_parse_logout(aim_session_t *sess, aim_frame_t *fr, ...) { + struct im_connection *ic = sess->aux_data; + struct oscar_data *odata = ic->proto_data; + int code; + va_list ap; + + va_start(ap, fr); + code = va_arg(ap, int); + va_end(ap); + + imcb_error( ic, "Connection aborted by server: %s", code == 1 ? + "someone else logged in with your account" : + "unknown reason" ); + + /* Tell BitlBee to disable auto_reconnect if code == 1, since that + means a concurrent login somewhere else. */ + odata->no_reconnect = code == 1; + + /* DO NOT log out here! Just tell the callback to do it. */ + odata->killme = TRUE; + + return 1; +} + static int conninitdone_chat(aim_session_t *sess, aim_frame_t *fr, ...) { struct im_connection *ic = sess->aux_data; struct chat_connection *chatcon; -- cgit v1.2.3 From 19176513584bf26fa69a8a946982d9c521038a17 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Wed, 3 Jun 2009 17:10:36 +0100 Subject: Fixed a bug that caused crashes when joining certain kinds of Google Talk chatrooms. Doesn't seem to be Google Talk specific, other than that this is the first time I see empty elements that cause this crash. A more proper/efficient fix may be to just move the break outside the inner if. --- protocols/jabber/conference.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index 480006bd..08bef4f5 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -233,8 +233,10 @@ void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bu if( ( s = xt_find_attr( c, "xmlns" ) ) && ( strcmp( s, XMLNS_MUC_USER ) == 0 ) ) { - c = xt_find_node( c->children, "item" ); - if( ( s = xt_find_attr( c, "jid" ) ) ) + struct xt_node *item; + + item = xt_find_node( c->children, "item" ); + if( ( s = xt_find_attr( item, "jid" ) ) ) { /* Yay, found what we need. :-) */ bud->ext_jid = jabber_normalize( s ); -- cgit v1.2.3 From b9369b55c99246a8feaee0ad24367044d92fa55d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 18 Jun 2009 00:17:15 +0100 Subject: Fixed compatibility with AIM mobile messages. Should work according to reports in bug #88 (where this patch comes from) and #bitlbee. Not sure about side effects, one way to find out... --- protocols/oscar/aim.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'protocols') diff --git a/protocols/oscar/aim.h b/protocols/oscar/aim.h index 9516996c..d1fc602a 100644 --- a/protocols/oscar/aim.h +++ b/protocols/oscar/aim.h @@ -143,6 +143,17 @@ struct client_info_s { "en", \ } +#define AIM_CLIENTINFO_KNOWNGOOD_5_1_3036 { \ + "AOL Instant Messenger, version 5.1.3036/WIN32", \ + 0x0109, \ + 0x0005, \ + 0x0001, \ + 0x0000, \ + 0x0bdc, \ + "us", \ + "en", \ +} + /* * I would make 4.1.2010 the default, but they seem to have found * an alternate way of breaking that one. @@ -151,7 +162,7 @@ struct client_info_s { * memory test, which may require you to have a WinAIM binary laying * around. (see login.c::memrequest()) */ -#define AIM_CLIENTINFO_KNOWNGOOD AIM_CLIENTINFO_KNOWNGOOD_3_5_1670 +#define AIM_CLIENTINFO_KNOWNGOOD AIM_CLIENTINFO_KNOWNGOOD_5_1_3036 #ifndef TRUE #define TRUE 1 -- cgit v1.2.3 From 4fefb772f530cd15ef3e92606532d3c6b193d96b Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 3 Oct 2009 20:27:50 +0100 Subject: Yahoo! can log in again. This code still needs major cleanups, use it only if you're very desparate. --- protocols/yahoo/libyahoo2.c | 310 ++++++++++++++++++++++++++++++++++++++++- protocols/yahoo/yahoo2_types.h | 5 +- 2 files changed, 306 insertions(+), 9 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index a61955c4..52655240 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -88,6 +88,12 @@ char *strchr (), *strrchr (); #endif #include "base64.h" +#include "http_client.h" + +static void yahoo_process_auth_response(struct http_request *req); + +/* What's this used for actually? */ +static void _yahoo_http_connected(int id, int fd, int error, void *data); #ifdef USE_STRUCT_CALLBACKS struct yahoo_callbacks *yc=NULL; @@ -168,6 +174,7 @@ enum yahoo_service { /* these are easier to see in hex */ YAHOO_SERVICE_PING, YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */ YAHOO_SERVICE_SYSMESSAGE = 0x14, + YAHOO_SERVICE_SKINNAME = 0x15, YAHOO_SERVICE_PASSTHROUGH2 = 0x16, YAHOO_SERVICE_CONFINVITE = 0x18, YAHOO_SERVICE_CONFLOGON, @@ -191,24 +198,49 @@ enum yahoo_service { /* these are easier to see in hex */ YAHOO_SERVICE_AUTHRESP = 0x54, YAHOO_SERVICE_LIST, YAHOO_SERVICE_AUTH = 0x57, + YAHOO_SERVICE_AUTHBUDDY = 0x6d, YAHOO_SERVICE_ADDBUDDY = 0x83, YAHOO_SERVICE_REMBUDDY, YAHOO_SERVICE_IGNORECONTACT, /* > 1, 7, 13 < 1, 66, 13, 0*/ YAHOO_SERVICE_REJECTCONTACT, YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */ + YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */ YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/ YAHOO_SERVICE_CHATGOTO, YAHOO_SERVICE_CHATJOIN, /* > 1 104-room 129-1600326591 62-2 */ YAHOO_SERVICE_CHATLEAVE, YAHOO_SERVICE_CHATEXIT = 0x9b, + YAHOO_SERVICE_CHATADDINVITE = 0x9d, YAHOO_SERVICE_CHATLOGOUT = 0xa0, YAHOO_SERVICE_CHATPING, YAHOO_SERVICE_COMMENT = 0xa8, - YAHOO_SERVICE_STEALTH = 0xb9, + YAHOO_SERVICE_GAME_INVITE = 0xb7, + YAHOO_SERVICE_STEALTH_PERM = 0xb9, + YAHOO_SERVICE_STEALTH_SESSION = 0xba, + YAHOO_SERVICE_AVATAR = 0xbc, YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, YAHOO_SERVICE_PICTURE = 0xbe, YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, - YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2 + YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, + YAHOO_SERVICE_YAB_UPDATE = 0xc4, + YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5, /* YMSG13, key 13: 2 = invisible, 1 = visible */ + YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6, /* YMSG13 */ + YAHOO_SERVICE_PICTURE_STATUS = 0xc7, /* YMSG13, key 213: 0 = none, 1 = avatar, 2 = picture */ + YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8, + YAHOO_SERVICE_AUDIBLE = 0xd0, + YAHOO_SERVICE_Y7_PHOTO_SHARING = 0xd2, + YAHOO_SERVICE_Y7_CONTACT_DETAILS = 0xd3,/* YMSG13 */ + YAHOO_SERVICE_Y7_CHAT_SESSION = 0xd4, + YAHOO_SERVICE_Y7_AUTHORIZATION = 0xd6, /* YMSG13 */ + YAHOO_SERVICE_Y7_FILETRANSFER = 0xdc, /* YMSG13 */ + YAHOO_SERVICE_Y7_FILETRANSFERINFO, /* YMSG13 */ + YAHOO_SERVICE_Y7_FILETRANSFERACCEPT, /* YMSG13 */ + YAHOO_SERVICE_Y7_MINGLE = 0xe1, /* YMSG13 */ + YAHOO_SERVICE_Y7_CHANGE_GROUP = 0xe7, /* YMSG13 */ + YAHOO_SERVICE_Y8_STATUS = 0xf0, /* YMSG15 */ + YAHOO_SERVICE_Y8_LIST = 0Xf1, /* YMSG15 */ + YAHOO_SERVICE_WEBLOGIN = 0x0226, + YAHOO_SERVICE_SMS_MSG = 0x02ea }; struct yahoo_pair { @@ -732,7 +764,7 @@ static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet data = y_new0(unsigned char, len + 1); memcpy(data + pos, "YMSG", 4); pos += 4; - pos += yahoo_put16(data + pos, 0x000c); + pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); pos += yahoo_put16(data + pos, 0x0000); pos += yahoo_put16(data + pos, pktlen + extra_pad); pos += yahoo_put16(data + pos, pkt->service); @@ -1479,6 +1511,62 @@ static void yahoo_process_status(struct yahoo_input_data *yid, struct yahoo_pack } } +static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +{ + struct yahoo_data *yd = yid->yd; + YList *l; + int last_packet = 0; + char *cur_group = NULL; + struct yahoo_buddy *newbud = NULL; + + /* we could be getting multiple packets here */ + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + + switch(pair->key) { + case 300: + case 301: + case 302: + case 303: + if ( 315 == atoi(pair->value) ) + last_packet = 1; + break; + case 65: + cur_group = strdup(pair->value); + break; + case 7: + newbud = y_new0(struct yahoo_buddy, 1); + newbud->id = strdup(pair->value); + if(cur_group) + newbud->group = strdup(cur_group); + else { + struct yahoo_buddy *lastbud = (struct yahoo_buddy *)y_list_nth( + yd->buddies, y_list_length(yd->buddies)-1)->data; + newbud->group = strdup(lastbud->group); + } + + yd->buddies = y_list_append(yd->buddies, newbud); + + break; + } + } + + /* we could be getting multiple packets here */ + if (last_packet) + return; + + YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); + + + /*** We login at the very end of the packet communication */ + if (!yd->logged_in) { + yd->logged_in = TRUE; + if(yd->current_status < 0) + yd->current_status = yd->initial_status; + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL); + } +} + static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; @@ -1548,7 +1636,8 @@ static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet yd->cookie_c = getcookie(pair->value); } - if(yd->cookie_y && yd->cookie_t && yd->cookie_c) + // if(yd->cookie_y && yd->cookie_t && yd->cookie_c) + if(yd->cookie_y && yd->cookie_t) YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id); break; @@ -2225,6 +2314,22 @@ static void yahoo_process_auth_0x0b(struct yahoo_input_data *yid, const char *se free(crypt_hash); } +static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) +{ + char *url; + + yid->yd->login_cookie = strdup(seed); + + url = g_strdup_printf( + "https://login.yahoo.com/config/pwtoken_get?" + "src=ymsgr&ts=&login=%s&passwd=%s&chal=%s", + yid->yd->user, yid->yd->password, seed); + + http_dorequest_url(url, yahoo_process_auth_response, yid); + + g_free(url); +} + static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { char *seed = NULL; @@ -2253,6 +2358,10 @@ static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet case 1: yahoo_process_auth_0x0b(yid, seed, sn); break; + case 2: + /* HTTPS */ + yahoo_process_auth_0x10(yid, seed, sn); + break; default: /* call error */ WARNING(("unknown auth type %d", m)); @@ -2660,6 +2769,8 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_GAMELOGOFF: case YAHOO_SERVICE_IDACT: case YAHOO_SERVICE_IDDEACT: + case YAHOO_SERVICE_Y6_STATUS_UPDATE: + case YAHOO_SERVICE_Y8_STATUS: yahoo_process_status(yid, pkt); break; case YAHOO_SERVICE_NOTIFY: @@ -2755,6 +2866,8 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_PICTURE_UPLOAD: yahoo_process_picture_upload(yid, pkt); break; + case YAHOO_SERVICE_Y8_LIST: /* Buddy List */ + yahoo_process_buddy_list(yid, pkt); default: WARNING(("unknown service 0x%02x", pkt->service)); yahoo_dump_unhandled(pkt); @@ -3531,6 +3644,189 @@ static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int ov && yahoo_get_webcam_data(yid) == 1); } +//#define LOG(x...) printf x + +static void yahoo_process_auth_response(struct http_request *req) +{ + char *line_end; + char *token; + char *cookie; + + int error_code = 0; + int is_ymsgr = 0; + + struct yahoo_data *yd = NULL; + struct yahoo_input_data *yid = req->data; + + unsigned char crypt_hash[25]; + + md5_byte_t result[16]; + md5_state_t ctx; + + struct yahoo_packet *packet =NULL; + + token = req->reply_body; + line_end = strstr(token, "\r\n"); + + if (line_end) { + *line_end = '\0'; + + line_end+=2; + } + + error_code = atoi((char *)token); + + switch(error_code) { + case 0: + /* successful */ + LOG(("successful\n")); + break; + case 1212: + /* Incorrect ID or password */ + LOG(("Incorrect ID or password\n")); + + return; + case 1213: + /* Security lock from too many failed login attempts */ + LOG(("Security lock from too many failed login attempts\n")); + + return; + + case 1214: + /* Security lock */ + LOG(("Security lock\n")); + + return; + + case 1235: + /* User ID not taken yet */ + LOG(("User ID not taken yet\n")); + + return; + + case 1216: + /* Seems to be a lock, but shows the same generic User ID/Password failure */ + LOG(("Seems to be a lock, but shows the same generic User ID/Password failure\n")); + + return; + case 100: + /* Username and password cannot be blank */ + LOG(("Username and password cannot be blank\n")); + + return; + default: + /* Unknown error code */ + LOG(("Unknown Error\n")); + + return; + } + + if ( !strncmp(line_end, "ymsgr=", 6) ) { + is_ymsgr = 1; + } + else if ( strncmp(line_end, "crumb=", 6) ) { + LOG(("Oops! There was no ymsgr=. Where do I get my token from now :(")); + LOG(("I got this:\n\n%s\n",line_end)); + return; + /* Error */ + } + + token = line_end+6; + + line_end = strstr(token, "\r\n"); + + if(line_end) { + *line_end = '\0'; + line_end+=2; + } + + /* Go for the crumb */ + if(is_ymsgr) { + char *url; + + url = g_strdup_printf( + "https://login.yahoo.com/config/pwtoken_login?" + "src=ymsgr&ts=&token=%s", token); + + http_dorequest_url(url, yahoo_process_auth_response, yid); + g_free(url); + + return; + } + + /* token is actually crumb */ + + if(!line_end) { + /* We did not get our cookies. Cry. */ + } + + cookie = strstr(req->reply_headers, "Set-Cookie: Y="); + + if(!cookie) { + /* Cry. */ + LOG(("NO Y Cookie!")); + return; + } + + cookie+=14; + + line_end = strstr(cookie, "\r\n"); + *line_end = '\0'; + + LOG(("Cookie length: %d", strlen(cookie))); + + yid->yd->cookie_y = strdup(cookie); + *line_end = ';'; + + cookie = strstr(req->reply_headers, "Set-Cookie: T="); + if(!cookie) { + LOG(("NO T Cookie!")); + /* Cry. */ + return; + } + + cookie+=14; + + line_end = strstr(cookie, "\r\n"); + *line_end = '\0'; + + yid->yd->cookie_t = strdup(cookie); + + LOG(("My Cookies ::\n Y: %s\nT: %s\n\n", yid->yd->cookie_y, yid->yd->cookie_t)); + + md5_init(&ctx); + md5_append(&ctx, (md5_byte_t *)token, strlen(token)); + md5_append(&ctx, (md5_byte_t *)yid->yd->login_cookie, strlen(yid->yd->login_cookie)); + md5_finish(&ctx, result); + + to_y64(crypt_hash, result, 16); + + yd = yid->yd; + + //yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); + + packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); + yahoo_packet_hash(packet, 1, yd->user); + yahoo_packet_hash(packet, 0, yd->user); + yahoo_packet_hash(packet, 277, yd->cookie_y); + yahoo_packet_hash(packet, 278, yd->cookie_t); + yahoo_packet_hash(packet, 307, crypt_hash); + yahoo_packet_hash(packet, 244, "2097087"); /* Rekkanoryo says this is the build number */ + yahoo_packet_hash(packet, 2, yd->user); + yahoo_packet_hash(packet, 2, "1"); + yahoo_packet_hash(packet, 98, "us"); /* TODO Put country code */ + yahoo_packet_hash(packet, 135, "9.0.0.1389"); + + yahoo_send_packet(yid, packet, 0); + + yahoo_packet_free(packet); + + /* We don't need this anymore */ + free(yd->login_cookie); + yd->login_cookie = NULL; +} + + static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = { yahoo_process_pager_connection, yahoo_process_ft_connection, @@ -3538,7 +3834,7 @@ static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = yahoo_process_webcam_master_connection, yahoo_process_webcam_connection, yahoo_process_chatcat_connection, - yahoo_process_search_connection + yahoo_process_search_connection, }; int yahoo_read_ready(int id, int fd, void *data) @@ -3556,7 +3852,7 @@ int yahoo_read_ready(int id, int fd, void *data) len = read(fd, buf, sizeof(buf)); } while(len == -1 && errno == EINTR); - if(len == -1 && errno == EAGAIN) /* we'll try again later */ + if(len == -1 && (errno == EAGAIN||errno == EINTR)) /* we'll try again later */ return 1; if (len <= 0) { @@ -4145,7 +4441,7 @@ void yahoo_stealth_buddy(int id, const char *who, int unstealth) if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, YAHOO_STATUS_AVAILABLE, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 7, who); yahoo_packet_hash(pkt, 31, unstealth?"2":"1"); diff --git a/protocols/yahoo/yahoo2_types.h b/protocols/yahoo/yahoo2_types.h index df1756eb..7453e487 100644 --- a/protocols/yahoo/yahoo2_types.h +++ b/protocols/yahoo/yahoo2_types.h @@ -84,7 +84,7 @@ enum yahoo_log_level { YAHOO_LOG_DEBUG }; -#define YAHOO_PROTO_VER 0x000b +#define YAHOO_PROTO_VER 0x0010 /* Yahoo style/color directives */ #define YAHOO_COLOR_BLACK "\033[30m" @@ -114,7 +114,8 @@ enum yahoo_connection_type { YAHOO_CONNECTION_WEBCAM_MASTER, YAHOO_CONNECTION_WEBCAM, YAHOO_CONNECTION_CHATCAT, - YAHOO_CONNECTION_SEARCH + YAHOO_CONNECTION_SEARCH, + YAHOO_CONNECTION_AUTH, }; enum yahoo_webcam_direction_type { -- cgit v1.2.3 From c3e349e0847b5b936d1040c56ea427a7f2ce0d7c Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 3 Oct 2009 23:25:36 +0100 Subject: Cleaned up Yahoo! fix: Error handling, and also not crashing when the connection disappears again before authentication finishes. --- protocols/yahoo/libyahoo2.c | 143 ++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 77 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index 52655240..deaa46df 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -92,9 +92,6 @@ char *strchr (), *strrchr (); static void yahoo_process_auth_response(struct http_request *req); -/* What's this used for actually? */ -static void _yahoo_http_connected(int id, int fd, int error, void *data); - #ifdef USE_STRUCT_CALLBACKS struct yahoo_callbacks *yc=NULL; @@ -1532,6 +1529,7 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_ last_packet = 1; break; case 65: + g_free(cur_group); cur_group = strdup(pair->value); break; case 7: @@ -1550,6 +1548,8 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_ break; } } + + g_free(cur_group); /* we could be getting multiple packets here */ if (last_packet) @@ -1557,7 +1557,6 @@ static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_ YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); - /*** We login at the very end of the packet communication */ if (!yd->logged_in) { yd->logged_in = TRUE; @@ -1636,7 +1635,6 @@ static void yahoo_process_list(struct yahoo_input_data *yid, struct yahoo_packet yd->cookie_c = getcookie(pair->value); } - // if(yd->cookie_y && yd->cookie_t && yd->cookie_c) if(yd->cookie_y && yd->cookie_t) YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id); @@ -3644,7 +3642,7 @@ static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int ov && yahoo_get_webcam_data(yid) == 1); } -//#define LOG(x...) printf x +/* #define LOG(x...) printf x */ static void yahoo_process_auth_response(struct http_request *req) { @@ -3655,15 +3653,22 @@ static void yahoo_process_auth_response(struct http_request *req) int error_code = 0; int is_ymsgr = 0; - struct yahoo_data *yd = NULL; struct yahoo_input_data *yid = req->data; - unsigned char crypt_hash[25]; + char crypt_hash[25]; md5_byte_t result[16]; md5_state_t ctx; - struct yahoo_packet *packet =NULL; + struct yahoo_packet *packet = NULL; + + if (y_list_find(inputs, yid) == NULL) + return; + + if (req->status_code != 200) { + error_code = 3000 + req->status_code; + goto FAIL; + } token = req->reply_body; line_end = strstr(token, "\r\n"); @@ -3671,54 +3676,46 @@ static void yahoo_process_auth_response(struct http_request *req) if (line_end) { *line_end = '\0'; - line_end+=2; + line_end += 2; + } + + if (sscanf(token, "%d", &error_code) != 1) { + error_code = 3000; + goto FAIL; } - - error_code = atoi((char *)token); switch(error_code) { case 0: /* successful */ - LOG(("successful\n")); break; + case 1212: - /* Incorrect ID or password */ LOG(("Incorrect ID or password\n")); + error_code = YAHOO_LOGIN_PASSWD; + goto FAIL; - return; case 1213: - /* Security lock from too many failed login attempts */ LOG(("Security lock from too many failed login attempts\n")); - - return; + error_code = YAHOO_LOGIN_LOCK; + goto FAIL; case 1214: - /* Security lock */ LOG(("Security lock\n")); - - return; + goto FAIL; case 1235: - /* User ID not taken yet */ LOG(("User ID not taken yet\n")); - - return; + error_code = YAHOO_LOGIN_UNAME; + goto FAIL; case 1216: - /* Seems to be a lock, but shows the same generic User ID/Password failure */ LOG(("Seems to be a lock, but shows the same generic User ID/Password failure\n")); + goto FAIL; - return; - case 100: - /* Username and password cannot be blank */ - LOG(("Username and password cannot be blank\n")); - - return; default: /* Unknown error code */ LOG(("Unknown Error\n")); - - return; + goto FAIL; } if ( !strncmp(line_end, "ymsgr=", 6) ) { @@ -3727,8 +3724,8 @@ static void yahoo_process_auth_response(struct http_request *req) else if ( strncmp(line_end, "crumb=", 6) ) { LOG(("Oops! There was no ymsgr=. Where do I get my token from now :(")); LOG(("I got this:\n\n%s\n",line_end)); - return; - /* Error */ + error_code = 2201; + goto FAIL; } token = line_end+6; @@ -3737,7 +3734,7 @@ static void yahoo_process_auth_response(struct http_request *req) if(line_end) { *line_end = '\0'; - line_end+=2; + line_end += 2; } /* Go for the crumb */ @@ -3747,8 +3744,9 @@ static void yahoo_process_auth_response(struct http_request *req) url = g_strdup_printf( "https://login.yahoo.com/config/pwtoken_login?" "src=ymsgr&ts=&token=%s", token); - + http_dorequest_url(url, yahoo_process_auth_response, yid); + g_free(url); return; @@ -3760,59 +3758,45 @@ static void yahoo_process_auth_response(struct http_request *req) /* We did not get our cookies. Cry. */ } - cookie = strstr(req->reply_headers, "Set-Cookie: Y="); - - if(!cookie) { + if((cookie = strstr(req->reply_headers, "Set-Cookie: Y=")) && + (line_end = strstr(cookie + 14, "\r\n"))) { + *line_end = '\0'; + yid->yd->cookie_y = strdup(cookie + 14); + *line_end = ';'; + } else { /* Cry. */ LOG(("NO Y Cookie!")); - return; + error_code = 2202; + goto FAIL; } - cookie+=14; - - line_end = strstr(cookie, "\r\n"); - *line_end = '\0'; - - LOG(("Cookie length: %d", strlen(cookie))); - - yid->yd->cookie_y = strdup(cookie); - *line_end = ';'; - - cookie = strstr(req->reply_headers, "Set-Cookie: T="); - if(!cookie) { - LOG(("NO T Cookie!")); + if((cookie = strstr(req->reply_headers, "Set-Cookie: T=")) && + (line_end = strstr(cookie + 14, "\r\n"))) { + *line_end = '\0'; + yid->yd->cookie_t = strdup(cookie + 14); + *line_end = ';'; + } else { /* Cry. */ - return; + LOG(("NO T Cookie!")); + error_code = 2203; + goto FAIL; } - cookie+=14; - - line_end = strstr(cookie, "\r\n"); - *line_end = '\0'; - - yid->yd->cookie_t = strdup(cookie); - - LOG(("My Cookies ::\n Y: %s\nT: %s\n\n", yid->yd->cookie_y, yid->yd->cookie_t)); - md5_init(&ctx); md5_append(&ctx, (md5_byte_t *)token, strlen(token)); md5_append(&ctx, (md5_byte_t *)yid->yd->login_cookie, strlen(yid->yd->login_cookie)); md5_finish(&ctx, result); - to_y64(crypt_hash, result, 16); - - yd = yid->yd; + to_y64((unsigned char*)crypt_hash, result, 16); - //yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); - - packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); - yahoo_packet_hash(packet, 1, yd->user); - yahoo_packet_hash(packet, 0, yd->user); - yahoo_packet_hash(packet, 277, yd->cookie_y); - yahoo_packet_hash(packet, 278, yd->cookie_t); + packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yid->yd->initial_status, yid->yd->session_id); + yahoo_packet_hash(packet, 1, yid->yd->user); + yahoo_packet_hash(packet, 0, yid->yd->user); + yahoo_packet_hash(packet, 277, yid->yd->cookie_y); + yahoo_packet_hash(packet, 278, yid->yd->cookie_t); yahoo_packet_hash(packet, 307, crypt_hash); yahoo_packet_hash(packet, 244, "2097087"); /* Rekkanoryo says this is the build number */ - yahoo_packet_hash(packet, 2, yd->user); + yahoo_packet_hash(packet, 2, yid->yd->user); yahoo_packet_hash(packet, 2, "1"); yahoo_packet_hash(packet, 98, "us"); /* TODO Put country code */ yahoo_packet_hash(packet, 135, "9.0.0.1389"); @@ -3822,8 +3806,13 @@ static void yahoo_process_auth_response(struct http_request *req) yahoo_packet_free(packet); /* We don't need this anymore */ - free(yd->login_cookie); - yd->login_cookie = NULL; + free(yid->yd->login_cookie); + yid->yd->login_cookie = NULL; + + return; + +FAIL: + YAHOO_CALLBACK(ext_yahoo_login_response)(yid->yd->client_id, error_code, NULL); } -- cgit v1.2.3 From bdad4079b4bbc8209bf17c81cafbf699f8c6d90d Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sun, 4 Oct 2009 19:28:41 +0100 Subject: Fixing a crash bug that causes crashes only with buggy Jabber conference servers, sending a "you left this chat" without first acknowledging you entering it. --- protocols/jabber/conference.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/conference.c b/protocols/jabber/conference.c index 08bef4f5..f434c58a 100644 --- a/protocols/jabber/conference.c +++ b/protocols/jabber/conference.c @@ -284,12 +284,15 @@ void jabber_chat_pkt_presence( struct im_connection *ic, struct jabber_buddy *bu } else if( type ) /* type can only be NULL or "unavailable" in this function */ { - s = strchr( bud->ext_jid, '/' ); - if( s ) *s = 0; - imcb_chat_remove_buddy( chat, bud->ext_jid, NULL ); - if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS ) - imcb_remove_buddy( ic, bud->ext_jid, NULL ); - if( s ) *s = '/'; + if( ( bud->flags & JBFLAG_IS_CHATROOM ) && bud->ext_jid ) + { + s = strchr( bud->ext_jid, '/' ); + if( s ) *s = 0; + imcb_chat_remove_buddy( chat, bud->ext_jid, NULL ); + if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS ) + imcb_remove_buddy( ic, bud->ext_jid, NULL ); + if( s ) *s = '/'; + } if( bud == jc->me ) jabber_chat_free( chat ); -- cgit v1.2.3 From fa295e3620bdf928b6a853ec7e42b8c7fc5262be Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Oct 2009 14:39:51 +0100 Subject: Added imcb_ask_auth() instead of reimplementing authorization requests in every protocol module. --- protocols/nogaim.c | 61 +++++++++++++++++++++++++++++++++++++++++++----------- protocols/nogaim.h | 13 +++++++++++- 2 files changed, 61 insertions(+), 13 deletions(-) (limited to 'protocols') diff --git a/protocols/nogaim.c b/protocols/nogaim.c index fd445324..710b7645 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -505,33 +505,70 @@ void imcb_buddy_nick_hint( struct im_connection *ic, char *handle, char *nick ) } } -/* prpl.c */ -struct show_got_added_data +struct imcb_ask_cb_data { struct im_connection *ic; char *handle; }; -void show_got_added_no( void *data ) +static void imcb_ask_auth_cb_no( void *data ) { - g_free( ((struct show_got_added_data*)data)->handle ); + struct imcb_ask_cb_data *cbd = data; + + cbd->ic->acc->prpl->auth_deny( cbd->ic, cbd->handle ); + + g_free( cbd->handle ); + g_free( cbd ); +} + +static void imcb_ask_auth_cb_yes( void *data ) +{ + struct imcb_ask_cb_data *cbd = data; + + cbd->ic->acc->prpl->auth_allow( cbd->ic, cbd->handle ); + + g_free( cbd->handle ); + g_free( cbd ); +} + +void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname ) +{ + struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); + char *s, *realname_ = NULL; + + if( realname != NULL ) + realname_ = g_strdup_printf( " (%s)", realname ); + + s = g_strdup_printf( "The user %s%s wants to add you to his/her buddy list.", + handle, realname_ ?: "" ); + + g_free( realname_ ); + + data->ic = ic; + data->handle = g_strdup( handle ); + query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); +} + + +static void imcb_ask_add_cb_no( void *data ) +{ + g_free( ((struct imcb_ask_cb_data*)data)->handle ); g_free( data ); } -void show_got_added_yes( void *data ) +static void imcb_ask_add_cb_yes( void *data ) { - struct show_got_added_data *sga = data; + struct imcb_ask_cb_data *cbd = data; - sga->ic->acc->prpl->add_buddy( sga->ic, sga->handle, NULL ); - /* imcb_add_buddy( sga->ic, NULL, sga->handle, sga->handle ); */ + cbd->ic->acc->prpl->add_buddy( cbd->ic, cbd->handle, NULL ); - return show_got_added_no( data ); + return imcb_ask_add_cb_no( data ); } -void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname ) +void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname ) { - struct show_got_added_data *data = g_new0( struct show_got_added_data, 1 ); + struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); char *s; /* TODO: Make a setting for this! */ @@ -542,7 +579,7 @@ void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname data->ic = ic; data->handle = g_strdup( handle ); - query_add( ic->irc, ic, s, show_got_added_yes, show_got_added_no, data ); + query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); } diff --git a/protocols/nogaim.h b/protocols/nogaim.h index ddfff07e..1e5df503 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -223,6 +223,10 @@ struct prpl { /* Mainly for AOL, since they think "Bung hole" == "Bu ngho le". *sigh* * - Most protocols will just want to set this to g_strcasecmp().*/ int (* handle_cmp) (const char *who1, const char *who2); + + /* Implement these callbacks if you want to use imcb_ask_auth() */ + void (* auth_allow) (struct im_connection *, const char *who); + void (* auth_deny) (struct im_connection *, const char *who); }; /* im_api core stuff. */ @@ -251,13 +255,20 @@ G_MODULE_EXPORT void imc_logout( struct im_connection *ic, int allow_reconnect ) G_MODULE_EXPORT void imcb_log( struct im_connection *ic, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); /* To tell the user an error, ie. before logging out when an error occurs. */ G_MODULE_EXPORT void imcb_error( struct im_connection *ic, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); + /* To ask a your about something. * - 'msg' is the question. * - 'data' can be your custom struct - it will be passed to the callbacks. * - 'doit' or 'dont' will be called depending of the answer of the user. */ G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont ); -G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname ); + +/* Two common questions you may want to ask: + * - X added you to his contact list, allow? + * - X is not in your contact list, want to add? + */ +G_MODULE_EXPORT void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname ); +G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname ); /* Buddy management */ /* This function should be called for each handle which are visible to the -- cgit v1.2.3 From ba168953ffe832133cf236df73e574fa54f8d911 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Oct 2009 14:48:44 +0100 Subject: More Yahoo! fixes: Adding and removing buddies works, and for the first time buddy add requests are actually handled; from what I can see this simply didn't exist in libyahoo2 yet so far. :-( I melded pieces of changes from http://geny.sf.net/ to make this stuff work. --- protocols/yahoo/libyahoo2.c | 147 ++++++++++++++++++++++++++++--------- protocols/yahoo/yahoo.c | 30 +++++++- protocols/yahoo/yahoo2.h | 3 + protocols/yahoo/yahoo2_callbacks.h | 12 +++ protocols/yahoo/yahoo2_types.h | 16 +++- 5 files changed, 167 insertions(+), 41 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index deaa46df..d6cab9e1 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -211,33 +211,23 @@ enum yahoo_service { /* these are easier to see in hex */ YAHOO_SERVICE_CHATLOGOUT = 0xa0, YAHOO_SERVICE_CHATPING, YAHOO_SERVICE_COMMENT = 0xa8, - YAHOO_SERVICE_GAME_INVITE = 0xb7, - YAHOO_SERVICE_STEALTH_PERM = 0xb9, - YAHOO_SERVICE_STEALTH_SESSION = 0xba, - YAHOO_SERVICE_AVATAR = 0xbc, + YAHOO_SERVICE_STEALTH = 0xb9, YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, YAHOO_SERVICE_PICTURE = 0xbe, YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, - YAHOO_SERVICE_YAB_UPDATE = 0xc4, - YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5, /* YMSG13, key 13: 2 = invisible, 1 = visible */ - YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6, /* YMSG13 */ - YAHOO_SERVICE_PICTURE_STATUS = 0xc7, /* YMSG13, key 213: 0 = none, 1 = avatar, 2 = picture */ - YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8, - YAHOO_SERVICE_AUDIBLE = 0xd0, - YAHOO_SERVICE_Y7_PHOTO_SHARING = 0xd2, - YAHOO_SERVICE_Y7_CONTACT_DETAILS = 0xd3,/* YMSG13 */ - YAHOO_SERVICE_Y7_CHAT_SESSION = 0xd4, - YAHOO_SERVICE_Y7_AUTHORIZATION = 0xd6, /* YMSG13 */ - YAHOO_SERVICE_Y7_FILETRANSFER = 0xdc, /* YMSG13 */ - YAHOO_SERVICE_Y7_FILETRANSFERINFO, /* YMSG13 */ - YAHOO_SERVICE_Y7_FILETRANSFERACCEPT, /* YMSG13 */ - YAHOO_SERVICE_Y7_MINGLE = 0xe1, /* YMSG13 */ - YAHOO_SERVICE_Y7_CHANGE_GROUP = 0xe7, /* YMSG13 */ - YAHOO_SERVICE_Y8_STATUS = 0xf0, /* YMSG15 */ - YAHOO_SERVICE_Y8_LIST = 0Xf1, /* YMSG15 */ - YAHOO_SERVICE_WEBLOGIN = 0x0226, - YAHOO_SERVICE_SMS_MSG = 0x02ea + YAHOO_SERVICE_Y6_VISIBILITY=0xc5, + YAHOO_SERVICE_Y6_STATUS_UPDATE=0xc6, + YAHOO_PHOTOSHARE_INIT=0xd2, + YAHOO_SERVICE_CONTACT_YMSG13=0xd6, + YAHOO_PHOTOSHARE_PREV=0xd7, + YAHOO_PHOTOSHARE_KEY=0xd8, + YAHOO_PHOTOSHARE_TRANS=0xda, + YAHOO_FILE_TRANSFER_INIT_YMSG13=0xdc, + YAHOO_FILE_TRANSFER_GET_YMSG13=0xdd, + YAHOO_FILE_TRANSFER_PUT_YMSG13=0xde, + YAHOO_SERVICE_YMSG15_STATUS=0xf0, + YAHOO_SERVICE_YMSG15_BUDDY_LIST=0xf1, }; struct yahoo_pair { @@ -775,7 +765,7 @@ static void yahoo_send_packet(struct yahoo_input_data *yid, struct yahoo_packet if( yid->type == YAHOO_CONNECTION_FT ) yahoo_send_data(yid->fd, data, len); else - yahoo_add_to_send_queue(yid, data, len); + yahoo_add_to_send_queue(yid, data, len); FREE(data); } @@ -1495,9 +1485,15 @@ static void yahoo_process_status(struct yahoo_input_data *yid, struct yahoo_pack struct user *u = users->data; if (u->name != NULL) { - if (pkt->service == YAHOO_SERVICE_LOGOFF || u->flags == 0) { + if (pkt->service == YAHOO_SERVICE_LOGOFF) { /* || u->flags == 0) { Not in YMSG16 */ YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0); } else { + /* Key 47 always seems to be 1 for YMSG16 */ + if(!u->state) + u->away = 0; + else + u->away = 1; + YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile); } } @@ -2514,7 +2510,7 @@ static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_pa bud->real_name = NULL; yd->buddies = y_list_append(yd->buddies, bud); - + /* Possibly called already, but at least the call above doesn't seem to happen every time (not anytime I tried). */ YAHOO_CALLBACK(ext_yahoo_contact_added)(yd->client_id, me, who, NULL); @@ -2523,6 +2519,26 @@ static void yahoo_process_buddyadd(struct yahoo_input_data *yid, struct yahoo_pa /* YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */ } +static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +{ + char* who=NULL; + char* me=NULL; + char* msg=NULL; + YList *l; + for (l = pkt->hash; l; l = l->next) { + struct yahoo_pair *pair = l->data; + if (pair->key == 4) + who = pair->value; + else if (pair->key == 5) + me = pair->value; + else + DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value)); + } + + if(pkt->status==3) + YAHOO_CALLBACK(ext_yahoo_contact_auth_request)(yid->yd->client_id, me, who, msg); +} + static void yahoo_process_buddydel(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { struct yahoo_data *yd = yid->yd; @@ -2734,7 +2750,7 @@ static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_ char *who = NULL; YList *l; - yahoo_dump_unhandled(pkt); + // yahoo_dump_unhandled(pkt); for (l = pkt->hash; l; l = l->next) { struct yahoo_pair *pair = l->data; if (pair->key == 5) @@ -2756,6 +2772,7 @@ static void yahoo_process_webcam_key(struct yahoo_input_data *yid, struct yahoo_ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service)); + yahoo_dump_unhandled(pkt); switch (pkt->service) { case YAHOO_SERVICE_USERSTAT: @@ -2768,7 +2785,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_IDACT: case YAHOO_SERVICE_IDDEACT: case YAHOO_SERVICE_Y6_STATUS_UPDATE: - case YAHOO_SERVICE_Y8_STATUS: + case YAHOO_SERVICE_YMSG15_STATUS: yahoo_process_status(yid, pkt); break; case YAHOO_SERVICE_NOTIFY: @@ -2782,6 +2799,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_NEWMAIL: yahoo_process_mail(yid, pkt); break; + case YAHOO_SERVICE_REJECTCONTACT: case YAHOO_SERVICE_NEWCONTACT: yahoo_process_contact(yid, pkt); break; @@ -2822,6 +2840,9 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_ADDBUDDY: yahoo_process_buddyadd(yid, pkt); break; + case YAHOO_SERVICE_CONTACT_YMSG13: + yahoo_process_contact_ymsg13(yid,pkt); + break; case YAHOO_SERVICE_REMBUDDY: yahoo_process_buddydel(yid, pkt); break; @@ -2850,7 +2871,6 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_CHATLOGON: case YAHOO_SERVICE_CHATLOGOFF: case YAHOO_SERVICE_CHATMSG: - case YAHOO_SERVICE_REJECTCONTACT: case YAHOO_SERVICE_PEERTOPEER: WARNING(("unhandled service 0x%02x", pkt->service)); yahoo_dump_unhandled(pkt); @@ -2864,7 +2884,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid, struct yahoo_pack case YAHOO_SERVICE_PICTURE_UPLOAD: yahoo_process_picture_upload(yid, pkt); break; - case YAHOO_SERVICE_Y8_LIST: /* Buddy List */ + case YAHOO_SERVICE_YMSG15_BUDDY_LIST: /* Buddy List */ yahoo_process_buddy_list(yid, pkt); default: WARNING(("unknown service 0x%02x", pkt->service)); @@ -4044,7 +4064,7 @@ void yahoo_send_typing(int id, const char *from, const char *who, int typ) pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yd->session_id); yahoo_packet_hash(pkt, 5, who); - yahoo_packet_hash(pkt, 4, from?from:yd->user); + yahoo_packet_hash(pkt, 1, from?from:yd->user); yahoo_packet_hash(pkt, 14, " "); yahoo_packet_hash(pkt, 13, typ ? "1" : "0"); yahoo_packet_hash(pkt, 49, "TYPING"); @@ -4346,12 +4366,24 @@ void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); - yahoo_packet_hash(pkt, 1, yd->user); - yahoo_packet_hash(pkt, 7, who); - yahoo_packet_hash(pkt, 65, group); + pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id); + if (msg != NULL) /* add message/request "it's me add me" */ yahoo_packet_hash(pkt, 14, msg); + else + yahoo_packet_hash(pkt,14,""); + + yahoo_packet_hash(pkt, 65, group); + yahoo_packet_hash(pkt, 97, "1"); + yahoo_packet_hash(pkt, 1, yd->user); + yahoo_packet_hash(pkt, 302, "319"); + yahoo_packet_hash(pkt, 300, "319"); + yahoo_packet_hash(pkt, 7, who); + yahoo_packet_hash(pkt, 334, "0"); + yahoo_packet_hash(pkt, 301, "319"); + yahoo_packet_hash(pkt, 303, "319"); + + yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); } @@ -4375,6 +4407,49 @@ void yahoo_remove_buddy(int id, const char *who, const char *group) yahoo_packet_free(pkt); } +void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){ + struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_data *yd; + + if(!yid) + return; + yd = yid->yd; + + struct yahoo_packet* pkt=NULL; + pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); + + yahoo_packet_hash(pkt,1,me ?: yd->user); + yahoo_packet_hash(pkt,5,who); + yahoo_packet_hash(pkt,13,"1"); + yahoo_packet_hash(pkt,334,"0"); + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); +} + +void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){ + struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_data *yd; + + if(!yid) + return; + yd = yid->yd; + + struct yahoo_packet* pkt=NULL; + pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); + + yahoo_packet_hash(pkt,1,me ?: yd->user); + yahoo_packet_hash(pkt,5,who); +// yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER); + yahoo_packet_hash(pkt,13,"2"); + yahoo_packet_hash(pkt,334,"0"); + yahoo_packet_hash(pkt,97,"1"); + yahoo_packet_hash(pkt,14,msg?:""); + + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); + +} + void yahoo_reject_buddy(int id, const char *who, const char *msg) { struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); @@ -4430,7 +4505,7 @@ void yahoo_stealth_buddy(int id, const char *who, int unstealth) if (!yd->logged_in) return; - pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, YAHOO_STATUS_AVAILABLE, yd->session_id); + pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); yahoo_packet_hash(pkt, 1, yd->user); yahoo_packet_hash(pkt, 7, who); yahoo_packet_hash(pkt, 31, unstealth?"2":"1"); diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 3e844c55..ea1b4dec 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -347,6 +347,20 @@ static struct groupchat *byahoo_chat_with( struct im_connection *ic, char *who ) return c; } +static void byahoo_auth_allow( struct im_connection *ic, const char *who ) +{ + struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data; + + yahoo_accept_buddy_ymsg13( yd->y2_id, NULL, who ); +} + +static void byahoo_auth_deny( struct im_connection *ic, const char *who ) +{ + struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data; + + yahoo_reject_buddy_ymsg13( yd->y2_id, NULL, who, NULL ); +} + void byahoo_initmodule( ) { struct prpl *ret = g_new0(struct prpl, 1); @@ -372,6 +386,9 @@ void byahoo_initmodule( ) ret->handle_cmp = g_strcasecmp; + ret->auth_allow = byahoo_auth_allow; + ret->auth_deny = byahoo_auth_deny; + register_protocol(ret); } @@ -921,11 +938,18 @@ void ext_yahoo_chat_yahooerror( int id, const char *me ) { } +void ext_yahoo_contact_auth_request( int id, const char *myid, const char *who, const char *msg ) +{ + struct im_connection *ic = byahoo_get_ic_by_id( id ); + + imcb_ask_auth( ic, who, NULL ); +} + void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg ) { - /* Groups schmoups. If I want to handle groups properly I can get the - buddy data from some internal libyahoo2 structure. */ - imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL ); + struct im_connection *ic = byahoo_get_ic_by_id( id ); + + imcb_add_buddy( ic, (char*) who, NULL ); } void ext_yahoo_rejected( int id, const char *who, const char *msg ) diff --git a/protocols/yahoo/yahoo2.h b/protocols/yahoo/yahoo2.h index e54e09fb..2184a321 100644 --- a/protocols/yahoo/yahoo2.h +++ b/protocols/yahoo/yahoo2.h @@ -216,6 +216,9 @@ const char * yahoo_get_profile_url( void ); void yahoo_buddyicon_request(int id, const char *who); +void yahoo_accept_buddy_ymsg13(int,const char*,const char*); +void yahoo_reject_buddy_ymsg13(int,const char*,const char*,const char*); + #include "yahoo_httplib.h" #ifdef __cplusplus diff --git a/protocols/yahoo/yahoo2_callbacks.h b/protocols/yahoo/yahoo2_callbacks.h index b7f4e99b..e2c8ea42 100644 --- a/protocols/yahoo/yahoo2_callbacks.h +++ b/protocols/yahoo/yahoo2_callbacks.h @@ -359,6 +359,18 @@ void YAHOO_CALLBACK_TYPE(ext_yahoo_conf_message)(int id, const char *me, const c void YAHOO_CALLBACK_TYPE(ext_yahoo_got_file)(int id, const char *me, const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize); +/* + * Name: ext_yahoo_contact_auth_request + * Called when a contact wants to add you to his/her contact list + * Params: + * id - the id that identifies the server connection + * myid - the identity s/he added + * who - who did it + * msg - any message sent + */ +void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_auth_request)(int id, const char *myid, const char *who, const char *msg); + + /* * Name: ext_yahoo_contact_added * Called when a contact is added to your list diff --git a/protocols/yahoo/yahoo2_types.h b/protocols/yahoo/yahoo2_types.h index 7453e487..3507e13a 100644 --- a/protocols/yahoo/yahoo2_types.h +++ b/protocols/yahoo/yahoo2_types.h @@ -56,7 +56,20 @@ enum yahoo_login_status { YAHOO_LOGIN_PASSWD = 13, YAHOO_LOGIN_LOCK = 14, YAHOO_LOGIN_DUPL = 99, - YAHOO_LOGIN_SOCK = -1 + YAHOO_LOGIN_SOCK = -1, +}; + +enum ypacket_status { + YPACKET_STATUS_DISCONNECTED = -1, + YPACKET_STATUS_DEFAULT = 0, + YPACKET_STATUS_SERVERACK = 1, + YPACKET_STATUS_GAME = 0x2, + YPACKET_STATUS_AWAY = 0x4, + YPACKET_STATUS_CONTINUED = 0x5, + YPACKET_STATUS_INVISIBLE = 12, + YPACKET_STATUS_NOTIFY = 0x16, /* TYPING */ + YPACKET_STATUS_WEBLOGIN = 0x5a55aa55, + YPACKET_STATUS_OFFLINE = 0x5a55aa56 }; enum yahoo_error { @@ -132,7 +145,6 @@ enum yahoo_stealth_visibility_type { /* chat member attribs */ #define YAHOO_CHAT_MALE 0x8000 #define YAHOO_CHAT_FEMALE 0x10000 -#define YAHOO_CHAT_FEMALE 0x10000 #define YAHOO_CHAT_DUNNO 0x400 #define YAHOO_CHAT_WEBCAM 0x10 -- cgit v1.2.3 From 037b66a34beef59e7c591ee868516f2305cea906 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Oct 2009 15:57:05 +0100 Subject: Fixed an ugly bug in the write handler that may have caused many weird bugs for a while already by only sending one packet even if more of them were generated during an event cycle. --- protocols/yahoo/yahoo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index ea1b4dec..96f619ed 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -468,9 +468,7 @@ gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condit { struct byahoo_write_ready_data *d = data; - yahoo_write_ready( d->id, d->fd, d->data ); - - return FALSE; + return yahoo_write_ready( d->id, d->fd, d->data ); } void ext_yahoo_login_response( int id, int succ, const char *url ) -- cgit v1.2.3 From 7ea8697c345d5d1e3f237a392b293abca948cdfa Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 10 Oct 2009 16:00:16 +0100 Subject: Setting Yahoo! away states works again. --- protocols/yahoo/libyahoo2.c | 53 +++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 23 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index d6cab9e1..e7005e38 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -4079,7 +4079,7 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt = NULL; - int service; + int old_status; char s[4]; if(!yid) @@ -4087,38 +4087,45 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away) yd = yid->yd; - if (msg) { + old_status = yd->current_status; + + if (msg && strncmp(msg,"Invisible",9)) { yd->current_status = YAHOO_STATUS_CUSTOM; } else { yd->current_status = state; } - if (yd->current_status == YAHOO_STATUS_AVAILABLE) - service = YAHOO_SERVICE_ISBACK; - else - service = YAHOO_SERVICE_ISAWAY; + /* Thank you libpurple :) */ + if (yd->current_status == YAHOO_STATUS_INVISIBLE) { + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash(pkt, 13, "2"); + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); + + return; + } + + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id); + snprintf(s, sizeof(s), "%d", yd->current_status); + yahoo_packet_hash(pkt, 10, s); - if ((away == 2) && (yd->current_status == YAHOO_STATUS_AVAILABLE)) { - pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_BRB, yd->session_id); - yahoo_packet_hash(pkt, 10, "999"); - yahoo_packet_hash(pkt, 47, "2"); - }else { - pkt = yahoo_packet_new(service, YAHOO_STATUS_AVAILABLE, yd->session_id); - snprintf(s, sizeof(s), "%d", yd->current_status); - yahoo_packet_hash(pkt, 10, s); - if (yd->current_status == YAHOO_STATUS_CUSTOM) { - yahoo_packet_hash(pkt, 19, msg); - yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); - } else { - yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); - } - - - + if (yd->current_status == YAHOO_STATUS_CUSTOM) { + yahoo_packet_hash(pkt, 19, msg); + } else { + yahoo_packet_hash(pkt, 19, ""); } + + yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); + + if(old_status == YAHOO_STATUS_INVISIBLE) { + pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); + yahoo_packet_hash(pkt, 13, "1"); + yahoo_send_packet(yid, pkt, 0); + yahoo_packet_free(pkt); + } } void yahoo_logoff(int id) -- cgit v1.2.3 From e71cfbc35f3d2f3aa4da9e72776505d945429cbe Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Tue, 13 Oct 2009 23:33:12 +0100 Subject: Turns out I *did* implement HTTPS auth for Yahoo! myself already, but I kept it as a patch somewhere in my homedir because I thought I didn't need it. I like this code more so I'll use it instead. --- protocols/yahoo/libyahoo2.c | 362 ++++++++++++++++++++++---------------------- 1 file changed, 178 insertions(+), 184 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index e7005e38..1d943df7 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -90,8 +90,6 @@ char *strchr (), *strrchr (); #include "base64.h" #include "http_client.h" -static void yahoo_process_auth_response(struct http_request *req); - #ifdef USE_STRUCT_CALLBACKS struct yahoo_callbacks *yc=NULL; @@ -2308,22 +2306,193 @@ static void yahoo_process_auth_0x0b(struct yahoo_input_data *yid, const char *se free(crypt_hash); } +struct yahoo_https_auth_data +{ + struct yahoo_input_data *yid; + char *token; + char *chal; +}; + +static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had); +static void yahoo_https_auth_token_finish(struct http_request *req); +static void yahoo_https_auth_init(struct yahoo_https_auth_data *had); +static void yahoo_https_auth_finish(struct http_request *req); + +/* Extract a value from a login.yahoo.com response. Assume CRLF-linebreaks + and FAIL miserably if they're not there... */ +static char *yahoo_ha_find_key(char *response, char *key) +{ + char *s, *end; + int len = strlen(key); + + s = response; + do { + if (strncmp(s, key, len) == 0 && s[len] == '=') { + s += len + 1; + if ((end = strchr(s, '\r'))) + return g_strndup(s, end - s); + else + return g_strdup(s); + } + + if ((s = strchr(s, '\n'))) + s ++; + } while (s && *s); + + return NULL; +} + +static enum yahoo_status yahoo_https_status_parse(int code) +{ + switch (code) + { + case 1212: return YAHOO_LOGIN_PASSWD; + case 1213: return YAHOO_LOGIN_LOCK; + case 1235: return YAHOO_LOGIN_UNAME; + default: return (enum yahoo_status) code; + } +} + static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) { - char *url; + struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1); + + had->yid = yid; + had->chal = g_strdup(seed); + + yahoo_https_auth_token_init(had); +} - yid->yd->login_cookie = strdup(seed); +static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had) +{ + struct yahoo_input_data *yid = had->yid; + struct yahoo_data *yd = yid->yd; + struct http_request *req; + char *login, *passwd, *chal; + char *url; + + login = g_strndup(yd->user, 3 * strlen(yd->user)); + http_encode(login); + passwd = g_strndup(yd->password, 3 * strlen(yd->password)); + http_encode(passwd); + chal = g_strndup(had->chal, 3 * strlen(had->chal)); + http_encode(chal); + + url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=%d&login=%s&passwd=%s&chal=%s", + (int) time(NULL), login, passwd, chal); + + req = http_dorequest_url(url, yahoo_https_auth_token_finish, had); + + g_free(url); + g_free(chal); + g_free(passwd); + g_free(login); +} - url = g_strdup_printf( - "https://login.yahoo.com/config/pwtoken_get?" - "src=ymsgr&ts=&login=%s&passwd=%s&chal=%s", - yid->yd->user, yid->yd->password, seed); +static void yahoo_https_auth_token_finish(struct http_request *req) +{ + struct yahoo_https_auth_data *had = req->data; + struct yahoo_input_data *yid = had->yid; + struct yahoo_data *yd = yid->yd; + int st; + + if (req->status_code != 200) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); + goto fail; + } + + if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); + goto fail; + } + + if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL); + goto fail; + } + + return yahoo_https_auth_init(had); + +fail: + g_free(had->token); + g_free(had->chal); + g_free(had); +} - http_dorequest_url(url, yahoo_process_auth_response, yid); +static void yahoo_https_auth_init(struct yahoo_https_auth_data *had) +{ + struct http_request *req; + char *url; + + url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=%d&token=%s", + (int) time(NULL), had->token); + + req = http_dorequest_url(url, yahoo_https_auth_finish, had); g_free(url); } +static void yahoo_https_auth_finish(struct http_request *req) +{ + struct yahoo_https_auth_data *had = req->data; + struct yahoo_input_data *yid = had->yid; + struct yahoo_data *yd = yid->yd; + struct yahoo_packet *pack; + char *crumb; + int st; + + md5_byte_t result[16]; + md5_state_t ctx; + + unsigned char yhash[32]; + + if (req->status_code != 200) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); + goto fail; + } + + if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); + goto fail; + } + + if ((yd->cookie_y = yahoo_ha_find_key(req->reply_body, "Y")) == NULL || + (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL || + (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) { + YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL); + goto fail; + } + + md5_init(&ctx); + md5_append(&ctx, (unsigned char*) crumb, 11); + md5_append(&ctx, (unsigned char*) had->chal, strlen(had->chal)); + md5_finish(&ctx, result); + to_y64(yhash, result, 16); + + pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); + yahoo_packet_hash(pack, 1, yd->user); + yahoo_packet_hash(pack, 0, yd->user); + yahoo_packet_hash(pack, 277, yd->cookie_y); + yahoo_packet_hash(pack, 278, yd->cookie_t); + yahoo_packet_hash(pack, 307, (char*) yhash); + yahoo_packet_hash(pack, 244, "524223"); + yahoo_packet_hash(pack, 2, yd->user); + yahoo_packet_hash(pack, 2, "1"); + yahoo_packet_hash(pack, 98, "us"); + yahoo_packet_hash(pack, 135, "7.5.0.647"); + + yahoo_send_packet(yid, pack, 0); + + yahoo_packet_free(pack); + + return; + +fail: + g_free(had->token); + g_free(had->chal); + g_free(had); +} + static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) { char *seed = NULL; @@ -2353,7 +2522,6 @@ static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet yahoo_process_auth_0x0b(yid, seed, sn); break; case 2: - /* HTTPS */ yahoo_process_auth_0x10(yid, seed, sn); break; default: @@ -3662,180 +3830,6 @@ static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int ov && yahoo_get_webcam_data(yid) == 1); } -/* #define LOG(x...) printf x */ - -static void yahoo_process_auth_response(struct http_request *req) -{ - char *line_end; - char *token; - char *cookie; - - int error_code = 0; - int is_ymsgr = 0; - - struct yahoo_input_data *yid = req->data; - - char crypt_hash[25]; - - md5_byte_t result[16]; - md5_state_t ctx; - - struct yahoo_packet *packet = NULL; - - if (y_list_find(inputs, yid) == NULL) - return; - - if (req->status_code != 200) { - error_code = 3000 + req->status_code; - goto FAIL; - } - - token = req->reply_body; - line_end = strstr(token, "\r\n"); - - if (line_end) { - *line_end = '\0'; - - line_end += 2; - } - - if (sscanf(token, "%d", &error_code) != 1) { - error_code = 3000; - goto FAIL; - } - - switch(error_code) { - case 0: - /* successful */ - break; - - case 1212: - LOG(("Incorrect ID or password\n")); - error_code = YAHOO_LOGIN_PASSWD; - goto FAIL; - - case 1213: - LOG(("Security lock from too many failed login attempts\n")); - error_code = YAHOO_LOGIN_LOCK; - goto FAIL; - - case 1214: - LOG(("Security lock\n")); - goto FAIL; - - case 1235: - LOG(("User ID not taken yet\n")); - error_code = YAHOO_LOGIN_UNAME; - goto FAIL; - - case 1216: - LOG(("Seems to be a lock, but shows the same generic User ID/Password failure\n")); - goto FAIL; - - default: - /* Unknown error code */ - LOG(("Unknown Error\n")); - goto FAIL; - } - - if ( !strncmp(line_end, "ymsgr=", 6) ) { - is_ymsgr = 1; - } - else if ( strncmp(line_end, "crumb=", 6) ) { - LOG(("Oops! There was no ymsgr=. Where do I get my token from now :(")); - LOG(("I got this:\n\n%s\n",line_end)); - error_code = 2201; - goto FAIL; - } - - token = line_end+6; - - line_end = strstr(token, "\r\n"); - - if(line_end) { - *line_end = '\0'; - line_end += 2; - } - - /* Go for the crumb */ - if(is_ymsgr) { - char *url; - - url = g_strdup_printf( - "https://login.yahoo.com/config/pwtoken_login?" - "src=ymsgr&ts=&token=%s", token); - - http_dorequest_url(url, yahoo_process_auth_response, yid); - - g_free(url); - - return; - } - - /* token is actually crumb */ - - if(!line_end) { - /* We did not get our cookies. Cry. */ - } - - if((cookie = strstr(req->reply_headers, "Set-Cookie: Y=")) && - (line_end = strstr(cookie + 14, "\r\n"))) { - *line_end = '\0'; - yid->yd->cookie_y = strdup(cookie + 14); - *line_end = ';'; - } else { - /* Cry. */ - LOG(("NO Y Cookie!")); - error_code = 2202; - goto FAIL; - } - - if((cookie = strstr(req->reply_headers, "Set-Cookie: T=")) && - (line_end = strstr(cookie + 14, "\r\n"))) { - *line_end = '\0'; - yid->yd->cookie_t = strdup(cookie + 14); - *line_end = ';'; - } else { - /* Cry. */ - LOG(("NO T Cookie!")); - error_code = 2203; - goto FAIL; - } - - md5_init(&ctx); - md5_append(&ctx, (md5_byte_t *)token, strlen(token)); - md5_append(&ctx, (md5_byte_t *)yid->yd->login_cookie, strlen(yid->yd->login_cookie)); - md5_finish(&ctx, result); - - to_y64((unsigned char*)crypt_hash, result, 16); - - packet = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yid->yd->initial_status, yid->yd->session_id); - yahoo_packet_hash(packet, 1, yid->yd->user); - yahoo_packet_hash(packet, 0, yid->yd->user); - yahoo_packet_hash(packet, 277, yid->yd->cookie_y); - yahoo_packet_hash(packet, 278, yid->yd->cookie_t); - yahoo_packet_hash(packet, 307, crypt_hash); - yahoo_packet_hash(packet, 244, "2097087"); /* Rekkanoryo says this is the build number */ - yahoo_packet_hash(packet, 2, yid->yd->user); - yahoo_packet_hash(packet, 2, "1"); - yahoo_packet_hash(packet, 98, "us"); /* TODO Put country code */ - yahoo_packet_hash(packet, 135, "9.0.0.1389"); - - yahoo_send_packet(yid, packet, 0); - - yahoo_packet_free(packet); - - /* We don't need this anymore */ - free(yid->yd->login_cookie); - yid->yd->login_cookie = NULL; - - return; - -FAIL: - YAHOO_CALLBACK(ext_yahoo_login_response)(yid->yd->client_id, error_code, NULL); -} - - static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = { yahoo_process_pager_connection, yahoo_process_ft_connection, -- cgit v1.2.3 From 99c8f1357f1ab85f3a98727cb8877403d965e3da Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 17 Oct 2009 15:48:21 +0100 Subject: Valgrind pointed me at some memory leaks in the Yahoo! codek, including one that existed for a while already. Fixed. --- protocols/yahoo/libyahoo2.c | 8 +++++--- protocols/yahoo/yahoo.c | 31 +++++++++++++++++-------------- 2 files changed, 22 insertions(+), 17 deletions(-) (limited to 'protocols') diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index 1d943df7..a1755cc9 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -2485,9 +2485,8 @@ static void yahoo_https_auth_finish(struct http_request *req) yahoo_packet_free(pack); - return; - fail: + g_free(crumb); g_free(had->token); g_free(had->chal); g_free(had); @@ -4134,7 +4133,10 @@ void yahoo_logoff(int id) LOG(("yahoo_logoff: current status: %d", yd->current_status)); - if(yd->current_status != -1) { + if(yd->current_status != -1 && 0) { + /* Meh. Don't send this. The event handlers are not going to + get to do this so it'll just leak memory. And the TCP + connection reset will hopefully be clear enough. */ pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); yd->current_status = -1; diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index 96f619ed..ac57d4b6 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -253,20 +253,23 @@ static void byahoo_set_away( struct im_connection *ic, char *state, char *msg ) static GList *byahoo_away_states( struct im_connection *ic ) { - GList *m = NULL; - - m = g_list_append( m, "Available" ); - m = g_list_append( m, "Be Right Back" ); - m = g_list_append( m, "Busy" ); - m = g_list_append( m, "Not At Home" ); - m = g_list_append( m, "Not At Desk" ); - m = g_list_append( m, "Not In Office" ); - m = g_list_append( m, "On Phone" ); - m = g_list_append( m, "On Vacation" ); - m = g_list_append( m, "Out To Lunch" ); - m = g_list_append( m, "Stepped Out" ); - m = g_list_append( m, "Invisible" ); - m = g_list_append( m, GAIM_AWAY_CUSTOM ); + static GList *m = NULL; + + if( m == NULL ) + { + m = g_list_append( m, "Available" ); + m = g_list_append( m, "Be Right Back" ); + m = g_list_append( m, "Busy" ); + m = g_list_append( m, "Not At Home" ); + m = g_list_append( m, "Not At Desk" ); + m = g_list_append( m, "Not In Office" ); + m = g_list_append( m, "On Phone" ); + m = g_list_append( m, "On Vacation" ); + m = g_list_append( m, "Out To Lunch" ); + m = g_list_append( m, "Stepped Out" ); + m = g_list_append( m, "Invisible" ); + m = g_list_append( m, GAIM_AWAY_CUSTOM ); + } return m; } -- cgit v1.2.3 From 74349eb5b77e2143289ef98201d03870e0d2366a Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Sat, 17 Oct 2009 16:13:40 +0100 Subject: If you can't find what you expect in an IQ packet, it doesn't mean it's incorrect, so stop spamming. Ideally it should return a feature-not- implemented but I'll do that later. --- protocols/jabber/iq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/iq.c b/protocols/jabber/iq.c index 38c5a5a9..875b5c81 100644 --- a/protocols/jabber/iq.c +++ b/protocols/jabber/iq.c @@ -50,10 +50,11 @@ xt_status jabber_pkt_iq( struct xt_node *node, gpointer data ) else if( strcmp( type, "get" ) == 0 ) { if( !( ( c = xt_find_node( node->children, "query" ) ) || - ( c = xt_find_node( node->children, "ping" ) ) ) || /* O_o WHAT is wrong with just ????? */ + ( c = xt_find_node( node->children, "ping" ) ) ) || !( s = xt_find_attr( c, "xmlns" ) ) ) { - imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); + /* Sigh. Who decided to suddenly invent new elements + instead of just sticking with ? */ return XT_HANDLED; } -- cgit v1.2.3 From b75acf6367400ff88428618719cefbbee648b0cb Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Thu, 22 Oct 2009 22:55:23 +0100 Subject: Don't include chat.h from bitlbee.h. make install-dev doesn't install chat.h and it shouldn't ... but things broke because bitlbee.h includes it. Fixes #534. --- protocols/nogaim.h | 1 + 1 file changed, 1 insertion(+) (limited to 'protocols') diff --git a/protocols/nogaim.h b/protocols/nogaim.h index 1e5df503..ade8c23f 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -43,6 +43,7 @@ #include "proxy.h" #include "query.h" #include "md5.h" +#include "chat.h" #define BUDDY_ALIAS_MAXLEN 388 /* because MSN names can be 387 characters */ -- cgit v1.2.3 From 4cf80bb798a4159f42a904cb830b99c87a0ca8e0 Mon Sep 17 00:00:00 2001 From: Wilmer van der Gaast Date: Fri, 23 Oct 2009 11:43:15 +0100 Subject: Shuffling a few more #includes. Much more shuffling will be needed. --- protocols/jabber/jabber.h | 3 ++- protocols/nogaim.c | 4 +++- protocols/nogaim.h | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'protocols') diff --git a/protocols/jabber/jabber.h b/protocols/jabber/jabber.h index ee453144..1180d2b9 100644 --- a/protocols/jabber/jabber.h +++ b/protocols/jabber/jabber.h @@ -26,8 +26,9 @@ #include -#include "xmltree.h" #include "bitlbee.h" +#include "md5.h" +#include "xmltree.h" extern GSList *jabber_connections; diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 710b7645..21f7dcb1 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -32,9 +32,11 @@ */ #define BITLBEE_CORE -#include "nogaim.h" #include +#include "nogaim.h" +#include "chat.h" + static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ); GSList *connections; diff --git a/protocols/nogaim.h b/protocols/nogaim.h index ade8c23f..dc6154e2 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -38,12 +38,12 @@ #ifndef _NOGAIM_H #define _NOGAIM_H +#include + #include "bitlbee.h" #include "account.h" #include "proxy.h" #include "query.h" -#include "md5.h" -#include "chat.h" #define BUDDY_ALIAS_MAXLEN 388 /* because MSN names can be 387 characters */ -- cgit v1.2.3