Esempio n. 1
0
int m_addfriend_norequest(uint8_t * client_id)
{
    if (getfriend_id(client_id) != -1)
        return -1;

    /* resize the friend list if necessary */
    realloc_friendlist(numfriends + 1);

    uint32_t i;
    for (i = 0; i <= numfriends; ++i) {
        if(friendlist[i].status == NOFRIEND) {
            DHT_addfriend(client_id);
            friendlist[i].status = FRIEND_REQUESTED;
            friendlist[i].crypt_connection_id = -1;
            friendlist[i].friend_request_id = -1;
            memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
            friendlist[i].statusmessage = calloc(1, 1);
            friendlist[i].statusmessage_length = 1;
            friendlist[i].userstatus = USERSTATUS_NONE;
            friendlist[i].message_id = 0;
            friendlist[i].receives_read_receipts = 1; /* default: YES */
            ++numfriends;
            return i;
        }
    }
    return -1;
}
Esempio n. 2
0
/* Set a friends DHT public key.
 * timestamp is the time (current_time_monotonic()) at which the key was last confirmed belonging to
 * the other peer.
 *
 * return -1 on failure.
 * return 0 on success.
 */
int onion_set_friend_DHT_pubkey(Onion_Client *onion_c, int friend_num, const uint8_t *dht_key, uint64_t timestamp)
{
    if ((uint32_t)friend_num >= onion_c->num_friends)
        return -1;

    if (onion_c->friends_list[friend_num].status == 0)
        return -1;

    if (onion_c->friends_list[friend_num].fake_client_id_timestamp >= timestamp)
        return -1;

    if (onion_c->friends_list[friend_num].is_fake_clientid) {
        if (memcmp(dht_key, onion_c->friends_list[friend_num].fake_client_id, crypto_box_PUBLICKEYBYTES) == 0) {
            return -1;
        }

        DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);
    }

    if (DHT_addfriend(onion_c->dht, dht_key) == 1) {
        return -1;
    }

    onion_c->friends_list[friend_num].last_seen = unix_time();
    onion_c->friends_list[friend_num].is_fake_clientid = 1;
    onion_c->friends_list[friend_num].fake_client_id_timestamp = timestamp;
    memcpy(onion_c->friends_list[friend_num].fake_client_id, dht_key, crypto_box_PUBLICKEYBYTES);

    return 0;
}
Esempio n. 3
0
int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
{
    if (getfriend_id(m, client_id) != -1)
        return -1;

    /* 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_CONFIRMED;
            m->friendlist[i].crypt_connection_id = -1;
            m->friendlist[i].friendrequest_lastsent = 0;
            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;
            m->friendlist[i].message_id = 0;
            m->friendlist[i].receives_read_receipts = 1; /* default: YES */

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

            return i;
        }
    }

    return -1;
}
Esempio n. 4
0
/* add a friend
   set the data that will be sent along with friend request
   client_id is the client id of the friend
   data is the data and length is the length
   returns the friend number if success
   return -1 if failure. */
