diff options
Diffstat (limited to 'core/Messenger.c')
-rw-r--r-- | core/Messenger.c | 49 |
1 files changed, 43 insertions, 6 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 | */ | ||
83 | static 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 | */ |
85 | void getaddress(Messenger *m, uint8_t *address) | 99 | void 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 | */ |
105 | int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) | 124 | int 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); |