Exemplo n.º 1
0
/*
 * returns a FRIEND_ADDRESS_SIZE byte address to give to others.
 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
 *
 */
void getaddress(Messenger *m, uint8_t *address)
{
    memcpy(address, m->net_crypto->self_public_key, crypto_box_PUBLICKEYBYTES);
    uint32_t nospam = get_nospam(&(m->fr));
    memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam));
    uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
    memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum));
}
Exemplo n.º 2
0
/* load the messenger from data of size length. */
int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
{
    if (length == ~0)
        return -1;

    if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3)
        return -1;

    length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3;
    load_keys(data);
    data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
    uint32_t nospam;
    memcpy(&nospam, data, sizeof(nospam));
    set_nospam(nospam);
    data += sizeof(nospam);
    uint32_t size;
    memcpy(&size, data, sizeof(size));
    data += sizeof(size);

    if (length < size)
        return -1;

    length -= size;

    if (DHT_load(data, size) == -1)
        return -1;

    data += size;
    memcpy(&size, data, sizeof(size));
    data += sizeof(size);

    if (length < size || size % sizeof(Friend) != 0)
        return -1;

    Friend *temp = malloc(size);
    memcpy(temp, data, size);

    uint16_t num = size / sizeof(Friend);

    uint32_t i;

    for (i = 0; i < num; ++i) {
        if (temp[i].status >= 3) {
            int fnum = m_addfriend_norequest(m, temp[i].client_id);
            setfriendname(m, fnum, temp[i].name);
            /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */
        } else if (temp[i].status != 0) {
            /* TODO: this is not a good way to do this. */
            uint8_t address[FRIEND_ADDRESS_SIZE];
            memcpy(address, temp[i].client_id, crypto_box_PUBLICKEYBYTES);
            memcpy(address + crypto_box_PUBLICKEYBYTES, &(temp[i].friendrequest_nospam), sizeof(uint32_t));
            uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
            memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), &checksum, sizeof(checksum));
            m_addfriend(m, address, temp[i].info, temp[i].info_size);
        }
    }

    free(temp);
    data += size;
    length -= size;

    uint16_t small_size;

    if (length < sizeof(small_size))
        return -1;

    memcpy(&small_size, data, sizeof(small_size));
    data += sizeof(small_size);
    length -= sizeof(small_size);

    if (length != small_size)
        return -1;

    setname(m, data, small_size);

    return 0;
}
Exemplo n.º 3
0
/*
 * add a friend
 * set the data that will be sent along with friend request
 * address is the address of the friend (returned by getaddress of the friend you wish to add) it must be FRIEND_ADDRESS_SIZE bytes. TODO: add checksum.
 * data is the data and length is the length
 * returns the friend number if success
 * return FA_TOOLONG if message length is too long
 * return FAERR_NOMESSAGE if no message (message length must be >= 1 byte)
 * return FAERR_OWNKEY if user's own key
 * return FAERR_ALREADYSENT if friend request already sent or already a friend
 * return FAERR_UNKNOWN for unknown error
 * return FAERR_BADCHECKSUM if bad checksum in address
 * return FAERR_SETNEWNOSPAM if the friend was already there but the nospam was different
 * (the nospam for that friend was set to the new one)
 * return FAERR_NOMEM if increasing the friend list size fails
 */
int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
{
    if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
                   - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
                   + crypto_box_ZEROBYTES))
        return FAERR_TOOLONG;

    uint8_t client_id[crypto_box_PUBLICKEYBYTES];
    memcpy(client_id, address, crypto_box_PUBLICKEYBYTES);
    uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
    memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));

    if (check != checksum)
        return FAERR_BADCHECKSUM;

    if (length < 1)
        return FAERR_NOMESSAGE;

    if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
        return FAERR_OWNKEY;

    int friend_id = getfriend_id(m, client_id);

    if (friend_id != -1) {
        uint32_t nospam;
        memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam));

        if (m->friendlist[friend_id].friendrequest_nospam == nospam)
            return FAERR_ALREADYSENT;

        m->friendlist[friend_id].friendrequest_nospam = nospam;
        return FAERR_SETNEWNOSPAM;
    }

    /* resize the friend list if necessary */
    if (realloc_friendlist(m, m->numfriends + 1) != 0)
        return FAERR_NOMEM;

    memset(&(m->friendlist[m->numfriends]), 0, sizeof(Friend));

    uint32_t i;

    for (i = 0; i <= m->numfriends; ++i)  {
        if (m->friendlist[i].status == NOFRIEND) {
            DHT_addfriend(client_id);
            m->friendlist[i].status = FRIEND_ADDED;
            m->friendlist[i].crypt_connection_id = -1;
            m->friendlist[i].friendrequest_lastsent = 0;
            m->friendlist[i].friendrequest_timeout = FRIENDREQUEST_TIMEOUT;
            memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
            m->friendlist[i].statusmessage = calloc(1, 1);
            m->friendlist[i].statusmessage_length = 1;
            m->friendlist[i].userstatus = USERSTATUS_NONE;
            memcpy(m->friendlist[i].info, data, length);
            m->friendlist[i].info_size = length;
            m->friendlist[i].message_id = 0;
            m->friendlist[i].receives_read_receipts = 1; /* default: YES */
            memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));

            if (m->numfriends == i)
                ++ m->numfriends;

            return i;
        }
    }

    return FAERR_UNKNOWN;
}