Browse code

core: relocated some folders from root and utils to misc

- utils keeps only the applications related to kamailio c code
- the other are now in misc/tools
- utils/misc/vim moved to misc/extra/
- obsolete and scripts folders moved to misc/

Daniel-Constantin Mierla authored on 07/12/2016 11:46:38
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,609 +0,0 @@
1
-/*
2
- * Presence Agent, subscribe handling
3
- *
4
- * $Id$
5
- *
6
- * Copyright (C) 2001-2003 FhG Fokus
7
- *
8
- * This file is part of ser, a free SIP server.
9
- *
10
- * ser is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License as published by
12
- * the Free Software Foundation; either version 2 of the License, or
13
- * (at your option) any later version
14
- *
15
- * For a license to use the ser software under conditions
16
- * other than those described here, or to purchase support for this
17
- * software, please contact iptel.org by e-mail at the following addresses:
18
- *    info@iptel.org
19
- *
20
- * ser is distributed in the hope that it will be useful,
21
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
- * GNU General Public License for more details.
24
- *
25
- * You should have received a copy of the GNU General Public License 
26
- * along with this program; if not, write to the Free Software 
27
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28
- *
29
- * History:
30
- * ---------
31
- * 2003-02-29 scratchpad compatibility abandoned
32
- * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
33
- */
34
-
35
-#include <string.h>
36
-#include <limits.h>
37
-#include "../../str.h"
38
-#include "../../dprint.h"
39
-#include "../../mem/mem.h"
40
-#include "../../parser/parse_uri.h"
41
-#include "../../parser/parse_from.h"
42
-#include "../../parser/parse_expires.h"
43
-#include "../../parser/parse_event.h"
44
-#include "../../data_lump_rpl.h"
45
-#include "presentity.h"
46
-#include "watcher.h"
47
-#include "notify.h"
48
-#include "paerrno.h"
49
-#include "pdomain.h"
50
-#include "pa_mod.h"
51
-#include "ptime.h"
52
-#include "reply.h"
53
-#include "subscribe.h"
54
-#include "auth.h"
55
-#include <cds/sstr.h>
56
-#include <cds/msg_queue.h>
57
-#include <cds/logger.h>
58
-#include <cds/sip_utils.h>
59
-#include <presence/utils.h>
60
-#include "offline_winfo.h"
61
-#include "mimetypes.h"
62
-
63
-#include <string.h>
64
-#include "../../mem/shm_mem.h"
65
-#include "../../dprint.h"
66
-#include "../../globals.h"
67
-#include "../../md5.h"
68
-#include "../../crc.h"
69
-#include "../../ip_addr.h"
70
-#include "../../socket_info.h"
71
-#include "../../modules/tm/ut.h"
72
-#include "../../modules/tm/h_table.h"
73
-#include "../../modules/tm/t_hooks.h"
74
-#include "../../modules/tm/t_funcs.h"
75
-#include "../../modules/tm/t_msgbuilder.h"
76
-#include "../../modules/tm/callid.h"
77
-#include "../../modules/tm/uac.h"
78
-
79
-#define DOCUMENT_TYPE "application/cpim-pidf+xml"
80
-#define DOCUMENT_TYPE_L (sizeof(DOCUMENT_TYPE) - 1)
81
-
82
-/*
83
- * Extract plain uri -- return URI without parameters
84
- * The uri will be in form username@domain
85
- *
86
- */
87
-static int extract_plain_uri(str* _uri)
88
-{
89
-	struct sip_uri puri;
90
-	int res = 0;
91
-
92
-	if (parse_uri(_uri->s, _uri->len, &puri) < 0) {
93
-		paerrno = PA_URI_PARSE;
94
-		LOG(L_ERR, "extract_plain_uri(): Error while parsing URI\n");
95
-		return -1;
96
-	}
97
-	
98
-	/* _uri->s = puri.user.s;
99
-	if ((!_uri->s) || (puri.user.len < 1)) {
100
-		_uri->s = puri.host.s;
101
-		_uri->len = puri.host.len;
102
-		return -1;
103
-	}*/
104
-	if (puri.user.len < 1) {
105
-		res = -1; /* it is uri without username ! */
106
-	}
107
-	_uri->len = puri.host.s + puri.host.len - _uri->s;
108
-	return res;
109
-}
110
-
111
-/*
112
- * Get presentity URI, which is stored in R-URI
113
- */
114
-int get_pres_uri(struct sip_msg* _m, str* _puri)
115
-{
116
-	if (_m->new_uri.s) {
117
-		_puri->s = _m->new_uri.s;
118
-		_puri->len = _m->new_uri.len;
119
-	} else {
120
-		_puri->s = _m->first_line.u.request.uri.s;
121
-		_puri->len = _m->first_line.u.request.uri.len;
122
-	}
123
-	LOG(L_DBG, "get_pres_uri: _puri=%.*s\n", _puri->len, _puri->s);
124
-
125
-	if (extract_plain_uri(_puri) < 0) {
126
-		_puri->s = get_to(_m)->uri.s;
127
-		_puri->len = get_to(_m)->uri.len;
128
-		LOG(L_DBG, "get_pres_uri(2): _puri=%.*s\n", _puri->len, _puri->s);
129
-	
130
-		if (extract_plain_uri(_puri) < 0) {
131
-			LOG(L_ERR, "get_pres_uri(): Error while extracting plain URI\n");
132
-			return -1;
133
-		}
134
-	}
135
-
136
-	return 0;
137
-}
138
-
139
-
140
-static int get_watch_uri(struct sip_msg* _m, str* _wuri, str *_dn)
141
-{
142
-	_wuri->s = get_from(_m)->uri.s;
143
-	_wuri->len = get_from(_m)->uri.len;
144
-	_dn->s = get_from(_m)->body.s;
145
-	_dn->len = get_from(_m)->body.len;
146
-
147
-	if (extract_plain_uri(_wuri) < 0) {
148
-		LOG(L_ERR, "get_watch_uri(): Error while extracting plain URI\n");
149
-		return -1;
150
-	}
151
-	
152
-	return 0;
153
-}
154
-
155
-static int get_dlg_id(struct sip_msg *_m, dlg_id_t *dst)
156
-{
157
-	if (!dst) return -1;
158
-	
159
-	memset(dst, 0, sizeof(*dst));
160
-	if (_m->to) dst->loc_tag = ((struct to_body*)_m->to->parsed)->tag_value;
161
-	if (_m->from) dst->rem_tag = ((struct to_body*)_m->from->parsed)->tag_value;
162
-	if (_m->callid) dst->call_id = _m->callid->body;
163
-	
164
-	return 0;
165
-}
166
-
167
-static time_t get_expires(struct sip_msg *_m)
168
-{
169
-	time_t e;
170
-	
171
-	if (_m->expires) e = ((exp_body_t*)_m->expires->parsed)->val;
172
-	else e = default_expires;
173
-	if (e > max_subscription_expiration) 
174
-		e = max_subscription_expiration;
175
-	return e;
176
-}
177
-
178
-/*
179
- * Parse all header fields that will be needed
180
- * to handle a SUBSCRIBE request
181
- */
182
-static int parse_hfs(struct sip_msg* _m, int accept_header_required)
183
-{
184
-	int rc = 0;
185
-	struct hdr_field *acc;
186
-	
187
-	/* EOH instead HDR_FROM_F | HDR_EVENT_F | HDR_EXPIRES_F | HDR_ACCEPT_F  
188
-	 * because we need all Accept headers */
189
-	if ( (rc = parse_headers(_m, HDR_EOH_F, 0)) == -1) {
190
-		paerrno = PA_PARSE_ERR;
191
-		LOG(L_ERR, "parse_hfs(): Error while parsing headers: rc=%d\n", rc);
192
-		return -1;
193
-	}
194
-
195
-	if (!_m->from) {
196
-		ERR("From header missing\n");
197
-		return -1;
198
-	}
199
-	
200
-	if (parse_from_header(_m) < 0) {
201
-		paerrno = PA_FROM_ERR;
202
-		LOG(L_ERR, "parse_hfs(): From malformed or missing\n");
203
-		return -6;
204
-	}
205
-
206
-	if (_m->event) {
207
-		if (parse_event(_m->event) < 0) {
208
-			/* can not parse Event header */
209
-			paerrno = PA_EVENT_PARSE;
210
-			LOG(L_ERR, "parse_hfs(): Error while parsing Event header field\n");
211
-			return -8;
212
-		}
213
-	}
214
-	else { 
215
-		/* no Event header -> bad message */
216
-		paerrno = PA_EVENT_PARSE;
217
-		LOG(L_ERR, "parse_hfs(): Error while parsing Event header field\n");
218
-		return -8;
219
-	}
220
-
221
-	if (_m->expires) {
222
-		if (parse_expires(_m->expires) < 0) {
223
-			paerrno = PA_EXPIRES_PARSE;
224
-			LOG(L_ERR, "parse_hfs(): Error while parsing Expires header field\n");
225
-			return -9;
226
-		}
227
-	}
228
-
229
-	/* now look for Accept header */
230
-	acc = _m->accept;
231
-	if (accept_header_required && (!acc)) {
232
-		LOG(L_ERR, "no accept header\n");
233
-		return -11;
234
-	}
235
-	
236
-	while (acc) { /* parse all accept headers */
237
-		if (acc->type == HDR_ACCEPT_T) {
238
-			DBG("parsing accept header: %.*s\n", FMT_STR(acc->body));
239
-			if (parse_accept_body(acc) < 0) {
240
-				paerrno = PA_ACCEPT_PARSE;
241
-				LOG(L_ERR, "parse_hfs(): Error while parsing Accept header field\n");
242
-				return -10;
243
-			}
244
-		}
245
-		acc = acc->next;
246
-	}
247
-
248
-	return 0;
249
-}
250
-
251
-/* returns 0 if package supported by PA */
252
-static inline int verify_event_package(int et)
253
-{
254
-	switch (et) {
255
-		case EVENT_PRESENCE: return 0;
256
-		case EVENT_PRESENCE_WINFO: 
257
-			if (watcherinfo_notify) return 0;
258
-			else return -1;
259
-		default: return -1;
260
-	}
261
-}
262
-
263
-/* get_event MUST be parsed when calling get event -> done by parse_hfs! */
264
-#define get_event(_m) ((event_t*)(_m->event->parsed))->parsed
265
-
266
-/*
267
- * Check if a message received has been constructed properly
268
- */
269
-static int check_message(struct sip_msg* _m)
270
-{
271
-	int eventtype = 0;
272
-	int *accepts_mimes = NULL;
273
-	event_mimetypes_t *em;
274
-	struct hdr_field *acc;
275
-
276
-	if ((!_m->event) || (!_m->event->parsed)) {
277
-		paerrno = PA_EXPIRES_PARSE;
278
-		ERR("Event header field not found\n");
279
-		return -1; /* should be verified in parse_hfs before */
280
-	}
281
-
282
-	/* event package verification */
283
-	eventtype = get_event(_m);
284
-	
285
-	if (verify_event_package(eventtype) != 0) {
286
-		INFO("Unsupported event package\n");
287
-		paerrno = PA_EVENT_UNSUPP;
288
-		return -1;
289
-	}
290
-
291
-	em = find_event_mimetypes(eventtype);
292
-	if (em) 
293
-		if (em->event_type == -1) em = NULL;
294
-	if (!em) {
295
-		paerrno = PA_EVENT_UNSUPP;
296
-		ERR("Unsupported event package\n");
297
-		return -1;
298
-	}
299
-
300
-	acc = _m->accept;
301
-	if (!acc) return 0; /* default will be used */
302
-	
303
-	while (acc) { /* go through all Accept headers */
304
-		if (acc->type == HDR_ACCEPT_T) {
305
-			/* it MUST be parsed from parse_hdr !!! */
306
-			accepts_mimes = acc->parsed;
307
-			if (check_mime_types(accepts_mimes, em) == 0) return 0;
308
-			
309
-			/* else, none of the mimetypes accepted are generated for this event package */
310
-			INFO("Accepts %.*s not valid for event package et=%.*s\n",
311
-				acc->body.len, acc->body.s, _m->event->body.len, _m->event->body.s);
312
-		}
313
-		acc = acc->next;
314
-	}
315
-	paerrno = PA_WRONG_ACCEPTS;
316
-	ERR("no satisfactory document type found\n");
317
-	return -1;
318
-}
319
-
320
-static int create_watcher(struct sip_msg* _m, struct watcher** _w)
321
-{
322
-	dlg_t* dialog;
323
-	str server_contact = STR_NULL;
324
-	int acc = 0;
325
-	str watch_uri;
326
-	str watch_dn;
327
-	int et;
328
-	time_t expires;
329
-	
330
-	et = get_event(_m);	
331
-	expires = get_expires(_m);
332
-	if (expires) expires += act_time;
333
-	
334
-	if (get_watch_uri(_m, &watch_uri, &watch_dn) < 0) {
335
-		paerrno = PA_URI_PARSE;
336
-		ERR("Error while extracting watcher URI\n");
337
-		return -1;
338
-	}
339
-	acc = get_preferred_event_mimetype(_m, et);
340
-	if (tmb.new_dlg_uas(_m, 200, &dialog) < 0) {
341
-		paerrno = PA_DIALOG_ERR;
342
-		ERR("Error while creating dialog state\n");
343
-		return -4;
344
-	}
345
-	
346
-	if (extract_server_contact(_m, &server_contact, 1) != 0) {
347
-		paerrno = PA_DIALOG_ERR;
348
-		ERR("Error while extracting server contact\n");
349
-		return -3;
350
-	}
351
-
352
-	if (new_watcher_no_wb(&watch_uri, expires, et, acc, dialog, 
353
-				&watch_dn, &server_contact, NULL, _w) < 0) {
354
-		ERR("Error while creating watcher\n");
355
-		tmb.free_dlg(dialog);
356
-		if (server_contact.s) mem_free(server_contact.s);
357
-		paerrno = PA_NO_MEMORY;
358
-		return -5;
359
-	}
360
-	if (server_contact.s) mem_free(server_contact.s);
361
-	
362
-	(*_w)->flags |= WFLAG_SUBSCRIPTION_CHANGED;
363
-	
364
-	return 0;
365
-}
366
-
367
-
368
-static inline int add_rpl_expires(struct sip_msg *_m, watcher_t *w)
369
-{
370
-	int i = 0;
371
-	char tmp[64];
372
-	
373
-	/* add expires header field into response */
374
-	if (w) i = w->expires - act_time;
375
-	if (i < 0) i = 0;
376
-	sprintf(tmp, "Expires: %d\r\n", i);
377
-	if (!add_lump_rpl(_m, tmp, strlen(tmp), LUMP_RPL_HDR)) {
378
-		ERR("Can't add Expires header to the response\n");
379
-		return -1;
380
-	}
381
-	
382
-	return 0;
383
-}
384
-
385
-int handle_renewal_subscription(struct sip_msg* _m, struct pdomain *d)
386
-{
387
-	struct presentity *p = NULL;
388
-	struct watcher* w = NULL;
389
-	str uid = STR_NULL;
390
-	dlg_id_t dlg_id;
391
-	int et, e;
392
-	
393
-	if (get_presentity_uid(&uid, _m) < 0) {
394
-		ERR("Error while extracting presentity UID\n");
395
-		paerrno = PA_INTERNAL_ERROR;
396
-		goto err;
397
-	}	
398
-
399
-	/* needed to find watcher (better to set outside of crit. sect. due to
400
-	 * better performance) */
401
-	et = get_event(_m);	
402
-	get_dlg_id(_m, &dlg_id);
403
-	
404
-	lock_pdomain(d);
405
-		
406
-	if (find_presentity_uid(d, &uid, &p) != 0) { 
407
-		/* presentity not found */
408
-		INFO("resubscription to nonexisting presentity %.*s\n", FMT_STR(uid));
409
-		paerrno = PA_SUBSCRIPTION_NOT_EXISTS;
410
-		goto err2;
411
-	}
412
-	
413
-	if (find_watcher_dlg(p, &dlg_id, et, &w) != 0) {
414
-		/* watcher not found */
415
-		INFO("resubscription for nonexisting watcher\n");
416
-		paerrno = PA_SUBSCRIPTION_NOT_EXISTS;
417
-		goto err2;
418
-	}
419
-	
420
-	e = get_expires(_m);
421
-	if (e) e += act_time;
422
-	
423
-	update_watcher(p, w, e, _m);
424
-	set_last_subscription_status(w->status);	
425
-	add_rpl_expires(_m, w);
426
-	if (send_reply(_m) >= 0) {
427
-		/* we have successfully sent the response */
428
-		if (send_notify(p, w) >= 0) {		
429
-			w->flags &= ~WFLAG_SUBSCRIPTION_CHANGED; /* notified */
430
-			
431
-			/* remove terminated watcher otherwise he will 
432
-			 * receive another NOTIFY generated from timer_pdomain */
433
-			if (is_watcher_terminated(w)) {
434
-				remove_watcher(p, w);
435
-				free_watcher(w);
436
-			}
437
-		} 
438
-	}
439
-	else {
440
-		ERR("Error while sending reply\n");
441
-	}
442
-	
443
-	unlock_pdomain(d);
444
-	
445
-	return 1;
446
-
447
-err2:
448
-	unlock_pdomain(d);
449
-	
450
-err:
451
-	set_last_subscription_status(WS_REJECTED);
452
-	
453
-	if (send_reply(_m) < 0) ERR("Error while sending reply\n");
454
-	return -1;
455
-}
456
-
457
-presentity_t *get_presentity(struct sip_msg *_m, struct pdomain *d, int allow_creation)
458
-{
459
-	str p_uri, uid;
460
-	presentity_t *p = NULL;
461
-	xcap_query_params_t xcap_params;
462
-/*	presence_rules_t *auth_rules = NULL;*/
463
-
464
-	if (get_presentity_uid(&uid, _m) < 0) {
465
-		ERR("Error while extracting presentity UID\n");
466
-		return NULL;
467
-	}
468
-	
469
-	if (find_presentity_uid(d, &uid, &p) > 0)  {
470
-		if (allow_creation) {
471
-			if (get_pres_uri(_m, &p_uri) < 0) {
472
-				ERR("Error while extracting presentity URI\n");
473
-			}
474
-			else {
475
-				/* presentity not found -> create new presentity */
476
-				memset(&xcap_params, 0, sizeof(xcap_params));
477
-				if (fill_xcap_params) fill_xcap_params(_m, &xcap_params);
478
-				if (new_presentity(d, &p_uri, &uid, &xcap_params, &p) < 0)
479
-					ERR("Error while creating new presentity\n");
480
-			}
481
-		}
482
-	}
483
-	return p;
484
-}
485
-
486
-int handle_new_subscription(struct sip_msg* _m, struct pdomain *d)
487
-{
488
-	struct presentity *p;
489
-	struct watcher* w;
490
-	struct retr_buf *req;
491
-	int is_terminated;
492
-	
493
-	if (create_watcher(_m, &w) < 0) {
494
-		ERR("can't create watcher\n");
495
-		goto err;
496
-	}
497
-
498
-	lock_pdomain(d);
499
-
500
-	p = get_presentity(_m, d, 1);
501
-	if (!p) goto err3;
502
-	
503
-	/* authorize watcher */
504
-	w->status = authorize_watcher(p, w);
505
-										   
506
-	switch (w->status) {
507
-		case WS_REJECTED:
508
-			unlock_pdomain(d);
509
-			free_watcher(w);
510
-			paerrno = PA_SUBSCRIPTION_REJECTED;
511
-			INFO("watcher rejected\n");
512
-			goto err;
513
-		case WS_PENDING:
514
-		case WS_PENDING_TERMINATED:
515
-			paerrno = PA_OK_WAITING_FOR_AUTH;
516
-		default:
517
-			break;
518
-	}
519
-	if (w->expires <= act_time) {
520
-		set_watcher_terminated_status(w);
521
-		is_terminated = 1;
522
-	}
523
-	else {
524
-		is_terminated = 0;	
525
-
526
-		if (append_watcher(p, w, 1) < 0) {
527
-			ERR("can't add watcher\n");
528
-			goto err3;
529
-		}
530
-	}
531
-	
532
-	if (prepare_notify(&req, p, w) < 0) {
533
-		ERR("can't send notify\n");
534
-		goto err4;
535
-	}
536
-
537
-	set_last_subscription_status(w->status);
538
-	add_rpl_expires(_m, w);
539
-	
540
-	unlock_pdomain(d);
541
-
542
-	send_reply(_m); 
543
-	
544
-	if (req) {
545
-		tmb.send_prepared_request(req);
546
-		w->flags &= ~WFLAG_SUBSCRIPTION_CHANGED; /* notified */
547
-		if (is_terminated) {
548
-			free_watcher(w);
549
-			w = NULL;
550
-		} 
551
-	}
552
-
553
-	return 1;
554
-	
555
-err4:
556
-	remove_watcher(p, w);
557
-
558
-err3:
559
-	unlock_pdomain(d);
560
-	free_watcher(w);
561
-	paerrno = PA_INTERNAL_ERROR;
562
-	
563
-err:
564
-	set_last_subscription_status(WS_REJECTED);
565
-	
566
-	if (paerrno == PA_OK) paerrno = PA_INTERNAL_ERROR;
567
-	if (send_reply(_m) < 0) ERR("Error while sending reply\n");
568
-	return -1;
569
-}
570
-
571
-/*
572
- * Handle a subscribe Request
573
- */
574
-int handle_subscription(struct sip_msg* _m, char* _domain, char* _s2)
575
-{
576
-	int res;
577
-	PROF_START_DECL(pa_response_generation)
578
-
579
-	PROF_START(pa_handle_subscription)
580
-
581
-	get_act_time();
582
-	paerrno = PA_OK;
583
-
584
-	if (parse_hfs(_m, 0) < 0) {
585
-		ERR("Error while parsing message header\n");
586
-		goto error;
587
-	}
588
-
589
-	if (check_message(_m) < 0) {
590
-		ERR("Error while checking message\n");
591
-		goto error;
592
-	}
593
-
594
-	if (has_to_tag(_m)) 
595
-		res = handle_renewal_subscription(_m, (struct pdomain*)_domain);
596
-	else
597
-		res = handle_new_subscription(_m, (struct pdomain*)_domain);
598
-
599
-	PROF_STOP(pa_handle_subscription)
600
-	return res;
601
-	
602
- error:
603
-	INFO("handle_subscription about to send_reply and return -2\n");
604
-	send_reply(_m);
605
-	set_last_subscription_status(WS_REJECTED);
606
-	PROF_STOP(pa_handle_subscription)
607
-	return -1;
608
-}
609
-
Browse code

