summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/Messenger.c49
-rw-r--r--core/Messenger.h8
2 files changed, 49 insertions, 8 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index ae7c5ff3..2721f8f6 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -75,12 +75,26 @@ int getclient_id(Messenger *m, int friend_id, uint8_t *client_id)
75 75
76 return -1; 76 return -1;
77} 77}
78/*
79 * returns a uint16_t that represents the checksum of address of length len
80 *
81 * TODO: Another checksum algorithm might be better.
82 */
83static uint16_t address_checksum(uint8_t *address, uint32_t len)
84{
85 uint8_t checksum[2] = {0};
86 uint16_t check;
87 uint32_t i;
88 for(i = 0; i < len; ++i)
89 checksum[i % 2] ^= address[i];
90 memcpy(&check, checksum, sizeof(check));
91 return check;
92}
78 93
79/* 94/*
80 * returns a FRIEND_ADDRESS_SIZE byte address to give to others. 95 * returns a FRIEND_ADDRESS_SIZE byte address to give to others.
81 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] 96 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
82 * 97 *
83 * TODO: add checksum.
84 */ 98 */
85void getaddress(Messenger *m, uint8_t *address) 99void getaddress(Messenger *m, uint8_t *address)
86{ 100{
@@ -88,12 +102,14 @@ void getaddress(Messenger *m, uint8_t *address)
88 memcpy(address, self_public_key, crypto_box_PUBLICKEYBYTES); 102 memcpy(address, self_public_key, crypto_box_PUBLICKEYBYTES);
89 uint32_t nospam = get_nospam(); 103 uint32_t nospam = get_nospam();
90 memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam)); 104 memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam));
105 uint16_t checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
106 memcpy(address + crypto_box_PUBLICKEYBYTES + sizeof(nospam), &checksum, sizeof(checksum));
91} 107}
92 108
93/* 109/*
94 * add a friend 110 * add a friend
95 * set the data that will be sent along with friend request 111 * set the data that will be sent along with friend request
96 * address is the address of the friend (returned by getaddress) it must be FRIEND_ADDRESS_SIZE bytes. TODO: add checksum. 112 * 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.
97 * data is the data and length is the length 113 * data is the data and length is the length
98 * returns the friend number if success 114 * returns the friend number if success
99 * return FA_TOOLONG if message length is too long 115 * return FA_TOOLONG if message length is too long
@@ -101,6 +117,9 @@ void getaddress(Messenger *m, uint8_t *address)
101 * return FAERR_OWNKEY if user's own key 117 * return FAERR_OWNKEY if user's own key
102 * return FAERR_ALREADYSENT if friend request already sent or already a friend 118 * return FAERR_ALREADYSENT if friend request already sent or already a friend
103 * return FAERR_UNKNOWN for unknown error 119 * return FAERR_UNKNOWN for unknown error
120 * return FAERR_BADCHECKSUM if bad checksum in address
121 * return FAERR_SETNEWNOSPAM if the friend was already there but the nospam was different
122 * (the nospam for that friend was set to the new one)
104 */ 123 */
105int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) 124int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
106{ 125{
@@ -110,12 +129,23 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
110 return FAERR_TOOLONG; 129 return FAERR_TOOLONG;
111 uint8_t client_id[crypto_box_PUBLICKEYBYTES]; 130 uint8_t client_id[crypto_box_PUBLICKEYBYTES];
112 memcpy(client_id, address, crypto_box_PUBLICKEYBYTES); 131 memcpy(client_id, address, crypto_box_PUBLICKEYBYTES);
132 uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
133 memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));
134 if (check != checksum)
135 return FAERR_BADCHECKSUM;
113 if (length < 1) 136 if (length < 1)
114 return FAERR_NOMESSAGE; 137 return FAERR_NOMESSAGE;
115 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 138 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
116 return FAERR_OWNKEY; 139 return FAERR_OWNKEY;
117 if (getfriend_id(m, client_id) != -1) 140 int friend_id = getfriend_id(m, client_id);
118 return FAERR_ALREADYSENT; 141 if (friend_id != -1) {
142 uint32_t nospam;
143 memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam));
144 if(m->friendlist[friend_id].friendrequest_nospam == nospam)
145 return FAERR_ALREADYSENT;
146 m->friendlist[friend_id].friendrequest_nospam = nospam;
147 return FAERR_SETNEWNOSPAM;
148 }
119 149
120 /* resize the friend list if necessary */ 150 /* resize the friend list if necessary */
121 realloc_friendlist(m, m->numfriends + 1); 151 realloc_friendlist(m, m->numfriends + 1);
@@ -730,6 +760,9 @@ void Messenger_save(Messenger *m, uint8_t *data)
730{ 760{
731 save_keys(data); 761 save_keys(data);
732 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 762 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
763 uint32_t nospam = get_nospam();
764 memcpy(data, &nospam, sizeof(nospam));
765 data += sizeof(nospam);
733 uint32_t size = DHT_size(); 766 uint32_t size = DHT_size();
734 memcpy(data, &size, sizeof(size)); 767 memcpy(data, &size, sizeof(size));
735 data += sizeof(size); 768 data += sizeof(size);
@@ -746,11 +779,15 @@ int Messenger_load(Messenger *m, uint8_t * data, uint32_t length)
746{ 779{
747 if (length == ~0) 780 if (length == ~0)
748 return -1; 781 return -1;
749 if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2) 782 if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3)
750 return -1; 783 return -1;
751 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 2; 784 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3;
752 load_keys(data); 785 load_keys(data);
753 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 786 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
787 uint32_t nospam;
788 memcpy(&nospam, data, sizeof(nospam));
789 set_nospam(nospam);
790 data += sizeof(nospam);
754 uint32_t size; 791 uint32_t size;
755 memcpy(&size, data, sizeof(size)); 792 memcpy(&size, data, sizeof(size));
756 data += sizeof(size); 793 data += sizeof(size);
diff --git a/core/Messenger.h b/core/Messenger.h
index 48e14cf7..9621176f 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -61,6 +61,8 @@ extern "C" {
61#define FAERR_OWNKEY -3 61#define FAERR_OWNKEY -3
62#define FAERR_ALREADYSENT -4 62#define FAERR_ALREADYSENT -4
63#define FAERR_UNKNOWN -5 63#define FAERR_UNKNOWN -5
64#define FAERR_BADCHECKSUM -6
65#define FAERR_SETNEWNOSPAM -7
64 66
65/* don't assume MAX_STATUSMESSAGE_LENGTH will stay at 128, it may be increased 67/* don't assume MAX_STATUSMESSAGE_LENGTH will stay at 128, it may be increased
66 to an absurdly large number later */ 68 to an absurdly large number later */
@@ -140,14 +142,13 @@ typedef struct Messenger {
140 * returns a FRIEND_ADDRESS_SIZE byte address to give to others. 142 * returns a FRIEND_ADDRESS_SIZE byte address to give to others.
141 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] 143 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
142 * 144 *
143 * TODO: add checksum.
144 */ 145 */
145void getaddress(Messenger *m, uint8_t *address); 146void getaddress(Messenger *m, uint8_t *address);
146 147
147/* 148/*
148 * add a friend 149 * add a friend
149 * set the data that will be sent along with friend request 150 * set the data that will be sent along with friend request
150 * address is the address of the friend (returned by getaddress) it must be FRIEND_ADDRESS_SIZE bytes. TODO: add checksum. 151 * 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.
151 * data is the data and length is the length 152 * data is the data and length is the length
152 * returns the friend number if success 153 * returns the friend number if success
153 * return -1 if message length is too long 154 * return -1 if message length is too long
@@ -155,6 +156,9 @@ void getaddress(Messenger *m, uint8_t *address);
155 * return -3 if user's own key 156 * return -3 if user's own key
156 * return -4 if friend request already sent or already a friend 157 * return -4 if friend request already sent or already a friend
157 * return -5 for unknown error 158 * return -5 for unknown error
159 * return -6 if bad checksum in address
160 * return -7 if the friend was already there but the nospam was different
161 * (the nospam for that friend was set to the new one)
158 */ 162 */
159int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length); 163int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length);
160 164