static void purplemot_set_info(PurpleConnection *gc, const char *info) { purple_debug_info("purplemot", "setting %s's user info to %s\n", gc->account->username, info); }
void np_message_show_readable(NPMessage *msg, const char *info, gboolean text_body) { GString *str; size_t body_len; const char *body; GList *l; g_return_if_fail(msg != NULL); str = g_string_new(NULL); /* Standard header. */ if (msg->charset == NULL) { g_string_append_printf(str, "MIME-Version: 1.0\r\n" "Content-Type: %s\r\n", msg->content_type); } else { g_string_append_printf(str, "MIME-Version: 1.0\r\n" "Content-Type: %s; charset=%s\r\n", msg->content_type, msg->charset); } for (l = msg->header_list; l; l = l->next) { char *key; const char *value; key = l->data; value = np_message_get_header_value(msg, key); g_string_append_printf(str, "%s: %s\r\n", key, value); } g_string_append(str, "\r\n"); body = np_message_get_bin_data(msg, &body_len); if (body != NULL) { if (msg->type == NP_MSG_TEXT) { g_string_append_len(str, body, body_len); g_string_append(str, "\r\n"); } else { size_t i; for (i = 0; i < body_len; i++, body++) { g_string_append_printf(str, "%02x ", (unsigned char)*body); if (i % 16 == 0 && i != 0) g_string_append_c(str, '\n'); } g_string_append_c(str, '\n'); } } purple_debug_info("np", "Message %s:\n{%s}\n", info, str->str); g_string_free(str, TRUE); }
/*------------------------------------------------------------------------ * The user has selected to change their profile. * * @param gc The connection object * @param fields The fields from the request pop-up */ static void mxit_profile_cb( PurpleConnection* gc, PurpleRequestFields* fields ) { struct MXitSession* session = purple_connection_get_protocol_data( gc ); PurpleRequestField* field = NULL; const char* name = NULL; const char* bday = NULL; const char* err = NULL; GList* entry = NULL; purple_debug_info( MXIT_PLUGIN_ID, "mxit_profile_cb\n" ); PURPLE_ASSERT_CONNECTION_IS_VALID(gc); /* validate name */ name = purple_request_fields_get_string( fields, "name" ); if ( ( !name ) || ( strlen( name ) < 3 ) ) { err = _( "The Display Name you entered is invalid." ); goto out; } /* validate birthdate */ bday = purple_request_fields_get_string( fields, "bday" ); if ( ( !bday ) || ( strlen( bday ) < 10 ) || ( !validateDate( bday ) ) ) { err = _( "The birthday you entered is invalid. The correct format is: 'YYYY-MM-DD'." ); goto out; } out: if ( !err ) { struct MXitProfile* profile = session->profile; GString* attributes = g_string_sized_new( 128 ); char attrib[512]; unsigned int acount = 0; /* update name */ g_strlcpy( profile->nickname, name, sizeof( profile->nickname ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_FULLNAME, CP_PROFILE_TYPE_UTF8, profile->nickname ); g_string_append( attributes, attrib ); acount++; /* update birthday */ g_strlcpy( profile->birthday, bday, sizeof( profile->birthday ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_BIRTHDATE, CP_PROFILE_TYPE_UTF8, profile->birthday ); g_string_append( attributes, attrib ); acount++; /* update gender */ profile->male = ( purple_request_fields_get_choice( fields, "male" ) != 0 ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_GENDER, CP_PROFILE_TYPE_BOOL, ( profile->male ) ? "1" : "0" ); g_string_append( attributes, attrib ); acount++; /* update title */ name = purple_request_fields_get_string( fields, "title" ); if ( !name ) profile->title[0] = '\0'; else g_strlcpy( profile->title, name, sizeof( profile->title ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_TITLE, CP_PROFILE_TYPE_UTF8, profile->title ); g_string_append( attributes, attrib ); acount++; /* update firstname */ name = purple_request_fields_get_string( fields, "firstname" ); if ( !name ) profile->firstname[0] = '\0'; else g_strlcpy( profile->firstname, name, sizeof( profile->firstname ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_FIRSTNAME, CP_PROFILE_TYPE_UTF8, profile->firstname ); g_string_append( attributes, attrib ); acount++; /* update lastname */ name = purple_request_fields_get_string( fields, "lastname" ); if ( !name ) profile->lastname[0] = '\0'; else g_strlcpy( profile->lastname, name, sizeof( profile->lastname ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_LASTNAME, CP_PROFILE_TYPE_UTF8, profile->lastname ); g_string_append( attributes, attrib ); acount++; /* update email address */ name = purple_request_fields_get_string( fields, "email" ); if ( !name ) profile->email[0] = '\0'; else g_strlcpy( profile->email, name, sizeof( profile->email ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_EMAIL, CP_PROFILE_TYPE_UTF8, profile->email ); g_string_append( attributes, attrib ); acount++; /* update mobile number */ name = purple_request_fields_get_string( fields, "mobilenumber" ); if ( !name ) profile->mobilenr[0] = '\0'; else g_strlcpy( profile->mobilenr, name, sizeof( profile->mobilenr ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_MOBILENR, CP_PROFILE_TYPE_UTF8, profile->mobilenr ); g_string_append( attributes, attrib ); acount++; /* update about me */ name = purple_request_fields_get_string( fields, "aboutme" ); if ( !name ) profile->aboutme[0] = '\0'; else g_strlcpy( profile->aboutme, name, sizeof( profile->aboutme ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_ABOUTME, CP_PROFILE_TYPE_UTF8, profile->aboutme ); g_string_append( attributes, attrib ); acount++; /* update where am i */ name = purple_request_fields_get_string( fields, "whereami" ); if ( !name ) profile->whereami[0] = '\0'; else g_strlcpy( profile->whereami, name, sizeof( profile->whereami ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%s", CP_PROFILE_WHEREAMI, CP_PROFILE_TYPE_UTF8, profile->whereami ); g_string_append( attributes, attrib ); acount++; /* relationship status */ field = purple_request_fields_get_field( fields, "relationship" ); entry = g_list_first( purple_request_field_list_get_selected( field ) ); profile->relationship = atoi( purple_request_field_list_get_data( field, entry->data ) ); g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%i", CP_PROFILE_RELATIONSHIP, CP_PROFILE_TYPE_SHORT, profile->relationship ); g_string_append( attributes, attrib ); acount++; /* update flags */ field = purple_request_fields_get_field( fields, "searchable" ); if ( purple_request_field_bool_get_value( field ) ) /* is searchable -> clear not-searchable flag */ profile->flags &= ~CP_PROF_NOT_SEARCHABLE; else profile->flags |= CP_PROF_NOT_SEARCHABLE; field = purple_request_fields_get_field( fields, "suggestable" ); if ( purple_request_field_bool_get_value( field ) ) /* is suggestable -> clear not-suggestable flag */ profile->flags &= ~CP_PROF_NOT_SUGGESTABLE; else profile->flags |= CP_PROF_NOT_SUGGESTABLE; g_snprintf( attrib, sizeof( attrib ), "\01%s\01%i\01%" G_GINT64_FORMAT, CP_PROFILE_FLAGS, CP_PROFILE_TYPE_LONG, profile->flags); g_string_append( attributes, attrib ); acount++; /* send the profile update to MXit */ mxit_send_extprofile_update( session, NULL, acount, attributes->str ); g_string_free( attributes, TRUE ); } else { /* show error to user */ mxit_popup( PURPLE_NOTIFY_MSG_ERROR, _( "Profile Update Error" ), err ); } }
static void flist_global_profile_cb(FListWebRequestData *req_data, gpointer user_data, JsonObject *root, const gchar *error_message) { FListAccount *fla = user_data; FListProfiles *flp = _flist_profiles(fla); JsonObject *info; GList *categories, *cur; int i, len; flp->global_profile_request = NULL; if(!root) { purple_debug_warning(FLIST_DEBUG, "Failed to obtain the global list of profile fields. Error Message: %s\n", error_message); return; } info = json_object_get_object_member(root, "info"); if(!info) { purple_debug_warning(FLIST_DEBUG, "We received the global list of profile fields, but it was empty.\n"); return; } purple_debug_info(FLIST_DEBUG, "Processing global profile fields...\n"); flp->category_table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); categories = json_object_get_members(info); cur = categories; while(cur) { const gchar *group_name; JsonObject *field_group; JsonArray *field_array; FListProfileFieldCategory *category; guint i, len; field_group = json_object_get_object_member(info, cur->data); group_name = json_object_get_string_member(field_group, "group"); field_array = json_object_get_array_member(field_group, "items"); category = g_new0(FListProfileFieldCategory, 1); category->name = g_strdup(group_name); len = json_array_get_length(field_array); for(i = 0; i < len; i++) { JsonObject *field_object = json_array_get_object_element(field_array, i); FListProfileField *field = g_new0(FListProfileField, 1); field->category = category; field->fieldid = g_strdup_printf("%d", (gint) json_object_get_int_member(field_object, "id")); field->name = g_strdup(json_object_get_string_member(field_object, "name")); category->fields = g_slist_prepend(category->fields, field); if(fla->debug_mode) { purple_debug_info(FLIST_DEBUG, "Global profile field processed. (ID: %s) (Category: %s) (Name: %s)\n", field->fieldid, field->category->name, field->name); } } category->fields = g_slist_sort(category->fields, (GCompareFunc) flist_profile_field_cmp); flp->category_list = g_slist_append(flp->category_list, category); g_hash_table_insert(flp->category_table, category->name, category); cur = g_list_next(cur); } g_list_free(categories); purple_debug_info(FLIST_DEBUG, "We received the global list of profile fields. Total Categories: %d\n", g_hash_table_size(flp->category_table)); }
PurpleRoomlist * ggp_chat_roomlist_get_list(PurpleConnection *gc) { ggp_chat_session_data *sdata = ggp_chat_get_sdata(gc); PurpleRoomlist *roomlist; GList *fields = NULL; int i; purple_debug_info("gg", "ggp_chat_roomlist_get_list\n"); roomlist = purple_roomlist_new(purple_connection_get_account(gc)); fields = g_list_append(fields, purple_roomlist_field_new( PURPLE_ROOMLIST_FIELD_STRING, _("Conference identifier"), "id", TRUE)); fields = g_list_append(fields, purple_roomlist_field_new( PURPLE_ROOMLIST_FIELD_STRING, _("Start Date"), "date", FALSE)); fields = g_list_append(fields, purple_roomlist_field_new( PURPLE_ROOMLIST_FIELD_INT, _("User Count"), "users", FALSE)); fields = g_list_append(fields, purple_roomlist_field_new( PURPLE_ROOMLIST_FIELD_STRING, _("Status"), "status", FALSE)); purple_roomlist_set_fields(roomlist, fields); for (i = sdata->chats_count - 1; i >= 0 ; i--) { PurpleRoomlistRoom *room; ggp_chat_local_info *chat = &sdata->chats[i]; const gchar *name; time_t date; const gchar *status; int count = chat->participants_count; date = (uint32_t)(chat->id >> 32); if (chat->conv) status = _("Joined"); else if (chat->left) /* Translators: For Gadu-Gadu, this is one possible status for a chat room. It means you had previously joined the chat room but you have since left it. You cannot rejoin without another invitation. */ status = _("Chat left"); else { status = _("Can join chat"); count--; } name = ggp_chat_get_name_from_id(chat->id); room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, name, NULL); purple_roomlist_room_add_field(roomlist, room, name); purple_roomlist_room_add_field(roomlist, room, purple_date_format_full(localtime(&date))); purple_roomlist_room_add_field(roomlist, room, GINT_TO_POINTER(count)); purple_roomlist_room_add_field(roomlist, room, status); purple_roomlist_room_add(roomlist, room); } /* TODO * purple_roomlist_set_in_progress(roomlist, FALSE); */ g_object_ref(roomlist); purple_timeout_add(1, ggp_chat_roomlist_get_list_finish, roomlist); return roomlist; }
static void cipher_test_pbkdf2(void) { PurpleCipher *cipher; PurpleHash *hash; int i = 0; gboolean fail = FALSE; purple_debug_info("cipher-test", "Running PBKDF2 tests\n"); while (!fail && pbkdf2_tests[i].answer) { pbkdf2_test *test = &pbkdf2_tests[i]; gchar digest[2 * 32 + 1 + 10]; gchar *digest_nss = NULL; gboolean ret, skip_nss = FALSE; i++; purple_debug_info("cipher-test", "Test %02d:\n", i); purple_debug_info("cipher-test", "\tTesting '%s' with salt:'%s' hash:%s iter_count:%d \n", test->passphrase, test->salt, test->hash, test->iter_count); if (!strcmp(test->hash, "sha1")) hash = purple_sha1_hash_new(); else if (!strcmp(test->hash, "sha256")) hash = purple_sha256_hash_new(); else hash = NULL; cipher = purple_pbkdf2_cipher_new(hash); g_object_set(G_OBJECT(cipher), "iter_count", GUINT_TO_POINTER(test->iter_count), NULL); g_object_set(G_OBJECT(cipher), "out_len", GUINT_TO_POINTER(test->out_len), NULL); purple_cipher_set_salt(cipher, (const guchar*)test->salt, test->salt ? strlen(test->salt): 0); purple_cipher_set_key(cipher, (const guchar*)test->passphrase, strlen(test->passphrase)); ret = purple_cipher_digest_to_str(cipher, digest, sizeof(digest)); purple_cipher_reset(cipher); if (!ret) { purple_debug_info("cipher-test", "\tfailed\n"); fail = TRUE; g_object_unref(cipher); g_object_unref(hash); continue; } if (g_strcmp0(test->hash, "sha1") != 0) skip_nss = TRUE; if (test->out_len != 16 && test->out_len != 32) skip_nss = TRUE; #ifdef HAVE_NSS if (!skip_nss) { digest_nss = cipher_pbkdf2_nss_sha1(test->passphrase, test->salt, test->iter_count, test->out_len); } #else skip_nss = TRUE; #endif purple_debug_info("cipher-test", "\tGot: %s\n", digest); if (digest_nss) purple_debug_info("cipher-test", "\tGot from NSS: %s\n", digest_nss); purple_debug_info("cipher-test", "\tWanted: %s\n", test->answer); if (g_strcmp0(digest, test->answer) == 0 && (skip_nss || g_strcmp0(digest, digest_nss) == 0)) { purple_debug_info("cipher-test", "\tTest OK\n"); } else { purple_debug_info("cipher-test", "\twrong answer\n"); fail = TRUE; } g_object_unref(cipher); g_object_unref(hash); } if (fail) purple_debug_info("cipher-test", "PBKDF2 tests FAILED\n\n"); else purple_debug_info("cipher-test", "PBKDF2 tests completed successfully\n\n"); }
static void om_got_events(OmegleAccount *oma, gchar *response, gsize len, gpointer userdata) { //[["waiting"], ["connected"]] gchar *who = userdata; const gchar *message; const gchar *event_type; JsonParser *parser; JsonNode *rootnode, *currentnode; JsonArray *array, *current; guint i; purple_debug_info("omegle", "got events: %s\n", response?response:"(null)"); if (!response || g_str_equal(response, "null")) { g_free(who); return; } parser = json_parser_new(); json_parser_load_from_data(parser, response, len, NULL); rootnode = json_parser_get_root(parser); if (!rootnode) { g_object_unref(parser); return; } array = json_node_get_array(rootnode); for(i=0; i<json_array_get_length(array); i++) { currentnode = json_array_get_element(array, i); current = json_node_get_array(currentnode); event_type = json_node_get_string(json_array_get_element(current, 0)); if (!event_type) { continue; } else if (g_str_equal(event_type, "waiting")) { serv_got_im(oma->pc, who, "Looking for someone you can chat with. Hang on.", PURPLE_MESSAGE_SYSTEM, time(NULL)); } else if (g_str_equal(event_type, "connected")) { serv_got_im(oma->pc, who, "You're now chatting with a random stranger. Say hi!", PURPLE_MESSAGE_SYSTEM, time(NULL)); } else if (g_str_equal(event_type, "gotMessage")) { //[["gotMessage","message goes here"]] message = json_node_get_string(json_array_get_element(current, 1)); if (message) serv_got_im(oma->pc, who, message, PURPLE_MESSAGE_RECV, time(NULL)); } else if (g_str_equal(event_type, "typing")) { serv_got_typing(oma->pc, who, 10, PURPLE_TYPING); } else if (g_str_equal(event_type, "stoppedTyping")) { serv_got_typing(oma->pc, who, 10, PURPLE_TYPED); } else if (g_str_equal(event_type, "strangerDisconnected")) { serv_got_im(oma->pc, who, "Your conversational partner has disconnected", PURPLE_MESSAGE_SYSTEM, time(NULL)); } } om_fetch_events(oma, g_strdup(who)); g_free(who); g_object_unref(parser); }
static void purplemot_remove_group(PurpleConnection *gc, PurpleGroup *group) { purple_debug_info("purplemot", "%s has removed group %s\n", gc->account->username, group->name); }
static void purplemot_roomlist_cancel(PurpleRoomlist *list) { purple_debug_info("purplemot", "%s asked to cancel room list request\n", list->account->username); }
static void purplemot_alias_buddy(PurpleConnection *gc, const char *who, const char *alias) { purple_debug_info("purplemot", "%s sets %s's alias to %s\n", gc->account->username, who, alias); }
static void purplemot_convo_closed(PurpleConnection *gc, const char *who) { purple_debug_info("purplemot", "%s's conversation with %s was closed\n", gc->account->username, who); }
static void purplemot_register_user(PurpleAccount *acct) { purple_debug_info("purplemot", "registering account for %s\n", acct->username); }
static void purplemot_rem_deny(PurpleConnection *gc, const char *name) { purple_debug_info("purplemot", "%s removes %s from their blocked list\n", gc->account->username, name); }
static void purplemot_add_deny(PurpleConnection *gc, const char *name) { purple_debug_info("purplemot", "%s adds %s to their blocked list\n", gc->account->username, name); }
static void waprpl_process_incoming_events(PurpleConnection * gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending authorization", 1, 4); break; case 2: purple_connection_update_progress(gc, "Awaiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connection established", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; PurpleAccount *account = purple_connection_get_account(gc); PurpleStatus *status = purple_account_get_active_status(account); waprpl_set_status(account, status); break; default: break; }; char *msg, *who, *prev, *url, *author; int status; int size; double lat, lng; unsigned long timestamp; /* Incoming messages */ while (1) { int r = waAPI_querynext(wconn->waAPI); switch (r) { case 0: if (waAPI_querychat(wconn->waAPI, &who, &msg, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who, msg); conv_add_message(gc, who, msg, author, timestamp); } break; case 1: if (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who, url); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); char *msg = g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a><br/><a href=\"%s\">%s</a>", url, imgid, url, url); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; case 2: if (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who, (float)lat, (float)lng); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); char *msg = g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>", lat, lng, imgid); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; case 3: if (waAPI_querychatsound(wconn->waAPI, &who, &url, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who, url); char *msg = g_strdup_printf("<a href=\"%s\">%s</a>", url, url); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; default: break; }; if (r < 0) break; } /* User status change */ while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message", "", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message", "", NULL); } } /* User typing info notify */ while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { purple_debug_info(WHATSAPP_ID, "%s is typing\n", who); serv_got_typing(gc, who, 0, PURPLE_TYPING); } else { purple_debug_info(WHATSAPP_ID, "%s is not typing\n", who); serv_got_typing(gc, who, 0, PURPLE_NOT_TYPING); serv_got_typing_stopped(gc, who); } } /* User profile picture */ char *icon, *hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc, who, g_memdup(icon, len), len, hash); } /* Groups update */ if (waAPI_getgroupsupdated(wconn->waAPI)) { /* Delete/update the chats that are in our list */ PurpleBlistNode *node; for (node = purple_blist_get_root(); node; node = purple_blist_node_next(node, FALSE)) { if (!PURPLE_BLIST_NODE_IS_CHAT(node)) continue; PurpleChat *ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) != acc) continue; GHashTable *hasht = purple_chat_get_components(ch); char *grid = g_hash_table_lookup(hasht, "id"); char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); if (str_array_find(gplist, grid) >= 0) { /* The group is in the system, update the fields */ char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, grid, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); } else { /* The group was deleted */ PurpleChat *del = (PurpleChat *) node; node = purple_blist_node_next(node, FALSE); purple_blist_remove_chat(del); } g_strfreev(gplist); } /* Add new groups */ char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); gchar **p; for (p = gplist; *p; p++) { gchar *gpid = *p; PurpleChat *ch = blist_find_chat_by_id(gc, gpid); if (!ch) { char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, gpid, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", gpid, sub); GHashTable *htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(gpid)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc, sub, htable); purple_blist_add_chat(ch, NULL, NULL); } /* Now update the open conversation that may exist */ char *id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation *conv = purple_find_chat(gc, prplid); char *subject, *owner, *part; if (conv && waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) conv_add_participants(conv, part, owner); } g_strfreev(gplist); } }
void AddMobileBuddy(struct fetion_account_data *sip,struct sipmsg *msg ,struct transaction *tc) { gint xml_len; xmlnode *root,*son,*item; gchar *body; const gchar *uri, *name ,*group_id; struct group_attr *g_attr=NULL; gchar *buddy_name; PurpleBuddy *b; PurpleGroup *g = NULL; struct fetion_buddy *bs; struct sipmsg *old=NULL; const gchar *real_name; real_name = purple_account_get_string(sip->account, "realname", sip->username); if(!real_name || strlen(real_name) < 1) { real_name = sip->username; } g_return_if_fail(tc->msg!=NULL); old = tc->msg; g_return_if_fail(old!=NULL); purple_debug_info("fetion:","AddMobileBuddy:oldmsg[%s]",old->body); root = xmlnode_from_str(old->body, old->bodylen); item = xmlnode_get_child(root,"contacts/buddies/buddy"); g_return_if_fail(item!=NULL); uri = xmlnode_get_attrib(item, "uri"); name = xmlnode_get_attrib(item, "local-name"); group_id = xmlnode_get_attrib(item, "buddy-lists"); buddy_name = g_strdup_printf("%s", uri); g_attr = g_hash_table_lookup(sip->group,group_id); g_return_if_fail(g_attr!=NULL); g = purple_find_group(g_attr->name); if(!g) g = purple_group_new(g_attr->name); b = purple_find_buddy(sip->account, buddy_name); if(!b){ b = purple_buddy_new(sip->account, buddy_name, NULL); } purple_blist_add_buddy(b, NULL, g, NULL); if(name!=NULL && *name!='\0') purple_blist_alias_buddy(b, name); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); xmlnode_free(root); root = xmlnode_new("args"); g_return_if_fail(root!=NULL); son = xmlnode_new_child(root,"contacts"); g_return_if_fail(son!=NULL); son = xmlnode_new_child(son,"mobile-buddies"); g_return_if_fail(son!=NULL); item = xmlnode_new_child(son,"mobile-buddy"); g_return_if_fail(item!=NULL); xmlnode_set_attrib(item,"expose-mobile-no","1"); xmlnode_set_attrib(item,"expose-name","1"); xmlnode_set_attrib(item,"invite","1"); xmlnode_set_attrib(item,"uri",buddy_name); xmlnode_set_attrib(item,"buddy-lists","1"); //xmlnode_set_attrib(item,"desc",sip->mobileno); xmlnode_set_attrib(item,"desc",real_name); body = g_strdup_printf(xmlnode_to_str(root,&xml_len)); purple_debug_info("fetion:","add_buddy:body=[%s]",body); send_sip_request(sip->gc,"S","","","N: AddMobileBuddy\r\n",body,NULL,(TransCallback) AddMobileBuddy_cb); g_free(buddy_name); xmlnode_free(root); g_free(body); }
static void skypeweb_close(PurpleConnection *pc) { SkypeWebAccount *sa; GSList *buddies; g_return_if_fail(pc != NULL); sa = purple_connection_get_protocol_data(pc); g_return_if_fail(sa != NULL); purple_timeout_remove(sa->authcheck_timeout); purple_timeout_remove(sa->poll_timeout); purple_timeout_remove(sa->watchdog_timeout); skypeweb_logout(sa); purple_signal_disconnect(purple_conversations_get_handle(), "conversation-updated", pc, PURPLE_CALLBACK(skypeweb_mark_conv_seen)); purple_debug_info("skypeweb", "destroying %d waiting connections\n", g_queue_get_length(sa->waiting_conns)); while (!g_queue_is_empty(sa->waiting_conns)) skypeweb_connection_destroy(g_queue_pop_tail(sa->waiting_conns)); g_queue_free(sa->waiting_conns); purple_debug_info("skypeweb", "destroying %d incomplete connections\n", g_slist_length(sa->conns)); while (sa->conns != NULL) skypeweb_connection_destroy(sa->conns->data); while (sa->dns_queries != NULL) { PurpleDnsQueryData *dns_query = sa->dns_queries->data; purple_debug_info("skypeweb", "canceling dns query for %s\n", purple_dnsquery_get_host(dns_query)); sa->dns_queries = g_slist_remove(sa->dns_queries, dns_query); purple_dnsquery_destroy(dns_query); } while (sa->url_datas) { purple_util_fetch_url_cancel(sa->url_datas->data); sa->url_datas = g_slist_delete_link(sa->url_datas, sa->url_datas); } buddies = purple_find_buddies(sa->account, NULL); while (buddies != NULL) { PurpleBuddy *buddy = buddies->data; skypeweb_buddy_free(buddy); purple_buddy_set_protocol_data(buddy, NULL); buddies = g_slist_delete_link(buddies, buddies); } g_hash_table_destroy(sa->sent_messages_hash); g_hash_table_destroy(sa->cookie_table); g_hash_table_destroy(sa->hostname_ip_cache); g_free(sa->messages_host); g_free(sa->skype_token); g_free(sa->registration_token); g_free(sa->endpoint); g_free(sa->username); g_free(sa); }
gboolean GetContactList_cb(struct fetion_account_data *sip, struct sipmsg *msg, struct transaction *tc) { xmlnode *item, *group, *isc; const gchar *name_group,*group_id; PurpleBuddy *b; PurpleGroup *g = NULL; struct fetion_buddy *bs; struct group_attr *g_attr; gint len = msg->bodylen; purple_debug(PURPLE_DEBUG_MISC, "fetion", "in process GetContactList response response: %d\n", msg->response); switch (msg->response) { case 200: /*Convert the contact from XML to Purple Buddies*/ isc = xmlnode_from_str(msg->body, len); purple_debug_info("fetion:","after xmlnode to str\n"); group = xmlnode_get_child(isc,"contacts/buddy-lists"); g_return_val_if_fail(group!=NULL,FALSE); /* ToDo. Find for all groups */ sip->GetContactFlag = 1; for((group = xmlnode_get_child(group, "buddy-list"));group;group = xmlnode_get_next_twin(group)) { purple_debug_info("fetion:","buddy-list\n"); name_group = xmlnode_get_attrib(group, "name"); group_id = xmlnode_get_attrib(group, "id"); g_return_val_if_fail(name_group!=NULL,FALSE); purple_debug_info("fetion", "name_group->%s\n", name_group); g = purple_find_group(name_group); if(!g) { g = purple_group_new(name_group); } g_attr= g_new0(struct group_attr,1); g_attr->name = g_strdup(name_group); g_attr->id = g_strdup(group_id); g_hash_table_insert(sip->group,g_attr->id,g_attr); g_hash_table_insert(sip->group2id,g_attr->name,g_attr); } group = xmlnode_get_child(isc,"contacts/buddies"); g_return_val_if_fail(group!=NULL,FALSE); for(item = xmlnode_get_child(group, "buddy"); item; item = xmlnode_get_next_twin(item)) { const gchar *uri, *name ; char *buddy_name; const gchar *g_id; uri = xmlnode_get_attrib(item, "uri"); name = xmlnode_get_attrib(item, "local-name"); g_id = xmlnode_get_attrib(item,"buddy-lists"); buddy_name = g_strdup_printf("%s", uri); if((g_id==NULL) ||(*g_id=='\0')||strlen(g_id)>1) { g = purple_find_group("未分组"); if(!g) g = purple_group_new("未分组"); } else { g_attr = g_hash_table_lookup(sip->group,g_id); g_return_val_if_fail(g_attr!=NULL,FALSE); g = purple_find_group(g_attr->name); if(!g) g = purple_group_new(g_attr->name); } b = purple_find_buddy(sip->account, buddy_name); if(!b){ b = purple_buddy_new(sip->account, buddy_name, NULL); } g_free(buddy_name); purple_blist_add_buddy(b, NULL, g, NULL); if(name!=NULL && *name!='\0') purple_blist_alias_buddy(b, name); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); purple_prpl_got_user_status(sip->account,uri,"mobile",NULL); } group = xmlnode_get_child(isc,"contacts/mobile-buddies"); g_return_val_if_fail(group!=NULL,FALSE); for(item = xmlnode_get_child(group, "mobile-buddy"); item; item = xmlnode_get_next_twin(item)) { const gchar *uri, *name ; gchar *buddy_name; const gchar *g_id; uri = xmlnode_get_attrib(item, "uri"); name = xmlnode_get_attrib(item, "local-name"); g_id = xmlnode_get_attrib(item, "buddy-lists"); buddy_name = g_strdup_printf("%s", uri); if((g_id==NULL) ||(*g_id=='\0')||strlen(g_id)>1) { g = purple_find_group("未分组"); if(!g) g = purple_group_new("未分组"); } else { g_attr = g_hash_table_lookup(sip->group,g_id); //g_return_val_if_fail(g_attr!=NULL,FALSE); if(g_attr==NULL) continue; g = purple_find_group(g_attr->name); if(!g) g = purple_group_new(g_attr->name); } b = purple_find_buddy(sip->account, buddy_name); if(!b){ b = purple_buddy_new(sip->account, buddy_name, uri); } g_free(buddy_name); purple_blist_add_buddy(b, NULL, g, NULL); if(name!=NULL && *name!='\0') purple_blist_alias_buddy(b, name); else purple_blist_alias_buddy(b, uri); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); purple_prpl_got_user_status(sip->account,uri,"mobile",NULL); } fetion_subscribe_exp(sip,NULL); //Add youself b = purple_find_buddy(sip->account, sip->uri); if(!b){ b = purple_buddy_new(sip->account, sip->uri, NULL); } purple_blist_add_buddy(b, NULL, g, NULL); purple_blist_alias_buddy(b, "轰炸自己"); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); purple_prpl_got_user_status(sip->account,sip->uri,"mobile",NULL); xmlnode_free(isc); break; default: GetContactList(sip); break; } return TRUE; }
static void cipher_test_aes(void) { PurpleCipher *cipher; int i = 0; gboolean fail = FALSE; purple_debug_info("cipher-test", "Running AES tests\n"); cipher = purple_aes_cipher_new(); if (cipher == NULL) { purple_debug_error("cipher-test", "AES cipher not found\n"); fail = TRUE; } while (!fail && aes_tests[i].cipher) { aes_test *test = &aes_tests[i]; gsize key_size; guchar *key; guchar cipher_s[1024], decipher_s[1024]; ssize_t cipher_len, decipher_len; gchar *cipher_b16, *deciphered; purple_debug_info("cipher-test", "Test %02d:\n", i); purple_debug_info("cipher-test", "\tTesting '%s' (%" G_GSIZE_FORMAT "bit) \n", test->plaintext ? test->plaintext : "(null)", strlen(test->key) * 8 / 2); i++; purple_cipher_reset(cipher); if (test->iv) { gsize iv_size; guchar *iv = purple_base16_decode(test->iv, &iv_size); g_assert(iv != NULL); purple_cipher_set_iv(cipher, iv, iv_size); g_free(iv); } key = purple_base16_decode(test->key, &key_size); g_assert(key != NULL); purple_cipher_set_key(cipher, key, key_size); g_free(key); if (purple_cipher_get_key_size(cipher) != key_size) { purple_debug_info("cipher-test", "\tinvalid key size\n"); fail = TRUE; continue; } cipher_len = purple_cipher_encrypt(cipher, (const guchar*)(test->plaintext ? test->plaintext : ""), test->plaintext ? (strlen(test->plaintext) + 1) : 0, cipher_s, sizeof(cipher_s)); if (cipher_len < 0) { purple_debug_info("cipher-test", "\tencryption failed\n"); fail = TRUE; continue; } cipher_b16 = purple_base16_encode(cipher_s, cipher_len); purple_debug_info("cipher-test", "\tGot: %s\n", cipher_b16); purple_debug_info("cipher-test", "\tWanted: %s\n", test->cipher); if (g_strcmp0(cipher_b16, test->cipher) != 0) { purple_debug_info("cipher-test", "\tencrypted data doesn't match\n"); g_free(cipher_b16); fail = TRUE; continue; } g_free(cipher_b16); decipher_len = purple_cipher_decrypt(cipher, cipher_s, cipher_len, decipher_s, sizeof(decipher_s)); if (decipher_len < 0) { purple_debug_info("cipher-test", "\tdecryption failed\n"); fail = TRUE; continue; } deciphered = (decipher_len > 0) ? (gchar*)decipher_s : NULL; if (g_strcmp0(deciphered, test->plaintext) != 0) { purple_debug_info("cipher-test", "\tdecrypted data doesn't match\n"); fail = TRUE; continue; } purple_debug_info("cipher-test", "\tTest OK\n"); } if (cipher != NULL) g_object_unref(cipher); if (fail) purple_debug_info("cipher-test", "AES tests FAILED\n\n"); else purple_debug_info("cipher-test", "AES tests completed successfully\n\n"); }
void purple_info(const std::string &msg) { purple_debug_info(PLUGIN_ID, "%s\n", msg.c_str()); }
/* return TRUE if avatar update was performed or there is no new requests, FALSE if we can request another one immediately */ static gboolean ggp_avatar_buddy_update_next(PurpleConnection *gc) { PurpleHttpRequest *req; ggp_avatar_session_data *avdata = ggp_avatar_get_avdata(gc); GList *pending_update_it; ggp_avatar_buddy_update_req *pending_update; PurpleBuddy *buddy; PurpleAccount *account = purple_connection_get_account(gc); time_t old_timestamp; const char *old_timestamp_str; pending_update_it = g_list_first(avdata->pending_updates); if (pending_update_it == NULL) return TRUE; pending_update = pending_update_it->data; avdata->pending_updates = g_list_remove(avdata->pending_updates, pending_update); buddy = purple_blist_find_buddy(account, ggp_uin_to_str(pending_update->uin)); if (!buddy) { if (ggp_str_to_uin(purple_account_get_username(account)) == pending_update->uin) { purple_debug_misc("gg", "ggp_avatar_buddy_update_next(%p): own " "avatar update requested, but we don't have " "ourselves on buddy list\n", gc); } else { purple_debug_warning("gg", "ggp_avatar_buddy_update_next(%p): " "%u update requested, but he's not on buddy " "list\n", gc, pending_update->uin); } return FALSE; } old_timestamp_str = purple_buddy_icons_get_checksum_for_user(buddy); old_timestamp = old_timestamp_str ? g_ascii_strtoull( old_timestamp_str, NULL, 10) : 0; if (old_timestamp == pending_update->timestamp) { if (purple_debug_is_verbose()) { purple_debug_misc("gg", "ggp_avatar_buddy_update_next(%p): " "%u have up to date avatar with ts=%lu\n", gc, pending_update->uin, pending_update->timestamp); } return FALSE; } if (old_timestamp > pending_update->timestamp) { purple_debug_warning("gg", "ggp_avatar_buddy_update_next(%p): " "saved timestamp for %u is newer than received " "(%lu > %lu)\n", gc, pending_update->uin, old_timestamp, pending_update->timestamp); } purple_debug_info("gg", "ggp_avatar_buddy_update_next(%p): " "updating %u with ts=%lu...\n", gc, pending_update->uin, pending_update->timestamp); pending_update->gc = gc; avdata->current_update = pending_update; req = purple_http_request_new(NULL); purple_http_request_set_url_printf(req, GGP_AVATAR_BUDDY_URL, pending_update->uin); purple_http_request_header_set(req, "User-Agent", GGP_AVATAR_USERAGENT); purple_http_request_set_max_len(req, GGP_AVATAR_SIZE_MAX); pending_update->request = purple_http_request(gc, req, ggp_avatar_buddy_update_received, pending_update); purple_http_request_unref(req); return TRUE; }
static void ssl_gnutls_handshake_cb(gpointer data, gint source, PurpleInputCondition cond) { PurpleSslConnection *gsc = data; PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc); ssize_t ret; /*purple_debug_info("gnutls", "Handshaking with %s\n", gsc->host);*/ ret = gnutls_handshake(gnutls_data->session); if(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) return; purple_input_remove(gnutls_data->handshake_handler); gnutls_data->handshake_handler = 0; if(ret != 0) { purple_debug_error("gnutls", "Handshake failed. Error %s\n", gnutls_strerror(ret)); if(gsc->error_cb != NULL) gsc->error_cb(gsc, PURPLE_SSL_HANDSHAKE_FAILED, gsc->connect_cb_data); purple_ssl_close(gsc); } else { /* Now we are cooking with gas! */ PurpleSslOps *ops = purple_ssl_get_ops(); GList * peers = ops->get_peer_certificates(gsc); PurpleCertificateScheme *x509 = purple_certificate_find_scheme("x509"); GList * l; /* TODO: Remove all this debugging babble */ purple_debug_info("gnutls", "Handshake complete\n"); for (l=peers; l; l = l->next) { PurpleCertificate *crt = l->data; GByteArray *z = x509->get_fingerprint_sha1(crt); gchar * fpr = purple_base16_encode_chunked(z->data, z->len); purple_debug_info("gnutls/x509", "Key print: %s\n", fpr); /* Kill the cert! */ x509->destroy_certificate(crt); g_free(fpr); g_byte_array_free(z, TRUE); } g_list_free(peers); { const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; gnutls_session_t session=gnutls_data->session; guint i; cert_list = gnutls_certificate_get_peers(session, &cert_list_size); purple_debug_info("gnutls", "Peer provided %d certs\n", cert_list_size); for (i=0; i<cert_list_size; i++) { gchar fpr_bin[256]; gsize fpr_bin_sz = sizeof(fpr_bin); gchar * fpr_asc = NULL; gchar tbuf[256]; gsize tsz=sizeof(tbuf); gchar * tasc = NULL; gnutls_x509_crt_t cert; gnutls_x509_crt_init(&cert); gnutls_x509_crt_import (cert, &cert_list[i], GNUTLS_X509_FMT_DER); gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA, fpr_bin, &fpr_bin_sz); fpr_asc = purple_base16_encode_chunked((const guchar *)fpr_bin, fpr_bin_sz); purple_debug_info("gnutls", "Lvl %d SHA1 fingerprint: %s\n", i, fpr_asc); tsz=sizeof(tbuf); gnutls_x509_crt_get_serial(cert,tbuf,&tsz); tasc=purple_base16_encode_chunked((const guchar *)tbuf, tsz); purple_debug_info("gnutls", "Serial: %s\n", tasc); g_free(tasc); tsz=sizeof(tbuf); gnutls_x509_crt_get_dn (cert, tbuf, &tsz); purple_debug_info("gnutls", "Cert DN: %s\n", tbuf); tsz=sizeof(tbuf); gnutls_x509_crt_get_issuer_dn (cert, tbuf, &tsz); purple_debug_info("gnutls", "Cert Issuer DN: %s\n", tbuf); g_free(fpr_asc); fpr_asc = NULL; gnutls_x509_crt_deinit(cert); } } /* TODO: The following logic should really be in libpurple */ /* If a Verifier was given, hand control over to it */ if (gsc->verifier) { GList *peers; /* First, get the peer cert chain */ peers = purple_ssl_get_peer_certificates(gsc); /* Now kick off the verification process */ purple_certificate_verify(gsc->verifier, gsc->host, peers, ssl_gnutls_verified_cb, gsc); purple_certificate_destroy_list(peers); } else { /* Otherwise, just call the "connection complete" callback */ gsc->connect_cb(gsc->connect_cb_data, gsc, cond); } } }
void qq_process_question(PurpleConnection *gc, guint8 *data, gint data_len, guint32 uid) { gint bytes; guint8 cmd, reply; gchar *question, *answer; guint16 code_len; guint8 *code; g_return_if_fail(data != NULL && data_len != 0); qq_show_packet("qq_process_question", data, data_len); bytes = 0; bytes += qq_get8(&cmd, data + bytes); if (cmd == QQ_QUESTION_GET) { bytes += qq_get_vstr(&question, QQ_CHARSET_DEFAULT, sizeof(guint8), data + bytes); bytes += qq_get_vstr(&answer, QQ_CHARSET_DEFAULT, sizeof(guint8), data + bytes); purple_debug_info("QQ", "Get buddy adding Q&A:\n%s\n%s\n", question, answer); g_free(question); g_free(answer); return; } if (cmd == QQ_QUESTION_SET) { bytes += qq_get8(&reply, data + bytes); if (reply == 0) { purple_debug_info("QQ", "Successed setting Q&A\n"); } else { purple_debug_warning("QQ", "Failed setting Q&A, reply %d\n", reply); } return; } g_return_if_fail(uid != 0); bytes += 2; /* skip 2 bytes, 0x(00 01)*/ if (cmd == QQ_QUESTION_REQUEST) { bytes += qq_get8(&reply, data + bytes); if (reply == 0x01) { purple_debug_warning("QQ", "Failed getting question, reply %d\n", reply); return; } bytes += qq_get_vstr(&question, QQ_CHARSET_DEFAULT, sizeof(guint8), data + bytes); purple_debug_info("QQ", "Get buddy question:\n%s\n", question); add_buddy_question_input(gc, uid, question); g_free(question); return; } if (cmd == QQ_QUESTION_ANSWER) { bytes += qq_get8(&reply, data + bytes); if (reply == 0x01) { purple_notify_error(gc, _("Add Buddy"), _("Invalid answer."), NULL); return; } bytes += qq_get16(&code_len, data + bytes); g_return_if_fail(code_len > 0); g_return_if_fail(bytes + code_len <= data_len); code = g_newa(guint8, code_len); bytes += qq_getdata(code, code_len, data + bytes); qq_request_add_buddy_by_question(gc, uid, code, code_len); return; } g_return_if_reached(); }
/** Determines whether one certificate has been issued and signed by another * * @param crt Certificate to check the signature of * @param issuer Issuer's certificate * * @return TRUE if crt was signed and issued by issuer, otherwise FALSE * @TODO Modify this function to return a reason for invalidity? */ static gboolean x509_certificate_signed_by(PurpleCertificate * crt, PurpleCertificate * issuer) { gnutls_x509_crt_t crt_dat; gnutls_x509_crt_t issuer_dat; unsigned int verify; /* used to store result from GnuTLS verifier */ int ret; gchar *crt_id = NULL; gchar *issuer_id = NULL; g_return_val_if_fail(crt, FALSE); g_return_val_if_fail(issuer, FALSE); /* Verify that both certs are the correct scheme */ g_return_val_if_fail(crt->scheme == &x509_gnutls, FALSE); g_return_val_if_fail(issuer->scheme == &x509_gnutls, FALSE); /* TODO: check for more nullness? */ crt_dat = X509_GET_GNUTLS_DATA(crt); issuer_dat = X509_GET_GNUTLS_DATA(issuer); /* Ensure crt issuer matches the name on the issuer cert. */ ret = gnutls_x509_crt_check_issuer(crt_dat, issuer_dat); if (ret <= 0) { if (ret < 0) { purple_debug_error("gnutls/x509", "GnuTLS error %d while checking certificate issuer match.", ret); } else { gchar *crt_id, *issuer_id, *crt_issuer_id; crt_id = purple_certificate_get_unique_id(crt); issuer_id = purple_certificate_get_unique_id(issuer); crt_issuer_id = purple_certificate_get_issuer_unique_id(crt); purple_debug_info("gnutls/x509", "Certificate %s is issued by " "%s, which does not match %s.\n", crt_id ? crt_id : "(null)", crt_issuer_id ? crt_issuer_id : "(null)", issuer_id ? issuer_id : "(null)"); g_free(crt_id); g_free(issuer_id); g_free(crt_issuer_id); } /* The issuer is not correct, or there were errors */ return FALSE; } /* Check basic constraints extension (if it exists then the CA flag must be set to true, and it must exist for certs with version 3 or higher. */ ret = gnutls_x509_crt_get_basic_constraints(issuer_dat, NULL, NULL, NULL); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { if (gnutls_x509_crt_get_version(issuer_dat) >= 3) { /* Reject cert (no basic constraints and cert version is >= 3). */ gchar *issuer_id = purple_certificate_get_unique_id(issuer); purple_debug_info("gnutls/x509", "Rejecting cert because the " "basic constraints extension is missing from issuer cert " "for %s. The basic constraints extension is required on " "all version 3 or higher certs (this cert is version %d).", issuer_id ? issuer_id : "(null)", gnutls_x509_crt_get_version(issuer_dat)); g_free(issuer_id); return FALSE; } else { /* Allow cert (no basic constraints and cert version is < 3). */ purple_debug_info("gnutls/x509", "Basic constraint extension is " "missing from issuer cert for %s. Allowing this because " "the cert is version %d and the basic constraints " "extension is only required for version 3 or higher " "certs.", issuer_id ? issuer_id : "(null)", gnutls_x509_crt_get_version(issuer_dat)); } } else if (ret <= 0) { /* Reject cert (CA flag is false in basic constraints). */ gchar *issuer_id = purple_certificate_get_unique_id(issuer); purple_debug_info("gnutls/x509", "Rejecting cert because the CA flag " "is set to false in the basic constraints extension for " "issuer cert %s. ret=%d\n", issuer_id ? issuer_id : "(null)", ret); g_free(issuer_id); return FALSE; } /* Now, check the signature */ /* The second argument is a ptr to an array of "trusted" issuer certs, but we're only using one trusted one */ ret = gnutls_x509_crt_verify(crt_dat, &issuer_dat, 1, /* Permit signings by X.509v1 certs (Verisign and possibly others have root certificates that predate the current standard) */ GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &verify); if (ret != 0) { purple_debug_error("gnutls/x509", "Attempted certificate verification caused a GnuTLS error code %d. I will just say the signature is bad, but you should look into this.\n", ret); return FALSE; } #ifdef HAVE_GNUTLS_CERT_INSECURE_ALGORITHM if (verify & GNUTLS_CERT_INSECURE_ALGORITHM) { /* * A certificate in the chain is signed with an insecure * algorithm. Put a warning into the log to make this error * perfectly clear as soon as someone looks at the debug log is * generated. */ crt_id = purple_certificate_get_unique_id(crt); issuer_id = purple_certificate_get_issuer_unique_id(crt); purple_debug_warning("gnutls/x509", "Insecure hash algorithm used by %s to sign %s\n", issuer_id, crt_id); } #endif if (verify & GNUTLS_CERT_INVALID) { /* Signature didn't check out, but at least there were no errors*/ if (!crt_id) crt_id = purple_certificate_get_unique_id(crt); if (!issuer_id) issuer_id = purple_certificate_get_issuer_unique_id(crt); purple_debug_error("gnutls/x509", "Bad signature from %s on %s\n", issuer_id, crt_id); g_free(crt_id); g_free(issuer_id); return FALSE; } /* if (ret, etc.) */ /* If we got here, the signature is good */ return TRUE; }
/*------------------------------------------------------------------------ * Callback when data is received from the HTTP server. * * @param user_data The MXit session object * @param source The file-descriptor on which data was received * @param cond Condition which caused the callback (PURPLE_INPUT_READ) */ static void mxit_cb_http_read( gpointer user_data, gint source, PurpleInputCondition cond ) { struct MXitSession* session = (struct MXitSession*) user_data; char buf[256]; int buflen; char* body; int bodylen; char* ch; int len; char* tmp; int res; #if 0 char* next; #endif purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_http_read\n" ); if ( session->rx_state == RX_STATE_RLEN ) { /* we are reading in the HTTP headers */ /* copy partial headers if we have any part saved */ memcpy( buf, session->rx_dbuf, session->rx_i ); buflen = session->rx_i; /* read bytes from the socket */ len = read( session->fd, buf + buflen, sizeof( buf ) - ( buflen + 1 ) ); if ( len <= 0 ) { /* connection has been terminated, or error occurred */ goto done; } buf[buflen+len] = '\0'; #if 0 nextpacket: #endif #ifdef DEBUG_HTTP purple_debug_info( MXIT_PLUGIN_ID, "HTTP POST READ 1: (%i)\n", len ); dump_bytes( session, buf + buflen, len ); #endif /* see if we have all the HTTP headers yet */ ch = strstr( buf, HTTP_11_SEPERATOR ); if ( !ch ) { /* we need to wait for more input, so save what we have */ session->rx_i = buflen + len; memcpy( session->rx_dbuf, buf, session->rx_i ); return; } buflen += len; /* we have the header's end now skip over the http separator to get the body offset */ ch += strlen( HTTP_11_SEPERATOR ); *(ch - 1) = '\0'; body = ch; res = buflen - ( ch - buf ); if ( res > 0 ) { /* we read more bytes than just the header so copy it over */ memcpy( session->rx_dbuf, ch, res ); session->rx_i = res; } else { session->rx_i = 0; } /* test for a good response */ if ( ( strncmp( buf, HTTP_11_200_OK, strlen( HTTP_11_200_OK ) ) != 0 ) && ( strncmp( buf, HTTP_11_100_CONT, strlen( HTTP_11_100_CONT ) ) != 0 ) ) { /* bad result */ purple_debug_error( MXIT_PLUGIN_ID, "HTTP error: %s\n", ch ); goto done; } /* find the content-length */ ch = (char*) purple_strcasestr( buf, HTTP_CONTENT_LEN ); if ( !ch ) { /* bad request. it does not contain a content-length header */ purple_debug_error( MXIT_PLUGIN_ID, "HTTP reply received without content-length header (ignoring packet)\n" ); goto done; } /* parse the content-length */ ch += strlen( HTTP_CONTENT_LEN ); tmp = strchr( ch, '\r' ); if ( !tmp ) { purple_debug_error( MXIT_PLUGIN_ID, "Received bad HTTP reply packet (ignoring packet)\n" ); goto done; } tmp = g_strndup( ch, tmp - ch ); bodylen = atoi( tmp ); g_free( tmp ); tmp = NULL; if ( buflen + bodylen >= CP_MAX_PACKET ) { /* this packet is way to big */ goto done; } else if ( buflen > ( ( body - buf ) + bodylen ) ) { /* we have a second packet here */ #if 0 next = body + bodylen; #endif session->rx_res = 0; } else { session->rx_res = bodylen - session->rx_i; } if ( session->rx_res == 0 ) { /* we have read all the data */ session->rx_i = bodylen; session->rx_state = RX_STATE_PROC; } else { /* there is still some data outstanding */ session->rx_state = RX_STATE_DATA; } } else if ( session->rx_state == RX_STATE_DATA ) { /* we are reading the HTTP content (body) */ /* read bytes from the socket */ len = read( session->fd, &session->rx_dbuf[session->rx_i], session->rx_res ); if ( len <= 0 ) { /* connection has been terminated, or error occurred */ goto done; } #ifdef DEBUG_HTTP purple_debug_info( MXIT_PLUGIN_ID, "HTTP POST READ 2: (%i)\n", len ); dump_bytes( session, &session->rx_dbuf[session->rx_i], len ); #endif session->rx_i += len; session->rx_res -= len; if ( session->rx_res == 0 ) { /* ok, so now we have read in the whole packet */ session->rx_state = RX_STATE_PROC; } } if ( session->rx_state == RX_STATE_PROC ) { mxit_parse_packet( session ); #if 0 if ( next ) { /* there is another packet of which we read some data */ /* reset input */ session->rx_state = RX_STATE_RLEN; session->rx_lbuf[0] = '\0'; session->rx_i = 0; session->rx_res = 0; /* move read data */ len = next - buf; buflen = len; memcpy( buf, next, len ); goto nextpacket; } #endif /* we are done */ goto done; } return; done: close( session->fd ); purple_input_remove( session->http_handler ); session->http_handler = 0; }
void waprpl_xfer_end(PurpleXfer * xfer) { purple_debug_info(WHATSAPP_ID, "Ended file tranfer!\n"); }
/*------------------------------------------------------------------------ * Display and update the user's profile. * * @param action The action object */ static void mxit_profile_action( PurplePluginAction* action ) { PurpleConnection* gc = (PurpleConnection*) action->context; struct MXitSession* session = purple_connection_get_protocol_data( gc ); struct MXitProfile* profile = session->profile; PurpleRequestFields* fields = NULL; PurpleRequestField* field = NULL; purple_debug_info( MXIT_PLUGIN_ID, "mxit_profile_action\n" ); /* ensure that we actually have the user's profile information */ if ( !profile ) { /* no profile information yet, so we cannot update */ mxit_popup( PURPLE_NOTIFY_MSG_WARNING, _( "Profile" ), _( "Your profile information is not yet retrieved. Please try again later." ) ); return; } fields = purple_request_fields_new(); /* Public information - what other users can see */ { PurpleRequestFieldGroup* public_group = purple_request_field_group_new( "Public information" ); /* display name */ field = purple_request_field_string_new( "name", _( "Display Name" ), profile->nickname, FALSE ); purple_request_field_group_add_field( public_group, field ); /* birthday */ field = purple_request_field_string_new( "bday", _( "Birthday" ), profile->birthday, FALSE ); purple_request_field_group_add_field( public_group, field ); if ( profile->flags & CP_PROF_DOBLOCKED ) purple_request_field_set_sensitive( field, FALSE ); /* gender */ field = purple_request_field_choice_new( "male", _( "Gender" ), GINT_TO_POINTER(profile->male ? 1 : 0)); purple_request_field_choice_add( field, _( "Female" ), GINT_TO_POINTER(0)); purple_request_field_choice_add( field, _( "Male" ), GINT_TO_POINTER(1)); purple_request_field_group_add_field( public_group, field ); /* first name */ field = purple_request_field_string_new( "firstname", _( "First Name" ), profile->firstname, FALSE ); purple_request_field_group_add_field( public_group, field ); /* last name */ field = purple_request_field_string_new( "lastname", _( "Last Name" ), profile->lastname, FALSE ); purple_request_field_group_add_field( public_group, field ); /* about me */ field = purple_request_field_string_new( "aboutme", _( "About Me" ), profile->aboutme, FALSE); purple_request_field_group_add_field( public_group, field ); /* where I live */ field = purple_request_field_string_new( "whereami", _( "Where I Live" ), profile->whereami, FALSE); purple_request_field_group_add_field( public_group, field ); /* relationship status */ field = purple_request_field_list_new( "relationship", _( "Relationship Status" ) ); purple_request_field_list_set_multi_select( field, FALSE ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_UNKNOWN ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_UNKNOWN ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_DONTSAY ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_DONTSAY ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_SINGLE ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_SINGLE ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_INVOLVED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_INVOLVED ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_ENGAGED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_ENGAGED ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_MARRIED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_MARRIED ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_COMPLICATED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_COMPLICATED ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_WIDOWED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_WIDOWED ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_SEPARATED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_SEPARATED ) ); purple_request_field_list_add_icon( field, mxit_relationship_to_name( MXIT_RELATIONSHIP_DIVORCED ), NULL, g_strdup_printf( "%i", MXIT_RELATIONSHIP_DIVORCED ) ); purple_request_field_list_add_selected( field, mxit_relationship_to_name( profile->relationship ) ); purple_request_field_group_add_field( public_group, field ); purple_request_fields_add_group( fields, public_group ); } /* Private information - what only MXit can see */ { PurpleRequestFieldGroup* private_group = purple_request_field_group_new( "Private information" ); /* title */ field = purple_request_field_string_new( "title", _( "Title" ), profile->title, FALSE ); purple_request_field_group_add_field( private_group, field ); /* email */ field = purple_request_field_string_new( "email", _( "Email" ), profile->email, FALSE ); purple_request_field_group_add_field( private_group, field ); /* mobile number */ field = purple_request_field_string_new( "mobilenumber", _( "Mobile Number" ), profile->mobilenr, FALSE ); purple_request_field_group_add_field( private_group, field ); /* is searchable */ field = purple_request_field_bool_new( "searchable", _( "Can be searched" ), ( ( profile->flags & CP_PROF_NOT_SEARCHABLE ) == 0) ); purple_request_field_group_add_field( private_group, field ); /* is suggestable */ field = purple_request_field_bool_new( "suggestable", _( "Can be suggested" ), ( ( profile->flags & CP_PROF_NOT_SUGGESTABLE ) == 0 ) ); purple_request_field_group_add_field( private_group, field ); purple_request_fields_add_group( fields, private_group ); } /* (reference: "libpurple/request.h") */ purple_request_fields( gc, _( "Profile" ), _( "Update your MXit Profile" ), NULL, fields, _( "Set" ), G_CALLBACK( mxit_profile_cb ), _( "Cancel" ), NULL, purple_request_cpar_from_connection(gc), gc ); }
void waprpl_xfer_cancel_send(PurpleXfer * xfer) { purple_debug_info(WHATSAPP_ID, "File tranfer cancel send!!!\n"); /* TODO: Add cancel call, should be pretty easy */ }
void waprpl_xfer_start(PurpleXfer * xfer) { purple_debug_info(WHATSAPP_ID, "Starting file tranfer...\n"); }
/** * purplemot_login - Login for an account. Establishes a connection * to the discovery server and initializes * * @param acct The account to be logged in */ static void purplemot_login(PurpleAccount *acct) { char **userparts; struct pm_account *account; int port; const char *username = purple_account_get_username(acct); PurpleConnection *gc = purple_account_get_connection(acct); GList *offline_messages; purple_debug_info("purplemot", "logging in %s\n", acct->username); // TODO(carl): initialize motmot here? if (strpbrk(username, " \t\v\r\n") != NULL) { purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Motmot server may not contain whitespace")); return; } gc->proto_data = account = g_new0(struct pm_account, 1); account->pa = acct; userparts = g_strsplit(username, "@", 2); purple_connection_set_display_name(gc, userparts[0]); account->server_host = g_strdup(userparts[1]); g_strfreev(userparts); port = purple_account_get_int(acct, "disc_port", DEFAULT_PORT); purple_connection_update_progress(gc, _("Connecting"), 0, /* which connection step this is */ 2); /* total number of steps */ purple_debug_info("motmot", "connecting to discovery server"); rpc_connect(account); purple_connection_update_progress(gc, _("Connected"), 1, /* which connection step this is */ 2); /* total number of steps */ purple_connection_set_state(gc, PURPLE_CONNECTED); /* fetch stored offline messages */ purple_debug_info("purplemot", "checking for offline messages for %s\n", acct->username); offline_messages = g_hash_table_lookup(goffline_messages, acct->username); while (offline_messages) { GOfflineMessage *message = (GOfflineMessage *)offline_messages->data; purple_debug_info("purplemot", "delivering offline message to %s: %s\n", acct->username, message->message); serv_got_im(gc, message->from, message->message, message->flags, message->mtime); offline_messages = g_list_next(offline_messages); g_free(message->from); g_free(message->message); g_free(message); } g_list_free(offline_messages); g_hash_table_remove(goffline_messages, &acct->username); }