diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/DHT.c | 55 | ||||
-rw-r--r-- | core/friend_requests.c | 44 | ||||
-rw-r--r-- | core/net_crypto.c | 51 | ||||
-rw-r--r-- | core/net_crypto.h | 10 |
4 files changed, 82 insertions, 78 deletions
@@ -932,49 +932,30 @@ static int send_NATping(uint8_t * public_key, uint64_t ping_id, uint8_t type) | |||
932 | } | 932 | } |
933 | 933 | ||
934 | /* Handle a received ping request for */ | 934 | /* Handle a received ping request for */ |
935 | static int handle_NATping(IP_Port source, uint8_t * packet, uint32_t length) | 935 | static int handle_NATping(IP_Port source, uint8_t * source_pubkey, uint8_t * packet, uint32_t length) |
936 | { | 936 | { |
937 | if (length < crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING | 937 | uint64_t ping_id; |
938 | || length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 938 | memcpy(&ping_id, packet + 1, sizeof(uint64_t)); |
939 | return 1; | ||
940 | |||
941 | /* check if request is for us. */ | ||
942 | if (id_equal(packet + 1, self_public_key)) { | ||
943 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
944 | uint8_t data[MAX_DATA_SIZE]; | ||
945 | |||
946 | int len = handle_request(public_key, data, packet, length); | ||
947 | if (len != sizeof(uint64_t) + 1) | ||
948 | return 1; | ||
949 | |||
950 | uint64_t ping_id; | ||
951 | memcpy(&ping_id, data + 1, sizeof(uint64_t)); | ||
952 | 939 | ||
953 | int friendnumber = friend_number(public_key); | 940 | int friendnumber = friend_number(source_pubkey); |
954 | if (friendnumber == -1) | 941 | if (friendnumber == -1) |
955 | return 1; | 942 | return 1; |
956 | 943 | ||
957 | Friend * friend = &friends_list[friendnumber]; | 944 | Friend * friend = &friends_list[friendnumber]; |
958 | 945 | ||
959 | if (data[0] == 0) { | 946 | if (packet[0] == 0) { |
960 | /* 1 is reply */ | 947 | /* 1 is reply */ |
961 | send_NATping(public_key, ping_id, 1); | 948 | send_NATping(source_pubkey, ping_id, 1); |
962 | friend->recvNATping_timestamp = unix_time(); | 949 | friend->recvNATping_timestamp = unix_time(); |
950 | return 0; | ||
951 | } else if (packet[0] == 1) { | ||
952 | if (friend->NATping_id == ping_id) { | ||
953 | friend->NATping_id = ((uint64_t)random_int() << 32) + random_int(); | ||
954 | friend->hole_punching = 1; | ||
963 | return 0; | 955 | return 0; |
964 | } else if (data[0] == 1) { | ||
965 | if (friend->NATping_id == ping_id) { | ||
966 | friend->NATping_id = ((uint64_t)random_int() << 32) + random_int(); | ||
967 | friend->hole_punching = 1; | ||
968 | return 0; | ||
969 | } | ||
970 | } | 956 | } |
971 | return 1; | ||
972 | } | 957 | } |
973 | 958 | return 1; | |
974 | /* if request is not for us, try routing it. */ | ||
975 | route_packet(packet + 1, packet, length); | ||
976 | |||
977 | return 0; | ||
978 | } | 959 | } |
979 | 960 | ||
980 | /* Get the most common ip in the ip_portlist | 961 | /* Get the most common ip in the ip_portlist |
@@ -1082,7 +1063,7 @@ void DHT_init(void) | |||
1082 | networking_registerhandler(1, &handle_ping_response); | 1063 | networking_registerhandler(1, &handle_ping_response); |
1083 | networking_registerhandler(2, &handle_getnodes); | 1064 | networking_registerhandler(2, &handle_getnodes); |
1084 | networking_registerhandler(3, &handle_sendnodes); | 1065 | networking_registerhandler(3, &handle_sendnodes); |
1085 | networking_registerhandler(254, &handle_NATping); | 1066 | cryptopacket_registerhandler(254, &handle_NATping); |
1086 | } | 1067 | } |
1087 | 1068 | ||
1088 | void doDHT(void) | 1069 | void doDHT(void) |
diff --git a/core/friend_requests.c b/core/friend_requests.c index 8276db29..ae19ebdd 100644 --- a/core/friend_requests.c +++ b/core/friend_requests.c | |||
@@ -123,39 +123,23 @@ static int request_received(uint8_t * client_id) | |||
123 | } | 123 | } |
124 | 124 | ||
125 | 125 | ||
126 | static int friendreq_handlepacket(IP_Port source, uint8_t * packet, uint32_t length) | 126 | static int friendreq_handlepacket(IP_Port source, uint8_t * source_pubkey, uint8_t * packet, uint32_t length) |
127 | { | 127 | { |
128 | if (packet[0] == 32) { | 128 | if (handle_friendrequest_isset == 0) |
129 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || | 129 | return 1; |
130 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | 130 | if (length <= sizeof(nospam)) |
131 | return 1; | 131 | return 1; |
132 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. | 132 | if (request_received(source_pubkey)) |
133 | if (handle_friendrequest_isset == 0) | 133 | return 1; |
134 | return 1; | 134 | if (memcmp(packet, &nospam, sizeof(nospam)) != 0) |
135 | 135 | return 1; | |
136 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 136 | |
137 | uint8_t data[MAX_DATA_SIZE]; | 137 | addto_receivedlist(source_pubkey); |
138 | int len = handle_request(public_key, data, packet, length); | 138 | (*handle_friendrequest)(source_pubkey, packet + 4, length - 4, handle_friendrequest_userdata); |
139 | if (len == -1) | 139 | return 0; |
140 | return 1; | ||
141 | if (len <= sizeof(nospam)) | ||
142 | return 1; | ||
143 | if (request_received(public_key)) | ||
144 | return 1; | ||
145 | if (memcmp(data, &nospam, sizeof(nospam)) != 0) | ||
146 | return 1; | ||
147 | |||
148 | addto_receivedlist(public_key); | ||
149 | (*handle_friendrequest)(public_key, data + 4, len - 4, handle_friendrequest_userdata); | ||
150 | } else { /* if request is not for us, try routing it. */ | ||
151 | if(route_packet(packet + 1, packet, length) == length) | ||
152 | return 0; | ||
153 | } | ||
154 | } | ||
155 | return 1; | ||
156 | } | 140 | } |
157 | 141 | ||
158 | void friendreq_init(void) | 142 | void friendreq_init(void) |
159 | { | 143 | { |
160 | networking_registerhandler(32, &friendreq_handlepacket); | 144 | cryptopacket_registerhandler(32, &friendreq_handlepacket); |
161 | } | 145 | } |
diff --git a/core/net_crypto.c b/core/net_crypto.c index ab18dd63..376708ab 100644 --- a/core/net_crypto.c +++ b/core/net_crypto.c | |||
@@ -221,15 +221,18 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length) | |||
221 | returns the length of the created packet on success */ | 221 | returns the length of the created packet on success */ |
222 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) | 222 | int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t length, uint8_t request_id) |
223 | { | 223 | { |
224 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + ENCRYPTION_PADDING) | 224 | if (MAX_DATA_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING) |
225 | return -1; | 225 | return -1; |
226 | uint8_t nonce[crypto_box_NONCEBYTES]; | 226 | uint8_t nonce[crypto_box_NONCEBYTES]; |
227 | uint8_t temp[MAX_DATA_SIZE]; | ||
228 | memcpy(temp + 1, data, length); | ||
229 | temp[0] = request_id; | ||
227 | random_nonce(nonce); | 230 | random_nonce(nonce); |
228 | int len = encrypt_data(public_key, self_secret_key, nonce, data, length, | 231 | int len = encrypt_data(public_key, self_secret_key, nonce, temp, length, |
229 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); | 232 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet); |
230 | if (len == -1) | 233 | if (len == -1) |
231 | return -1; | 234 | return -1; |
232 | packet[0] = request_id; | 235 | packet[0] = 32; |
233 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); | 236 | memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES); |
234 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); | 237 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, self_public_key, crypto_box_PUBLICKEYBYTES); |
235 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); | 238 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES); |
@@ -241,7 +244,7 @@ int create_request(uint8_t *packet, uint8_t *public_key, uint8_t *data, uint32_t | |||
241 | in data if a friend or ping request was sent to us and returns the length of the data. | 244 | in data if a friend or ping request was sent to us and returns the length of the data. |
242 | packet is the request packet and length is its length | 245 | packet is the request packet and length is its length |
243 | return -1 if not valid request. */ | 246 | return -1 if not valid request. */ |
244 | int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length) | 247 | static int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *request_id, uint8_t *packet, uint16_t length) |
245 | { | 248 | { |
246 | 249 | ||
247 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && | 250 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING && |
@@ -249,16 +252,51 @@ int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t | |||
249 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { | 252 | memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) { |
250 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); | 253 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES); |
251 | uint8_t nonce[crypto_box_NONCEBYTES]; | 254 | uint8_t nonce[crypto_box_NONCEBYTES]; |
255 | uint8_t temp[MAX_DATA_SIZE]; | ||
252 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); | 256 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES); |
253 | int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, | 257 | int len1 = decrypt_data(public_key, self_secret_key, nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES, |
254 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), data); | 258 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp); |
255 | if(len1 == -1) | 259 | if(len1 == -1 || len1 == 0) |
256 | return -1; | 260 | return -1; |
261 | request_id[0] = temp[0]; | ||
262 | --len1; | ||
263 | memcpy(data, temp + 1, len1); | ||
257 | return len1; | 264 | return len1; |
258 | } else | 265 | } else |
259 | return -1; | 266 | return -1; |
260 | } | 267 | } |
261 | 268 | ||
269 | static cryptopacket_handler_callback cryptopackethandlers[256] = {0}; | ||
270 | |||
271 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb) | ||
272 | { | ||
273 | cryptopackethandlers[byte] = cb; | ||
274 | } | ||
275 | |||
276 | static int cryptopacket_handle(IP_Port source, uint8_t * packet, uint32_t length) | ||
277 | { | ||
278 | if (packet[0] == 32) { | ||
279 | if (length <= crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + ENCRYPTION_PADDING || | ||
280 | length > MAX_DATA_SIZE + ENCRYPTION_PADDING) | ||
281 | return 1; | ||
282 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {// check if request is for us. | ||
283 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
284 | uint8_t data[MAX_DATA_SIZE]; | ||
285 | uint8_t number; | ||
286 | int len = handle_request(public_key, data, &number, packet, length); | ||
287 | if (len == -1 || len == 0) | ||
288 | return 1; | ||
289 | if (!cryptopackethandlers[number]) return 1; | ||
290 | cryptopackethandlers[number](source, public_key, data, len - 1); | ||
291 | |||
292 | } else { /* if request is not for us, try routing it. */ | ||
293 | if(route_packet(packet + 1, packet, length) == length) | ||
294 | return 0; | ||
295 | } | ||
296 | } | ||
297 | return 1; | ||
298 | } | ||
299 | |||
262 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key | 300 | /* Send a crypto handshake packet containing an encrypted secret nonce and session public key |
263 | to peer with connection_id and public_key | 301 | to peer with connection_id and public_key |
264 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ | 302 | the packet is encrypted with a random nonce which is sent in plain text with the packet */ |
@@ -579,6 +617,7 @@ void initNetCrypto(void) | |||
579 | { | 617 | { |
580 | memset(crypto_connections, 0 ,sizeof(crypto_connections)); | 618 | memset(crypto_connections, 0 ,sizeof(crypto_connections)); |
581 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); | 619 | memset(incoming_connections, -1 ,sizeof(incoming_connections)); |
620 | networking_registerhandler(32, &cryptopacket_handle); | ||
582 | uint32_t i; | 621 | uint32_t i; |
583 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) | 622 | for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) |
584 | crypto_connections[i].number = ~0; | 623 | crypto_connections[i].number = ~0; |
diff --git a/core/net_crypto.h b/core/net_crypto.h index 135e099d..570b9373 100644 --- a/core/net_crypto.h +++ b/core/net_crypto.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define NET_CRYPTO_H | 25 | #define NET_CRYPTO_H |
26 | 26 | ||
27 | #include "Lossless_UDP.h" | 27 | #include "Lossless_UDP.h" |
28 | #include "DHT.h" | ||
28 | 29 | ||
29 | #ifdef __cplusplus | 30 | #ifdef __cplusplus |
30 | extern "C" { | 31 | extern "C" { |
@@ -88,11 +89,10 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length); | |||
88 | returns the length of the created packet on success */ | 89 | returns the length of the created packet on success */ |
89 | int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); | 90 | int create_request(uint8_t *packet, uint8_t * public_key, uint8_t *data, uint32_t length, uint8_t request_id); |
90 | 91 | ||
91 | /* puts the senders public key in the request in public_key, the data from the request | 92 | |
92 | in data if a friend or ping request was sent to us and returns the length of the data. | 93 | typedef int (*cryptopacket_handler_callback)(IP_Port ip_port, uint8_t * source_pubkey, uint8_t *data, uint32_t len); |
93 | packet is the request packet and length is its length | 94 | /* Function to call when request beginning with byte is received */ |
94 | return -1 if not valid request. */ | 95 | void cryptopacket_registerhandler(uint8_t byte, cryptopacket_handler_callback cb); |
95 | int handle_request(uint8_t *public_key, uint8_t *data, uint8_t *packet, uint16_t length); | ||
96 | 96 | ||
97 | /* Start a secure connection with other peer who has public_key and ip_port | 97 | /* Start a secure connection with other peer who has public_key and ip_port |
98 | returns -1 if failure | 98 | returns -1 if failure |