📄 olsrd_secure.c
字号:
olsr_u8_t sha1_hash[SIGNATURE_SIZE]; struct stamp *entry; msg = (struct r_respmsg *)in_msg; olsr_printf(1, "[ENC]Response-response message received\n"); olsr_printf(3, "[ENC]To: %s\n", olsr_ip_to_string((union olsr_ip_addr *)&msg->destination)); if(if_ifwithaddr((union olsr_ip_addr *)&msg->destination) == NULL) { olsr_printf(1, "[ENC]Not for us...\n"); return 0; } /* Check signature */ { olsr_u8_t checksum_cache[512 + KEYLENGTH]; /* Create packet + key cache */ /* First the OLSR packet + signature message - digest */ memcpy(checksum_cache, msg, sizeof(struct r_respmsg) - SIGNATURE_SIZE); /* Then the key */ memcpy(&checksum_cache[sizeof(struct r_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH); /* Create the hash */ CHECKSUM(checksum_cache, (sizeof(struct r_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, sha1_hash); } if(memcmp(sha1_hash, &msg->signature, SIGNATURE_SIZE) != 0) { olsr_printf(1, "[ENC]Signature missmatch in response-response!\n"); return 0; } olsr_printf(3, "[ENC]Signature verified\n"); /* Now to check the digest from the emitted challenge */ if((entry = lookup_timestamp_entry((union olsr_ip_addr *)&msg->originator)) == NULL) { olsr_printf(1, "[ENC]Received response-response from non-registered node %s!\n", olsr_ip_to_string((union olsr_ip_addr *)&msg->originator)); return 0; } /* Generate the digest */ olsr_printf(3, "[ENC]Entry-challenge 0x%x\n", entry->challenge); { olsr_u8_t checksum_cache[512 + KEYLENGTH]; /* First the challenge received */ memcpy(checksum_cache, &entry->challenge, 4); /* Then the local IP */ memcpy(&checksum_cache[sizeof(olsr_u32_t)], &msg->originator, olsr_cnf->ipsize); /* Create the hash */ CHECKSUM(checksum_cache, sizeof(olsr_u32_t) + olsr_cnf->ipsize, sha1_hash); } if(memcmp(msg->res_sig, sha1_hash, SIGNATURE_SIZE) != 0) { olsr_printf(1, "[ENC]Error in response signature from %s!\n", olsr_ip_to_string((union olsr_ip_addr *)&msg->originator)); return 0; } olsr_printf(3, "[ENC]Challenge-response signature ok\n"); /* Update entry! */ entry->challenge = 0; entry->validated = 1; entry->diff = now.tv_sec - msg->timestamp; /* update validtime - validated entry */ entry->valtime = GET_TIMESTAMP(TIMESTAMP_HOLD_TIME * 1000); olsr_printf(1, "[ENC]%s registered with diff %d!\n", olsr_ip_to_string((union olsr_ip_addr *)&msg->originator), entry->diff); return 1;}intparse_challenge(char *in_msg){ struct challengemsg *msg; olsr_u8_t sha1_hash[SIGNATURE_SIZE]; struct stamp *entry; olsr_u32_t hash; msg = (struct challengemsg *)in_msg; olsr_printf(1, "[ENC]Challenge message received\n"); olsr_printf(3, "[ENC]To: %s\n", olsr_ip_to_string((union olsr_ip_addr *)&msg->destination)); if(if_ifwithaddr((union olsr_ip_addr *)&msg->destination) == NULL) { olsr_printf(1, "[ENC]Not for us...\n"); return 0; } /* Create entry if not registered */ if((entry = lookup_timestamp_entry((union olsr_ip_addr *)&msg->originator)) == NULL) { entry = malloc(sizeof(struct stamp)); memcpy(&entry->addr, &msg->originator, olsr_cnf->ipsize); hash = olsr_hashing((union olsr_ip_addr *)&msg->originator); /* Queue */ timestamps[hash].next->prev = entry; entry->next = timestamps[hash].next; timestamps[hash].next = entry; entry->prev = ×tamps[hash]; } else { /* Check configuration timeout */ if(!TIMED_OUT(entry->conftime)) { /* If registered - do not accept! */ olsr_printf(1, "[ENC]Challenge from registered node...dropping!\n"); return 0; } else { olsr_printf(1, "[ENC]Challenge from registered node...accepted!\n"); } } olsr_printf(3, "[ENC]Challenge: 0x%lx\n", (unsigned long)ntohl(msg->challenge)); /* ntohl() returns a unsignedlong onwin32 */ /* Check signature */ { olsr_u8_t checksum_cache[512 + KEYLENGTH]; /* Create packet + key cache */ /* First the OLSR packet + signature message - digest */ memcpy(checksum_cache, msg, sizeof(struct challengemsg) - SIGNATURE_SIZE); /* Then the key */ memcpy(&checksum_cache[sizeof(struct challengemsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH); /* Create the hash */ CHECKSUM(checksum_cache, (sizeof(struct challengemsg) - SIGNATURE_SIZE) + KEYLENGTH, sha1_hash); } if(memcmp(sha1_hash, &msg->signature, SIGNATURE_SIZE) != 0) { olsr_printf(1, "[ENC]Signature missmatch in challenge!\n"); return 0; } olsr_printf(3, "[ENC]Signature verified\n"); entry->diff = 0; entry->validated = 0; /* update validtime - not validated */ entry->conftime = GET_TIMESTAMP(EXCHANGE_HOLD_TIME * 1000); /* Build and send response */ send_cres((union olsr_ip_addr *)&msg->originator, (union olsr_ip_addr *)&msg->destination, ntohl(msg->challenge), entry); return 1;}/** * Build and transmit a challenge response * message. * */intsend_cres(union olsr_ip_addr *to, union olsr_ip_addr *from, olsr_u32_t chal_in, struct stamp *entry){ struct c_respmsg crmsg; olsr_u32_t challenge; olsr_printf(1, "[ENC]Building CRESPONSE message\n"); challenge = rand() << 16; challenge |= rand(); entry->challenge = challenge; olsr_printf(3, "[ENC]Challenge-response: 0x%x\n", challenge); /* Fill challengemessage */ crmsg.olsr_msgtype = TYPE_CRESPONSE; crmsg.olsr_vtime = 0; crmsg.olsr_msgsize = htons(sizeof(struct c_respmsg)); memcpy(&crmsg.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize); crmsg.ttl = 1; crmsg.hopcnt = 0; crmsg.seqno = htons(get_msg_seqno()); /* set timestamp */ crmsg.timestamp = now.tv_sec; olsr_printf(3, "[ENC]Timestamp %ld\n", crmsg.timestamp); /* Fill subheader */ memcpy(&crmsg.destination, to, olsr_cnf->ipsize); crmsg.challenge = htonl(challenge); /* Create digest of received challenge + IP */ { olsr_u8_t checksum_cache[512 + KEYLENGTH]; /* Create packet + key cache */ /* First the challenge received */ memcpy(checksum_cache, &chal_in, 4); /* Then the local IP */ memcpy(&checksum_cache[sizeof(olsr_u32_t)], from, olsr_cnf->ipsize); /* Create the hash */ CHECKSUM(checksum_cache, sizeof(olsr_u32_t) + olsr_cnf->ipsize, crmsg.res_sig); } /* Now create the digest of the message and the key */ { olsr_u8_t checksum_cache[512 + KEYLENGTH]; /* Create packet + key cache */ /* First the OLSR packet + signature message - digest */ memcpy(checksum_cache, &crmsg, sizeof(struct c_respmsg) - SIGNATURE_SIZE); /* Then the key */ memcpy(&checksum_cache[sizeof(struct c_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH); /* Create the hash */ CHECKSUM(checksum_cache, (sizeof(struct c_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, crmsg.signature); } olsr_printf(3, "[ENC]Sending challenge response to %s challenge 0x%x\n", olsr_ip_to_string(to), challenge); /* Add to buffer */ net_outbuffer_push(olsr_in_if, &crmsg, sizeof(struct c_respmsg)); /* Send the request */ net_output(olsr_in_if); return 1;}/** * Build and transmit a response response * message. * */static intsend_rres(union olsr_ip_addr *to, union olsr_ip_addr *from, olsr_u32_t chal_in){ struct r_respmsg rrmsg; olsr_printf(1, "[ENC]Building RRESPONSE message\n"); /* Fill challengemessage */ rrmsg.olsr_msgtype = TYPE_RRESPONSE; rrmsg.olsr_vtime = 0; rrmsg.olsr_msgsize = htons(sizeof(struct r_respmsg)); memcpy(&rrmsg.originator, &olsr_cnf->main_addr, olsr_cnf->ipsize); rrmsg.ttl = 1; rrmsg.hopcnt = 0; rrmsg.seqno = htons(get_msg_seqno()); /* set timestamp */ rrmsg.timestamp = now.tv_sec; olsr_printf(3, "[ENC]Timestamp %ld\n", rrmsg.timestamp); /* Fill subheader */ memcpy(&rrmsg.destination, to, olsr_cnf->ipsize); /* Create digest of received challenge + IP */ { olsr_u8_t checksum_cache[512 + KEYLENGTH]; /* Create packet + key cache */ /* First the challenge received */ memcpy(checksum_cache, &chal_in, 4); /* Then the local IP */ memcpy(&checksum_cache[sizeof(olsr_u32_t)], from, olsr_cnf->ipsize); /* Create the hash */ CHECKSUM(checksum_cache, sizeof(olsr_u32_t) + olsr_cnf->ipsize, rrmsg.res_sig); } /* Now create the digest of the message and the key */ { olsr_u8_t checksum_cache[512 + KEYLENGTH]; /* Create packet + key cache */ /* First the OLSR packet + signature message - digest */ memcpy(checksum_cache, &rrmsg, sizeof(struct r_respmsg) - SIGNATURE_SIZE); /* Then the key */ memcpy(&checksum_cache[sizeof(struct r_respmsg) - SIGNATURE_SIZE], aes_key, KEYLENGTH); /* Create the hash */ CHECKSUM(checksum_cache, (sizeof(struct r_respmsg) - SIGNATURE_SIZE) + KEYLENGTH, rrmsg.signature); } olsr_printf(3, "[ENC]Sending response response to %s\n", olsr_ip_to_string(to)); /* add to buffer */ net_outbuffer_push(olsr_in_if, &rrmsg, sizeof(struct r_respmsg)); /* Send the request */ net_output(olsr_in_if); return 1;}static struct stamp *lookup_timestamp_entry(union olsr_ip_addr *adr){ olsr_u32_t hash; struct stamp *entry; hash = olsr_hashing(adr); for(entry = timestamps[hash].next; entry != ×tamps[hash]; entry = entry->next) { if(memcmp(&entry->addr, adr, olsr_cnf->ipsize) == 0) { olsr_printf(3, "[ENC]Match for %s\n", olsr_ip_to_string(adr)); return entry; } } olsr_printf(1, "[ENC]No match for %s\n", olsr_ip_to_string(adr)); return NULL;}/** *Find timed out entries and delete them * *@return nada */voidtimeout_timestamps(void* foo __attribute__((unused))){ struct stamp *tmp_list; struct stamp *entry_to_delete; int index; for(index=0;index<HASHSIZE;index++) { tmp_list = timestamps[index].next; /*Traverse MID list*/ while(tmp_list != ×tamps[index]) { /*Check if the entry is timed out*/ if((TIMED_OUT(tmp_list->valtime)) && (TIMED_OUT(tmp_list->conftime))) { entry_to_delete = tmp_list; tmp_list = tmp_list->next; olsr_printf(1, "[ENC]timestamp info for %s timed out.. deleting it\n", olsr_ip_to_string(&entry_to_delete->addr)); /*Delete it*/ entry_to_delete->next->prev = entry_to_delete->prev; entry_to_delete->prev->next = entry_to_delete->next; free(entry_to_delete); } else tmp_list = tmp_list->next; } } return;}static intread_key_from_file(char *file){ FILE *kf; size_t keylen; keylen = 16; kf = fopen(file, "r"); olsr_printf(1, "[ENC]Reading key from file \"%s\"\n", file); if(kf == NULL) { olsr_printf(1, "[ENC]Could not open keyfile %s!\nError: %s\n", file, strerror(errno)); return -1; } if(fread(aes_key, 1, keylen, kf) != keylen) { olsr_printf(1, "[ENC]Could not read key from keyfile %s!\nError: %s\n", file, strerror(errno)); fclose(kf); return 0; } fclose(kf); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -