Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 132426) +++ channels/chan_sip.c (working copy) @@ -1130,6 +1130,7 @@ struct sockaddr_in defaddr; /*!< Default IP address, used until registration */ struct ast_ha *ha; /*!< Access control list */ + struct ast_ha *contactha; /*!< Restrict what IPs are allowed in the Contact header (for registration) */ struct ast_variable *chanvars; /*!< Variables to set for channel created by user */ struct sip_pvt *mwipvt; /*!< Subscription for MWI */ int lastmsg; @@ -8238,13 +8239,24 @@ } else port = STANDARD_SIP_PORT; oldsin = peer->addr; + + /* Check that they're allowed to register at this IP */ + /* XXX This could block for a long time XXX */ + hp = ast_gethostbyname(n, &ahp); + if (!hp) { + ast_log(LOG_WARNING, "Invalid host '%s'\n", n); + *peer->fullcontact = '\0'; + ast_string_field_set(pvt, our_contact, ""); + return PARSE_REGISTER_FAILED; + } + if (ast_apply_ha(peer->contactha, (struct sockaddr_in *)hp->h_addr) != AST_SENSE_ALLOW) { + ast_log(LOG_WARNING, "Host '%s' disallowed by rule\n", n); + *peer->fullcontact = '\0'; + ast_string_field_set(pvt, our_contact, ""); + return PARSE_REGISTER_FAILED; + } + if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) { - /* XXX This could block for a long time XXX */ - hp = ast_gethostbyname(n, &ahp); - if (!hp) { - ast_log(LOG_WARNING, "Invalid host '%s'\n", n); - return PARSE_REGISTER_FAILED; - } peer->addr.sin_family = AF_INET; memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr)); peer->addr.sin_port = htons(port); @@ -16824,6 +16836,8 @@ } } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) { peer->ha = ast_append_ha(v->name, v->value, peer->ha); + } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) { + peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha); } else if (!strcasecmp(v->name, "port")) { if (!realtime && ast_test_flag(&peer->flags[1], SIP_PAGE2_DYNAMIC)) peer->defaddr.sin_port = htons(atoi(v->value)); Index: configs/sip.conf.sample =================================================================== --- configs/sip.conf.sample (revision 132426) +++ configs/sip.conf.sample (working copy) @@ -499,6 +499,10 @@ ; outboundproxy ; rfc2833compensate ; t38pt_usertpsource +; contactpermit ; Limit what a host may register as (a neat trick +; contactdeny ; is to register at the same IP as a SIP provider, +; ; then call oneself, and get redirected to that +; ; same location). ;[sip_proxy] ; For incoming calls only. Example: FWD (Free World Dialup)