void friendlist_onFriendAdded(ToxWindow *self, Tox *m, uint32_t num, bool sort) { realloc_friends(Friends.max_idx + 1); memset(&Friends.list[Friends.max_idx], 0, sizeof(ToxicFriend)); uint32_t i; for (i = 0; i <= Friends.max_idx; ++i) { if (Friends.list[i].active) { continue; } ++Friends.num_friends; Friends.list[i].num = num; Friends.list[i].active = true; Friends.list[i].chatwin = -1; Friends.list[i].connection_status = TOX_CONNECTION_NONE; Friends.list[i].status = TOX_USER_STATUS_NONE; Friends.list[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON; Tox_Err_Friend_Get_Public_Key pkerr; tox_friend_get_public_key(m, num, (uint8_t *) Friends.list[i].pub_key, &pkerr); if (pkerr != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) { fprintf(stderr, "tox_friend_get_public_key failed (error %d)\n", pkerr); } Tox_Err_Friend_Get_Last_Online loerr; time_t t = tox_friend_get_last_online(m, num, &loerr); if (loerr != TOX_ERR_FRIEND_GET_LAST_ONLINE_OK) { t = 0; } update_friend_last_online(i, t); char tempname[TOX_MAX_NAME_LENGTH] = {0}; get_nick_truncate(m, tempname, num); snprintf(Friends.list[i].name, sizeof(Friends.list[i].name), "%s", tempname); Friends.list[i].namelength = strlen(Friends.list[i].name); if (i == Friends.max_idx) { ++Friends.max_idx; } if (sort) { sort_friendlist_index(); } #ifdef AUDIO init_friend_AV(i); #endif return; } }
/** * @brief Get the public key part of the ToxID only */ ToxPk Core::getFriendPublicKey(uint32_t friendNumber) const { uint8_t rawid[TOX_PUBLIC_KEY_SIZE]; if (!tox_friend_get_public_key(tox, friendNumber, rawid, nullptr)) { qWarning() << "getFriendPublicKey: Getting public key failed"; return ToxPk(); } return ToxPk(rawid); }
/** * @brief Get the public key part of the ToxID only */ QString Core::getFriendPublicKey(uint32_t friendNumber) const { uint8_t rawid[TOX_PUBLIC_KEY_SIZE]; if (!tox_friend_get_public_key(tox, friendNumber, rawid, nullptr)) { qWarning() << "getFriendPublicKey: Getting public key failed"; return QString(); } QByteArray data((char*)rawid, TOX_PUBLIC_KEY_SIZE); QString id = data.toHex().toUpper(); return id; }
/* Returns true if friendnumber's Tox ID is in the masterkeys list, false otherwise. Note that it only compares the public key portion of the IDs. */ bool friend_is_master(Tox *m, uint32_t friendnumber) { if (!file_exists(MASTERLIST_FILE)) { FILE *fp = fopen(MASTERLIST_FILE, "w"); if (fp == NULL) { fprintf(stderr, "Warning: failed to create masterkeys file\n"); return false; } fclose(fp); fprintf(stderr, "Warning: creating new masterkeys file. Did you lose the old one?\n"); return false; } FILE *fp = fopen(MASTERLIST_FILE, "r"); if (fp == NULL) { fprintf(stderr, "Warning: failed to read masterkeys file\n"); return false; } char friend_key[TOX_PUBLIC_KEY_SIZE]; if (tox_friend_get_public_key(m, friendnumber, (uint8_t *) friend_key, NULL) == 0) { fclose(fp); return false; } char id[256]; while (fgets(id, sizeof(id), fp)) { int len = strlen(id); if (--len < TOX_PUBLIC_KEY_SIZE) continue; char *key_bin = hex_string_to_bin(id); if (memcmp(key_bin, friend_key, TOX_PUBLIC_KEY_SIZE) == 0) { free(key_bin); fclose(fp); return true; } free(key_bin); } fclose(fp); return false; }
QString Core::getFriendAddress(uint32_t friendNumber) const { // If we don't know the full address of the client, return just the id, otherwise get the full address uint8_t rawid[TOX_PUBLIC_KEY_SIZE]; if (!tox_friend_get_public_key(tox, friendNumber, rawid, nullptr)) { qWarning() << "getFriendAddress: Getting public key failed"; return QString(); } QByteArray data((char*)rawid,TOX_PUBLIC_KEY_SIZE); QString id = data.toHex().toUpper(); QString addr = Settings::getInstance().getFriendAdress(id); if (addr.size() > id.size()) return addr; return id; }
/** * Return a friend's Tox ID in short form. Return value must be freed. */ char * twc_get_friend_id_short(Tox *tox, int32_t friend_number) { uint8_t client_id[TOX_PUBLIC_KEY_SIZE]; TOX_ERR_FRIEND_GET_PUBLIC_KEY err; size_t short_id_length = weechat_config_integer(twc_config_short_id_size); char *hex_address = malloc(short_id_length + 1); tox_friend_get_public_key(tox, friend_number, client_id, &err); /* return a zero public key on failure */ if (err != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) memset(client_id, 0, TOX_PUBLIC_KEY_SIZE); twc_bin2hex(client_id, short_id_length / 2, hex_address); return hex_address; }
void Core::loadFriends() { const uint32_t friendCount = tox_self_get_friend_list_size(tox); if (friendCount > 0) { // assuming there are not that many friends to fill up the whole stack uint32_t *ids = new uint32_t[friendCount]; tox_self_get_friend_list(tox, ids); uint8_t clientId[TOX_PUBLIC_KEY_SIZE]; for (int32_t i = 0; i < static_cast<int32_t>(friendCount); ++i) { if (tox_friend_get_public_key(tox, ids[i], clientId, nullptr)) { emit friendAdded(ids[i], CUserId::toString(clientId)); const size_t nameSize = tox_friend_get_name_size(tox, ids[i], nullptr); if (nameSize && nameSize != SIZE_MAX) { uint8_t *name = new uint8_t[nameSize]; if (tox_friend_get_name(tox, ids[i], name, nullptr)) emit friendUsernameChanged(ids[i], CString::toString(name, nameSize)); delete[] name; } const size_t statusMessageSize = tox_friend_get_status_message_size(tox, ids[i], nullptr); if (statusMessageSize != SIZE_MAX) { uint8_t *statusMessage = new uint8_t[statusMessageSize]; if (tox_friend_get_status_message(tox, ids[i], statusMessage, nullptr)) { emit friendStatusMessageChanged(ids[i], CString::toString(statusMessage, statusMessageSize)); } delete[] statusMessage; } checkLastOnline(ids[i]); } } delete[] ids; } }
void utox_friend_init(Tox *tox, uint32_t friend_number){ int size; // get friend pointer FRIEND *f = &friend[friend_number]; uint8_t name[TOX_MAX_NAME_LENGTH]; // Set scroll position to bottom of window. f->msg.scroll = 1.0; // Get and set the public key for this friend number and set it. tox_friend_get_public_key(tox, friend_number, f->cid, 0); // Set the friend number we got from toxcore f->number = friend_number; // Get and set friend name and length size = tox_friend_get_name_size(tox, friend_number, 0); tox_friend_get_name(tox, friend_number, name, 0); // Set the name for utox as well friend_setname(f, name, size); // Get and set the status message size = tox_friend_get_status_message_size(tox, friend_number, 0); f->status_message = malloc(size); tox_friend_get_status_message(tox, friend_number, f->status_message, 0); f->status_length = size; // Get the hex version of this friends ID char_t cid[TOX_PUBLIC_KEY_SIZE * 2]; cid_to_string(cid, f->cid); init_avatar(&f->avatar, cid, NULL, NULL); // Get the chat backlog log_read(tox, friend_number); // Load the meta data, if it exists. friend_meta_data_read(tox, friend_number); }
void Core::loadFriends() { const uint32_t friendCount = tox_self_get_friend_list_size(tox); if (friendCount <= 0) { return; } // assuming there are not that many friends to fill up the whole stack uint32_t* ids = new uint32_t[friendCount]; tox_self_get_friend_list(tox, ids); uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00}; for (uint32_t i = 0; i < friendCount; ++i) { if (!tox_friend_get_public_key(tox, ids[i], friendPk, nullptr)) { continue; } emit friendAdded(ids[i], ToxPk(friendPk)); GET_FRIEND_PROPERTY(Username, tox_friend_get_name, true); GET_FRIEND_PROPERTY(StatusMessage, tox_friend_get_status_message, false); checkLastOnline(ids[i]); } delete[] ids; }
END_TEST START_TEST(test_save_friend) { Tox *tox1 = tox_new(0, 0); Tox *tox2 = tox_new(0, 0); ck_assert_msg(tox1 || tox2, "Failed to create 2 tox instances"); uint32_t to_compare = 974536; tox_callback_friend_request(tox2, accept_friend_request, &to_compare); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); uint32_t test = tox_friend_add(tox1, address, (uint8_t *)"Gentoo", 7, 0); ck_assert_msg(test != UINT32_MAX, "Failed to add friend"); size_t size = tox_get_savedata_size(tox1); uint8_t data[size]; tox_get_savedata(tox1, data); size_t size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t enc_data[size2]; TOX_ERR_ENCRYPTION error1; bool ret = tox_pass_encrypt(data, size, "correcthorsebatterystaple", 25, enc_data, &error1); ck_assert_msg(ret, "failed to encrypted save: %u", error1); ck_assert_msg(tox_is_data_encrypted(enc_data), "magic number missing"); struct Tox_Options options; tox_options_default(&options); options.savedata_type = TOX_SAVEDATA_TYPE_TOX_SAVE; options.savedata_data = enc_data; options.savedata_length = size2; TOX_ERR_NEW err2; Tox *tox3 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_LOAD_ENCRYPTED, "wrong error! %u. should fail with %u", err2, TOX_ERR_NEW_LOAD_ENCRYPTED); uint8_t dec_data[size]; TOX_ERR_DECRYPTION err3; ret = tox_pass_decrypt(enc_data, size2, "correcthorsebatterystaple", 25, dec_data, &err3); ck_assert_msg(ret, "failed to decrypt save: %u", err3); options.savedata_data = dec_data; options.savedata_length = size; tox3 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to load from decrypted data: %u", err2); uint8_t address2[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox3, 0, address2, 0); ck_assert_msg(ret, "no friends!"); ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match!"); size = tox_get_savedata_size(tox3); uint8_t data2[size]; tox_get_savedata(tox3, data2); TOX_PASS_KEY key; memcpy(key.salt, salt, 32); memcpy(key.key, known_key2, crypto_box_BEFORENMBYTES); size2 = size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH; uint8_t encdata2[size2]; ret = tox_pass_key_encrypt(data2, size, &key, encdata2, &error1); ck_assert_msg(ret, "failed to key encrypt %u", error1); ck_assert_msg(tox_is_data_encrypted(encdata2), "magic number the second missing"); uint8_t out1[size], out2[size]; ret = tox_pass_decrypt(encdata2, size2, pw, pwlen, out1, &err3); ck_assert_msg(ret, "failed to pw decrypt %u", err3); ret = tox_pass_key_decrypt(encdata2, size2, &key, out2, &err3); ck_assert_msg(ret, "failed to key decrypt %u", err3); ck_assert_msg(memcmp(out1, out2, size) == 0, "differing output data"); // and now with the code in use (I only bothered with manually to debug this, and it seems a waste // to remove the manual check now that it's there) options.savedata_data = out1; options.savedata_length = size; Tox *tox4 = tox_new(&options, &err2); ck_assert_msg(err2 == TOX_ERR_NEW_OK, "failed to new the third"); uint8_t address5[TOX_PUBLIC_KEY_SIZE]; ret = tox_friend_get_public_key(tox4, 0, address5, 0); ck_assert_msg(ret, "no friends! the third"); ck_assert_msg(memcmp(address, address2, TOX_PUBLIC_KEY_SIZE) == 0, "addresses don't match! the third"); tox_kill(tox1); tox_kill(tox2); tox_kill(tox3); tox_kill(tox4); }