00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "olsrd_secure.h"
00048
00049 #include <stdio.h>
00050 #include <string.h>
00051 #include <stdlib.h>
00052 #ifdef linux
00053 #include <linux/in_route.h>
00054 #endif
00055 #include <unistd.h>
00056 #include <errno.h>
00057 #include <signal.h>
00058
00059 #include "defs.h"
00060 #include "ipcalc.h"
00061 #include "olsr.h"
00062 #include "parser.h"
00063 #include "olsr_timer.h"
00064 #include "olsr_socket.h"
00065 #include "net_olsr.h"
00066 #include "common/string.h"
00067 #include "olsr_logging.h"
00068 #include "os_time.h"
00069
00070 #ifdef USE_OPENSSL
00071
00072
00073 #include <openssl/sha.h>
00074
00075 #define CHECKSUM SHA1
00076 #define SCHEME SHA1_INCLUDING_KEY
00077
00078 #else
00079
00080
00081 #include "md5.h"
00082
00083 static void
00084 MD5_checksum(const uint8_t * data, const uint16_t data_len, uint8_t * hashbuf)
00085 {
00086 MD5_CTX context;
00087
00088 MD5Init(&context);
00089 MD5Update(&context, data, data_len);
00090 MD5Final(hashbuf, &context);
00091 }
00092
00093 #define CHECKSUM MD5_checksum
00094 #define SCHEME MD5_INCLUDING_KEY
00095
00096 #endif
00097
00098 #ifdef OS
00099 #undef OS
00100 #endif
00101
00102 #ifdef WIN32
00103 #undef EWOULDBLOCK
00104 #define EWOULDBLOCK WSAEWOULDBLOCK
00105 #define OS "Windows"
00106 #endif
00107 #ifdef linux
00108 #define OS "GNU/Linux"
00109 #endif
00110 #ifdef __FreeBSD__
00111 #define OS "FreeBSD"
00112 #endif
00113
00114 #ifndef OS
00115 #define OS "Undefined"
00116 #endif
00117
00118 static struct timeval now;
00119
00120
00121 struct stamp {
00122 union olsr_ip_addr addr;
00123
00124 int diff;
00125 uint32_t challenge;
00126 uint8_t validated;
00127 uint32_t valtime;
00128 uint32_t conftime;
00129 struct stamp *prev;
00130 struct stamp *next;
00131 };
00132
00133
00134 #define TIMESTAMP_HOLD_TIME 30
00135
00136
00137 #define EXCHANGE_HOLD_TIME 5
00138
00139 static struct stamp timestamps[HASHSIZE];
00140
00141
00142 char keyfile[FILENAME_MAX + 1];
00143 char aes_key[16];
00144
00145
00146 #if 0
00147 static void olsr_event(void);
00148 #endif
00149 static int send_challenge(struct interface *olsr_if_config, const union olsr_ip_addr *);
00150 static int send_cres(struct interface *olsr_if_config, union olsr_ip_addr *, union olsr_ip_addr *, uint32_t, struct stamp *);
00151 static int send_rres(struct interface *olsr_if_config, union olsr_ip_addr *, union olsr_ip_addr *, uint32_t);
00152 static int parse_challenge(struct interface *olsr_if_config, uint8_t *);
00153 static int parse_cres(struct interface *olsr_if_config, uint8_t *);
00154 static int parse_rres(uint8_t *);
00155 static int check_auth(struct interface *olsr_if_config, uint8_t *, int *);
00156 #if 0
00157 static int ipc_send(char *, int);
00158 #endif
00159 static int add_signature(uint8_t *, int *);
00160 static int validate_packet(struct interface *olsr_if_config, const uint8_t *, int *);
00161 static uint8_t *secure_preprocessor(uint8_t *packet, struct interface *olsr_if_config, union olsr_ip_addr *from_addr, int *length);
00162 static void timeout_timestamps(void *);
00163 static int check_timestamp(struct interface *olsr_if_config, const union olsr_ip_addr *, time_t);
00164 static struct stamp *lookup_timestamp_entry(const union olsr_ip_addr *);
00165 static int read_key_from_file(const char *);
00166
00167 static struct olsr_timer_info *timeout_timestamps_timer_info;
00168
00175 int
00176 secure_plugin_init(void)
00177 {
00178 int i;
00179
00180
00181
00182 for (i = 0; i < HASHSIZE; i++) {
00183 timestamps[i].next = ×tamps[i];
00184 timestamps[i].prev = ×tamps[i];
00185 }
00186 OLSR_INFO(LOG_PLUGINS, "Timestamp database initialized\n");
00187
00188 if (!strlen(keyfile))
00189 strscpy(keyfile, KEYFILE, sizeof(keyfile));
00190
00191 i = read_key_from_file(keyfile);
00192
00193 if (i < 0) {
00194 OLSR_ERROR(LOG_PLUGINS, "[ENC]Could not read key from file %s!\nExitting!\n\n", keyfile);
00195 olsr_exit(1);
00196 }
00197 if (i == 0) {
00198 OLSR_ERROR(LOG_PLUGINS, "[ENC]There was a problem reading key from file %s. Is the key long enough?\nExitting!\n\n", keyfile);
00199 olsr_exit(1);
00200 }
00201
00202
00203 add_ptf(&add_signature);
00204
00205 olsr_preprocessor_add_function(&secure_preprocessor);
00206
00207
00208 timeout_timestamps_timer_info = olsr_timer_add("Secure: Timeout Timestamps", &timeout_timestamps, true);
00209
00210
00211 olsr_timer_start(2 * MSEC_PER_SEC, 0, NULL, timeout_timestamps_timer_info);
00212
00213 return 1;
00214 }
00215
00216 int
00217 plugin_ipc_init(void)
00218 {
00219 return 1;
00220 }
00221
00222
00223
00224
00225 void
00226 secure_plugin_exit(void)
00227 {
00228 olsr_preprocessor_remove_function(&secure_preprocessor);
00229 }
00230
00231
00232 #if 0
00233
00237 static void
00238 olsr_event(void)
00239 {
00240
00241 }
00242 #endif
00243
00244 #if 0
00245 static int
00246 ipc_send(char *data __attribute__ ((unused)), int size __attribute__ ((unused)))
00247 {
00248 return 1;
00249 }
00250 #endif
00251
00252 static uint8_t *
00253 secure_preprocessor(uint8_t *packet, struct interface *olsr_if_config, union olsr_ip_addr *from_addr
00254 __attribute__ ((unused)), int *length)
00255 {
00256 struct olsr_packet *olsr = (struct olsr_packet *)packet;
00257 #if !defined REMOVE_LOG_DEBUG
00258 struct ipaddr_str buf;
00259 #endif
00260
00261
00262
00263 check_auth(olsr_if_config, packet, length);
00264
00265
00266
00267
00268
00269 if (!validate_packet(olsr_if_config, packet, length)) {
00270 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Rejecting packet from %s\n", olsr_ip_to_string(&buf, from_addr));
00271 return NULL;
00272 }
00273
00274 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Packet from %s OK size %d\n", olsr_ip_to_string(&buf, from_addr), *length);
00275
00276
00277 olsr->size = htons(*length);
00278 return packet;
00279 }
00280
00281
00282
00290 static int
00291 check_auth(struct interface *olsr_if_config, uint8_t *pck, int *size __attribute__ ((unused)))
00292 {
00293
00294 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Checking packet for challenge response message...\n");
00295
00296 switch (pck[4]) {
00297 case (TYPE_CHALLENGE):
00298 parse_challenge(olsr_if_config, &pck[4]);
00299 break;
00300
00301 case (TYPE_CRESPONSE):
00302 parse_cres(olsr_if_config, &pck[4]);
00303 break;
00304
00305 case (TYPE_RRESPONSE):
00306 parse_rres(&pck[4]);
00307 break;
00308
00309 default:
00310 return 0;
00311 }
00312
00313 return 1;
00314 }
00315
00316
00317
00326 int
00327 add_signature(uint8_t * pck, int *size)
00328 {
00329 struct s_olsrmsg *msg;
00330 #ifdef DEBUG
00331 #endif
00332
00333 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Adding signature for packet size %d\n", *size);
00334
00335 msg = (struct s_olsrmsg *)(ARM_NOWARN_ALIGN(&pck[*size]));
00336
00337 ((struct olsr_packet *)pck)->size = htons(*size + sizeof(struct s_olsrmsg));
00338
00339
00340 msg->olsr_msgtype = MESSAGE_TYPE;
00341 msg->olsr_vtime = 0;
00342 msg->olsr_msgsize = htons(sizeof(struct s_olsrmsg));
00343 memcpy(&msg->originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
00344 msg->ttl = 1;
00345 msg->hopcnt = 0;
00346 msg->seqno = htons(get_msg_seqno());
00347
00348
00349 msg->sig.type = ONE_CHECKSUM;
00350 msg->sig.algorithm = SCHEME;
00351 memset(&msg->sig.reserved, 0, 2);
00352
00353
00354 msg->sig.timestamp = htonl(now.tv_sec);
00355 OLSR_DEBUG(LOG_PLUGINS, "[ENC]timestamp: %ld\n", (long)now.tv_sec);
00356
00357
00358 *size += sizeof(struct s_olsrmsg);
00359
00360 {
00361 uint8_t checksum_cache[512 + KEYLENGTH];
00362
00363
00364 memcpy(checksum_cache, pck, *size - SIGNATURE_SIZE);
00365
00366 memcpy(&checksum_cache[*size - SIGNATURE_SIZE], aes_key, KEYLENGTH);
00367
00368
00369 CHECKSUM(checksum_cache, (*size - SIGNATURE_SIZE) + KEYLENGTH, &pck[*size - SIGNATURE_SIZE]);
00370 }
00371
00372 #if 0
00373 {
00374 unsigned int i;
00375 int j;
00376 const uint8_t *sigmsg;
00377 OLSR_PRINTF(1, "Signature message:\n");
00378
00379 j = 0;
00380 sigmsg = (uint8_t *) msg;
00381
00382 for (i = 0; i < sizeof(struct s_olsrmsg); i++) {
00383 OLSR_PRINTF(1, " %3i", sigmsg[i]);
00384 j++;
00385 if (j == 4) {
00386 OLSR_PRINTF(1, "\n");
00387 j = 0;
00388 }
00389 }
00390 }
00391 #endif
00392
00393 OLSR_DEBUG(LOG_PLUGINS, "[ENC] Message signed\n");
00394
00395 return 1;
00396 }
00397
00398
00399
00400 static int
00401 validate_packet(struct interface *olsr_if_config, const uint8_t *pck, int *size)
00402 {
00403 int packetsize;
00404 uint8_t sha1_hash[SIGNATURE_SIZE];
00405 const struct s_olsrmsg *sig;
00406 time_t rec_time;
00407
00408
00409 packetsize = *size - sizeof(struct s_olsrmsg);
00410
00411 if (packetsize < 4)
00412 return 0;
00413
00414 sig = (const struct s_olsrmsg *)(ARM_CONST_NOWARN_ALIGN)&pck[packetsize];
00415
00416
00417
00418 #if 0
00419 {
00420 unsigned int i;
00421 int j;
00422 const uint8_t *sigmsg;
00423 OLSR_PRINTF(1, "Input message:\n");
00424
00425 j = 0;
00426 sigmsg = (const uint8_t *)sig;
00427
00428 for (i = 0; i < sizeof(struct s_olsrmsg); i++) {
00429 OLSR_PRINTF(1, " %3i", sigmsg[i]);
00430 j++;
00431 if (j == 4) {
00432 OLSR_PRINTF(1, "\n");
00433 j = 0;
00434 }
00435 }
00436 }
00437 #endif
00438
00439
00440 if ((sig->olsr_msgtype != MESSAGE_TYPE) ||
00441 (sig->olsr_vtime != 0) || (sig->olsr_msgsize != ntohs(sizeof(struct s_olsrmsg))) || (sig->ttl != 1) || (sig->hopcnt != 0)) {
00442 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Packet not sane!\n");
00443 return 0;
00444 }
00445
00446
00447 switch (sig->sig.type) {
00448 case (ONE_CHECKSUM):
00449 switch (sig->sig.algorithm) {
00450 case (SCHEME):
00451 goto one_checksum_SHA;
00452 break;
00453
00454 }
00455 break;
00456
00457 default:
00458 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Unsupported sceme: %d enc: %d!\n", sig->sig.type, sig->sig.algorithm);
00459 return 0;
00460 }
00461
00462
00463 one_checksum_SHA:
00464
00465 {
00466 uint8_t checksum_cache[512 + KEYLENGTH];
00467
00468
00469 memcpy(checksum_cache, pck, *size - SIGNATURE_SIZE);
00470
00471 memcpy(&checksum_cache[*size - SIGNATURE_SIZE], aes_key, KEYLENGTH);
00472
00473
00474 CHECKSUM(checksum_cache, *size - SIGNATURE_SIZE + KEYLENGTH, sha1_hash);
00475 }
00476
00477 #if 0
00478 OLSR_PRINTF(1, "Recevied hash:\n");
00479
00480 sigmsg = (const uint8_t *)sig->sig.signature;
00481
00482 for (i = 0; i < SIGNATURE_SIZE; i++) {
00483 OLSR_PRINTF(1, " %3i", sigmsg[i]);
00484 }
00485 OLSR_PRINTF(1, "\n");
00486
00487 OLSR_PRINTF(1, "Calculated hash:\n");
00488
00489 sigmsg = sha1_hash;
00490
00491 for (i = 0; i < SIGNATURE_SIZE; i++) {
00492 OLSR_PRINTF(1, " %3i", sigmsg[i]);
00493 }
00494 OLSR_PRINTF(1, "\n");
00495 #endif
00496
00497 if (memcmp(sha1_hash, sig->sig.signature, SIGNATURE_SIZE) != 0) {
00498 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Signature missmatch\n");
00499 return 0;
00500 }
00501
00502
00503 rec_time = ntohl(sig->sig.timestamp);
00504
00505 if (!check_timestamp(olsr_if_config, (const union olsr_ip_addr *)&sig->originator, rec_time)) {
00506 #if !defined REMOVE_LOG_DEBUG
00507 struct ipaddr_str buf;
00508 #endif
00509 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Timestamp missmatch in packet from %s!\n",
00510 olsr_ip_to_string(&buf, (const union olsr_ip_addr *)&sig->originator));
00511 return 0;
00512 }
00513
00514 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Received timestamp %ld diff: %ld\n", (long)rec_time,
00515 (long)now.tv_sec - (long)rec_time);
00516
00517
00518 *size = packetsize;
00519 return 1;
00520 }
00521
00522
00523 int
00524 check_timestamp(struct interface *olsr_if_config, const union olsr_ip_addr *originator, time_t tstamp)
00525 {
00526 struct stamp *entry;
00527 int diff;
00528
00529 entry = lookup_timestamp_entry(originator);
00530
00531 if (!entry) {
00532
00533
00534 send_challenge(olsr_if_config, originator);
00535
00536 return 0;
00537 }
00538
00539 if (!entry->validated) {
00540 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Message from non-validated host!\n");
00541 return 0;
00542 }
00543
00544 diff = entry->diff - (now.tv_sec - tstamp);
00545
00546 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Timestamp slack: %d\n", diff);
00547
00548 if ((diff > UPPER_DIFF) || (diff < LOWER_DIFF)) {
00549 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Timestamp scew detected!!\n");
00550 return 0;
00551 }
00552
00553
00554 entry->diff = ((now.tv_sec - tstamp) + entry->diff) ? ((now.tv_sec - tstamp) + entry->diff) / 2 : 0;
00555
00556 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Diff set to : %d\n", entry->diff);
00557
00558
00559
00560 entry->valtime = olsr_clock_getAbsolute(TIMESTAMP_HOLD_TIME * 1000);
00561
00562 return 1;
00563 }
00564
00565
00574 int
00575 send_challenge(struct interface *olsr_if_config, const union olsr_ip_addr *new_host)
00576 {
00577 struct challengemsg cmsg;
00578 struct stamp *entry;
00579 uint32_t challenge, hash;
00580 #if !defined REMOVE_LOG_DEBUG
00581 struct ipaddr_str buf;
00582 #endif
00583
00584 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Building CHALLENGE message\n");
00585
00586
00587
00588
00589 challenge = rand() << 16;
00590 challenge |= rand();
00591
00592
00593 cmsg.olsr_msgtype = TYPE_CHALLENGE;
00594 cmsg.olsr_vtime = 0;
00595 cmsg.olsr_msgsize = htons(sizeof(struct challengemsg));
00596 memcpy(&cmsg.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
00597 cmsg.ttl = 1;
00598 cmsg.hopcnt = 0;
00599 cmsg.seqno = htons(get_msg_seqno());
00600
00601
00602 memcpy(&cmsg.destination, new_host, olsr_cnf->ipsize);
00603 cmsg.challenge = htonl(challenge);
00604
00605 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Size: %lu\n", (unsigned long)sizeof(struct challengemsg));
00606
00607 {
00608 uint8_t checksum_cache[512 + KEYLENGTH];
00609
00610
00611 memcpy(checksum_cache, &cmsg, sizeof(struct challengemsg) - SIGNATURE_SIZE);
00612
00613 memcpy(&checksum_cache[sizeof(struct challengemsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
00614
00615
00616 CHECKSUM(checksum_cache, (sizeof(struct challengemsg) - SIGNATURE_SIZE) + KEYLENGTH, cmsg.signature);
00617 }
00618 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Sending timestamp request to %s challenge 0x%x\n", olsr_ip_to_string(&buf, new_host), challenge);
00619
00620
00621 net_outbuffer_push(olsr_if_config, &cmsg, sizeof(struct challengemsg));
00622
00623
00624 net_output(olsr_if_config);
00625
00626
00627 entry = malloc(sizeof(struct stamp));
00628
00629 entry->diff = 0;
00630 entry->validated = 0;
00631 entry->challenge = challenge;
00632
00633 memcpy(&entry->addr, new_host, olsr_cnf->ipsize);
00634
00635
00636 entry->conftime = olsr_clock_getAbsolute(EXCHANGE_HOLD_TIME * 1000);
00637
00638 hash = olsr_ip_hashing(new_host);
00639
00640
00641 timestamps[hash].next->prev = entry;
00642 entry->next = timestamps[hash].next;
00643 timestamps[hash].next = entry;
00644 entry->prev = ×tamps[hash];
00645
00646
00647 return 1;
00648
00649 }
00650
00651 int
00652 parse_cres(struct interface *olsr_if_config, uint8_t *in_msg)
00653 {
00654 struct c_respmsg *msg;
00655 uint8_t sha1_hash[SIGNATURE_SIZE];
00656 struct stamp *entry;
00657 #if !defined REMOVE_LOG_DEBUG
00658 struct ipaddr_str buf;
00659 #endif
00660
00661 msg = (struct c_respmsg *)(ARM_NOWARN_ALIGN(in_msg));
00662
00663 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge-response message received\n");
00664 OLSR_DEBUG(LOG_PLUGINS, "[ENC]To: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->destination));
00665
00666 if (if_ifwithaddr((union olsr_ip_addr *)&msg->destination) == NULL) {
00667 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Not for us...\n");
00668 return 0;
00669 }
00670
00671 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge: 0x%lx\n", (unsigned long)ntohl(msg->challenge));
00672
00673
00674
00675 {
00676 uint8_t checksum_cache[512 + KEYLENGTH];
00677
00678
00679 memcpy(checksum_cache, msg, sizeof(struct c_respmsg) - SIGNATURE_SIZE);
00680
00681 memcpy(&checksum_cache[sizeof(struct c_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
00682
00683
00684 CHECKSUM(checksum_cache, (sizeof(struct c_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, sha1_hash);
00685 }
00686
00687 if (memcmp(sha1_hash, &msg->signature, SIGNATURE_SIZE) != 0) {
00688 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Signature missmatch in challenge-response!\n");
00689 return 0;
00690 }
00691
00692 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Signature verified\n");
00693
00694
00695
00696 if ((entry = lookup_timestamp_entry((const union olsr_ip_addr *)&msg->originator)) == NULL) {
00697 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Received challenge-response from non-registered node %s!\n",
00698 olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator));
00699 return 0;
00700 }
00701
00702
00703 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Entry-challenge 0x%x\n", entry->challenge);
00704
00705 {
00706 uint8_t checksum_cache[512 + KEYLENGTH];
00707
00708 memcpy(checksum_cache, &entry->challenge, 4);
00709
00710 memcpy(&checksum_cache[sizeof(uint32_t)], &msg->originator, olsr_cnf->ipsize);
00711
00712
00713 CHECKSUM(checksum_cache, sizeof(uint32_t) + olsr_cnf->ipsize, sha1_hash);
00714 }
00715
00716 if (memcmp(msg->res_sig, sha1_hash, SIGNATURE_SIZE) != 0) {
00717 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Error in challenge signature from %s!\n",
00718 olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator));
00719
00720 return 0;
00721 }
00722
00723 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge-response signature ok\n");
00724
00725
00726
00727
00728 entry->challenge = 0;
00729 entry->validated = 1;
00730 entry->diff = now.tv_sec - msg->timestamp;
00731
00732
00733 entry->valtime = olsr_clock_getAbsolute(TIMESTAMP_HOLD_TIME * 1000);
00734
00735 OLSR_DEBUG(LOG_PLUGINS, "[ENC]%s registered with diff %d!\n",
00736 olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator), entry->diff);
00737
00738
00739 send_rres(olsr_if_config, (union olsr_ip_addr *)&msg->originator, (union olsr_ip_addr *)&msg->destination, ntohl(msg->challenge));
00740
00741 return 1;
00742 }
00743
00744
00745 int
00746 parse_rres(uint8_t *in_msg)
00747 {
00748 struct r_respmsg *msg;
00749 uint8_t sha1_hash[SIGNATURE_SIZE];
00750 struct stamp *entry;
00751 #if !defined REMOVE_LOG_DEBUG
00752 struct ipaddr_str buf;
00753 #endif
00754
00755 msg = (struct r_respmsg *)(ARM_NOWARN_ALIGN(in_msg));
00756
00757 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Response-response message received\n");
00758 OLSR_DEBUG(LOG_PLUGINS, "[ENC]To: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->destination));
00759
00760 if (if_ifwithaddr((union olsr_ip_addr *)&msg->destination) == NULL) {
00761 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Not for us...\n");
00762 return 0;
00763 }
00764
00765
00766
00767 {
00768 uint8_t checksum_cache[512 + KEYLENGTH];
00769
00770
00771 memcpy(checksum_cache, msg, sizeof(struct r_respmsg) - SIGNATURE_SIZE);
00772
00773 memcpy(&checksum_cache[sizeof(struct r_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
00774
00775
00776 CHECKSUM(checksum_cache, (sizeof(struct r_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, sha1_hash);
00777 }
00778
00779 if (memcmp(sha1_hash, &msg->signature, SIGNATURE_SIZE) != 0) {
00780 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Signature missmatch in response-response!\n");
00781 return 0;
00782 }
00783
00784 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Signature verified\n");
00785
00786
00787
00788 if ((entry = lookup_timestamp_entry((const union olsr_ip_addr *)&msg->originator)) == NULL) {
00789 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Received response-response from non-registered node %s!\n",
00790 olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator));
00791 return 0;
00792 }
00793
00794
00795 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Entry-challenge 0x%x\n", entry->challenge);
00796
00797 {
00798 uint8_t checksum_cache[512 + KEYLENGTH];
00799
00800 memcpy(checksum_cache, &entry->challenge, 4);
00801
00802 memcpy(&checksum_cache[sizeof(uint32_t)], &msg->originator, olsr_cnf->ipsize);
00803
00804
00805 CHECKSUM(checksum_cache, sizeof(uint32_t) + olsr_cnf->ipsize, sha1_hash);
00806 }
00807
00808 if (memcmp(msg->res_sig, sha1_hash, SIGNATURE_SIZE) != 0) {
00809 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Error in response signature from %s!\n",
00810 olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator));
00811
00812 return 0;
00813 }
00814
00815 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge-response signature ok\n");
00816
00817
00818
00819
00820 entry->challenge = 0;
00821 entry->validated = 1;
00822 entry->diff = now.tv_sec - msg->timestamp;
00823
00824
00825 entry->valtime = olsr_clock_getAbsolute(TIMESTAMP_HOLD_TIME * 1000);
00826
00827 OLSR_DEBUG(LOG_PLUGINS, "[ENC]%s registered with diff %d!\n",
00828 olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->originator), entry->diff);
00829
00830 return 1;
00831 }
00832
00833
00834 int
00835 parse_challenge(struct interface *olsr_if_config, uint8_t *in_msg)
00836 {
00837 struct challengemsg *msg;
00838 uint8_t sha1_hash[SIGNATURE_SIZE];
00839 struct stamp *entry;
00840 uint32_t hash;
00841 #if !defined REMOVE_LOG_DEBUG
00842 struct ipaddr_str buf;
00843 #endif
00844
00845 msg = (struct challengemsg *)(ARM_NOWARN_ALIGN(in_msg));
00846
00847 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge message received\n");
00848 OLSR_DEBUG(LOG_PLUGINS, "[ENC]To: %s\n", olsr_ip_to_string(&buf, (union olsr_ip_addr *)&msg->destination));
00849
00850 if (if_ifwithaddr((union olsr_ip_addr *)&msg->destination) == NULL) {
00851 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Not for us...\n");
00852 return 0;
00853 }
00854
00855
00856 if ((entry = lookup_timestamp_entry((const union olsr_ip_addr *)&msg->originator)) == NULL) {
00857 entry = malloc(sizeof(struct stamp));
00858 memcpy(&entry->addr, &msg->originator, olsr_cnf->ipsize);
00859
00860 hash = olsr_ip_hashing((union olsr_ip_addr *)&msg->originator);
00861
00862
00863 timestamps[hash].next->prev = entry;
00864 entry->next = timestamps[hash].next;
00865 timestamps[hash].next = entry;
00866 entry->prev = ×tamps[hash];
00867 } else {
00868
00869 if (!olsr_clock_isPast(entry->conftime)) {
00870
00871 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge from registered node...dropping!\n");
00872 return 0;
00873 } else {
00874 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge from registered node...accepted!\n");
00875 }
00876 }
00877
00878 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge: 0x%lx\n", (unsigned long)ntohl(msg->challenge));
00879
00880
00881
00882 {
00883 uint8_t checksum_cache[512 + KEYLENGTH];
00884
00885
00886 memcpy(checksum_cache, msg, sizeof(struct challengemsg) - SIGNATURE_SIZE);
00887
00888 memcpy(&checksum_cache[sizeof(struct challengemsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
00889
00890
00891 CHECKSUM(checksum_cache, (sizeof(struct challengemsg) - SIGNATURE_SIZE) + KEYLENGTH, sha1_hash);
00892 }
00893 if (memcmp(sha1_hash, &msg->signature, SIGNATURE_SIZE) != 0) {
00894 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Signature missmatch in challenge!\n");
00895 return 0;
00896 }
00897
00898 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Signature verified\n");
00899
00900
00901 entry->diff = 0;
00902 entry->validated = 0;
00903
00904
00905 entry->conftime = olsr_clock_getAbsolute(EXCHANGE_HOLD_TIME * 1000);
00906
00907
00908
00909 send_cres(olsr_if_config, (union olsr_ip_addr *)&msg->originator,
00910 (union olsr_ip_addr *)&msg->destination, ntohl(msg->challenge), entry);
00911
00912 return 1;
00913 }
00914
00915
00916
00917
00918
00924 int
00925 send_cres(struct interface *olsr_if_config, union olsr_ip_addr *to, union olsr_ip_addr *from, uint32_t chal_in, struct stamp *entry)
00926 {
00927 struct c_respmsg crmsg;
00928 uint32_t challenge;
00929 #if !defined REMOVE_LOG_DEBUG
00930 struct ipaddr_str buf;
00931 #endif
00932
00933 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Building CRESPONSE message\n");
00934
00935 challenge = rand() << 16;
00936 challenge |= rand();
00937
00938 entry->challenge = challenge;
00939
00940 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Challenge-response: 0x%x\n", challenge);
00941
00942
00943 crmsg.olsr_msgtype = TYPE_CRESPONSE;
00944 crmsg.olsr_vtime = 0;
00945 crmsg.olsr_msgsize = htons(sizeof(struct c_respmsg));
00946 memcpy(&crmsg.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
00947 crmsg.ttl = 1;
00948 crmsg.hopcnt = 0;
00949 crmsg.seqno = htons(get_msg_seqno());
00950
00951
00952 crmsg.timestamp = now.tv_sec;
00953 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Timestamp %ld\n", (long)crmsg.timestamp);
00954
00955
00956 memcpy(&crmsg.destination, to, olsr_cnf->ipsize);
00957 crmsg.challenge = htonl(challenge);
00958
00959
00960
00961 {
00962 uint8_t checksum_cache[512 + KEYLENGTH];
00963
00964
00965 memcpy(checksum_cache, &chal_in, 4);
00966
00967 memcpy(&checksum_cache[sizeof(uint32_t)], from, olsr_cnf->ipsize);
00968
00969
00970 CHECKSUM(checksum_cache, sizeof(uint32_t) + olsr_cnf->ipsize, crmsg.res_sig);
00971 }
00972
00973
00974
00975 {
00976 uint8_t checksum_cache[512 + KEYLENGTH];
00977
00978
00979 memcpy(checksum_cache, &crmsg, sizeof(struct c_respmsg) - SIGNATURE_SIZE);
00980
00981 memcpy(&checksum_cache[sizeof(struct c_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
00982
00983
00984 CHECKSUM(checksum_cache, (sizeof(struct c_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, crmsg.signature);
00985 }
00986
00987 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Sending challenge response to %s challenge 0x%x\n", olsr_ip_to_string(&buf, to), challenge);
00988
00989
00990 net_outbuffer_push(olsr_if_config, &crmsg, sizeof(struct c_respmsg));
00991
00992 net_output(olsr_if_config);
00993
00994 return 1;
00995 }
00996
00997
00998
00999
01000
01001
01007 static int
01008 send_rres(struct interface *olsr_if_config, union olsr_ip_addr *to, union olsr_ip_addr *from, uint32_t chal_in)
01009 {
01010 struct r_respmsg rrmsg;
01011 #if !defined REMOVE_LOG_DEBUG
01012 struct ipaddr_str buf;
01013 #endif
01014
01015 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Building RRESPONSE message\n");
01016
01017
01018
01019 rrmsg.olsr_msgtype = TYPE_RRESPONSE;
01020 rrmsg.olsr_vtime = 0;
01021 rrmsg.olsr_msgsize = htons(sizeof(struct r_respmsg));
01022 memcpy(&rrmsg.originator, &olsr_cnf->router_id, olsr_cnf->ipsize);
01023 rrmsg.ttl = 1;
01024 rrmsg.hopcnt = 0;
01025 rrmsg.seqno = htons(get_msg_seqno());
01026
01027
01028 rrmsg.timestamp = now.tv_sec;
01029 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Timestamp %ld\n", (long)rrmsg.timestamp);
01030
01031
01032 memcpy(&rrmsg.destination, to, olsr_cnf->ipsize);
01033
01034
01035
01036 {
01037 uint8_t checksum_cache[512 + KEYLENGTH];
01038
01039
01040 memcpy(checksum_cache, &chal_in, 4);
01041
01042 memcpy(&checksum_cache[sizeof(uint32_t)], from, olsr_cnf->ipsize);
01043
01044
01045 CHECKSUM(checksum_cache, sizeof(uint32_t) + olsr_cnf->ipsize, rrmsg.res_sig);
01046 }
01047
01048
01049
01050 {
01051 uint8_t checksum_cache[512 + KEYLENGTH];
01052
01053
01054 memcpy(checksum_cache, &rrmsg, sizeof(struct r_respmsg) - SIGNATURE_SIZE);
01055
01056 memcpy(&checksum_cache[sizeof(struct r_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH);
01057
01058
01059 CHECKSUM(checksum_cache, (sizeof(struct r_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, rrmsg.signature);
01060 }
01061
01062 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Sending response response to %s\n", olsr_ip_to_string(&buf, to));
01063
01064
01065 net_outbuffer_push(olsr_if_config, &rrmsg, sizeof(struct r_respmsg));
01066
01067
01068 net_output(olsr_if_config);
01069
01070 return 1;
01071 }
01072
01073
01074
01075 static struct stamp *
01076 lookup_timestamp_entry(const union olsr_ip_addr *adr)
01077 {
01078 uint32_t hash;
01079 struct stamp *entry;
01080 #if !defined REMOVE_LOG_DEBUG
01081 struct ipaddr_str buf;
01082 #endif
01083
01084 hash = olsr_ip_hashing(adr);
01085
01086 for (entry = timestamps[hash].next; entry != ×tamps[hash]; entry = entry->next) {
01087 if (memcmp(&entry->addr, adr, olsr_cnf->ipsize) == 0) {
01088 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Match for %s\n", olsr_ip_to_string(&buf, adr));
01089 return entry;
01090 }
01091 }
01092
01093 OLSR_DEBUG(LOG_PLUGINS, "[ENC]No match for %s\n", olsr_ip_to_string(&buf, adr));
01094
01095 return NULL;
01096 }
01097
01098
01099
01105 void
01106 timeout_timestamps(void *foo __attribute__ ((unused)))
01107 {
01108 struct stamp *tmp_list;
01109 struct stamp *entry_to_delete;
01110 int idx;
01111
01112
01113 os_gettimeofday(&now, NULL);
01114
01115 for (idx = 0; idx < HASHSIZE; idx++) {
01116 tmp_list = timestamps[idx].next;
01117
01118 while (tmp_list != ×tamps[idx]) {
01119
01120 if ((olsr_clock_isPast(tmp_list->valtime)) && (olsr_clock_isPast(tmp_list->conftime))) {
01121 #if !defined REMOVE_LOG_DEBUG
01122 struct ipaddr_str buf;
01123 #endif
01124 entry_to_delete = tmp_list;
01125 tmp_list = tmp_list->next;
01126
01127 OLSR_DEBUG(LOG_PLUGINS, "[ENC]timestamp info for %s timed out.. deleting it\n",
01128 olsr_ip_to_string(&buf, &entry_to_delete->addr));
01129
01130
01131 entry_to_delete->next->prev = entry_to_delete->prev;
01132 entry_to_delete->prev->next = entry_to_delete->next;
01133
01134 free(entry_to_delete);
01135 } else
01136 tmp_list = tmp_list->next;
01137 }
01138 }
01139
01140 return;
01141 }
01142
01143
01144
01145 static int
01146 read_key_from_file(const char *file)
01147 {
01148 FILE *kf;
01149 size_t keylen;
01150
01151 keylen = 16;
01152 kf = fopen(file, "r");
01153
01154 OLSR_DEBUG(LOG_PLUGINS, "[ENC]Reading key from file \"%s\"\n", file);
01155
01156 if (kf == NULL) {
01157 OLSR_WARN(LOG_PLUGINS, "[ENC]Could not open keyfile %s!\nError: %s\n", file, strerror(errno));
01158 return -1;
01159 }
01160
01161 if (fread(aes_key, 1, keylen, kf) != keylen) {
01162 OLSR_WARN(LOG_PLUGINS, "[ENC]Could not read key from keyfile %s!\nError: %s\n", file, strerror(errno));
01163 fclose(kf);
01164 return 0;
01165 }
01166
01167
01168 fclose(kf);
01169 return 1;
01170 }
01171
01172
01173
01174
01175
01176
01177
01178