/*------------------------------------------------------------------------ * Enable the user to change their PIN. * * @param action The action object */ static void mxit_change_pin_action( PurplePluginAction* action ) { PurpleConnection* gc = (PurpleConnection*) action->context; PurpleRequestFields* fields = NULL; PurpleRequestFieldGroup* group = NULL; PurpleRequestField* field = NULL; purple_debug_info( MXIT_PLUGIN_ID, "mxit_change_pin_action\n" ); fields = purple_request_fields_new(); group = purple_request_field_group_new( NULL ); purple_request_fields_add_group( fields, group ); /* pin */ field = purple_request_field_string_new( "pin", _( "PIN" ), purple_connection_get_password( gc ), FALSE ); purple_request_field_string_set_masked( field, TRUE ); purple_request_field_group_add_field( group, field ); /* verify pin */ field = purple_request_field_string_new( "pin2", _( "Verify PIN" ), purple_connection_get_password( gc ), FALSE ); purple_request_field_string_set_masked( field, TRUE ); purple_request_field_group_add_field( group, field ); /* (reference: "libpurple/request.h") */ purple_request_fields( gc, _( "Change PIN" ), _( "Change MXit PIN" ), NULL, fields, _( "Set" ), G_CALLBACK( mxit_change_pin_cb ), _( "Cancel" ), NULL, purple_request_cpar_from_connection(gc), gc ); }
static void fx_login(PurpleAccount *account) { PurplePresence *presence; PurpleConnection *pc = purple_account_get_connection(account); const gchar *mobileno = purple_account_get_username(account); const gchar *password = purple_connection_get_password(pc); const gchar *status_id; fetion_account *ac = session_new(account); /* construct a user object */ ac->user = fetion_user_new(mobileno, password); ac->account = account; ac->gc = pc; ac->chan_ready = 1; purple_connection_set_protocol_data(pc, ac); presence = purple_account_get_presence(account); status_id = get_status_id(ac->user->state); if(ac->user->state == 0) status_id = "Hidden"; purple_presence_set_status_active(presence, status_id, TRUE); purple_connection_update_progress(pc, "Connecting", 1, 2); purple_ssl_connect(ac->account, SSI_SERVER, PURPLE_SSL_DEFAULT_PORT, (PurpleSslInputFunction)ssi_auth_action, (PurpleSslErrorFunction)0, ac); }
void jabber_auth_start_old(JabberStream *js) { PurpleAccount *account; JabberIq *iq; PurpleXmlNode *query, *username; account = purple_connection_get_account(js->gc); /* * We can end up here without encryption if the server doesn't support * <stream:features/> and we're not using old-style SSL. If the user * is requiring SSL/TLS, we need to enforce it. */ if (!jabber_stream_is_ssl(js) && g_str_equal("require_tls", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) { purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("You require encryption, but it is not available on this server.")); return; } if (js->registration) { jabber_register_start(js); return; } /* * IQ Auth doesn't have support for resource binding, so we need to pick a * default resource so it will work properly. jabberd14 throws an error and * iChat server just fails silently. */ if (!js->user->resource || *js->user->resource == '\0') { g_free(js->user->resource); js->user->resource = g_strdup("Home"); } #ifdef HAVE_CYRUS_SASL /* If we have Cyrus SASL, then passwords will have been set * to OPTIONAL for this protocol. So, we need to do our own * password prompting here */ if (!purple_connection_get_password(js->gc)) { purple_account_request_password(account, G_CALLBACK(auth_old_pass_cb), G_CALLBACK(auth_no_pass_cb), js->gc); return; } #endif iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:auth"); query = purple_xmlnode_get_child(iq->node, "query"); username = purple_xmlnode_new_child(query, "username"); purple_xmlnode_insert_data(username, js->user->node, -1); jabber_iq_set_callback(iq, auth_old_cb, NULL); jabber_iq_send(iq); }
static void client_login_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { OscarData *od; PurpleConnection *gc; char *token, *secret, *session_key; time_t hosttime; int password_len; char *password; od = user_data; gc = od->gc; od->url_data = NULL; if (error_message != NULL || len == 0) { gchar *tmp; if (error_message != NULL) tmp = g_strdup_printf(_("Error requesting %s: %s"), URL_CLIENT_LOGIN, error_message); else tmp = g_strdup_printf(_("Error requesting %s"), URL_CLIENT_LOGIN); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp); g_free(tmp); return; } if (!parse_client_login_response(gc, url_text, len, &token, &secret, &hosttime)) return; password_len = strlen(purple_connection_get_password(gc)); password = g_strdup_printf("%.*s", od->icq ? MIN(password_len, MAXICQPASSLEN) : password_len, purple_connection_get_password(gc)); session_key = hmac_sha256(password, secret); g_free(password); g_free(secret); send_start_oscar_session(od, token, session_key, hosttime); g_free(token); g_free(session_key); }
static gboolean do_login(PurpleConnection *gc) { char *buf, *tmp = NULL; char hostname[256]; const char *username, *realname; struct irc_conn *irc = gc->proto_data; const char *pass = purple_connection_get_password(gc); if (pass && *pass) { buf = irc_format(irc, "vv", "PASS", pass); if (irc_send(irc, buf) < 0) { /* purple_connection_error(gc, "Error sending password"); */ g_free(buf); return FALSE; } g_free(buf); } gethostname(hostname, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; realname = purple_account_get_string(irc->account, "realname", ""); username = purple_account_get_string(irc->account, "username", ""); if (username == NULL || *username == '\0') { username = g_get_user_name(); } if (username != NULL && strchr(username, ' ') != NULL) { tmp = g_strdup(username); while ((buf = strchr(tmp, ' ')) != NULL) { *buf = '_'; } } buf = irc_format(irc, "vvvv:", "USER", tmp ? tmp : username, hostname, irc->server, strlen(realname) ? realname : IRC_DEFAULT_ALIAS); g_free(tmp); if (irc_send(irc, buf) < 0) { /* purple_connection_error(gc, "Error registering with server");*/ g_free(buf); return FALSE; } g_free(buf); buf = irc_format(irc, "vn", "NICK", purple_connection_get_display_name(gc)); if (irc_send(irc, buf) < 0) { /* purple_connection_error(gc, "Error sending nickname");*/ g_free(buf); return FALSE; } g_free(buf); irc->recv_time = time(NULL); return TRUE; }
/** * This function sends a request to * https://api.screenname.aol.com/auth/clientLogin with the user's * username and password and receives the user's session key, which is * used to request a connection to the BOSS server. */ void send_client_login(OscarData *od, const char *username) { PurpleConnection *gc; GString *request, *body; const char *tmp; char *password; int password_len; gc = od->gc; /* * We truncate ICQ passwords to 8 characters. There is probably a * limit for AIM passwords, too, but we really only need to do * this for ICQ because older ICQ clients let you enter a password * as long as you wanted and then they truncated it silently. * * And we can truncate based on the number of bytes and not the * number of characters because passwords for AIM and ICQ are * supposed to be plain ASCII (I don't know if this has always been * the case, though). */ tmp = purple_connection_get_password(gc); password_len = strlen(tmp); password = g_strndup(tmp, od->icq ? MIN(password_len, MAXICQPASSLEN) : password_len); /* Construct the body of the HTTP POST request */ body = g_string_new(""); g_string_append_printf(body, "devId=%s", get_client_key(od)); g_string_append_printf(body, "&f=xml"); g_string_append_printf(body, "&pwd=%s", purple_url_encode(password)); g_string_append_printf(body, "&s=%s", purple_url_encode(username)); g_free(password); /* Construct an HTTP POST request */ request = g_string_new("POST /auth/clientLogin HTTP/1.0\r\n" "Connection: close\r\n" "Accept: */*\r\n"); /* Tack on the body */ g_string_append_printf(request, "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n"); g_string_append_printf(request, "Content-Length: %" G_GSIZE_FORMAT "\r\n\r\n", body->len); g_string_append_len(request, body->str, body->len); g_string_free(body, TRUE); /* Send the POST request */ od->url_data = purple_util_fetch_url_request_len_with_account( purple_connection_get_account(gc), URL_CLIENT_LOGIN, TRUE, NULL, FALSE, request->str, FALSE, -1, client_login_cb, od); g_string_free(request, TRUE); }
/*when connect, do the SOAP Style windows Live ID authentication */ void msn_nexus_connect(MsnNexus *nexus) { MsnSession *session = nexus->session; const char *username; const char *password; char *password_xml; GString *domains; char *request; int i; MsnSoapMessage *soap; purple_debug_info("msn", "Starting Windows Live ID authentication\n"); msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE); username = purple_account_get_username(session->account); password = purple_connection_get_password(session->account->gc); if (g_utf8_strlen(password, -1) > 16) { /* max byte size for 16 utf8 characters is 64 + 1 for the null */ gchar truncated[65]; g_utf8_strncpy(truncated, password, 16); password_xml = g_markup_escape_text(truncated, -1); } else { password_xml = g_markup_escape_text(password, -1); } purple_debug_info("msn", "Logging on %s, with policy '%s', nonce '%s'\n", username, nexus->policy, nexus->nonce); domains = g_string_new(NULL); for (i = 0; i < nexus->token_len; i++) { g_string_append_printf(domains, MSN_SSO_RST_TEMPLATE, i+1, ticket_domains[i][SSO_VALID_TICKET_DOMAIN], ticket_domains[i][SSO_VALID_TICKET_POLICY] != NULL ? ticket_domains[i][SSO_VALID_TICKET_POLICY] : nexus->policy); } request = g_strdup_printf(MSN_SSO_TEMPLATE, username, password_xml, domains->str); g_free(password_xml); g_string_free(domains, TRUE); soap = msn_soap_message_new(NULL, xmlnode_from_str(request, -1)); g_free(request); msn_soap_message_send(session, soap, MSN_SSO_SERVER, SSO_POST_URL, TRUE, nexus_got_response_cb, nexus); }
static void finish_plaintext_authentication(JabberStream *js) { JabberIq *iq; PurpleXmlNode *query, *x; iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth"); query = purple_xmlnode_get_child(iq->node, "query"); x = purple_xmlnode_new_child(query, "username"); purple_xmlnode_insert_data(x, js->user->node, -1); x = purple_xmlnode_new_child(query, "resource"); purple_xmlnode_insert_data(x, js->user->resource, -1); x = purple_xmlnode_new_child(query, "password"); purple_xmlnode_insert_data(x, purple_connection_get_password(js->gc), -1); jabber_iq_set_callback(iq, auth_old_result_cb, NULL); jabber_iq_send(iq); }
void twitter_send_request(PurpleAccount *account, gboolean post, const char *url, const char *query_string, TwitterSendRequestSuccessFunc success_callback, TwitterSendRequestErrorFunc error_callback, gpointer data) { gchar *request; const char *pass = purple_connection_get_password(purple_account_get_connection(account)); const char *sn = purple_account_get_username(account); char *auth_text = g_strdup_printf("%s:%s", sn, pass); char *auth_text_b64 = purple_base64_encode((guchar *) auth_text, strlen(auth_text)); gboolean use_https = purple_account_get_bool(account, "use_https", FALSE) && purple_ssl_is_supported(); char *host = "twitter.com"; TwitterSendRequestData *request_data = g_new0(TwitterSendRequestData, 1); char *full_url = g_strdup_printf("%s://%s%s", use_https ? "https" : "http", host, url); request_data->account = account; request_data->user_data = data; request_data->success_func = success_callback; request_data->error_func = error_callback; g_free(auth_text); request = g_strdup_printf( "%s %s%s%s HTTP/1.0\r\n" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5)\r\n" "Host: %s\r\n" "Authorization: Basic %s\r\n" "Content-Length: %d\r\n\r\n" "%s", post ? "POST" : "GET", full_url, (!post && query_string ? "?" : ""), (!post && query_string ? query_string : ""), host, auth_text_b64, query_string && post ? strlen(query_string) : 0, query_string && post ? query_string : ""); g_free(auth_text_b64); purple_util_fetch_url_request(full_url, TRUE, "Mozilla/4.0 (compatible; MSIE 5.5)", TRUE, request, FALSE, twitter_send_request_cb, request_data); g_free(full_url); g_free(request); }
/*------------------------------------------------------------------------ * Generate the Transport-Layer crypto key. * (Note: this function is not-thread safe) * * @param session The MXit Session object * @return The transport-layer crypto key. */ static char* transport_layer_key( struct MXitSession* session ) { static char key[16 + 1]; const char* password = purple_connection_get_password( session->con ); int passlen = strlen( password ); /* initialize with initial key */ g_strlcpy( key, INITIAL_KEY, sizeof( key ) ); /* client key (8 bytes) */ memcpy( key, session->clientkey, strlen( session->clientkey ) ); /* add last 8 characters of the PIN (no padding if less characters) */ if ( passlen <= 8 ) memcpy( key + 8, password, passlen ); else memcpy( key + 8, password + ( passlen - 8 ), 8 ); return key; }
/*------------------------------------------------------------------------ * Encrypt the user's cleartext password using the AES 128-bit (ECB) * encryption algorithm. * * @param session The MXit session object * @return The encrypted & encoded password. Must be g_free'd when no longer needed. */ char* mxit_encrypt_password( struct MXitSession* session ) { char key[16 + 1]; char exkey[512]; GString* pass = NULL; GString* encrypted = NULL; char* base64; unsigned int i; purple_debug_info( MXIT_PLUGIN_ID, "mxit_encrypt_password\n" ); /* build the AES encryption key */ g_strlcpy( key, INITIAL_KEY, sizeof( key ) ); memcpy( key, session->clientkey, strlen( session->clientkey ) ); ExpandKey( (unsigned char*) key, (unsigned char*) exkey ); /* build the secret data to be encrypted: SECRET_HEADER + password */ pass = g_string_new( SECRET_HEADER ); g_string_append( pass, purple_connection_get_password( session->con ) ); padding_add( pass ); /* add ISO10126 padding */ /* now encrypt the secret. we encrypt each block separately (ECB mode) */ encrypted = g_string_sized_new( pass->len ); for ( i = 0; i < pass->len; i += 16 ) { char block[16]; Encrypt( (unsigned char*) pass->str + i, (unsigned char*) exkey, (unsigned char*) block ); g_string_append_len( encrypted, block, 16 ); } /* now base64 encode the encrypted password */ base64 = purple_base64_encode( (unsigned char*) encrypted->str, encrypted->len ); g_string_free( encrypted, TRUE ); g_string_free( pass, TRUE ); return base64; }
/* 002 - MSG_CLIENT_LOGIN */ static void nap_login_connect(gpointer data, gint source, const gchar *error_message) { PurpleConnection *gc = data; struct nap_data *ndata = (struct nap_data *)gc->proto_data; gchar *buf; if (!g_list_find(purple_connections_get_all(), gc)) { close(source); return; } if (source < 0) { purple_connection_error(gc, _("Unable to connect.")); return; } /* Clear the nonblocking flag This protocol should be updated to support nonblocking I/O if anyone is going to actually use it */ fcntl(source, F_SETFL, 0); ndata->fd = source; /* Update the login progress status display */ buf = g_strdup_printf("Logging in: %s", purple_account_get_username(gc->account)); purple_connection_update_progress(gc, buf, 1, NAPSTER_CONNECT_STEPS); g_free(buf); /* Write our signon data */ nap_write_packet(gc, 2, "%s %s 0 \"purple %s\" 0", purple_account_get_username(gc->account), purple_connection_get_password(gc), PP_VERSION); /* And set up the input watcher */ gc->inpa = purple_input_add(ndata->fd, PURPLE_INPUT_READ, nap_callback, gc); }
static void url_cmd (MsnCmdProc *cmdproc, MsnCommand *cmd) { MsnSession *session; PurpleConnection *connection; const gchar *rru; const gchar *url; gchar creds[64]; glong tmp_timestamp; session = cmdproc->session; connection = purple_account_get_connection (session->account); rru = cmd->params[1]; url = cmd->params[2]; session->passport_info.mail_url_timestamp = time (NULL); tmp_timestamp = session->passport_info.mail_url_timestamp - session->passport_info.sl; { PurpleCipher *cipher; PurpleCipherContext *context; guchar digest[16]; gchar *buf; buf = pecan_strdup_printf ("%s%ld%s", session->passport_info.mspauth ? session->passport_info.mspauth : "BOGUS", tmp_timestamp, purple_connection_get_password (connection)); cipher = purple_ciphers_find_cipher ("md5"); context = purple_cipher_context_new (cipher, NULL); purple_cipher_context_append (context, (const guchar *) buf, strlen (buf)); purple_cipher_context_digest (context, sizeof (digest), digest, NULL); purple_cipher_context_destroy (context); g_free (buf); memset (creds, 0, sizeof (creds)); { gchar buf2[3]; gint i; for (i = 0; i < 16; i++) { g_snprintf (buf2, sizeof (buf2), "%02x", digest[i]); strcat (creds, buf2); } } } g_free (session->passport_info.mail_url); session->passport_info.mail_url = g_strdup_printf ("%s&auth=%s&creds=%s&sl=%ld&username=%s&mode=ttl&sid=%s&id=2&rru=%ssvc_mail&js=yes", url, session->passport_info.mspauth, creds, tmp_timestamp, msn_session_get_username (session), session->passport_info.sid, rru); /* The user wants to check his email */ if (cmd->trans && cmd->trans->data) { purple_notify_uri (connection, session->passport_info.mail_url); return; } if (purple_account_get_check_mail (session->account)) { static gboolean is_initial = TRUE; if (!is_initial) return; if (session->inbox_unread_count > 0) { const gchar *passport; const gchar *main_url; passport = msn_session_get_username (session); main_url = session->passport_info.mail_url; purple_notify_emails (connection, session->inbox_unread_count, FALSE, NULL, NULL, &passport, &main_url, NULL, NULL); } is_initial = FALSE; } }
static gboolean do_login(PurpleConnection *gc) { char *buf, *tmp = NULL; char *server; const char *nickname, *identname, *realname; struct irc_conn *irc = gc->proto_data; const char *pass = purple_connection_get_password(gc); #ifdef HAVE_CYRUS_SASL const gboolean use_sasl = purple_account_get_bool(irc->account, "sasl", FALSE); #endif if (pass && *pass) { #ifdef HAVE_CYRUS_SASL if (use_sasl) buf = irc_format(irc, "vv:", "CAP", "REQ", "sasl"); else /* intended to fall through */ #endif buf = irc_format(irc, "v:", "PASS", pass); if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); } realname = purple_account_get_string(irc->account, "realname", ""); identname = purple_account_get_string(irc->account, "username", ""); if (identname == NULL || *identname == '\0') { identname = g_get_user_name(); } if (identname != NULL && strchr(identname, ' ') != NULL) { tmp = g_strdup(identname); while ((buf = strchr(tmp, ' ')) != NULL) { *buf = '_'; } } if (*irc->server == ':') { /* Same as hostname, above. */ server = g_strdup_printf("0%s", irc->server); } else { server = g_strdup(irc->server); } buf = irc_format(irc, "vvvv:", "USER", tmp ? tmp : identname, "*", server, strlen(realname) ? realname : IRC_DEFAULT_ALIAS); g_free(tmp); g_free(server); if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); nickname = purple_connection_get_display_name(gc); buf = irc_format(irc, "vn", "NICK", nickname); irc->reqnick = g_strdup(nickname); irc->nickused = FALSE; if (irc_send(irc, buf) < 0) { g_free(buf); return FALSE; } g_free(buf); irc->recv_time = time(NULL); return TRUE; }
static JabberSaslState scram_start(JabberStream *js, PurpleXmlNode *mechanisms, PurpleXmlNode **out, char **error) { PurpleXmlNode *reply; JabberScramData *data; guint64 cnonce; #ifdef CHANNEL_BINDING gboolean binding_supported = TRUE; #endif gchar *dec_out, *enc_out; gchar *prepped_node, *tmp; gchar *prepped_pass; prepped_node = jabber_saslprep(js->user->node); if (!prepped_node) { *error = g_strdup(_("Unable to canonicalize username")); return JABBER_SASL_STATE_FAIL; } tmp = escape_username(prepped_node); g_free(prepped_node); prepped_node = tmp; prepped_pass = jabber_saslprep(purple_connection_get_password(js->gc)); if (!prepped_pass) { g_free(prepped_node); *error = g_strdup(_("Unable to canonicalize password")); return JABBER_SASL_STATE_FAIL; } data = js->auth_mech_data = g_new0(JabberScramData, 1); data->hash = mech_to_hash(js->auth_mech->name); data->password = prepped_pass; #ifdef CHANNEL_BINDING if (strstr(js->auth_mech_name, "-PLUS")) data->channel_binding = TRUE; #endif cnonce = ((guint64)g_random_int() << 32) | g_random_int(); data->cnonce = purple_base64_encode((guchar *)&cnonce, sizeof(cnonce)); data->auth_message = g_string_new(NULL); g_string_printf(data->auth_message, "n=%s,r=%s", prepped_node, data->cnonce); g_free(prepped_node); data->step = 1; reply = purple_xmlnode_new("auth"); purple_xmlnode_set_namespace(reply, NS_XMPP_SASL); purple_xmlnode_set_attrib(reply, "mechanism", js->auth_mech->name); /* TODO: Channel binding */ dec_out = g_strdup_printf("%c,,%s", 'n', data->auth_message->str); enc_out = purple_base64_encode((guchar *)dec_out, strlen(dec_out)); purple_debug_misc("jabber", "initial SCRAM message '%s'\n", dec_out); purple_xmlnode_insert_data(reply, enc_out, -1); g_free(enc_out); g_free(dec_out); *out = reply; return JABBER_SASL_STATE_CONTINUE; }
void login_connect_cb(gpointer data, PurpleSslConnection *gsc, PurpleInputCondition cond) { MsnNexus *nexus; MsnSession *session; char *username, *password, *encpass; char *request_str, *head, *tail; char *buffer = NULL; guint32 ctint; nexus = data; g_return_if_fail(nexus != NULL); session = nexus->session; g_return_if_fail(session != NULL); msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE); username = g_strdup(purple_url_encode(purple_account_get_username(session->account))); password = g_utf8_strncpy(g_strdup(purple_connection_get_password(session->account->gc)), purple_connection_get_password(session->account->gc), 16); encpass = g_strdup(purple_url_encode(password)); g_free(password); ctint = strtoul((char *)g_hash_table_lookup(nexus->challenge_data, "ct"), NULL, 10) + 200; head = g_strdup_printf( "GET %s HTTP/1.1\r\n" "Authorization: Passport1.4 OrgVerb=GET,OrgURL=%s,sign-in=%s", nexus->login_path, (char *)g_hash_table_lookup(nexus->challenge_data, "ru"), username); tail = g_strdup_printf( "lc=%s,id=%s,tw=%s,fs=%s,ru=%s,ct=%" G_GUINT32_FORMAT ",kpp=%s,kv=%s,ver=%s,tpf=%s\r\n" "User-Agent: MSMSGS\r\n" "Host: %s\r\n" "Connection: Keep-Alive\r\n" "Cache-Control: no-cache\r\n", nexus_challenge_data_lookup(nexus->challenge_data, "lc"), nexus_challenge_data_lookup(nexus->challenge_data, "id"), nexus_challenge_data_lookup(nexus->challenge_data, "tw"), nexus_challenge_data_lookup(nexus->challenge_data, "fs"), nexus_challenge_data_lookup(nexus->challenge_data, "ru"), ctint, nexus_challenge_data_lookup(nexus->challenge_data, "kpp"), nexus_challenge_data_lookup(nexus->challenge_data, "kv"), nexus_challenge_data_lookup(nexus->challenge_data, "ver"), nexus_challenge_data_lookup(nexus->challenge_data, "tpf"), nexus->login_host); buffer = g_strdup_printf("%s,pwd=XXXXXXXX,%s\r\n", head, tail); request_str = g_strdup_printf("%s,pwd=%s,%s\r\n", head, encpass, tail); purple_debug_misc("msn", "Sending: {%s}\n", buffer); g_free(buffer); g_free(head); g_free(tail); g_free(username); g_free(encpass); nexus->write_buf = request_str; nexus->written_len = 0; nexus->read_len = 0; nexus->written_cb = nexus_login_written_cb; nexus->input_handler = purple_input_add(gsc->fd, PURPLE_INPUT_WRITE, nexus_write_cb, nexus); nexus_write_cb(nexus, gsc->fd, PURPLE_INPUT_WRITE); return; }
static JabberSaslState digest_md5_handle_challenge(JabberStream *js, PurpleXmlNode *packet, PurpleXmlNode **response, char **msg) { PurpleXmlNode *reply = NULL; char *enc_in = purple_xmlnode_get_data(packet); char *dec_in; char *enc_out; GHashTable *parts; JabberSaslState state = JABBER_SASL_STATE_CONTINUE; if (!enc_in) { *msg = g_strdup(_("Invalid response from server")); return JABBER_SASL_STATE_FAIL; } dec_in = (char *)purple_base64_decode(enc_in, NULL); purple_debug_misc("jabber", "decoded challenge (%" G_GSIZE_FORMAT "): %s\n", strlen(dec_in), dec_in); parts = jabber_auth_digest_md5_parse(dec_in); if (g_hash_table_lookup(parts, "rspauth")) { char *rspauth = g_hash_table_lookup(parts, "rspauth"); char *expected_rspauth = js->auth_mech_data; if (rspauth && purple_strequal(rspauth, expected_rspauth)) { reply = purple_xmlnode_new("response"); purple_xmlnode_set_namespace(reply, NS_XMPP_SASL); } else { *msg = g_strdup(_("Invalid challenge from server")); state = JABBER_SASL_STATE_FAIL; } g_free(js->auth_mech_data); js->auth_mech_data = NULL; } else { /* assemble a response, and send it */ /* see RFC 2831 */ char *realm; char *nonce; /* Make sure the auth string contains everything that should be there. This isn't everything in RFC2831, but it is what we need. */ nonce = g_hash_table_lookup(parts, "nonce"); /* we're actually supposed to prompt the user for a realm if * the server doesn't send one, but that really complicates things, * so i'm not gonna worry about it until is poses a problem to * someone, or I get really bored */ realm = g_hash_table_lookup(parts, "realm"); if(!realm) realm = js->user->domain; if (nonce == NULL || realm == NULL) { *msg = g_strdup(_("Invalid challenge from server")); state = JABBER_SASL_STATE_FAIL; } else { GString *response = g_string_new(""); char *a2; char *auth_resp; char *cnonce; cnonce = g_strdup_printf("%x%u%x", g_random_int(), (int)time(NULL), g_random_int()); a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm); auth_resp = generate_response_value(js->user, purple_connection_get_password(js->gc), nonce, cnonce, a2, realm); g_free(a2); a2 = g_strdup_printf(":xmpp/%s", realm); js->auth_mech_data = generate_response_value(js->user, purple_connection_get_password(js->gc), nonce, cnonce, a2, realm); g_free(a2); g_string_append_printf(response, "username=\"%s\"", js->user->node); g_string_append_printf(response, ",realm=\"%s\"", realm); g_string_append_printf(response, ",nonce=\"%s\"", nonce); g_string_append_printf(response, ",cnonce=\"%s\"", cnonce); g_string_append_printf(response, ",nc=00000001"); g_string_append_printf(response, ",qop=auth"); g_string_append_printf(response, ",digest-uri=\"xmpp/%s\"", realm); g_string_append_printf(response, ",response=%s", auth_resp); g_string_append_printf(response, ",charset=utf-8"); g_free(auth_resp); g_free(cnonce); enc_out = purple_base64_encode((guchar *)response->str, response->len); purple_debug_misc("jabber", "decoded response (%" G_GSIZE_FORMAT "): %s\n", response->len, response->str); reply = purple_xmlnode_new("response"); purple_xmlnode_set_namespace(reply, NS_XMPP_SASL); purple_xmlnode_insert_data(reply, enc_out, -1); g_free(enc_out); g_string_free(response, TRUE); } } g_free(enc_in); g_free(dec_in); g_hash_table_destroy(parts); *response = reply; return state; }
static void auth_old_cb(JabberStream *js, const char *from, JabberIqType type, const char *id, PurpleXmlNode *packet, gpointer data) { JabberIq *iq; PurpleXmlNode *query, *x; const char *pw = purple_connection_get_password(js->gc); if (type == JABBER_IQ_ERROR) { PurpleConnectionError reason = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; char *msg = jabber_parse_error(js, packet, &reason); purple_connection_error(js->gc, reason, msg); g_free(msg); } else if (type == JABBER_IQ_RESULT) { query = purple_xmlnode_get_child(packet, "query"); if (js->stream_id && *js->stream_id && purple_xmlnode_get_child(query, "digest")) { char *s, *hash; iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth"); query = purple_xmlnode_get_child(iq->node, "query"); x = purple_xmlnode_new_child(query, "username"); purple_xmlnode_insert_data(x, js->user->node, -1); x = purple_xmlnode_new_child(query, "resource"); purple_xmlnode_insert_data(x, js->user->resource, -1); x = purple_xmlnode_new_child(query, "digest"); s = g_strdup_printf("%s%s", js->stream_id, pw); hash = jabber_calculate_data_hash(s, strlen(s), "sha1"); purple_xmlnode_insert_data(x, hash, -1); g_free(hash); g_free(s); jabber_iq_set_callback(iq, auth_old_result_cb, NULL); jabber_iq_send(iq); } else if ((x = purple_xmlnode_get_child(query, "crammd5"))) { /* For future reference, this appears to be a custom OS X extension * to non-SASL authentication. */ const char *challenge; gchar digest[33]; PurpleCipher *hmac; PurpleHash *md5; gssize diglen; /* Calculate the MHAC-MD5 digest */ md5 = purple_md5_hash_new(); hmac = purple_hmac_cipher_new(md5); challenge = purple_xmlnode_get_attrib(x, "challenge"); purple_cipher_set_key(hmac, (guchar *)pw, strlen(pw)); purple_cipher_append(hmac, (guchar *)challenge, strlen(challenge)); diglen = purple_cipher_digest_to_str(hmac, digest, 33); g_object_unref(hmac); g_object_unref(md5); g_return_if_fail(diglen > 0); /* Create the response query */ iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth"); query = purple_xmlnode_get_child(iq->node, "query"); x = purple_xmlnode_new_child(query, "username"); purple_xmlnode_insert_data(x, js->user->node, -1); x = purple_xmlnode_new_child(query, "resource"); purple_xmlnode_insert_data(x, js->user->resource, -1); x = purple_xmlnode_new_child(query, "crammd5"); purple_xmlnode_insert_data(x, digest, 32); jabber_iq_set_callback(iq, auth_old_result_cb, NULL); jabber_iq_send(iq); } else if(purple_xmlnode_get_child(query, "password")) { PurpleAccount *account = purple_connection_get_account(js->gc); if(!jabber_stream_is_ssl(js) && !purple_account_get_bool(account, "auth_plain_in_clear", FALSE)) { char *msg = g_strdup_printf(_("%s requires plaintext authentication over an unencrypted connection. Allow this and continue authentication?"), purple_account_get_username(account)); purple_request_yes_no(js->gc, _("Plaintext Authentication"), _("Plaintext Authentication"), msg, 1, purple_request_cpar_from_account(account), account, allow_plaintext_auth, disallow_plaintext_auth); g_free(msg); return; } finish_plaintext_authentication(js); } else { purple_connection_error(js->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, _("Server does not use any supported authentication method")); return; } } }
void fetion_login(PurpleAccount * account) { PurpleConnection *gc; struct fetion_account_data *sip; gchar **userserver; gint ret; const char *username = purple_account_get_username(account); gc = purple_account_get_connection(account); gc->proto_data = sip = g_new0(struct fetion_account_data, 1); sip->gc = gc; sip->tg = 0; //temp group chat id sip->cseq = 0; sip->account = account; sip->registerexpire = 400; sip->reregister = time(NULL) + 100; sip->txbuf = purple_circ_buffer_new(0); sip->impresa = NULL; sip->icon_buf = purple_circ_buffer_new(0); sip->GetContactFlag = 0; purple_debug_info("Fetion:", "shit\n"); userserver = g_strsplit(username, "@", 2); purple_connection_set_display_name(gc, userserver[0]); if (IsCMccNo(userserver[0])) { sip->username = NULL; sip->mobileno = g_strdup(userserver[0]); } else { sip->mobileno = NULL; sip->username = g_strdup(userserver[0]); } // sip->servername = g_strdup(userserver[1]); sip->SysCfgServer = g_strdup("nav.fetion.com.cn"); sip->password = g_strdup(purple_connection_get_password(gc)); g_strfreev(userserver); sip->buddies = g_hash_table_new((GHashFunc) fetion_ht_hash_nick, (GEqualFunc) fetion_ht_equals_nick); sip->tempgroup = g_hash_table_new((GHashFunc) fetion_ht_hash_nick, (GEqualFunc) fetion_ht_equals_nick); sip->group = g_hash_table_new((GHashFunc) fetion_ht_hash_nick, (GEqualFunc) fetion_ht_equals_nick); sip->group2id = g_hash_table_new((GHashFunc) fetion_ht_hash_nick, (GEqualFunc) fetion_ht_equals_nick); purple_connection_update_progress(gc, _("Connecting"), 1, 2); /* TODO: Set the status correctly. */ sip->status = g_strdup("available"); sip->registertimeout = purple_timeout_add(60000, (GSourceFunc) LoginToSsiPortal, sip); //Try to get systemconfig sip->ServerVersion = NULL; sip->ServiceNoVersion = NULL; sip->ParaVersion = NULL; sip->HttpAppVersion = NULL; sip->ClientCfgVersion = NULL; sip->HintsVersion = NULL; ret = ParseCfg(sip); //if(ret!=0) sip->SysCfg.conn = purple_proxy_connect(NULL, sip->account, sip->SysCfgServer, 80, (PurpleProxyConnectFunction) RetriveSysCfg, sip); }
static JabberSaslState fb_handle_challenge(JabberStream *js, xmlnode *packet, xmlnode **response, char **msg) { xmlnode *reply = NULL; gchar *challenge; guchar *decoded; gsize decoded_len; gchar **pairs, *method, *nonce; gsize i; GString *request; gchar *enc_out; /* Get base64-encoded challenge from XML */ challenge = xmlnode_get_data(packet); if (challenge == NULL) { *msg = g_strdup(_("Invalid response from server")); return JABBER_SASL_STATE_FAIL; } /* Decode challenge */ decoded = purple_base64_decode(challenge, &decoded_len); if (decoded == NULL) { purple_debug_error("jabber", "X-FACEBOOK-PLATFORM challenge " "wasn't valid base64: %s\n", challenge); *msg = g_strdup(_("Invalid response from server")); g_free(challenge); return JABBER_SASL_STATE_FAIL; } g_free(challenge); /* NULL-terminate the challenge so we can parse it */ challenge = g_strndup((const gchar *)decoded, decoded_len); g_free(decoded); purple_debug_misc("jabber", "X-FACEBOOK-PLATFORM decoded " "challenge is %s\n", challenge); /* Get method and nonce */ method = NULL; nonce = NULL; pairs = g_strsplit(challenge, "&", 0); for (i = 0; pairs[i] != NULL; i++) { if (g_str_has_prefix(pairs[i], "method=")) { g_free(method); // TODO: Should url decode this value method = g_strdup(strchr(pairs[i], '=') + 1); } else if (g_str_has_prefix(pairs[i], "nonce=")) { g_free(nonce); // TODO: Should url decode this value nonce = g_strdup(strchr(pairs[i], '=') + 1); } } g_strfreev(pairs); if (!method || !nonce) { purple_debug_error("jabber", "X-FACEBOOK-PLATFORM challenge " "is missing method or nonce: %s\n", challenge); *msg = g_strdup(_("Invalid response from server")); g_free(method); g_free(nonce); g_free(challenge); return JABBER_SASL_STATE_FAIL; } g_free(challenge); request = purple_fbapi_construct_request(purple_connection_get_account(js->gc), method, "v", "1.0", "session_key", purple_connection_get_password(js->gc), "nonce", nonce, NULL); g_free(method); g_free(nonce); purple_debug_misc("jabber", "X-FACEBOOK-PLATFORM response before " "encoding is %s\n", request->str); enc_out = purple_base64_encode((const guchar *)request->str, request->len); g_string_free(request, TRUE); reply = xmlnode_new("response"); xmlnode_set_namespace(reply, NS_XMPP_SASL); xmlnode_insert_data(reply, enc_out, -1); g_free(enc_out); *response = reply; return JABBER_SASL_STATE_CONTINUE; }