/** * TODO move it to rfc2617.c * * @param auth_res return value of authentication. Maybe the it will be not affected. * @result if authentication should continue (1) or not (0) * */ static int auth_check_hdr_md5(struct sip_msg* msg, auth_body_t* auth, auth_result_t* auth_res) { int ret; /* Check credentials correctness here */ if (check_dig_cred(&auth->digest) != E_DIG_OK) { LOG(L_ERR, "auth:pre_auth: Credentials are not filled properly\n"); *auth_res = BAD_CREDENTIALS; return 0; } ret = check_nonce(auth, &secret1, &secret2, msg); if (ret!=0){ if (ret==3 || ret==4){ /* failed auth_extra_checks or stale */ auth->stale=1; /* we mark the nonce as stale (hack that makes our life much easier) */ *auth_res = STALE_NONCE; return 0; } else if (ret==6) { *auth_res = NONCE_REUSED; return 0; } else { DBG("auth:pre_auth: Invalid nonce value received (ret %d)\n", ret); *auth_res = NOT_AUTHENTICATED; return 0; } } return 1; }
static void prepare_push_cert_sha1(struct child_process *proc) { static int already_done; if (!push_cert.len) return; if (!already_done) { struct strbuf gpg_output = STRBUF_INIT; struct strbuf gpg_status = STRBUF_INIT; int bogs /* beginning_of_gpg_sig */; already_done = 1; if (write_sha1_file(push_cert.buf, push_cert.len, "blob", push_cert_sha1)) hashclr(push_cert_sha1); memset(&sigcheck, '\0', sizeof(sigcheck)); sigcheck.result = 'N'; bogs = parse_signature(push_cert.buf, push_cert.len); if (verify_signed_buffer(push_cert.buf, bogs, push_cert.buf + bogs, push_cert.len - bogs, &gpg_output, &gpg_status) < 0) { ; /* error running gpg */ } else { sigcheck.payload = push_cert.buf; sigcheck.gpg_output = gpg_output.buf; sigcheck.gpg_status = gpg_status.buf; parse_gpg_output(&sigcheck); } strbuf_release(&gpg_output); strbuf_release(&gpg_status); nonce_status = check_nonce(push_cert.buf, bogs); } if (!is_null_sha1(push_cert_sha1)) { argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT=%s", sha1_to_hex(push_cert_sha1)); argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s", sigcheck.signer ? sigcheck.signer : ""); argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s", sigcheck.key ? sigcheck.key : ""); argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_STATUS=%c", sigcheck.result); if (push_cert_nonce) { argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_NONCE=%s", push_cert_nonce); argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_NONCE_STATUS=%s", nonce_status); if (nonce_status == NONCE_SLOP) argv_array_pushf(&proc->env_array, "GIT_PUSH_CERT_NONCE_SLOP=%ld", nonce_stamp_slop); } } }
/* * Search the pending referral cache entry that matches the nonce. */ lispd_pending_referral_cache_entry *lookup_pending_referral_cache_entry_by_nonce (uint64_t nonce) { lispd_pending_referral_cache_entry *pending_referral = NULL; lispd_pending_referral_cache_list *aux_list = pening_referrals_list; while (aux_list != NULL){ if (check_nonce(aux_list->pending_referral_cache_entry->nonces, nonce) == GOOD){ pending_referral = aux_list->pending_referral_cache_entry; break; } aux_list = aux_list->next; } return (pending_referral); }
static int find_challenge(const pjsip_rx_data *rdata, const struct ast_sip_auth *auth) { struct pjsip_authorization_hdr *auth_hdr = (pjsip_authorization_hdr *) &rdata->msg_info.msg->hdr; int challenge_found = 0; char nonce[64]; while ((auth_hdr = (pjsip_authorization_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, auth_hdr->next))) { ast_copy_pj_str(nonce, &auth_hdr->credential.digest.nonce, sizeof(nonce)); if (check_nonce(nonce, rdata, auth) && !pj_strcmp2(&auth_hdr->credential.digest.realm, auth->realm)) { challenge_found = 1; break; } } return challenge_found; }
int process_map_reply_probe_record( uint8_t **cur_ptr, uint64_t nonce) { lispd_pkt_mapping_record_t *record = NULL; lispd_mapping_elt *mapping = NULL; lispd_map_cache_entry *cache_entry = NULL; lispd_locator_elt *aux_locator = NULL; lispd_locator_elt *locator = NULL; rmt_locator_extended_info *rmt_locator_ext_inf = NULL; lispd_locators_list *locators_list[2] = {NULL,NULL}; lisp_addr_t aux_eid_prefix; int aux_eid_prefix_length = 0; int aux_iid = 0; int ctr = 0; int locators_probed = 0; record = (lispd_pkt_mapping_record_t *)(*cur_ptr); mapping = new_map_cache_mapping(aux_eid_prefix,aux_eid_prefix_length,aux_iid); if (mapping == NULL){ return (BAD); } *cur_ptr = (uint8_t *)&(record->eid_prefix_afi); if (!pkt_process_eid_afi(cur_ptr,mapping)){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_probe_record: Error processing the EID of the map reply record"); free_mapping_elt(mapping); return (BAD); } mapping->eid_prefix_length = record->eid_prefix_length; if (record->locator_count != 0 ){ /* Serch map cache entry exist*/ cache_entry = lookup_map_cache_exact(mapping->eid_prefix,mapping->eid_prefix_length); if (cache_entry == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_probe_record: No map cache entry found for %s/%d", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); free_mapping_elt(mapping); return (BAD); } /* Check instane id.*/ if (cache_entry->mapping->iid != mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_probe_record: Instance ID of the map reply doesn't match with the map cache entry"); free_mapping_elt(mapping); return (BAD); } /* Free auxiliar mapping used to search the map cache entry*/ free_mapping_elt(mapping); /* * Check probed locators of the list. Only one locator can be probed per message */ for (ctr=0 ; ctr < record->locator_count ; ctr++){ err = process_map_reply_probe_locator (cur_ptr, cache_entry->mapping, nonce, &locator); if (err == ERR_MALLOC){ return (BAD); } if (locator == NULL){ // The current locator is not probed continue; } rmt_locator_ext_inf = (rmt_locator_extended_info *)(locator->extended_info); /* Check the nonce of the message match with the one stored in the structure of the locator */ if ((check_nonce(rmt_locator_ext_inf->rloc_probing_nonces,nonce)) == GOOD){ free(rmt_locator_ext_inf->rloc_probing_nonces); rmt_locator_ext_inf->rloc_probing_nonces = NULL; if (locators_probed == 0){ aux_locator = locator; locators_probed ++; }else{ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: Invalid Map-Reply Probe. Only one locator can be probed per message"); return (BAD); } }else{ lispd_log_msg(LISP_LOG_DEBUG_1,"The nonce of the Map-Reply Probe doesn't match the nonce of the generated Map-Request Probe. Discarding message ..."); return (BAD); } } locator = aux_locator; if (locator == NULL){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: Invalid Map-Reply Probe. No probed locator of the received message matches with the " "locators of the mapping stored in the map cahce database."); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_1,"Map-Reply probe reachability to RLOC %s of the EID cache entry %s/%d", get_char_from_lisp_addr_t(*(locator->locator_addr)), get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix), cache_entry->mapping->eid_prefix_length); }else{ // Probe of a negative map cache -> proxy-etr if(proxy_etrs != NULL && compare_lisp_addr_t(&(mapping->eid_prefix),&(proxy_etrs->mapping->eid_prefix)) == 0){ cache_entry = proxy_etrs; locators_list[0] = proxy_etrs->mapping->head_v4_locators_list; locators_list[1] = proxy_etrs->mapping->head_v6_locators_list; for (ctr=0 ; ctr < 2 ; ctr++){ while (locators_list[ctr]!=NULL){ aux_locator = locators_list[ctr]->locator; rmt_locator_ext_inf = (rmt_locator_extended_info *)(aux_locator->extended_info); if ((check_nonce(rmt_locator_ext_inf->rloc_probing_nonces,nonce)) == GOOD){ free (rmt_locator_ext_inf->rloc_probing_nonces); rmt_locator_ext_inf->rloc_probing_nonces = NULL; locator = aux_locator; break; } locators_list[ctr] = locators_list[ctr]->next; } if (locator != NULL){ break; } } if (locator == NULL){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: The nonce of the Negative Map-Reply Probe don't match any nonce of Proxy-ETR locators"); free_mapping_elt(mapping); return (BAD); } free_mapping_elt(mapping); }else{ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: The received negative Map-Reply Probe has not been requested: %s/%d", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); free_mapping_elt(mapping); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_1,"Map-Reply probe reachability to the PETR with RLOC %s", get_char_from_lisp_addr_t(*(locator->locator_addr))); } if (*(locator->state) == DOWN){ *(locator->state) = UP; lispd_log_msg(LISP_LOG_DEBUG_1,"Map-Reply Probe received for locator %s -> Locator state changes to UP", get_char_from_lisp_addr_t(*(locator->locator_addr))); /* [re]Calculate balancing locator vectors if it has been a change of status*/ calculate_balancing_vectors ( cache_entry->mapping, &(((rmt_mapping_extended_info *)cache_entry->mapping->extended_info)->rmt_balancing_locators_vecs)); } /* * Reprogramming timers of rloc probing */ rmt_locator_ext_inf = (rmt_locator_extended_info *)(locator->extended_info); if (rmt_locator_ext_inf->probe_timer == NULL){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_map_reply_probe_record: The received Map-Reply Probe was not requested"); return (BAD); } start_timer(rmt_locator_ext_inf->probe_timer, rloc_probe_interval, (timer_callback)rloc_probing,rmt_locator_ext_inf->probe_timer->cb_argument); if (record->locator_count != 0 ){ lispd_log_msg(LISP_LOG_DEBUG_2,"Reprogramed RLOC probing of the locator %s of the EID %s/%d in %d seconds", get_char_from_lisp_addr_t(*(locator->locator_addr)), get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix), cache_entry->mapping->eid_prefix_length, rloc_probe_interval); }else{ lispd_log_msg(LISP_LOG_DEBUG_2,"Reprogramed RLOC probing of the locator %s (PETR) in %d seconds", get_char_from_lisp_addr_t(*(locator->locator_addr)), rloc_probe_interval); } return (GOOD); }
int process_map_reply_record(uint8_t **cur_ptr, uint64_t nonce) { lispd_pkt_mapping_record_t *record = NULL; lispd_mapping_elt *mapping = NULL; lispd_map_cache_entry *cache_entry = NULL; lisp_addr_t aux_eid_prefix; int aux_eid_prefix_length = 0; int aux_iid = 0; int ctr = 0; uint8_t is_new_mapping = FALSE; record = (lispd_pkt_mapping_record_t *)(*cur_ptr); mapping = new_map_cache_mapping(aux_eid_prefix,aux_eid_prefix_length,aux_iid); if (mapping == NULL){ return (BAD); } *cur_ptr = (uint8_t *)&(record->eid_prefix_afi); if (!pkt_process_eid_afi(cur_ptr,mapping)){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: Error processing the EID of the map reply record"); free_mapping_elt(mapping); return (BAD); } mapping->eid_prefix_length = record->eid_prefix_length; /* * Check if the map replay corresponds to a not active map cache */ cache_entry = lookup_nonce_in_no_active_map_caches(mapping->eid_prefix.afi, nonce); if (cache_entry != NULL){ if (cache_entry->mapping->iid != mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: Instance ID of the map reply doesn't match with the inactive map cache entry"); free_mapping_elt(mapping); return (BAD); } /* * If the eid prefix of the received map reply doesn't match the inactive map cache entry (x.x.x.x/32 or x:x:x:x:x:x:x:x/128),then * we remove the inactie entry from the database and store it again with the correct eix prefix (for instance /24). */ if (cache_entry->mapping->eid_prefix_length != mapping->eid_prefix_length){ if (change_map_cache_prefix_in_db(mapping->eid_prefix, mapping->eid_prefix_length, cache_entry) != GOOD){ free_mapping_elt(mapping); return (BAD); } } cache_entry->active = 1; stop_timer(cache_entry->request_retry_timer); cache_entry->request_retry_timer = NULL; lispd_log_msg(LISP_LOG_DEBUG_2," Activating map cache entry %s/%d", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); free_mapping_elt(mapping); is_new_mapping = TRUE; } /* If the nonce is not found in the no active cache enties, then it should be an active cache entry */ else { /* Serch map cache entry exist*/ cache_entry = lookup_map_cache_exact(mapping->eid_prefix,mapping->eid_prefix_length); if (cache_entry == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: No map cache entry found for %s/%d", get_char_from_lisp_addr_t(mapping->eid_prefix),mapping->eid_prefix_length); free_mapping_elt(mapping); return (BAD); } /* Check the found map cache entry contain the nonce of the map reply*/ if (check_nonce(cache_entry->nonces,nonce)==BAD){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: The nonce of the Map-Reply doesn't match the nonce of the generated Map-Request. Discarding message ..."); free_mapping_elt(mapping); return (BAD); }else { free(cache_entry->nonces); cache_entry->nonces = NULL; } /* Stop timer of Map Requests retransmits */ if (cache_entry->smr_inv_timer != NULL){ stop_timer(cache_entry->smr_inv_timer); cache_entry->smr_inv_timer = NULL; } /* Check instane id.*/ if (cache_entry->mapping->iid != mapping->iid){ lispd_log_msg(LISP_LOG_DEBUG_2,"process_map_reply_record: Instance ID of the map reply doesn't match with the map cache entry"); free_mapping_elt(mapping); return (BAD); } lispd_log_msg(LISP_LOG_DEBUG_2," A map cache entry already exists for %s/%d, replacing locators list of this entry", get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix), cache_entry->mapping->eid_prefix_length); free_locator_list(cache_entry->mapping->head_v4_locators_list); free_locator_list(cache_entry->mapping->head_v6_locators_list); cache_entry->mapping->head_v4_locators_list = NULL; cache_entry->mapping->head_v6_locators_list = NULL; free_mapping_elt(mapping); } cache_entry->actions = record->action; cache_entry->ttl = ntohl(record->ttl); cache_entry->active_witin_period = 1; cache_entry->timestamp = time(NULL); //locator_count updated when adding the processed locators /* Generate the locators */ for (ctr=0 ; ctr < record->locator_count ; ctr++){ if ((process_map_reply_locator (cur_ptr, cache_entry->mapping)) != GOOD){ return(BAD); } } if (is_loggable(LISP_LOG_DEBUG_2)){ dump_map_cache_entry(cache_entry, LISP_LOG_DEBUG_2); } /* [re]Calculate balancing locator vectors if it is not a negative map reply*/ if (cache_entry->mapping->locator_count != 0){ calculate_balancing_vectors ( cache_entry->mapping, &(((rmt_mapping_extended_info *)cache_entry->mapping->extended_info)->rmt_balancing_locators_vecs)); } /* * Reprogramming timers */ /* Expiration cache timer */ if (!cache_entry->expiry_cache_timer){ cache_entry->expiry_cache_timer = create_timer (EXPIRE_MAP_CACHE_TIMER); } start_timer(cache_entry->expiry_cache_timer, cache_entry->ttl*60, (timer_callback)map_cache_entry_expiration, (void *)cache_entry); lispd_log_msg(LISP_LOG_DEBUG_1,"The map cache entry %s/%d will expire in %d minutes.", get_char_from_lisp_addr_t(cache_entry->mapping->eid_prefix), cache_entry->mapping->eid_prefix_length, cache_entry->ttl); /* RLOC probing timer */ if (is_new_mapping == TRUE && rloc_probe_interval != 0){ programming_rloc_probing(cache_entry); } return (TRUE); }
int main (int argc, char **argv) { int last_argc = -1; int with_progress = 0; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--help")) { usage (0); exit (0); } else if (!strcmp (*argv, "--verbose")) { verbose++; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose += 2; debug++; argc--; argv++; } else if (!strcmp (*argv, "--progress")) { argc--; argv++; with_progress = 1; } else if (!strncmp (*argv, "--", 2)) die ("unknown option '%s'", *argv); else break; } if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); /* No valuable keys are create, so we can speed up our RNG. */ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); if (with_progress) gcry_set_progress_handler (progress_cb, NULL); if (!argc) { check_rsa_keys (); check_elg_keys (); check_dsa_keys (); check_ecc_keys (); check_nonce (); } else { for (; argc; argc--, argv++) if (!strcmp (*argv, "rsa")) check_rsa_keys (); else if (!strcmp (*argv, "elg")) check_elg_keys (); else if (!strcmp (*argv, "dsa")) check_dsa_keys (); else if (!strcmp (*argv, "ecc")) check_ecc_keys (); else if (!strcmp (*argv, "nonce")) check_nonce (); else usage (1); } return error_count? 1:0; }
/* * Purpose of this function is to find credentials with given realm, * do sanity check, validate credential correctness and determine if * we should really authenticate (there must be no authentication for * ACK and CANCEL */ auth_result_t pre_auth(struct sip_msg* _m, str* _realm, int _hftype, struct hdr_field** _h) { int ret; auth_body_t* c; struct sip_uri uri; /* ACK and CANCEL must be always authorized, there is * no way how to challenge ACK and CANCEL cannot be * challenged because it must have the same CSeq as * the request to be cancelled */ if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) return AUTHORIZED; if (_realm->len == 0) { if (get_realm(_m, _hftype, &uri) < 0) { LOG(L_ERR, "pre_auth(): Error while extracting realm\n"); if (send_resp(_m, 400, MESSAGE_400, 0, 0) == -1) { LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n"); } return ERROR; } *_realm = uri.host; strip_realm(_realm); } /* Try to find credentials with corresponding realm * in the message, parse them and return pointer to * parsed structure */ ret = find_credentials(_m, _realm, _hftype, _h); if (ret < 0) { LOG(L_ERR, "pre_auth(): Error while looking for credentials\n"); if (send_resp(_m, (ret == -2) ? 500 : 400, (ret == -2) ? MESSAGE_500 : MESSAGE_400, 0, 0) == -1) { LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n"); } return ERROR; } else if (ret > 0) { DBG("pre_auth(): Credentials with given realm not found\n"); return NOT_AUTHORIZED; } /* Pointer to the parsed credentials */ c = (auth_body_t*)((*_h)->parsed); /* Check credentials correctness here */ if (check_dig_cred(&(c->digest)) != E_DIG_OK) { LOG(L_ERR, "pre_auth(): Credentials received are not filled properly\n"); if (send_resp(_m, 400, MESSAGE_400, 0, 0) == -1) { LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n"); } return ERROR; } if (check_nonce(&c->digest.nonce, &secret) != 0) { DBG("pre_auth(): Invalid nonce value received\n"); return NOT_AUTHORIZED; } return DO_AUTHORIZATION; }
int process_info_reply_msg( uint8_t *packet, lisp_addr_t local_rloc) { uint8_t *ptr = packet; uint8_t lisp_type = 0; uint8_t reply = 0; uint64_t nonce = 0; uint16_t key_id = 0; uint16_t auth_data_len = 0; uint8_t *auth_data_pos = NULL; uint32_t ttl = 0; uint8_t eid_mask_len = 0; lisp_addr_t eid_prefix = {.afi=AF_UNSPEC}; uint16_t ms_udp_port = 0; uint16_t etr_udp_port = 0; uint32_t info_reply_hdr_len = 0; uint32_t lcaf_addr_len = 0; uint32_t pckt_len = 0; uint16_t *lcaf_afi = NULL; lisp_addr_t global_etr_rloc = {.afi=AF_UNSPEC}; lisp_addr_t ms_rloc = {.afi=AF_UNSPEC}; lisp_addr_t private_etr_rloc = {.afi=AF_UNSPEC}; lispd_rtr_locators_list *rtr_locators_list = NULL; lispd_mapping_elt *mapping = NULL; lispd_locator_elt *locator = NULL; lcl_locator_extended_info *lcl_locator_ext_inf = NULL; char rtrs_list_str[2000]; int rtrs_list_str_size = 0; lispd_rtr_locators_list *aux_rtr_locators_list = NULL; uint8_t is_behind_nat = FALSE; /* * Get source port and address. */ err = extract_info_nat_header(ptr, &lisp_type, &reply, &nonce, &key_id, &auth_data_len, &auth_data_pos, &ttl, &eid_mask_len, &eid_prefix, &info_reply_hdr_len); if (err != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_info_reply_msg: Couldn't process Info Reply message"); return (BAD); } ptr = CO(ptr,info_reply_hdr_len); lcaf_afi = (uint16_t *)ptr; if ( ntohs(*lcaf_afi) != LISP_AFI_LCAF){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_info_reply_msg: Malformed packet"); return (BAD); } ptr = CO(ptr,FIELD_AFI_LEN); /* Extract Info-Reply body fields */ err = extract_nat_lcaf_data(ptr, &ms_udp_port, &etr_udp_port, &global_etr_rloc, &ms_rloc, &private_etr_rloc, &rtr_locators_list, &lcaf_addr_len); if (err == BAD) { lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Error extracting packet data"); return (BAD); } /* Leave only RTR with same afi as the local rloc where we received the message */ remove_rtr_locators_with_afi_different_to(&rtr_locators_list, local_rloc.afi); lcaf_addr_len = lcaf_addr_len + FIELD_AFI_LEN; /* Print the extracted information of the message */ if (is_loggable(LISP_LOG_DEBUG_2)){ aux_rtr_locators_list = rtr_locators_list; rtrs_list_str[0] = '\0'; while (aux_rtr_locators_list != NULL){ sprintf(rtrs_list_str + rtrs_list_str_size, " %s ", get_char_from_lisp_addr_t(aux_rtr_locators_list->locator->address)); rtrs_list_str_size = rtrs_list_str_size + strlen(rtrs_list_str); aux_rtr_locators_list = aux_rtr_locators_list->next; } lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply message data->" "Nonce: %s , KeyID: %hu ,TTL: %u , EID-prefix: %s/%hhu , " "MS UDP Port Number: %hu , ETR UDP Port Number: %hu , Global ETR RLOC Address: %s , " "MS RLOC Address: %s , Private ETR RLOC Address: %s, RTR RLOC Compatible list: %s", get_char_from_nonce(nonce), key_id, ttl, get_char_from_lisp_addr_t(eid_prefix),eid_mask_len, ms_udp_port, etr_udp_port, get_char_from_lisp_addr_t(global_etr_rloc), get_char_from_lisp_addr_t(ms_rloc),get_char_from_lisp_addr_t(private_etr_rloc),rtrs_list_str); } /* Checking the nonce */ if (check_nonce(nat_ir_nonce,nonce) == GOOD ){ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Correct nonce field checking "); free(nat_ir_nonce); nat_ir_nonce = NULL; }else{ lispd_log_msg(LISP_LOG_DEBUG_1, "Info-Reply: Error checking nonce field. No Info Request generated with nonce: %s", get_char_from_nonce (nonce)); return (BAD); } /* Check authentication data */ pckt_len = info_reply_hdr_len + lcaf_addr_len; if(BAD == check_auth_field(key_id, map_servers->key, (void *) packet, pckt_len, auth_data_pos)){ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Error checking auth data field"); return(BAD); }else{ lispd_log_msg(LISP_LOG_DEBUG_2, "Info-Reply: Correct auth data field checking"); } // TODO Select the best RTR from the list retrieved from the Info-Reply /* Check if behind NAT */ switch (compare_lisp_addr_t(&global_etr_rloc, &local_rloc)) { case 0: is_behind_nat = FALSE; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: MN is not behind NAT"); break; case 1: case 2: is_behind_nat = TRUE; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: MN is behind NAT"); break; case -1: is_behind_nat = UNKNOWN; lispd_log_msg(LISP_LOG_DEBUG_2, "NAT Traversal: Unknown state"); break; } if (is_behind_nat == TRUE){ if (rtr_locators_list == NULL){ lispd_log_msg(LISP_LOG_WARNING, "process_info_reply_msg: The interface with IP address %s is behind NAT" " but there is no RTR compatible with local AFI", get_char_from_lisp_addr_t(local_rloc)); } mapping = lookup_eid_exact_in_db(eid_prefix, eid_mask_len); if (mapping == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Info Reply is not for any local EID"); return (BAD); } locator = get_locator_from_mapping(mapping,local_rloc); if (locator == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2, "process_info_reply_msg: Info Reply received in the wrong locator"); return (BAD); } lcl_locator_ext_inf = (lcl_locator_extended_info *)locator->extended_info; if (lcl_locator_ext_inf->rtr_locators_list != NULL){ free_rtr_list(lcl_locator_ext_inf->rtr_locators_list); } lcl_locator_ext_inf->rtr_locators_list = rtr_locators_list; if (nat_status == NO_NAT || nat_status == PARTIAL_NAT){ nat_status = PARTIAL_NAT; }else{ nat_status = FULL_NAT; } }else{ if (nat_status == FULL_NAT || nat_status == PARTIAL_NAT){ nat_status = PARTIAL_NAT; }else{ nat_status = NO_NAT; } } /* If we are behind NAT, the program timer to send Info Request after TTL minutes */ if (is_behind_nat == TRUE){ if (info_reply_ttl_timer == NULL) { info_reply_ttl_timer = create_timer(INFO_REPLY_TTL_TIMER); } start_timer(info_reply_ttl_timer, ttl*60, info_request, (void *)mapping); lispd_log_msg(LISP_LOG_DEBUG_1, "Reprogrammed info request in %d minutes",ttl); }else{ stop_timer(info_reply_ttl_timer); info_reply_ttl_timer = NULL; } /* Once we know the NAT state we send a Map-Register */ map_register(NULL,NULL); return (GOOD); }
/* * Purpose of this function is to find credentials with given realm, * do sanity check, validate credential correctness and determine if * we should really authenticate (there must be no authentication for * ACK and CANCEL */ auth_result_t pre_auth(struct sip_msg* _m, str* _realm, hdr_types_t _hftype, struct hdr_field** _h) { int ret; auth_body_t* c; struct sip_uri *uri; /* ACK and CANCEL must be always authorized, there is * no way how to challenge ACK and CANCEL cannot be * challenged because it must have the same CSeq as * the request to be canceled */ if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) return AUTHORIZED; if (_realm->len == 0) { if (get_realm(_m, _hftype, &uri) < 0) { LM_ERR("failed to extract realm\n"); if (send_resp(_m, 400, &auth_400_err, 0, 0) == -1) { LM_ERR("failed to send 400 reply\n"); } return ERROR; } *_realm = uri->host; strip_realm(_realm); } /* Try to find credentials with corresponding realm * in the message, parse them and return pointer to * parsed structure */ ret = find_credentials(_m, _realm, _hftype, _h); if (ret < 0) { LM_ERR("failed to find credentials\n"); if (send_resp(_m, (ret == -2) ? 500 : 400, (ret == -2) ? &auth_500_err : &auth_400_err, 0, 0) == -1) { LM_ERR("failed to send 400 reply\n"); } return ERROR; } else if (ret > 0) { LM_DBG("credentials with given realm not found\n"); return NO_CREDENTIALS; } /* Pointer to the parsed credentials */ c = (auth_body_t*)((*_h)->parsed); /* Check credentials correctness here */ if (check_dig_cred(&(c->digest)) != E_DIG_OK) { LM_DBG("received credentials are not filled properly\n"); if (send_resp(_m, 400, &auth_400_err, 0, 0) == -1) { LM_ERR("failed to send 400 reply\n"); } return ERROR; } if (mark_authorized_cred(_m, *_h) < 0) { LM_ERR("failed to mark parsed credentials\n"); if (send_resp(_m, 500, &auth_400_err, 0, 0) == -1) { LM_ERR("failed to send 400 reply\n"); } return ERROR; } if (is_nonce_stale(&c->digest.nonce)) { LM_DBG("stale nonce value received\n"); c->stale = 1; return STALE_NONCE; } if (check_nonce(&c->digest.nonce, &secret) != 0) { LM_DBG("invalid nonce value received\n"); c->stale = 1; return STALE_NONCE; } return DO_AUTHORIZATION; }