blob: fa31a81396fc5763364a98794ce3c94a280f633d [file] [log] [blame]
Brian Waters13d96012017-12-08 16:53:31 -06001/*********************************************************************************************************
2* Software License Agreement (BSD License) *
3* Author: Alexandre Westfahl <awestfahl@freediameter.net> *
4* *
5* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. *
6* *
7* All rights reserved. *
8* *
9* Redistribution and use of this software in source and binary forms, with or without modification, are *
10* permitted provided that the following conditions are met: *
11* *
12* * Redistributions of source code must retain the above *
13* copyright notice, this list of conditions and the *
14* following disclaimer. *
15* *
16* * Redistributions in binary form must reproduce the above *
17* copyright notice, this list of conditions and the *
18* following disclaimer in the documentation and/or other *
19* materials provided with the distribution. *
20* *
21* * Neither the name of the Teraoka Laboratory nor the *
22* names of its contributors may be used to endorse or *
23* promote products derived from this software without *
24* specific prior written permission of Teraoka Laboratory *
25* *
26* *
27* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
28* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
29* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
30* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
31* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
32* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
33* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
34* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
35*********************************************************************************************************/
36#include "app_sip.h"
37
38
39int app_sip_SAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, void * opaque, enum disp_action * act)
40{
41 TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
42
43 struct msg *ans, *qry;
44 struct avp *avp;
45 struct avp_hdr *avphdr, *sipaorhdr, *usernamehdr, *sipuserdataalreadyavailable;
46 union avp_value value;
47 int ret=0, assignment_type=0, got_datatype=1;
48
49
50 struct listdatatype
51 {
52 struct fd_list datatype;
53 char * type;
54 size_t typelen;
55 };
56
57 //Result_Code to return in the answer
58 char result[55];
59
60 if (msg == NULL)
61 return EINVAL;
62
63
64 // Create answer header
65 qry = *msg;
66 CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
67 ans = *msg;
68
69 //Add the Auth-Application-Id
70 {
71 CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
72 value.i32 = 6;
73 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
74 CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
75 }
76 // Add the Auth-Session-State AVP
77 {
78
79 CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
80 CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
81
82 CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
83 CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
84 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
85 }
86 //Retrieve SIP-AOR
87 {
88 CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
89 if(avp!=NULL)
90 {
91 CHECK_FCT( fd_msg_avp_hdr( avp, &sipaorhdr ) );
92 }
93 else
94 sipaorhdr=NULL;
95
96 }
97
98 //We check if we have a username AVP
99 {
100 CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.User_Name, &avp) );
101 if(avp!=NULL)
102 {
103 CHECK_FCT( fd_msg_avp_hdr( avp, &usernamehdr ) );
104
105 ret=get_password(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, NULL);
106
107
108 if(ret==1)
109 {//not found
110 strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN");
111 goto out;
112 }
113 else if(ret==2)
114 {//error
115 //We couldn't make the request, we must stop process!
116 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
117 goto out;
118 }
119 else if(ret==0)
120 {//found
121
122 if(sipaorhdr!=NULL)
123 {
124 //We must check that this user can use this SIP-AOR
125 ret=check_sipaor(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len,(const char *) sipaorhdr->avp_value->os.data,sipaorhdr->avp_value->os.len);
126
127 if(ret==0)
128 {
129 //The SIP-AOR and Username are ok!
130 ret=clear_pending_flag(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len);
131 if(ret==2)
132 {
133 TRACE_DEBUG(INFO,"ERROR: We couldn't clear the flag of pending authentication.'");
134 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
135 goto out;
136 }
137 }
138 else if(ret==1)
139 {//not found
140 strcpy(result,"DIAMETER_ERROR_IDENTITIES_DONT_MATCH");
141 goto out;
142 }
143 else
144 {//error
145 //We couldn't make the request, we must stop process!
146 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
147 goto out;
148 }
149 }
150 else
151 {
152 TRACE_DEBUG(INFO,"ERROR: There is no SIP-AOR AVP!'");
153 strcpy(result,"DIAMETER_ERROR_IDENTITIES_DONT_MATCH");
154 goto out;
155 }
156 }
157 }
158 else
159 {
160 if(sipaorhdr!=NULL)
161 {//If we have a SIP-AOR, we want the user to check it.
162 strcpy(result,"DIAMETER_USER_NAME_REQUIRED");
163 goto out;
164 }
165 usernamehdr=NULL;
166 }
167
168 }
169
170 //We get the SIP_Server_Assignment_Type
171 {
172 CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_Assignment_Type, &avp) );
173 CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ) );
174
175 assignment_type=avphdr->avp_value->i32;
176 }
177
178
179
180
181
182 //We get SIP_User_Data_Already_Available AVP
183 {
184 CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_User_Data_Already_Available, &avp) );
185 CHECK_FCT( fd_msg_avp_hdr( avp, &sipuserdataalreadyavailable ) );
186 }
187
188 if(assignment_type==1 || assignment_type==2)
189 {//registration & re-registration
190 if(count_avp(qry,CODE_SIP_AOR,0)==1)
191 {
192
193 if(sipuserdataalreadyavailable->avp_value->i32==0)
194 {//Data not available, we must provide it
195 ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
196
197 if(ret==0)
198 {
199 //We found and added datatype
200 got_datatype=1;
201 }
202 else if(ret==1)
203 {
204 //No data type was found
205 got_datatype=0;
206 }
207 else
208 {//error
209 //We couldn't make the request, we must stop process!
210 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
211 goto out;
212 }
213 }
214 strcpy(result,"DIAMETER_SUCCESS");
215 goto out;
216 }
217 else
218 {//There is more than 1 SIP-AOR AVP
219 strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES");
220 goto out;
221 }
222 }
223 else if(assignment_type==3)
224 {//Unregistered user
225
226 //TODO:place user unknown here!
227 if(count_avp(qry,CODE_SIP_AOR,0)==1)
228 {
229 if(sipuserdataalreadyavailable->avp_value->i32==0)
230 {//Data not available, we must provide it
231 if(got_datatype==1)
232 {
233 ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
234
235 if(ret==0)
236 {
237 //We found and added datatype
238 got_datatype=1;
239 }
240 else if(ret==1)
241 {
242 //No data type was found
243 got_datatype=0;
244 }
245 else
246 {//error
247 //We couldn't make the request, we must stop process!
248 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
249 goto out;
250 }
251 }
252 }
253 strcpy(result,"DIAMETER_SUCCESS");
254 goto out;
255 }
256 else
257 {//There is more than 1 SIP-AOR AVP
258 strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES");
259 goto out;
260 }
261
262 if(sipuserdataalreadyavailable->avp_value->i32==0)
263 {//Data not available, we must provide it
264 if(got_datatype==1)
265 {
266 ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
267
268 if(ret==0)
269 {
270 //We found and added datatype
271 got_datatype=1;
272 }
273 else if(ret==1)
274 {
275 //No data type was found
276 got_datatype=0;
277 }
278 else
279 {//error
280 //We couldn't make the request, we must stop process!
281 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
282 goto out;
283 }
284 }
285 }
286
287 CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) );
288 if(avp!=NULL)
289 {
290 CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ));
291
292 set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len);
293 strcpy(result,"DIAMETER_SUCCESS");
294 goto out;
295 }
296 else
297 {
298 TRACE_DEBUG(INFO,"There is no SIP_Server_URI AVP in this Unregistered User Request!");
299 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
300 goto out;
301 }
302 }
303 else if(assignment_type==4 || assignment_type==5 || assignment_type==11 || assignment_type==8)
304 {//Unregistered user
305
306 if(got_datatype==1)
307 {
308 if(sipuserdataalreadyavailable->avp_value->i32==0)
309 {//Data not available, we must provide it
310
311 ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
312
313 if(ret==0)
314 {
315 //We found and added datatype
316 got_datatype=1;
317 }
318 else if(ret==1)
319 {
320 //No data type was found
321 got_datatype=0;
322 }
323 else
324 {//error
325 //We couldn't make the request, we must stop process!
326 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
327 goto out;
328 }
329 }
330 }
331
332 if(sipaorhdr==NULL)
333 {
334 //We don't have any SIP-AOR to unregister, this is strange!'
335 TRACE_DEBUG(INFO, "There was no SIP-AOR in this request, we can't proceed request!'");
336 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
337 goto out;
338 }
339 else
340 {
341 //TODO: unregister SIP-Server-URI for all SIP-AOR
342 }
343 strcpy(result,"DIAMETER_SUCCESS");
344 goto out;
345 }
346 else if(assignment_type==6 || assignment_type==7)
347 {
348
349
350 CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) );
351 if(avp!=NULL)
352 {
353 CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ));
354
355 //TODO: set SIP server URI for each AOR
356
357 //TODO: unregister all SIP-AOR provided
358
359 //set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len);
360 strcpy(result,"DIAMETER_SUCCESS");
361 goto out;
362 }
363 else
364 {
365
366
367 //TODO: unregister all SIP-AOR provided
368
369 //TODO: clear sip server uri in database for the sip-aor
370
371
372 TRACE_DEBUG(INFO,"There is no SIP_Server_URI AVP in this Deregistration User Request! We just unregister SIP-AOR");
373 strcpy(result,"DIAMETER_SUCCESS_SERVER_NAME_NOT_STORED");
374 goto out;
375 }
376 }
377 else if(assignment_type==0)
378 {
379
380
381 CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Server_URI, &avp) );
382 if(avp!=NULL)
383 {
384 unsigned char * sipserver_uri;
385 size_t sipserverurilen;
386
387
388
389
390 ret=get_sipserver_uri(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len, &sipserver_uri, &sipserverurilen);
391
392 if(ret==0)
393 {//found
394 CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr ));
395
396
397
398
399 if(strncmp((char *)avphdr->avp_value->os.data,(char *)sipserver_uri,sipserverurilen))
400 {
401 if(got_datatype==1)
402 {
403 if(sipuserdataalreadyavailable->avp_value->i32==0)
404 {//Data not available, we must provide it
405
406 ret=add_user_datatype(sipaorhdr->avp_value->os.data, sipaorhdr->avp_value->os.len,ans);
407
408 if(ret==0)
409 {
410 //We found and added datatype
411 got_datatype=1;
412 }
413 else if(ret==1)
414 {
415 //No data type was found
416 got_datatype=0;
417 }
418 else
419 {//error
420 //We couldn't make the request, we must stop process!
421 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
422 goto out;
423 }
424 }
425 }
426 }
427 else
428 {//error
429 TRACE_DEBUG(FULL,"SIP_Server_URI is different from the one in database");
430 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
431 goto out;
432 }
433 }
434 else
435 {
436 TRACE_DEBUG(FULL,"SIP_Server_URI is different from the one in database");
437 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
438 goto out;
439 }
440
441
442
443
444
445
446
447 //set_real_sipserver_uri(usernamehdr->avp_value->os.data, usernamehdr->avp_value->os.len, avphdr->avp_value->os.data,avphdr->avp_value->os.len);
448 strcpy(result,"DIAMETER_SUCCESS");
449 goto out;
450 }
451 else
452 {
453 TRACE_DEBUG(INFO, "There was no SIP_Server_URI in this request, we can't proceed request!'");
454 strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
455 goto out;
456 }
457 }
458 else if(assignment_type==9 || assignment_type==10)
459 {
460 if(count_avp(qry, CODE_SIP_AOR,0)==1)
461 {
462 //TODO: remove SIP-server URI for sip_aor
463 //TODO: unregister it
464 strcpy(result,"DIAMETER_SUCCESS");
465 goto out;
466 }
467 else
468 {//There is more than 1 SIP-AOR AVP
469 strcpy(result,"DIAMETER_AVP_OCCURS_TOO_MANY_TIMES");
470 goto out;
471 }
472 }
473 out:
474 CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
475
476
477 //fd_msg_dump_walk(INFO,ans);
478
479 CHECK_FCT( fd_msg_send( msg, NULL, NULL ));
480
481
482
483 return 0;
484}