int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
{
    if (length == 0 || length >=
        (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
        return -1;
    if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
        return -1;
    if (getfriend_id(client_id) != -1)
        return -1;
    uint32_t i;
    for (i = 0; i <= numfriends; ++i) {
        if(friendlist[i].status == 0) {
            DHT_addfriend(client_id);
            friendlist[i].status = 1;
            friendlist[i].crypt_connection_id = -1;
            friendlist[i].friend_request_id = -1;
            memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
            friendlist[i].userstatus = calloc(1, 1);
            friendlist[i].userstatus_length = 1;
            memcpy(friendlist[i].info, data, length);
            friendlist[i].info_size = length;

            ++numfriends;
            return i;
        }
    }
    return -1;
}
Esempio n. 5
0
static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key, void *userdata)
{
    if ((NUM_FIRST == number && !first) || (NUM_LAST == number && !last)) {
        Onions *on = (Onions *)object;
        uint16_t count = 0;
        int ret = DHT_addfriend(on->onion->dht, dht_public_key, &dht_ip_callback, object, number, &count);
        ck_assert_msg(ret == 0, "DHT_addfriend() did not return 0");
        ck_assert_msg(count == 1, "Count not 1, count is %u", count);

        if (NUM_FIRST == number && !first) {
            first = 1;

            if (memcmp(dht_public_key, last_dht_pk, crypto_box_PUBLICKEYBYTES) != 0) {
                ck_abort_msg("Error wrong dht key.");
            }

            return;
        }

        if (NUM_LAST == number && !last) {
            last = 1;

            if (memcmp(dht_public_key, first_dht_pk, crypto_box_PUBLICKEYBYTES) != 0) {
                ck_abort_msg("Error wrong dht key.");
            }

            return;
        }

        ck_abort_msg("Error.");
    }
}
Esempio n. 6
0
/* Callback for dht public key changes. */
static void dht_pk_callback(void *object, int32_t number, const uint8_t *dht_public_key)
{
    Friend_Connections *fr_c = object;
    Friend_Conn *friend_con = get_conn(fr_c, number);

    if (!friend_con)
        return;

    friend_con->dht_ping_lastrecv = unix_time();

    if (memcmp(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES) == 0)
        return;

    if (friend_con->dht_lock) {
        if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) {
            printf("a. Could not delete dht peer. Please report this.\n");
            return;
        }

        friend_con->dht_lock = 0;
    }

    DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, object, number, &friend_con->dht_lock);

    if (friend_con->crypt_connection_id == -1) {
        friend_new_connection(fr_c, number);
    }

    set_connection_dht_public_key(fr_c->net_crypto, friend_con->crypt_connection_id, dht_public_key);
    onion_set_friend_DHT_pubkey(fr_c->onion_c, friend_con->onion_friendnum, dht_public_key);

    memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES);
}
Esempio n. 7
0
/*
 * add a friend
 * set the data that will be sent along with friend request
 * client_id is the client id of the friend
 * 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
 */
int m_addfriend(uint8_t *client_id, 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;
    if (length < 1)
        return FAERR_NOMESSAGE;
    if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
        return FAERR_OWNKEY;
    if (getfriend_id(client_id) != -1)
        return FAERR_ALREADYSENT;

    uint32_t i;
    for (i = 0; i <= numfriends && i <= MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */
        if(friendlist[i].status == NOFRIEND) {
            DHT_addfriend(client_id);
            friendlist[i].status = FRIEND_ADDED;
            friendlist[i].crypt_connection_id = -1;
            friendlist[i].friend_request_id = -1;
            memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
            friendlist[i].userstatus = calloc(1, 1);
            friendlist[i].userstatus_length = 1;
            friendlist[i].userstatus_kind = USERSTATUS_KIND_OFFLINE;
            memcpy(friendlist[i].info, data, length);
            friendlist[i].info_size = length;

            ++numfriends;
            return i;
        }
    }
    return FAERR_UNKNOWN;
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
    //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
    
    if (argc < 4) {
        printf("usage %s ip port client_id(of friend to find ip_port of)\n", argv[0]);
        exit(0);
    }
    DHT_addfriend((uint8_t *)argv[3]);
    
    //initialize networking
    //bind to ip 0.0.0.0:PORT
    IP ip;
    ip.i = 0;
    init_networking(ip, PORT);
    
    int randdomnum = random_int();
    memcpy(self_client_id, &randdomnum, 4);
    

    perror("Initialization");
    IP_Port bootstrap_ip_port;
    bootstrap_ip_port.port = htons(atoi(argv[2]));
    //bootstrap_ip_port.ip.c[0] = 127;
    //bootstrap_ip_port.ip.c[1] = 0;
    //bootstrap_ip_port.ip.c[2] = 0;
    //bootstrap_ip_port.ip.c[3] = 1;
    bootstrap_ip_port.ip.i = inet_addr(argv[1]);
    DHT_bootstrap(bootstrap_ip_port);
    
    IP_Port ip_port;
    uint8_t data[MAX_UDP_PACKET_SIZE];
    uint32_t length;
    
    while(1)
    {
            
        doDHT();
        
        while(receivepacket(&ip_port, data, &length) != -1)
        {
            if(DHT_handlepacket(data, length, ip_port))
            {
                //unhandled packet
                printpacket(data, length, ip_port);
            }
            else
            {
                printf("Received handled packet with length: %u\n", length);
            }
        }
        print_clientlist();
        print_friendlist();
        c_sleep(300);
    }
    
    shutdown_networking();
    return 0;   
}
Esempio n. 9
0
static int handle_fakeid_announce(void *object, uint8_t *source_pubkey, uint8_t *data, uint32_t length)
{
    Onion_Client *onion_c = object;

    if (length < FAKEID_DATA_MIN_LENGTH)
        return 1;

    if (length > FAKEID_DATA_MAX_LENGTH)
        return 1;

    if ((length - FAKEID_DATA_MIN_LENGTH) % sizeof(Node_format) != 0)
        return 1;

    int friend_num = onion_friend_num(onion_c, source_pubkey);

    if (friend_num == -1)
        return 1;

    uint64_t no_replay;
    net_to_host(data + 1, sizeof(no_replay));
    memcpy(&no_replay, data + 1, sizeof(uint64_t));

    if (no_replay <= onion_c->friends_list[friend_num].last_noreplay)
        return 1;

    onion_c->friends_list[friend_num].last_noreplay = no_replay;

    if (memcmp(data + 1 + sizeof(uint64_t), onion_c->friends_list[friend_num].fake_client_id,
               crypto_box_PUBLICKEYBYTES) != 0) {
        DHT_delfriend(onion_c->dht, onion_c->friends_list[friend_num].fake_client_id);

        onion_c->friends_list[friend_num].last_seen = unix_time();

        if (DHT_addfriend(onion_c->dht, data + 1 + sizeof(uint64_t)) == 1) {
            return 1;
        }

        onion_c->friends_list[friend_num].is_fake_clientid = 1;
        memcpy(onion_c->friends_list[friend_num].fake_client_id, data + 1 + sizeof(uint64_t), crypto_box_PUBLICKEYBYTES);
    }

    uint16_t num_nodes = (length - FAKEID_DATA_MIN_LENGTH) / sizeof(Node_format);
    Node_format nodes[num_nodes];
    memcpy(nodes, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, sizeof(nodes));
    uint32_t i;

    for (i = 0; i < num_nodes; ++i) {
        to_host_family(&nodes[i].ip_port.ip);
        DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id);
    }

    return 0;
}
Esempio n. 10
0
int m_addfriend_norequest(uint8_t * client_id)
{
    if (getfriend_id(client_id) != -1)
        return -1;
    uint32_t i;
    for (i = 0; i <= numfriends; ++i) {
        if(friendlist[i].status == 0) {
            DHT_addfriend(client_id);
            friendlist[i].status = 2;
            friendlist[i].crypt_connection_id = -1;
            friendlist[i].friend_request_id = -1;
            memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
            friendlist[i].userstatus = calloc(1, 1);
            friendlist[i].userstatus_length = 1;
            numfriends++;
            return i;
        }
    }
    return -1;
}
Esempio n. 11
0
int m_addfriend_norequest(uint8_t * client_id)
{
    if (getfriend_id(client_id) != -1)
        return -1;
    uint32_t i;
    for (i = 0; i <= numfriends && i <= MAX_NUM_FRIENDS; ++i) { /*TODO: dynamic memory allocation to allow for more than MAX_NUM_FRIENDS friends */
        if(friendlist[i].status == NOFRIEND) {
            DHT_addfriend(client_id);
            friendlist[i].status = FRIEND_REQUESTED;
            friendlist[i].crypt_connection_id = -1;
            friendlist[i].friend_request_id = -1;
            memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE);
            friendlist[i].userstatus = calloc(1, 1);
            friendlist[i].userstatus_length = 1;
            numfriends++;
            return i;
        }
    }
    return -1;
}
Esempio n. 12
0
static void change_dht_pk(Friend_Connections *fr_c, int friendcon_id, const uint8_t *dht_public_key)
{
    Friend_Conn *friend_con = get_conn(fr_c, friendcon_id);

    if (!friend_con)
        return;

    friend_con->dht_pk_lastrecv = unix_time();

    if (friend_con->dht_lock) {
        if (DHT_delfriend(fr_c->dht, friend_con->dht_temp_pk, friend_con->dht_lock) != 0) {
            printf("a. Could not delete dht peer. Please report this.\n");
            return;
        }

        friend_con->dht_lock = 0;
    }

    DHT_addfriend(fr_c->dht, dht_public_key, dht_ip_callback, fr_c, friendcon_id, &friend_con->dht_lock);
    memcpy(friend_con->dht_temp_pk, dht_public_key, crypto_box_PUBLICKEYBYTES);
}
Esempio n. 13
0
/*
 * add a friend
 * set the data that will be sent along with friend request
 * client_id is the client id of the friend
 * 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
 */
int m_addfriend(uint8_t *client_id, 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;
    if (length < 1)
        return FAERR_NOMESSAGE;
    if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
        return FAERR_OWNKEY;
    if (getfriend_id(client_id) != -1)
        return FAERR_ALREADYSENT;

    /* resize the friend list if necessary */
    realloc_friendlist(numfriends + 1);

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

            ++numfriends;
            return i;
        }
    }
    return FAERR_UNKNOWN;
}
Esempio n. 14
0
int main(int argc, char *argv[])
{
    //memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32);
    
    if (argc < 4) {
        printf("usage %s ip port public_key\n", argv[0]);
        exit(0);
    }
    new_keys();
    printf("OUR ID: ");
    uint32_t i;
    for(i = 0; i < 32; i++) {
        if(self_public_key[i] < 16)
            printf("0");
        printf("%hhX",self_public_key[i]);
    }
    
    char temp_id[128];
    printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n");
    if(scanf("%s", temp_id) != 1)
        exit(0);
    
    DHT_addfriend(hex_string_to_bin(temp_id));
    
    /* initialize networking */
    /* bind to ip 0.0.0.0:PORT */
    IP ip;
    ip.i = 0;
    init_networking(ip, PORT);
    

    perror("Initialization");
    IP_Port bootstrap_ip_port;
    bootstrap_ip_port.port = htons(atoi(argv[2]));
    /* bootstrap_ip_port.ip.c[0] = 127;
     * bootstrap_ip_port.ip.c[1] = 0;
     * bootstrap_ip_port.ip.c[2] = 0;
     * bootstrap_ip_port.ip.c[3] = 1; */
    bootstrap_ip_port.ip.i = inet_addr(argv[1]);
    DHT_bootstrap(bootstrap_ip_port, hex_string_to_bin(argv[3]));
    
    IP_Port ip_port;
    uint8_t data[MAX_UDP_PACKET_SIZE];
    uint32_t length;
    
    while(1) {
            
        doDHT();
        
        while(receivepacket(&ip_port, data, &length) != -1) {
            if(DHT_handlepacket(data, length, ip_port) && friendreq_handlepacket(data, length, ip_port)) {
                //unhandled packet
                printpacket(data, length, ip_port);
            } else {
                printf("Received handled packet with length: %u\n", length);
            }
        }
        print_clientlist();
        print_friendlist();
        c_sleep(300);
    }
    
    shutdown_networking();
    return 0;   
}
int main(int argc, char *argv[])
{
    if (argc < 4) {
        printf("usage %s ip port filename(of file to send)\n", argv[0]);
        exit(0);
    }
    new_keys();
    printf("OUR ID: ");
    uint32_t i;
    for(i = 0; i < 32; i++) {
        if(self_public_key[i] < 16)
            printf("0");
        printf("%hhX",self_public_key[i]);
    }
    printf("\n");
    
    memcpy(self_client_id, self_public_key, 32);
    
    char temp_id[128];
    printf("Enter the client_id of the friend to connect to (32 bytes HEX format):\n");
    scanf("%s", temp_id);
    
    uint8_t friend_id[32];
    memcpy(friend_id, hex_string_to_bin(temp_id), 32);
    
    /* memcpy(self_client_id, "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", 32); */
    

    DHT_addfriend(friend_id);
    IP_Port friend_ip;
    int connection = -1;
    int inconnection = -1;
    
    uint8_t acceptedfriend_public_key[crypto_box_PUBLICKEYBYTES];
    int friendrequest = -1;
    uint8_t request_data[512];
    
    /* initialize networking
     * bind to ip 0.0.0.0:PORT */
    IP ip;
    ip.i = 0;
    init_networking(ip, PORT);
    initNetCrypto();
    
    perror("Initialization");
    IP_Port bootstrap_ip_port;
    bootstrap_ip_port.port = htons(atoi(argv[2]));
    bootstrap_ip_port.ip.i = inet_addr(argv[1]);
    DHT_bootstrap(bootstrap_ip_port);
    
    IP_Port ip_port;
    uint8_t data[MAX_UDP_PACKET_SIZE];
    uint32_t length;
    
    uint8_t buffer1[128];
    int read1 = 0;
    uint8_t buffer2[128];
    int read2 = 0;
    FILE *file1 = fopen(argv[3], "rb");
    if ( file1==NULL ){printf("Error opening file.\n");return 1;}
    FILE *file2 = fopen("received.txt", "wb");
    if ( file2==NULL ){return 1;}
    read1 = fread(buffer1, 1, 128, file1);
    
    while(1) {
        while(receivepacket(&ip_port, data, &length) != -1) {
            if(rand() % 3 != 1) { /* simulate packet loss */
                if(DHT_handlepacket(data, length, ip_port) && LosslessUDP_handlepacket(data, length, ip_port)) {
                    /* if packet is not recognized */
                    printf("Received unhandled packet with length: %u\n", length);
                } else {
                    printf("Received handled packet with length: %u\n", length);
                }
            }
        }
        friend_ip = DHT_getfriendip(friend_id);
        if(friend_ip.ip.i != 0) {
            if(connection == -1 && friendrequest == -1) {
                printf("Sending friend request to peer:");
                printip(friend_ip);
                friendrequest = send_friendrequest(friend_id, friend_ip,(uint8_t *) "Hello World", 12);
                /* connection = crypto_connect((uint8_t *)friend_id, friend_ip); */
                /* connection = new_connection(friend_ip); */
            }
            if(check_friendrequest(friendrequest) == 1) {
                printf("Started connecting to friend:");
                connection = crypto_connect(friend_id, friend_ip);
            }
        }
        if(inconnection == -1) {
            uint8_t secret_nonce[crypto_box_NONCEBYTES];
            uint8_t public_key[crypto_box_PUBLICKEYBYTES];
            uint8_t session_key[crypto_box_PUBLICKEYBYTES];
            inconnection = crypto_inbound(public_key, secret_nonce, session_key);
            inconnection = accept_crypto_inbound(inconnection, acceptedfriend_public_key, secret_nonce, session_key);
            /* inconnection = incoming_connection(); */
            if(inconnection != -1) {
                printf("Someone connected to us:\n");
               /* printip(connection_ip(inconnection)); */
            }
        }
        if(handle_friendrequest(acceptedfriend_public_key, request_data) > 1) {
            printf("RECIEVED FRIEND REQUEST: %s\n", request_data);
        }

        /* if someone connected to us write what he sends to a file
         * also send him our file. */
        if(inconnection != -1) {
            if(write_cryptpacket(inconnection, buffer1, read1)) {
                printf("Wrote data1.\n");
                read1 = fread(buffer1, 1, 128, file1);
            }
            read2 = read_cryptpacket(inconnection, buffer2);
            if(read2 != 0) {
                printf("Received data1.\n");
                if(!fwrite(buffer2, read2, 1, file2)) {
                        printf("file write error1\n");
                }
                if(read2 < 128) {
                    printf("Closed file1 %u\n", read2);
                    fclose(file2);
                }
            }
            /* if buffer is empty and the connection timed out. */
            else if(is_cryptoconnected(inconnection) == 4) {
                crypto_kill(inconnection);
            }
        }
        /* if we are connected to a friend send him data from the file.
         * also put what he sends us in a file. */
        if(is_cryptoconnected(connection) >= 3)  {
            if(write_cryptpacket(0, buffer1, read1)) {
                printf("Wrote data2.\n");
                read1 = fread(buffer1, 1, 128, file1);
            }
            read2 = read_cryptpacket(0, buffer2);
            if(read2 != 0) {
                printf("Received data2.\n");
                if(!fwrite(buffer2, read2, 1, file2)) {
                        printf("file write error2\n");
                }
                if(read2 < 128) {
                    printf("Closed file2 %u\n", read2);
                    fclose(file2);
                }
            }
            /* if buffer is empty and the connection timed out. */
            else if(is_cryptoconnected(connection) == 4) {
                crypto_kill(connection);
            }
        }
        doDHT();
        doLossless_UDP();
        doNetCrypto();
        /*print_clientlist();
         *print_friendlist();
         *c_sleep(300); */
        c_sleep(1);
    }
    
    shutdown_networking();
    return 0;   
}
Esempio n. 16
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;
}