00001
00054 #include "nds.h"
00055
00056 #include "../../parser/hf.h"
00057 #include "../../parser/msg_parser.h"
00058 #include "../../parser/parse_via.h"
00059 #include "../../mem/shm_mem.h"
00060
00061 #include "mod.h"
00062 #include "sip.h"
00063 #include "db.h"
00064
00065
00066 extern int (*sl_reply)(struct sip_msg* _msg, char* _str1, char* _str2);
00071 str untrusted_headers[]={
00072 {"P-Asserted-Identity",19},
00073 {"P-Access-Network-Info",21},
00074 {"P-Charging-Vector",17},
00075 {"P-Charging-Function-Addresses",29},
00076 {0,0}
00077 };
00078
00080 static str *trusted_domains=0;
00081
00082
00083
00093 int I_NDS_check_trusted(struct sip_msg* msg, char* str1, char* str2)
00094 {
00095 int result;
00096 LOG(L_ERR,"DBG:"M_NAME":I_NDS_check_trusted: Starting ...\n");
00097 if (msg->first_line.type!=SIP_REQUEST) {
00098 LOG(L_ERR,"ERR:"M_NAME":I_NDS_check_trusted: The message is not a request\n");
00099 result = CSCF_RETURN_TRUE;
00100 goto done;
00101 }
00102 if (I_NDS_is_trusted(msg,str1,str2)){
00103 LOG(L_INFO,"INF:"M_NAME":I_NDS_check_trusted: Message comes from a trusted domain\n");
00104 result = CSCF_RETURN_TRUE;
00105 goto done;
00106 } else {
00107 LOG(L_INFO,"INF:"M_NAME":I_NDS_check_trusted: Message comes from an untrusted domain\n");
00108 result = CSCF_RETURN_FALSE;
00109 if (msg->first_line.u.request.method.len==8 &&
00110 memcmp(msg->first_line.u.request.method.s,"REGISTER",8)==0){
00111 sl_reply(msg,(char*)403,MSG_403);
00112 LOG(L_INFO,"INF:"M_NAME":I_NDS_check_trusted: REGISTER request terminated.\n");
00113 } else {
00114 if (!I_NDS_strip_headers(msg,str1,str2)){
00115 result = CSCF_RETURN_ERROR;
00116 sl_reply(msg,(char*)500,MSG_500);
00117 LOG(L_INFO,"INF:"M_NAME":I_NDS_check_trusted: Stripping untrusted headers failed, Responding with 500.\n");
00118 }
00119 }
00120 }
00121
00122 done:
00123 LOG(L_ERR,"DBG:"M_NAME":I_NDS_check_trusted: ... Done\n");
00124 return result;
00125 }
00126
00135 int I_NDS_is_trusted(struct sip_msg *msg, char* str1, char* str2)
00136 {
00137 struct via_body *vb;
00138 str subdomain;
00139 int i;
00140
00141 vb = msg->via1;
00142 if (!vb) {
00143 LOG(L_ERR,"ERR:"M_NAME":I_NDS_is_trusted: Error VIA1 hdr not found\n");
00144 return 0;
00145 }
00146 subdomain=vb->host;
00147 LOG(L_DBG,"DBG:"M_NAME":I_NDS_is_trusted: Message comes from <%.*s>\n",
00148 subdomain.len,subdomain.s);
00149
00150 i=0;
00151 while(trusted_domains[i].len){
00152 if (trusted_domains[i].len<=subdomain.len){
00153 if (strncasecmp(subdomain.s+subdomain.len-trusted_domains[i].len,
00154 trusted_domains[i].s,
00155 trusted_domains[i].len)==0 &&
00156 (trusted_domains[i].len==subdomain.len ||
00157 subdomain.s[subdomain.len-trusted_domains[i].len-1]=='.'))
00158 {
00159 LOG(L_DBG,"DBG:"M_NAME":I_NDS_is_trusted: <%.*s> matches <%.*s>\n",
00160 subdomain.len,subdomain.s,trusted_domains[i].len,trusted_domains[i].s);
00161 return CSCF_RETURN_TRUE;
00162 } else {
00163
00164
00165 }
00166 }
00167 i++;
00168 }
00169 return CSCF_RETURN_FALSE;
00170 }
00171
00172
00173
00182 int I_NDS_strip_headers(struct sip_msg *msg, char* str1, char* str2)
00183 {
00184 struct hdr_field *hdr;
00185 int i,cnt=0;
00186 if (parse_headers(msg,HDR_EOH_F,0)<0) return 0;
00187 for (hdr = msg->headers;hdr;hdr = hdr->next)
00188 for (i=0;untrusted_headers[i].len;i++)
00189 if (hdr->name.len == untrusted_headers[i].len &&
00190 strncasecmp(hdr->name.s,untrusted_headers[i].s,hdr->name.len)==0){
00191 if (!cscf_del_header(msg,hdr)) return 0;
00192 cnt++;
00193 }
00194 LOG(L_DBG,"DBG:"M_NAME":I_NDS_strip_headers: Deleted %d headers\n",cnt);
00195 return cnt;
00196 }
00197
00198
00199
00207 int I_NDS_get_trusted_domains()
00208 {
00209 int i;
00210
00211 if (trusted_domains!=0){
00212 i=0;
00213 while(trusted_domains[i].s){
00214 shm_free(trusted_domains[i].s);
00215 i++;
00216 }
00217 shm_free(trusted_domains);
00218 }
00219 return icscf_db_get_nds(&trusted_domains);
00220 }
00221