all: updated FSF address in GPL text

Anthony Messina authored on 04/07/2014 09:36:37 • Daniel-Constantin Mierla committed on 04/07/2014 09:37:36
Showing 1 changed files
... ...
@@ -24,7 +24,7 @@
24 24
  *
25 25
  * You should have received a copy of the GNU General Public License 
26 26
  * along with this program; if not, write to the Free Software 
27
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28 28
  *
29 29
  * History:
30 30
  * ---------
Browse code

pa(s): obsoleted

Moved pa to obsolete/ because it does not compile (needs upgrade
to the current DB libs) and it does not have a maintainer.

Andrei Pelinescu-Onciul authored on 09/12/2009 09:53:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,609 @@
1
+/*
2
+ * Presence Agent, subscribe handling
3
+ *
4
+ * $Id$
5
+ *
6
+ * Copyright (C) 2001-2003 FhG Fokus
7
+ *
8
+ * This file is part of ser, a free SIP server.
9
+ *
10
+ * ser is free software; you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation; either version 2 of the License, or
13
+ * (at your option) any later version
14
+ *
15
+ * For a license to use the ser software under conditions
16
+ * other than those described here, or to purchase support for this
17
+ * software, please contact iptel.org by e-mail at the following addresses:
18
+ *    info@iptel.org
19
+ *
20
+ * ser is distributed in the hope that it will be useful,
21
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
+ * GNU General Public License for more details.
24
+ *
25
+ * You should have received a copy of the GNU General Public License 
26
+ * along with this program; if not, write to the Free Software 
27
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28
+ *
29
+ * History:
30
+ * ---------
31
+ * 2003-02-29 scratchpad compatibility abandoned
32
+ * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
33
+ */
34
+
35
+#include <string.h>
36
+#include <limits.h>
37
+#include "../../str.h"
38
+#include "../../dprint.h"
39
+#include "../../mem/mem.h"
40
+#include "../../parser/parse_uri.h"
41
+#include "../../parser/parse_from.h"
42
+#include "../../parser/parse_expires.h"
43
+#include "../../parser/parse_event.h"
44
+#include "../../data_lump_rpl.h"
45
+#include "presentity.h"
46
+#include "watcher.h"
47
+#include "notify.h"
48
+#include "paerrno.h"
49
+#include "pdomain.h"
50
+#include "pa_mod.h"
51
+#include "ptime.h"
52
+#include "reply.h"
53
+#include "subscribe.h"
54
+#include "auth.h"
55
+#include <cds/sstr.h>
56
+#include <cds/msg_queue.h>
57
+#include <cds/logger.h>
58
+#include <cds/sip_utils.h>
59
+#include <presence/utils.h>
60
+#include "offline_winfo.h"
61
+#include "mimetypes.h"
62
+
63
+#include <string.h>
64
+#include "../../mem/shm_mem.h"
65
+#include "../../dprint.h"
66
+#include "../../globals.h"
67
+#include "../../md5.h"
68
+#include "../../crc.h"
69
+#include "../../ip_addr.h"
70
+#include "../../socket_info.h"
71
+#include "../../modules/tm/ut.h"
72
+#include "../../modules/tm/h_table.h"
73
+#include "../../modules/tm/t_hooks.h"
74
+#include "../../modules/tm/t_funcs.h"
75
+#include "../../modules/tm/t_msgbuilder.h"
76
+#include "../../modules/tm/callid.h"
77
+#include "../../modules/tm/uac.h"
78
+
79
+#define DOCUMENT_TYPE "application/cpim-pidf+xml"
80
+#define DOCUMENT_TYPE_L (sizeof(DOCUMENT_TYPE) - 1)
81
+
82
+/*
83
+ * Extract plain uri -- return URI without parameters
84
+ * The uri will be in form username@domain
85
+ *
86
+ */
87
+static int extract_plain_uri(str* _uri)
88
+{
89
+	struct sip_uri puri;
90
+	int res = 0;
91
+
92
+	if (parse_uri(_uri->s, _uri->len, &puri) < 0) {
93
+		paerrno = PA_URI_PARSE;
94
+		LOG(L_ERR, "extract_plain_uri(): Error while parsing URI\n");
95
+		return -1;
96
+	}
97
+	
98
+	/* _uri->s = puri.user.s;
99
+	if ((!_uri->s) || (puri.user.len < 1)) {
100
+		_uri->s = puri.host.s;
101
+		_uri->len = puri.host.len;
102
+		return -1;
103
+	}*/
104
+	if (puri.user.len < 1) {
105
+		res = -1; /* it is uri without username ! */
106
+	}
107
+	_uri->len = puri.host.s + puri.host.len - _uri->s;
108
+	return res;
109
+}
110
+
111
+/*
112
+ * Get presentity URI, which is stored in R-URI
113
+ */
114
+int get_pres_uri(struct sip_msg* _m, str* _puri)
115
+{
116
+	if (_m->new_uri.s) {
117
+		_puri->s = _m->new_uri.s;
118
+		_puri->len = _m->new_uri.len;
119
+	} else {
120
+		_puri->s = _m->first_line.u.request.uri.s;
121
+		_puri->len = _m->first_line.u.request.uri.len;
122
+	}
123
+	LOG(L_DBG, "get_pres_uri: _puri=%.*s\n", _puri->len, _puri->s);
124
+
125
+	if (extract_plain_uri(_puri) < 0) {
126
+		_puri->s = get_to(_m)->uri.s;
127
+		_puri->len = get_to(_m)->uri.len;
128
+		LOG(L_DBG, "get_pres_uri(2): _puri=%.*s\n", _puri->len, _puri->s);
129
+	
130
+		if (extract_plain_uri(_puri) < 0) {
131
+			LOG(L_ERR, "get_pres_uri(): Error while extracting plain URI\n");
132
+			return -1;
133
+		}
134
+	}
135
+
136
+	return 0;
137
+}
138
+
139
+
140
+static int get_watch_uri(struct sip_msg* _m, str* _wuri, str *_dn)
141
+{
142
+	_wuri->s = get_from(_m)->uri.s;
143
+	_wuri->len = get_from(_m)->uri.len;
144
+	_dn->s = get_from(_m)->body.s;
145
+	_dn->len = get_from(_m)->body.len;
146
+
147
+	if (extract_plain_uri(_wuri) < 0) {
148
+		LOG(L_ERR, "get_watch_uri(): Error while extracting plain URI\n");
149
+		return -1;
150
+	}
151
+	
152
+	return 0;
153
+}
154
+
155
+static int get_dlg_id(struct sip_msg *_m, dlg_id_t *dst)
156
+{
157
+	if (!dst) return -1;
158
+	
159
+	memset(dst, 0, sizeof(*dst));
160
+	if (_m->to) dst->loc_tag = ((struct to_body*)_m->to->parsed)->tag_value;
161
+	if (_m->from) dst->rem_tag = ((struct to_body*)_m->from->parsed)->tag_value;
162
+	if (_m->callid) dst->call_id = _m->callid->body;
163
+	
164
+	return 0;
165
+}
166
+
167
+static time_t get_expires(struct sip_msg *_m)
168
+{
169
+	time_t e;
170
+	
171
+	if (_m->expires) e = ((exp_body_t*)_m->expires->parsed)->val;
172
+	else e = default_expires;
173
+	if (e > max_subscription_expiration) 
174
+		e = max_subscription_expiration;
175
+	return e;
176
+}
177
+
178
+/*
179
+ * Parse all header fields that will be needed
180
+ * to handle a SUBSCRIBE request
181
+ */
182
+static int parse_hfs(struct sip_msg* _m, int accept_header_required)
183
+{
184
+	int rc = 0;
185
+	struct hdr_field *acc;
186
+	
187
+	/* EOH instead HDR_FROM_F | HDR_EVENT_F | HDR_EXPIRES_F | HDR_ACCEPT_F  
188
+	 * because we need all Accept headers */
189
+	if ( (rc = parse_headers(_m, HDR_EOH_F, 0)) == -1) {
190
+		paerrno = PA_PARSE_ERR;
191
+		LOG(L_ERR, "parse_hfs(): Error while parsing headers: rc=%d\n", rc);
192
+		return -1;
193
+	}
194
+
195
+	if (!_m->from) {
196
+		ERR("From header missing\n");
197
+		return -1;
198
+	}
199
+	
200
+	if (parse_from_header(_m) < 0) {
201
+		paerrno = PA_FROM_ERR;
202
+		LOG(L_ERR, "parse_hfs(): From malformed or missing\n");
203
+		return -6;
204
+	}
205
+
206
+	if (_m->event) {
207
+		if (parse_event(_m->event) < 0) {
208
+			/* can not parse Event header */
209
+			paerrno = PA_EVENT_PARSE;
210
+			LOG(L_ERR, "parse_hfs(): Error while parsing Event header field\n");
211
+			return -8;
212
+		}
213
+	}
214
+	else { 
215
+		/* no Event header -> bad message */
216
+		paerrno = PA_EVENT_PARSE;
217
+		LOG(L_ERR, "parse_hfs(): Error while parsing Event header field\n");
218
+		return -8;
219
+	}
220
+
221
+	if (_m->expires) {
222
+		if (parse_expires(_m->expires) < 0) {
223
+			paerrno = PA_EXPIRES_PARSE;
224
+			LOG(L_ERR, "parse_hfs(): Error while parsing Expires header field\n");
225
+			return -9;
226
+		}
227
+	}
228
+
229
+	/* now look for Accept header */
230
+	acc = _m->accept;
231
+	if (accept_header_required && (!acc)) {
232
+		LOG(L_ERR, "no accept header\n");
233
+		return -11;
234
+	}
235
+	
236
+	while (acc) { /* parse all accept headers */
237
+		if (acc->type == HDR_ACCEPT_T) {
238
+			DBG("parsing accept header: %.*s\n", FMT_STR(acc->body));
239
+			if (parse_accept_body(acc) < 0) {
240
+				paerrno = PA_ACCEPT_PARSE;
241
+				LOG(L_ERR, "parse_hfs(): Error while parsing Accept header field\n");
242
+				return -10;
243
+			}
244
+		}
245
+		acc = acc->next;
246
+	}
247
+
248
+	return 0;
249
+}
250
+
251
+/* returns 0 if package supported by PA */
252
+static inline int verify_event_package(int et)
253
+{
254
+	switch (et) {
255
+		case EVENT_PRESENCE: return 0;
256
+		case EVENT_PRESENCE_WINFO: 
257
+			if (watcherinfo_notify) return 0;
258
+			else return -1;
259
+		default: return -1;
260
+	}
261
+}
262
+
263
+/* get_event MUST be parsed when calling get event -> done by parse_hfs! */
264
+#define get_event(_m) ((event_t*)(_m->event->parsed))->parsed
265
+
266
+/*
267
+ * Check if a message received has been constructed properly
268
+ */
269
+static int check_message(struct sip_msg* _m)
270
+{
271
+	int eventtype = 0;
272
+	int *accepts_mimes = NULL;
273
+	event_mimetypes_t *em;
274
+	struct hdr_field *acc;
275
+
276
+	if ((!_m->event) || (!_m->event->parsed)) {
277
+		paerrno = PA_EXPIRES_PARSE;
278
+		ERR("Event header field not found\n");
279
+		return -1; /* should be verified in parse_hfs before */
280
+	}
281
+
282
+	/* event package verification */
283
+	eventtype = get_event(_m);