Browse code

Merge branch 'master' into ims_ipsec_keys_expansion_fixes

riccardv authored on 24/05/2022 10:37:22 • GitHub committed on 24/05/2022 10:37:22
Showing 15 changed files
... ...
@@ -25,7 +25,7 @@ Gergely Kovacs
25 25
               5.6. callid_cache_limit (integer)
26 26
               5.7. certificate_cache_limit (integer)
27 27
               5.8. cainfo_path (string)
28
-              5.9. accept_pem_certs ([0|1])
28
+              5.9. accept_pem_certs (int)
29 29
 
30 30
         6. Functions
31 31
 
... ...
@@ -91,7 +91,7 @@ Chapter 1. Admin Guide
91 91
         5.6. callid_cache_limit (integer)
92 92
         5.7. certificate_cache_limit (integer)
93 93
         5.8. cainfo_path (string)
94
-        5.9. accept_pem_certs ([0|1])
94
+        5.9. accept_pem_certs (int)
95 95
 
96 96
    6. Functions
97 97
 
... ...
@@ -174,7 +174,7 @@ Chapter 1. Admin Guide
174 174
    5.6. callid_cache_limit (integer)
175 175
    5.7. certificate_cache_limit (integer)
176 176
    5.8. cainfo_path (string)
177
-   5.9. accept_pem_certs ([0|1])
177
+   5.9. accept_pem_certs (int)
178 178
 
179 179
 5.1. privatekey_path (string)
180 180
 
... ...
@@ -296,11 +296,12 @@ modparam("auth_identity","certificate_cache_limit",4096)
296 296
 modparam("auth_identity","cainfo_path","/etc/ssl/certs/ca-certificates.crt")
297 297
 ...
298 298
 
299
-5.9. accept_pem_certs ([0|1])
299
+5.9. accept_pem_certs (int)
300 300
 
301 301
    Note: this parameter is for verifier service.
302 302
 
303 303
    Enables the acquired certificate processing if it is in PEM format.
304
+   Value can be 0 or 1.
304 305
 
305 306
    This parameter is optional. The default value is "0".
306 307
 
307 308
deleted file mode 100644
... ...
@@ -1,629 +0,0 @@
1
-<?xml version='1.0'?>
2
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3
-  "http://www.oasis-open.org/docbookid/id/g/4.5/docbookx.dtd">
4
-
5
-
6
-<refentry xml:id="module.auth_identity"
7
-          xmlns:xi="http://www.w3.org/2001/XInclude"
8
-          xmlns:serdoc="http://sip-router.org/xml/serdoc">
9
-  <refmeta>
10
-    <refentrytitle>auth_identity</refentrytitle>
11
-    <manvolnum>7</manvolnum>
12
-  </refmeta>
13
-  <refnamediv>
14
-    <refname>auth_identity</refname>
15
-    <refpurpose>Securely identify originator of SIP messages.</refpurpose>
16
-  </refnamediv>
17
-
18
-  <refsect1>
19
-    <title>Description</title>
20
-    <para>
21
-      The <command>auth_identity</command> SER module provides
22
-      functionalities for securely identifying originators of SIP
23
-      messages by implementing the mechanism described in RFC 4474
24
-      and known as SIP Identity framework.
25
-    </para>
26
-    <para>
27
-      The module provides two services:
28
-      The <emphasis>authorizer</emphasis> authorizes a message and adds
29
-      Identity and Identity-Info headers to forwarded requests.
30
-      The <emphasis>verifier</emphasis> verifies the identity of a
31
-      received message.
32
-    </para>
33
-    <para>
34
-      In order to use the <command>auth_identity</command> module you
35
-      have to provide a certificate. More information can be found in
36
-      the section
37
-      <serdoc:link linkend="module.auth_identity.certificates">Certificates
38
-      </serdoc:link> below.
39
-    </para>
40
-  </refsect1>
41
-
42
-  <refsect1 xml:id="module.auth_identity.functions">
43
-    <title>Functions</title>
44
-
45
-    <refsect2 xml:id="function.auth_add_identity">
46
-      <title>
47
-        <function>auth_add_identity</function>
48
-        ()
49
-      </title>
50
-      <para>
51
-        Allowed in request processing only.
52
-      </para>
53
-      <para>
54
-        The <function>auth_add_identity()</function> function authorizes
55
-        a request by adding identity information to it.
56
-      </para>
57
-      <para>
58
-        It calculates a SHA1 hash over certain components of the message
59
-        and encrypts it using the private key given through the
60
-        <serdoc:modparam
61
-          module="auth_identity">privatekey_path</serdoc:modparam>
62
-        parameter. The resulting cyphertext is appended to the message
63
-        as the content of the Identity header field.
64
-      </para>
65
-      <para>
66
-        To allow the receiver to decypher the identity information, it adds
67
-        the URL where the receiver may find the certificate in the
68
-        Indentity-Info header field. This URL is set through the
69
-        <serdoc:modparam
70
-          module="auth_identity">certificate_url</serdoc:modparam>
71
-        parameter.
72
-      </para>
73
-      <para>
74
-        <emphasis>Note:</emphasis> After the function has been called,
75
-        the following header fields must not be modified:
76
-        From, To, Call-ID, CSeq, Date, Contact. Additionally, the
77
-        message body must remain unmodified, too.
78
-      </para>
79
-    </refsect2>
80
-
81
-    <refsect2 xml:id="function.auth_date_proc">
82
-      <title>
83
-        <function>auth_date_proc</function>
84
-        ()
85
-      </title>
86
-      <para>
87
-        Allowed in request processing only.
88
-      </para>
89
-      <para>
90
-        The <function>auth_date_proc()</function> checks the age of a
91
-        request to be authroized. If the time given in the Date header
92
-        field of the request differs by more than the amount of seconds
93
-        given by the
94
-        <serdoc:modparam module="auth_identity">msg_timeout</serdoc:modparam>
95
-        parameter, the function returns <literal>false</literal>. It also
96
-        returns <literal>false</literal> if the certificate used by the
97
-        authorizer has expired.
98
-      </para>
99
-    </refsect2>
100
-
101
-    <refsect2 xml:id="function.vrfy_check_callid">
102
-      <title>
103
-        <function>vrfy_check_callid</function>
104
-        ()
105
-      </title>
106
-      <para>
107
-        Allowed in request processing only.
108
-      </para>
109
-      <para>
110
-        The <function>vrfy_check_callid()</function> checks whether a
111
-        request for this call has been processed within the
112
-        time given by the
113
-        <serdoc:modparam
114
-          module="auth_identity">auth_validity_time</serdoc:modparam>
115
-        parameter.
116
-      </para>
117
-      <para>
118
-        The function generates a call identifier from the Call-ID and CSqe
119
-        header fields and the Tag parameter of the From header field and
120
-        compares it with the values stored in the Call-ID cache.
121
-      </para>
122
-      <para>
123
-        It returns <literal>false</literal> if the value is found and thus
124
-        the request is replayed or <literal>true</literal> otherwise.
125
-      </para>
126
-    </refsect2>
127
-
128
-    <refsect2 xml:id="function.vrfy_check_certificate">
129
-      <title>
130
-        <function>vrfy_check_certificate</function>
131
-        ()
132
-      </title>
133
-      <para>
134
-        Allowed in request processing only.
135
-      </para>
136
-      <para>
137
-        The <function>vrfy_check_certificate()</function> function
138
-        checks the downloaded certificate and returns <literal>true</literal>
139
-        if it is valid or <literal>false</literal> otherwise.
140
-      </para>
141
-      <para>
142
-        A certificate is considered valid if it has not yet expired and
143
-        if its subject is identical to the domain part of the URL.
144
-      </para>
145
-      <!-- XXX Er, which URL? -->
146
-      <para>
147
-        Before <function>vrfy_check_certificate()</function> can be called,
148
-        the function <function>vrfy_check_date()</function> must have been
149
-        called and returned <literal>true</literal>.
150
-      </para>
151
-    </refsect2>
152
-
153
-    <refsect2 xml:id="function.vrfy_check_date">
154
-      <title>
155
-        <function>vrfy_check_date</function>
156
-        ()
157
-      </title>
158
-      <para>
159
-        Allowed in request processing only.
160
-      </para>
161
-      <para>
162
-        The <function>vrfy_check_date()</function> function checks
163
-        the date of the request currently being processed. It returns
164
-        <literal>false</literal> if the time in the Date header field
165
-        of the request differs from the current system time by more than
166
-        the number of seconds given by the
167
-        <serdoc:modparam
168
-          module="auth_identity">auth_validity_time</serdoc:modparam>
169
-        parameter.
170
-      </para>
171
-    </refsect2>
172
-
173
-    <refsect2 xml:id="function.vrfy_check_msgvalidity">
174
-      <title>
175
-        <function>vrfy_check_msgvalidity</function>
176
-        ()
177
-      </title>
178
-      <para>
179
-        Allowed in request processing only.
180
-      </para>
181
-      <para>
182
-        The <function>vrfy_check_msgvalidity()</function> function
183
-        checks the integrity of the request currently being processed.
184
-      </para>
185
-      <para>
186
-        It does so by calculating a SHA1 hash over certain parts of the
187
-        message and comparing it with the hash value that results from
188
-        decrypting the content of the Identity header field using the
189
-        certificate previously retrieved using the
190
-        <function>vrfy_get_certificate()</function> function.
191
-      </para>
192
-      <para>
193
-        The function returns <literal>true</literal> if the two hashes
194
-        match.
195
-      </para>
196
-    </refsect2>
197
-
198
-    <refsect2 xml:id="function.vrfy_get_certificate">
199
-      <title>
200
-        <function>vrfy_get_certificate</function>
201
-        ()
202
-      </title>
203
-      <para>
204
-        Allowed in request processing only.
205
-      </para>
206
-      <para>
207
-        The <function>vrfy_get_certificate()</function> tries to get
208
-        the certificate from the URL given in the Identity-Info header
209
-        field of the currently processed request.
210
-      </para>
211
-      <para>
212
-        It returns <literal>true</literal> if the certifcate was
213
-        successfully loaded in a format that the module can process or
214
-        <literal>false</literal> otherwise.
215
-      </para>
216
-    </refsect2>
217
-
218
-  </refsect1>
219
-
220
-
221
-  <refsect1 xml:id="module.auth_identity.parameters">
222
-    <title>Module Parameters</title>
223
-
224
-    <refsect2 xml:id="module.auth_identity.accept_pem_certs">
225
-      <title><parameter>accept_pem_certs</parameter></title>
226
-      <serdoc:paraminfo>
227
-        <serdoc:paramtype>boolean</serdoc:paramtype>
228
-        <serdoc:paramdefault>no</serdoc:paramdefault>
229
-      </serdoc:paraminfo>
230
-      <para>
231
-        The <parameter>accept_pem_certs</parameter> parameter defines,
232
-        whether the verifier should process certificates in PEM format.
233
-      </para>
234
-    </refsect2>
235
-
236
-    <refsect2 xml:id="module.auth_identity.auth_validity_time">
237
-      <title><parameter>auth_validity_time</parameter></title>
238
-      <serdoc:paraminfo>
239
-        <serdoc:paramtype>integer</serdoc:paramtype>
240
-        <serdoc:paramdefault>3600</serdoc:paramdefault>
241
-      </serdoc:paraminfo>
242
-      <para>
243
-        The <parameter>auth_validity_time</parameter> parameter
244
-        sets the maximum age of a verified message.
245
-      </para>
246
-    </refsect2>
247
-
248
-    <refsect2 xml:id="module.auth_identity.cainfo_path">
249
-      <title><parameter>cainfo_path</parameter></title>
250
-      <serdoc:paraminfo>
251
-        <serdoc:paramtype>string</serdoc:paramtype>
252
-        <serdoc:paramdefault>""</serdoc:paramdefault>
253
-      </serdoc:paraminfo>
254
-      <para>
255
-        The <parameter>cainfo_path</parameter> paramter contains the
256
-        path and name of a file that contains trusted certificates.
257
-      </para>
258
-      <para>
259
-        The file should contain one or more certificates in PEM format
260
-        concatenated together. It is necessary if the verifier should
261
-        accept self-signed certifcates.
262
-      </para>
263
-    </refsect2>
264
-
265
-    <refsect2 xml:id="module.auth_identity.callid_cache_limit">
266
-      <title><parameter>callid_cache_limit</parameter></title>
267
-      <serdoc:paraminfo>
268
-        <serdoc:paramtype>integer</serdoc:paramtype>
269
-        <serdoc:paramdefault>262144</serdoc:paramdefault>
270
-      </serdoc:paraminfo>
271
-      <para>
272
-        The <parameter>callid_cache_limit</parameter> parameter
273
-        limits the number of entries in the Call-ID cache.
274
-      </para>
275
-      <para>
276
-        The Call-IDs of previously verified messages are stored in the
277
-        Call-ID cache for some time in order to recognize call
278
-        replay attacks. The cache uses shared memory. Each entry is
279
-        about 100 bytes in size.
280
-      </para>
281
-    </refsect2>
282
-
283
-    <refsect2 xml:id="module.auth_identity.certificate_cache_limit">
284
-      <title><parameter>certificate_cache_limit</parameter></title>
285
-      <serdoc:paraminfo>
286
-        <serdoc:paramtype>integer</serdoc:paramtype>
287
-        <serdoc:paramdefault>32768</serdoc:paramdefault>
288
-      </serdoc:paraminfo>
289
-      <para>
290
-        The <parameter>certificate_cache_limit</parameter> parameter
291
-        limits the number of entries stored in the certificate cache.
292
-      </para>
293
-      <para>
294
-        Each retrieved certificate is placed in the certificate cache
295
-        to speed up processing should it be needed again.
296
-      </para>
297
-      <para>
298
-        The cahce uses shared memory. Each entry is approximately 600
299
-        bytes in size.
300
-      </para>
301
-    </refsect2>
302
-
303
-    <refsect2 xml:id="module.auth_identity.certificate_path">
304
-      <title><parameter>certificate_path</parameter></title>
305
-      <serdoc:paraminfo>
306
-        <serdoc:paramtype>string</serdoc:paramtype>
307
-        <serdoc:paramdefault>""</serdoc:paramdefault>
308
-      </serdoc:paraminfo>
309
-      <para>
310
-        The <parameter>certificate_path</parameter> parameter must be
311
-        set to path and name of the file that contains the certificate
312
-        of the authentication service in PEM format.
313
-      </para>
314
-      <para>
315
-        The parameter is required for the authentication service to work.
316
-      </para>
317
-    </refsect2>
318
-
319
-    <refsect2 xml:id="module.auth_identity.certificate_url">
320
-      <title><parameter>certificate_url</parameter></title>
321
-      <serdoc:paraminfo>
322
-        <serdoc:paramtype>string</serdoc:paramtype>
323
-        <serdoc:paramdefault>""</serdoc:paramdefault>
324
-      </serdoc:paraminfo>
325
-      <para>
326
-        The <parameter>certificate_url</parameter> parameter must be
327
-        set to the URL where a verifier can retrieve the certificate.
328
-        The URL will be stored in the Identity-Info header of any
329
-        authorized request.
330
-      </para>
331
-      <para>
332
-        The certificate must be available at the given URL in DER
333
-        format.
334
-      </para>
335
-      <para>
336
-        The parameter is required for the authentication service to work.
337
-      </para>
338
-    </refsect2>
339
-
340
-    <refsect2 xml:id="module.auth_identity.msg_timeout">
341
-      <title><parameter>msg_timeout</parameter></title>
342
-      <serdoc:paraminfo>
343
-        <serdoc:paramtype>int</serdoc:paramtype>
344
-        <serdoc:paramdefault>600</serdoc:paramdefault>
345
-      </serdoc:paraminfo>
346
-      <para>
347
-        The <parameter>msg_timeout</parameter> parameter contains the
348
-        maximum age of a request to be authorized in seconds.
349
-      </para>
350
-      <para>
351
-        The authorizer will compare the time given in the Date header field
352
-        of the request with its own current time.
353
-      </para>
354
-    </refsect2>
355
-
356
-    <refsect2 xml:id="module.auth_identity.privatekey_path">
357
-      <title><parameter>privatekey_path</parameter></title>
358
-      <serdoc:paraminfo>
359
-        <serdoc:paramtype>string</serdoc:paramtype>
360
-        <serdoc:paramdefault>""</serdoc:paramdefault>
361
-      </serdoc:paraminfo>
362
-      <para>
363
-        The <parameter>privatekey_path</parameter> must be set to the paht
364
-        and name of the file that contains the private key of the
365
-        authentication service in PEM format.
366
-      </para>
367
-      <para>
368
-        The parameter is required for the authentication service to work.
369
-      </para>
370
-    </refsect2>
371
-
372
-  </refsect1>
373
-
374
-  <refsect1 id="modules.auth_identity.examples">
375
-    <title>Examples</title>
376
-    <para>
377
-      The <emphasis>authentifier</emphasis> is typically included in the
378
-      part of the routing
379
-      logic that sends a request to a foreign domain. In the
380
-      <filename>ser-oob.cfg</filename> configuration, this is the
381
-      <varname>route[OUTBOUND]</varname>. With an authentifier included,
382
-      it looks like this:
383
-    </para>
384
-    <programlisting><![CDATA[
385
-route[OUTBOUND]
386
-{
387
-	if ($f.did && !$t.did) {
388
-		# Authentication service
389
-		if (method=="INVITE" || method=="OPTION") {
390
-			# Identity and Identity-info headers must not exist
391
-			if (@identity) {
392
-				sl_reply("403", "Invalid Identity header");
393
-				drop;
394
-			}
395
-			if (@identity_info) {
396
-				sl_reply("403", "Invalid Identity-info header");
397
-				drop;
398
-			}
399
-
400
-			if (!auth_date_proc()) {
401
-				sl_reply("403", "Invalid Date value");
402
-				drop;
403
-			}
404
-
405
-			if (!auth_add_identity()) {
406
-				sl_reply("480", "Authentication error");
407
-				drop;
408
-			}
409
-		}
410
-		route(FORWARD);
411
-	}
412
-}
413
-]]></programlisting>
414
-    <para>
415
-      The <emphasis>verifier</emphasis> should be run after you discovered
416
-      that a request originates from a foreign domain (for your own domains,
417
-      you should be doing digest authentication instead).
418
-    </para>
419
-    <para>
420
-      While you should reject any request that does contain an Identity
421
-      header but does not verify, it is up to your local policy, what to
422
-      do with messages that do not contain an Identity header at all.
423
-      You could reject them or divert them to voice mail or any of a number
424
-      of other options.
425
-    </para>
426
-    <para>
427
-      The following config snippet rejects any message that does not have
428
-      an Identity header.
429
-    </para>
430
-    <programlisting><![CDATA[
431
-	if (method=="INVITE" || method=="OPTIONS") {
432
-		if (!@identity) {
433
-			sl_reply("428", "Use Identity Header");
434
-			drop;
435
-		}
436
-		if (!@identity_info) {
437
-			sl_reply("436", "Bad Identity-Info");
438
-			drop;
439
-		}
440
-
441
-		if (!vrfy_check_date()) {
442
-			sl_reply("403", "Outdated Date header value");
443
-			drop;
444
-		}
445
-
446
-		if (!vrfy_get_certificate()) {
447
-			sl_reply("436", "Bad Identity-Info");
448
-			drop;
449
-		}
450
-
451
-		if (!vrfy_check_certificate()) {
452
-			sl_reply("437", "Unsupported Certificate");
453
-			drop;
454
-		}
455
-
456
-		if (!vrfy_check_msgvalidity()) {
457
-			sl_reply("438", "Invalid Identity Header");
458
-			drop;
459
-		}
460
-
461
-		if (!vrfy_check_callid()) {
462
-			sl_reply("403", "Message is replayed");
463
-			drop;
464
-		}
465
-	}
466
-]]></programlisting>
467
-  </refsect1>
468
-
469
-  <refsect1 id="mdoule.auth_identity.how-it-works">
470
-    <title>The SIP Identity Mechanism</title>
471
-    <para>
472
-      The SIP Identity Mechanism is defined in RFC 4474 "Enhancements for
473
-      Authenticated Identity Management in the Session Initiation Protocol
474
-      (SIP)". Its main purpose is to affirm the identity of the originator
475
-      of a request as stated in the From header field of the request.
476
-      While basic SIP provides a mechanism for a user agent to proof its
477
-      authenticity to the proxy serving the domain of the address used
478
-      by the user agent, no such mechanism exists to proof the authenticity
479
-      to other proxies or end points. The SIP Identity Mechanism mends this
480
-      oversight.
481
-    </para>
482
-    <para>
483
-      The mechanism allows a proxy to cryptographically sign a message as
484
-      authentic before sending it to another proxy. It does so after
485
-      making sure the sender actually is who he claims and is allowed to
486
-      use the address in the context of the message.
487
-    </para>
488
-    <para>
489
-      If the proxy is satisfied, it creates two header fields: Identity and
490
-      Identity-Info. The Identity header field contains a signed hash over
491
-      the following components of the message:
492
-    </para>
493
-    <itemizedlist>
494
-      <listitem>
495
-        the address given in the From header field,
496
-      </listitem>
497
-      <listitem>
498
-        the address given in the To header field,
499
-      </listitem>
500
-      <listitem>
501
-        the Call-ID,
502
-      </listitem>
503
-      <listitem>
504
-        the content of the CSeq header field,
505
-      </listitem>
506
-      <listitem>
507
-        the content of the Date header field,
508
-      </listitem>
509
-      <listitem>
510
-        the address given in the Contact header field if present, and
511
-      </listitem>
512
-      <listitem>
513
-        the body of the message.
514
-      </listitem>
515
-    </itemizedlist>
516
-    <para>
517
-      The hash is signed with a certificate for the domain. A URL pointing
518
-      to a place where an interested party can download a copy of the
519
-      certificate is placed into the Identity-Info header field.
520
-    </para>
521
-    <para>
522
-      If the message arrives at a proxy or user agent that wishes to verify
523
-      the authenticity, this device downloads the certificate and itself
524
-      forms the hash over the above components. If both hashes match, the
525
-      message has been authenticated by the proxy of the domain of the
526
-      certificate and has not been tempered with on the way.
527
-    </para>
528
-  </refsect1>
529
-
530
-  <refsect1 id="modules.auth_identity.credentials">
531
-    <title>Certificates</title>
532
-    <para>
533
-      In order to use the <command>auth_identity</command> module, you need a
534
-      certificate for your domain. There is two options, how to get one: you
535
-      buy one from a certification authority or you create your own
536
-      certification authority and use a self-signed certificate.  If you plan
537
-      to provide real  inter-domain calls for your domain, you should pick the
538
-      first option. Although it is more expensive, it guarantees proper
539
-      interaction between domains.
540
-    </para>
541
-    <para>
542
-      Either way, you will end up with a private key and a certificate which
543
-      includes the public key for that private key. You can use the same key
544
-      and certificate as for the TLS encrypted SIP transport. Because of
545
-      this, details on the process of acquiring them can be found in 
546
-      <serdoc:module>tls</serdoc:module>.
547
-    </para>
548
-    <para>
549
-      Once you have the certificate and private key, you set the module
550
-      parameter
551
-      <serdoc:modparam module="auth_identity">certificate_path</serdoc:modparam>
552
-      to point to the file containing the certificate and
553
-      <serdoc:modparam module="auth_identity">privatekey_path</serdoc:modparam>
554
-      to point to the file with the private key.
555
-    </para>
556
-    <para>
557
-      Finally, you have to put a public version of your certificate onto
558
-      a web server somewhere. This version must be DER encoded and,
559
-      obviously, must not contain the private key. You can create this
560
-      by issuing
561
-    </para>
562
-    <programlisting><![CDATA[
563
-# openssl x509 -in your_certificate.crt -outform der -out your_certificate.der
564
-]]></programlisting>
565
-    <para>
566
-      You then place the DER encoded certificate into a publicly
567
-      available directory on your webserver and state the URL to the
568
-      file in the parameter
569
-      <serdoc:modparam module="auth_identity">certificate_url</serdoc:modparam>.
570
-    </para>
571
-  </refsect1>
572
-
573
-  <!--
574
-    Compilation sections only go into the Admin Guide since we assume
575
-    that if you read a manpage you already have installed the module.
576
-  --> 
577
-  <refsect1 role="admin-guide">
578
-    <title>Compilation</title>
579
-    <para>
580
-      This <command>auth_identity</command> module needs the following
581
-      headers and libraries:
582
-    </para>
583
-    <itemizedlist>
584
-      <listitem>
585
-        <emphasis>OpenSSL</emphasis> (version 0.9.8 or higher) for
586
-        cryptographic functions,
587
-      </listitem>
588
-      <listitem>
589
-        <emphasis>libcURL</emphasis> for HTTP, HTTPS functions.
590
-      </listitem>
591
-    </itemizedlist>
592
-    <para>
593
-      If you'd like to use the <emphasis>TLS</emphasis> module, too,
594
-      you will have to change <varname>LIB</varname> variable in the
595
-      Makefile to the value that is by default commented out.
596
-    </para>
597
-  </refsect1>
598
-
599
-  <refsect1>
600
-    <title>Known Limitations</title>
601
-    <para>
602
-      Both authorizer and verifier currently only support SIP requests
603
-      except for responses to CANCEL and REGISTER requests.
604
-    </para>
605
-    <para>
606
-      The verifier does not support the subjectAltName extension of
607
-      certificates.
608
-    </para>
609
-  </refsect1>
610
-
611
-  <refsect1 role="manpage">
612
-    <title>Authors</title>
613
-    <para>
614
-      Written by Gergely Kovacs and Martin Hoffmann.
615
-    </para>
616
-  </refsect1>
617
-
618
-  <refsect1 role="manpage">
619
-    <title>See Also</title>
620
-    <simplelist type="inline">
621
-      <member><serdoc:sbin>ser</serdoc:sbin></member>
622
-      <member><serdoc:file>ser.cfg</serdoc:file></member>
623
-    </simplelist>
624
-  </refsect1>
625
-
626
-</refentry>
627
-
628
-<!-- vim:sw=2 sta et sts=2 ai
629
-  -->
... ...
@@ -190,11 +190,11 @@ modparam("auth_identity","cainfo_path","/etc/ssl/certs/ca-certificates.crt")
190 190
 		</section>
191 191
 
192 192
 		<section id="accept_pem_certs">
193
-			<title><varname>accept_pem_certs</varname> ([0|1])</title>
193
+			<title><varname>accept_pem_certs</varname> (int)</title>
194 194
 			<para>Note: this parameter is for verifier service.</para>
195 195
 			<para>
196 196
 				Enables the acquired certificate processing if it is in PEM
197
-				format.
197
+				format. Value can be 0 or 1.
198 198
 			</para>
199 199
 			<para>
200 200
 				This parameter is optional. The default value is "0".
... ...
@@ -51,6 +51,8 @@ Tsvetomir Dimitrov
51 51
               3.6. ipsec_reuse_server_port (int)
52 52
               3.7. ipsec_spi_id_start (int)
53 53
               3.8. ipsec_spi_id_range (int)
54
+              3.9. ipsec_preferred_alg (string)
55
+              3.10. ipsec_preferred_ealg (string)
54 56
 
55 57
         4. Functions
56 58
 
... ...
@@ -68,9 +70,11 @@ Tsvetomir Dimitrov
68 70
    1.6. ipsec_reuse_server_port parameter usage
69 71
    1.7. ipsec_spi_id_start parameter usage
70 72
    1.8. ipsec_spi_id_range parameter usage
71
-   1.9. ipsec_create
72
-   1.10. ipsec_forward
73
-   1.11. ipsec_destroy
73
+   1.9. ipsec_preferred_alg parameter usage
74
+   1.10. ipsec_preferred_ealg parameter usage
75
+   1.11. ipsec_create
76
+   1.12. ipsec_forward
77
+   1.13. ipsec_destroy
74 78
 
75 79
 Chapter 1. Admin Guide
76 80
 
... ...
@@ -92,6 +96,8 @@ Chapter 1. Admin Guide
92 96
         3.6. ipsec_reuse_server_port (int)
93 97
         3.7. ipsec_spi_id_start (int)
94 98
         3.8. ipsec_spi_id_range (int)
99
+        3.9. ipsec_preferred_alg (string)
100
+        3.10. ipsec_preferred_ealg (string)
95 101
 
96 102
    4. Functions
97 103
 
... ...
@@ -130,6 +136,8 @@ Chapter 1. Admin Guide
130 136
    3.6. ipsec_reuse_server_port (int)
131 137
    3.7. ipsec_spi_id_start (int)
132 138
    3.8. ipsec_spi_id_range (int)
139
+   3.9. ipsec_preferred_alg (string)
140
+   3.10. ipsec_preferred_ealg (string)
133 141
 
134 142
 3.1. ipsec_listen_addr (string)
135 143
 
... ...
@@ -159,8 +167,7 @@ modparam("ims_ipsec_pcscf", "ipsec_listen_addr6", "")
159 167
 
160 168
 3.3. ipsec_client_port (int)
161 169
 
162
-   Start port number which will be bound for incoming (server) IPSec
163
-   traffic.
170
+   Port number which will be bound for incoming (server) IPSec traffic.
164 171
 
165 172
    Default value is 5062.
166 173
 
... ...
@@ -171,8 +178,7 @@ modparam("ims_ipsec_pcscf", "ipsec_client_port", 5062)
171 178
 
172 179
 3.4. ipsec_server_port (int)
173 180
 
174
-   Start port number which will be bound for incoming (server) IPSec
175
-   traffic.
181
+   Port number which will be bound for incoming (server) IPSec traffic.
176 182
 
177 183
    Default value is 5063.
178 184
 
... ...
@@ -183,11 +189,7 @@ modparam("ims_ipsec_pcscf", "ipsec_server_port", 5063)
183 189
 
184 190
 3.5. ipsec_max_connections (int)
185 191
 
186
-   Maximum IPSec connections for the process. E.g. if
187
-   ipsec_client_port=5100, ipsec_server_port=6100 and
188
-   ipsec_max_connections=10, all client ports between 5100 and 5109 and
189
-   all server ports between 6100 and 6109 will be used for maximum to 10
190
-   IPSec connections.
192
+   Maximum simultanious IPSec connections
191 193
 
192 194
    Default value is 2.
193 195
 
... ...
@@ -198,11 +200,10 @@ modparam("ims_ipsec_pcscf", "ipsec_max_connections", 10)
198 200
 
199 201
 3.6. ipsec_reuse_server_port (int)
200 202
 
201
-   Reuse (1) or not (0) the P-CSCF Server port for Re-registration for one
202
-   UA. When set to 0 - During Re-registration P-CSCF will distribute new
203
-   P-CSCF client and P-CSCF server ports. When set to 1 - During
204
-   Re-registration P-CSCF will reuse the old P-CSCF server port and will
205
-   distribute a new P-CSCF client port.
203
+   Reuse (1) or not (0) the P-CSCF IPSec information for Re-registration
204
+   for one UA. When set to 0 - During Re-registration P-CSCF will create
205
+   new IPSec tunnels. When set to 1 - During Re-registration P-CSCF will
206
+   reuse the old IPSec tunnels.
206 207
 
207 208
    Default value is 1.
208 209
 
... ...
@@ -238,6 +239,33 @@ modparam("ims_ipsec_pcscf", "ipsec_spi_id_start", 100)
238 239
 modparam("ims_ipsec_pcscf", "ipsec_spi_id_range", 1000)
239 240
 ...
240 241
 
242
+3.9. ipsec_preferred_alg (string)
243
+
244
+   A name of an authentication algorithm which the Proxy-CSCF will prefer
245
+   when creating IPSec tunnels.
246
+
247
+   Default value is empty string (null) - the last algorithm in the
248
+   Sec-Agree header will be used.
249
+
250
+   Example 1.9. ipsec_preferred_alg parameter usage
251
+...
252
+modparam("ims_ipsec_pcscf", "ipsec_preferred_alg", "hmac-sha-1-96")
253
+...
254
+
255
+3.10. ipsec_preferred_ealg (string)
256
+
257
+   A name of an encrytion algorithm which the Proxy-CSCF will prefer when
258
+   creating IPSec tunnels.
259
+
260
+   Default value is empty string (null) - the last algorithm in the
261
+   Sec-Agree header will be used. Note that the possibility of it being
262
+   the "null" algorithm is not insignificant.
263
+
264
+   Example 1.10. ipsec_preferred_ealg parameter usage
265
+...
266
+modparam("ims_ipsec_pcscf", "ipsec_preferred_ealg", "aes-cbc")
267
+...
268
+
241 269
 4. Functions
242 270
 
243 271
    4.1. ipsec_create(domain)
... ...
@@ -258,7 +286,7 @@ modparam("ims_ipsec_pcscf", "ipsec_spi_id_range", 1000)
258 286
        every registration. This is an optional parameter, default value -
259 287
        0.
260 288
 
261
-   Example 1.9. ipsec_create
289
+   Example 1.11. ipsec_create
262 290
 ...
263 291
 ipsec_create("location");
264 292
 # or
... ...
@@ -278,7 +306,7 @@ ipsec_create("location", "1");
278 306
        the memory. Useful when contact alias is disabled. This is an
279 307
        optional parameter, default value - 0.
280 308
 
281
-   Example 1.10. ipsec_forward
309
+   Example 1.12. ipsec_forward
282 310
 ...
283 311
 ipsec_forward("location");
284 312
 # or
... ...
@@ -293,7 +321,7 @@ ipsec_forward("location", "1");
293 321
      * domain - Logical domain within the registrar. If a database is used
294 322
        then this must be name of the table which stores the contacts.
295 323
 
296
-   Example 1.11. ipsec_destroy
324
+   Example 1.13. ipsec_destroy
297 325
 ...
298 326
 ipsec_destroy("location");
299 327
 ...
... ...
@@ -50,7 +50,6 @@
50 50
 
51 51
 #include "ipsec.h"
52 52
 #include "spi_gen.h"
53
-#include "port_gen.h"
54 53
 #include "cmd.h"
55 54
 #include "sec_agree.h"
56 55
 
... ...
@@ -351,57 +350,26 @@ static int update_contact_ipsec_params(ipsec_t* s, const struct sip_msg* m, ipse
351 350
     s->ik.len = ik.len;
352 351
 
353 352
     // Generate SPI
354
-    if((s->spi_pc = acquire_spi()) == 0) {
355
-        LM_ERR("Error generating client SPI for IPSEC tunnel creation\n");
356
-        shm_free(s->ck.s);
357
-        s->ck.s = NULL; s->ck.len = 0;
358
-        shm_free(s->ik.s);
359
-        s->ik.s = NULL; s->ik.len = 0;
360
-        return -1;
353
+    if(s_old) {
354
+        if(s_old->spi_pc && s_old->spi_ps && s_old->port_pc && s_old->port_ps) {
355
+            LM_INFO("Reusing IPSEC tunnel\n");
356
+            s->spi_pc = s_old->spi_pc;
357
+            s->spi_ps = s_old->spi_ps;
358
+            s->port_pc = s_old->port_pc;
359
+            s->port_ps = s_old->port_ps;
360
+            return 0;
361
+        }
361 362
     }
362 363
 
363
-    if((s->spi_ps = acquire_spi()) == 0) {
364
-        LM_ERR("Error generating server SPI for IPSEC tunnel creation\n");
364
+    if(acquire_spi(&s->spi_pc, &s->spi_ps, &s->port_pc, &s->port_ps) == 0) {
365
+        LM_ERR("Error generating client SPI for IPSEC tunnel creation\n");
365 366
         shm_free(s->ck.s);
366 367
         s->ck.s = NULL; s->ck.len = 0;
367 368
         shm_free(s->ik.s);
368 369
         s->ik.s = NULL; s->ik.len = 0;
369
-
370
-		release_spi(s->spi_pc);
371 370
         return -1;
372 371
     }
373 372
 
374
-    if((s->port_pc = acquire_cport()) == 0){
375
-        LM_ERR("No free client port for IPSEC tunnel creation\n");
376
-		shm_free(s->ck.s);
377
-		s->ck.s = NULL; s->ck.len = 0;
378
-		shm_free(s->ik.s);
379
-		s->ik.s = NULL; s->ik.len = 0;
380
-
381
-		release_spi(s->spi_pc);
382
-		release_spi(s->spi_ps);
383
-        return -1;
384
-    }
385
-
386
-	// use the same P-CSCF server port if it is present
387
-	if(s_old){
388
-		s->port_ps = s_old->port_ps;
389
-	}else{
390
-		if((s->port_ps = acquire_sport()) == 0){
391
-			LM_ERR("No free server port for IPSEC tunnel creation\n");
392
-			shm_free(s->ck.s);
393
-			s->ck.s = NULL; s->ck.len = 0;
394
-			shm_free(s->ik.s);
395
-			s->ik.s = NULL; s->ik.len = 0;
396
-
397
-			release_cport(s->port_pc);
398
-
399
-			release_spi(s->spi_pc);
400
-			release_spi(s->spi_ps);
401
-			return -1;
402
-		}
403
-	}
404
-
405 373
 	return 0;
406 374
 }
407 375
 
... ...
@@ -508,12 +476,7 @@ static int destroy_ipsec_tunnel(str remote_addr, ipsec_t* s, unsigned short rece
508 476
     remove_policy(sock, remote_addr, ipsec_addr, s->port_us, s->port_pc, s->spi_pc, ip_addr.af, IPSEC_POLICY_DIRECTION_IN);
509 477
 
510 478
     // Release SPIs
511
-    release_spi(s->spi_pc);
512
-    release_spi(s->spi_ps);
513
-
514
-    // Release the client and the server ports
515
-    release_cport(s->port_pc);
516
-    release_sport(s->port_ps);
479
+    release_spi(s->spi_pc, s->spi_ps, s->port_pc, s->port_ps);
517 480
 
518 481
     close_mnl_socket(sock);
519 482
     return 0;
... ...
@@ -692,74 +655,69 @@ int ipsec_create(struct sip_msg* m, udomain_t* d, int _cflags)
692 655
 
693 656
     struct sip_msg* req = t->uas.request;
694 657
 
658
+    // Parse security parameters from the REGISTER request and get some data for the new tunnels
659
+    security_t* req_sec_params = cscf_get_security(req);
660
+    ipsec_t* s;
661
+    ipsec_t* old_s = NULL;
662
+
695 663
     // Update contacts only for initial registration, for re-registration the existing contacts shouldn't be updated.
696 664
     if(ci.via_port == SIP_PORT){
697 665
         LM_DBG("Registration for contact with AOR [%.*s], VIA [%d://%.*s:%d], received_host [%d://%.*s:%d]\n",
698 666
                 ci.aor.len, ci.aor.s, ci.via_prot, ci.via_host.len, ci.via_host.s, ci.via_port,
699 667
                 ci.received_proto, ci.received_host.len, ci.received_host.s, ci.received_port);
700 668
 
701
-        ipsec_t* s = pcontact->security_temp->data.ipsec;
669
+        if(req_sec_params == NULL)
670
+            s = pcontact->security_temp->data.ipsec;
671
+        else
672
+            s = req_sec_params->data.ipsec;
673
+    }else{
674
+        LM_DBG("RE-Registration for contact with AOR [%.*s], VIA [%d://%.*s:%d], received_host [%d://%.*s:%d]\n",
675
+                ci.aor.len, ci.aor.s, ci.via_prot, ci.via_host.len, ci.via_host.s, ci.via_port,
676
+                ci.received_proto, ci.received_host.len, ci.received_host.s, ci.received_port);
702 677
 
703
-		// for initial Registration use a new P-CSCF server port
704
-        if(update_contact_ipsec_params(s, m, NULL) != 0) {
678
+        if(req_sec_params == NULL) {
679
+            LM_CRIT("No security parameters in REGISTER request\n");
705 680
             goto cleanup;
706 681
         }
707 682
 
708
-        if(create_ipsec_tunnel(&req->rcv.src_ip, s) != 0){
709
-            goto cleanup;
710
-        }
683
+        s = req_sec_params->data.ipsec;
684
+        old_s = (ipsec_reuse_server_port && pcontact->security_temp) ? pcontact->security_temp->data.ipsec : NULL;
685
+    }
711 686
 
712
-        if (ul.update_pcontact(d, &ci, pcontact) != 0){
713
-            LM_ERR("Error updating contact\n");
714
-            goto cleanup;
715
-        }
687
+    if(update_contact_ipsec_params(s, m, old_s) != 0) {
688
+        goto cleanup;
689
+    }
716 690
 
691
+    if(create_ipsec_tunnel(&req->rcv.src_ip, s) != 0){
692
+        goto cleanup;
693
+    }
694
+
695
+    if (ul.update_pcontact(d, &ci, pcontact) != 0){
696
+        LM_ERR("Error updating contact\n");
697
+        goto cleanup;
698
+    }
699
+
700
+    if(ci.via_port == SIP_PORT){
717 701
         // Update temp security parameters
718 702
         if(ul.update_temp_security(d, pcontact->security_temp->type, pcontact->security_temp, pcontact) != 0){
719 703
             LM_ERR("Error updating temp security\n");
720 704
         }
705
+    }
721 706
 
722
-        if(add_supported_secagree_header(m) != 0) {
723
-            goto cleanup;
724
-        }
725 707
 
726
-        if(add_security_server_header(m, s) != 0) {
727
-            goto cleanup;
728
-        }
708
+    if(add_supported_secagree_header(m) != 0) {
709
+        goto cleanup;
710
+    }
729 711
 
712
+    if(add_security_server_header(m, s) != 0) {
713
+        goto cleanup;
714
+    }
715
+
716
+    if(ci.via_port == SIP_PORT){
730 717
         if(ul.register_ulcb(pcontact, PCSCF_CONTACT_EXPIRE|PCSCF_CONTACT_DELETE, ipsec_on_expire, (void*)&pcontact->received_port) != 1) {
731 718
             LM_ERR("Error subscribing for contact\n");
732 719
             goto cleanup;
733 720
         }
734
-    }else{
735
-        LM_DBG("RE-Registration for contact with AOR [%.*s], VIA [%d://%.*s:%d], received_host [%d://%.*s:%d]\n",
736
-                ci.aor.len, ci.aor.s, ci.via_prot, ci.via_host.len, ci.via_host.s, ci.via_port,
737
-                ci.received_proto, ci.received_host.len, ci.received_host.s, ci.received_port);
738
-        
739
-        security_t* req_sec_params = NULL;
740
-
741
-        // Parse security parameters from the REGISTER request and get some data for the new tunnels
742
-        if((req_sec_params = cscf_get_security(req)) == NULL) {
743
-            LM_CRIT("No security parameters in REGISTER request\n");
744
-            goto cleanup;
745
-        }
746
-
747
-		// for Re-Registration use the same P-CSCF server port if 'ipsec reuse server port' is enabled
748
-        if(update_contact_ipsec_params(req_sec_params->data.ipsec, m, ipsec_reuse_server_port ? pcontact->security_temp->data.ipsec : NULL) != 0) {
749
-            goto cleanup;
750
-        }
751
-
752
-        if(create_ipsec_tunnel(&req->rcv.src_ip, req_sec_params->data.ipsec) != 0){
753
-            goto cleanup;
754
-        }
755
-
756
-        if(add_supported_secagree_header(m) != 0) {
757
-            goto cleanup;
758
-        }
759
-
760
-        if(add_security_server_header(m, req_sec_params->data.ipsec) != 0) {
761
-            goto cleanup;
762
-        }
763 721
     }
764 722
 
765 723
     ret = IPSEC_CMD_SUCCESS;    // all good, set ret to SUCCESS, and exit
... ...
@@ -1004,10 +962,9 @@ int ipsec_reconfig()
1004 962
 		return 0;
1005 963
 	}
1006 964
 
1007
-	clean_spi_list();
1008
-	clean_port_lists();
1009
-
1010
-	LM_DBG("Clean all ipsec tunnels\n");
965
+	if(clean_spi_list() != 0) {
966
+		return 1;
967
+	}
1011 968
 
1012 969
 	return ipsec_cleanall();
1013 970
 }
... ...
@@ -82,7 +82,7 @@ modparam("ims_ipsec_pcscf", "ipsec_listen_addr6", "")
82 82
     <section>
83 83
       <title><varname>ipsec_client_port</varname> (int)</title>
84 84
 
85
-      <para>Start port number which will be bound for incoming (server) IPSec traffic.</para>
85
+      <para>Port number which will be bound for incoming (server) IPSec traffic.</para>
86 86
 
87 87
       <para><emphasis>Default value is 5062.</emphasis></para>
88 88
 
... ...
@@ -100,7 +100,7 @@ modparam("ims_ipsec_pcscf", "ipsec_client_port", 5062)
100 100
     <section>
101 101
       <title><varname>ipsec_server_port</varname> (int)</title>
102 102
 
103
-      <para>Start port number which will be bound for incoming (server) IPSec traffic.</para>
103
+      <para>Port number which will be bound for incoming (server) IPSec traffic.</para>
104 104
 
105 105
       <para><emphasis>Default value is 5063.</emphasis></para>
106 106
 
... ...
@@ -118,9 +118,7 @@ modparam("ims_ipsec_pcscf", "ipsec_server_port", 5063)
118 118
     <section>
119 119
       <title><varname>ipsec_max_connections</varname> (int)</title>
120 120
 
121
-      <para>Maximum IPSec connections for the process. E.g. if ipsec_client_port=5100, ipsec_server_port=6100 and
122
-      ipsec_max_connections=10, all client ports between 5100 and 5109 and all server ports between 6100 and 6109
123
-      will be used for maximum to 10 IPSec connections.</para>
121
+      <para>Maximum simultanious IPSec connections</para>
124 122
 
125 123
       <para><emphasis>Default value is 2.</emphasis></para>
126 124
 
... ...
@@ -138,11 +136,9 @@ modparam("ims_ipsec_pcscf", "ipsec_max_connections", 10)
138 136
     <section>
139 137
       <title><varname>ipsec_reuse_server_port</varname> (int)</title>
140 138
 
141
-      <para>Reuse (1) or not (0) the P-CSCF Server port for Re-registration for one UA.
142
-      When set to 0 - During Re-registration P-CSCF will distribute new P-CSCF client and
143
-      P-CSCF server ports.
144
-      When set to 1 - During Re-registration P-CSCF will reuse the old P-CSCF server port and
145
-      will distribute a new P-CSCF client port.</para>
139
+      <para>Reuse (1) or not (0) the P-CSCF IPSec information for Re-registration for one UA.
140
+      When set to 0 - During Re-registration P-CSCF will create new IPSec tunnels.
141
+      When set to 1 - During Re-registration P-CSCF will reuse the old IPSec tunnels.</para>
146 142
 
147 143
       <para><emphasis>Default value is 1.</emphasis></para>
148 144
 
... ...
@@ -192,6 +188,40 @@ modparam("ims_ipsec_pcscf", "ipsec_spi_id_start", 100)
192 188
         <programlisting format="linespecific">
193 189
 ...
194 190
 modparam("ims_ipsec_pcscf", "ipsec_spi_id_range", 1000)
191
+...
192
+        </programlisting>
193
+      </example>
194
+    </section>
195
+
196
+    <section>
197
+      <title><varname>ipsec_preferred_alg</varname> (string)</title>
198
+
199
+      <para>A name of an authentication algorithm which the Proxy-CSCF will <emphasis>prefer</emphasis> when creating IPSec tunnels.</para>
200
+      <para><emphasis>Default value is empty string (null) - the last algorithm in the Sec-Agree header will be used.</emphasis></para>
201
+
202
+      <example>
203
+        <title><varname>ipsec_preferred_alg</varname> parameter usage</title>
204
+
205
+        <programlisting format="linespecific">
206
+...
207
+modparam("ims_ipsec_pcscf", "ipsec_preferred_alg", "hmac-sha-1-96")
208
+...
209
+        </programlisting>
210
+      </example>
211
+    </section>
212
+
213
+    <section>
214
+      <title><varname>ipsec_preferred_ealg</varname> (string)</title>
215
+
216
+      <para>A name of an encrytion algorithm which the Proxy-CSCF will <emphasis>prefer</emphasis> when creating IPSec tunnels.</para>
217
+      <para><emphasis>Default value is empty string (null) - the last algorithm in the Sec-Agree header will be used. Note that the possibility of it being the "null" algorithm is not insignificant.</emphasis></para>
218
+
219
+      <example>
220
+        <title><varname>ipsec_preferred_ealg</varname> parameter usage</title>
221
+
222
+        <programlisting format="linespecific">
223
+...
224
+modparam("ims_ipsec_pcscf", "ipsec_preferred_ealg", "aes-cbc")
195 225
 ...
196 226
         </programlisting>
197 227
       </example>
... ...
@@ -28,8 +28,6 @@
28 28
 
29 29
 #include "cmd.h"
30 30
 #include "spi_gen.h"
31
-#include "port_gen.h"
32
-
33 31
 
34 32
 MODULE_VERSION
35 33
 
... ...
@@ -45,6 +43,8 @@ int ipsec_reuse_server_port = 1;
45 43
 int ipsec_max_connections = 2;
46 44
 int spi_id_start = 100;
47 45
 int spi_id_range = 1000;
46
+str ipsec_preferred_alg= STR_NULL;
47
+str ipsec_preferred_ealg= STR_NULL;
48 48
 int xfrm_user_selector = 143956232;
49 49
 
50 50
 ip_addr_t ipsec_listen_ip_addr;
... ...
@@ -92,6 +92,8 @@ static param_export_t params[] = {
92 92
 	{"ipsec_max_connections",	INT_PARAM, &ipsec_max_connections	},
93 93
 	{"ipsec_spi_id_start",		INT_PARAM, &spi_id_start			},
94 94
 	{"ipsec_spi_id_range",		INT_PARAM, &spi_id_range			},
95
+	{"ipsec_preferred_alg",		PARAM_STR, &ipsec_preferred_alg		},
96
+	{"ipsec_preferred_ealg",	PARAM_STR, &ipsec_preferred_ealg	},
95 97
 	{0, 0, 0}
96 98
 };
97 99
 
... ...
@@ -302,16 +304,11 @@ static int mod_init(void) {
302 304
 	}
303 305
 
304 306
 	int res = 0;
305
-	if((res = init_spi_gen(spi_id_start, spi_id_range)) != 0) {
307
+    if((res = init_spi_gen(spi_id_start, spi_id_range, ipsec_server_port, ipsec_client_port, ipsec_max_connections)) != 0) {
306 308
 		LM_ERR("Error initialising spi generator. Error: %d\n", res);
307 309
 		return -1;
308 310
 	}
309 311
 
310
-	if((res = init_port_gen(ipsec_server_port, ipsec_client_port, ipsec_max_connections)) != 0) {
311
-		LM_ERR("Error initialising port generator. Error: %d\n", res);
312
-		return -1;
313
-	}
314
-
315 312
 	init_flag = 1;
316 313
 
317 314
 	return 0;
... ...
@@ -327,9 +324,6 @@ static void mod_destroy(void)
327 324
 		LM_ERR("Error destroying spi generator\n");
328 325
 	}
329 326
 
330
-	if(destroy_port_gen() != 0){
331
-		LM_ERR("Error destroying port generator\n");
332
-	}
333 327
 }
334 328
 
335 329
 static int child_init(int rank)
... ...
@@ -24,7 +24,6 @@
24 24
 
25 25
 #include "ipsec.h"
26 26
 #include "spi_gen.h"
27
-#include "port_gen.h"
28 27
 
29 28
 #include "../../core/dprint.h"
30 29
 #include "../../core/mem/pkg.h"
... ...
@@ -205,7 +204,6 @@ int add_sa(struct mnl_socket* nl_sock, const struct ip_addr *src_addr_param, con
205 204
         return -1;
206 205
     }
207 206
 
208
-
209 207
     mnl_attr_put(l_nlh, XFRMA_ALG_AUTH, sizeof(struct xfrm_algo) + l_auth_algo->alg_key_len, l_auth_algo);
210 208
 
211 209
     // add encription algorithm for this SA
... ...
@@ -830,13 +828,7 @@ static int delete_unused_sa_cb(const struct nlmsghdr *nlh, void *data)
830 828
 
831 829
     // NOTE: Release the Proxy SPIs and Ports only here. Do not release the same SPIs and ports in delete unsused policy callback.
832 830
     // Release SPIs
833
-    release_spi(ipsec.spi_pc);
834
-    release_spi(ipsec.spi_ps);
835
-
836
-    // Release the client and the server ports
837
-    release_cport(ipsec.port_pc);
838
-    release_sport(ipsec.port_ps);
839
-
831
+    release_spi(ipsec.spi_pc, ipsec.spi_ps, ipsec.port_pc, ipsec.port_ps);
840 832
     return MNL_CB_OK;
841 833
 }
842 834
 
843 835
deleted file mode 100644
... ...
@@ -1,227 +0,0 @@
1
-/*
2
- * IMS IPSEC PCSCF module
3
- *
4
- * Copyright (C) 2018 Tsvetomir Dimitrov
5
- * Copyright (C) 2019 Aleksandar Yosifov
6
- *
7
- * This file is part of Kamailio, a free SIP server.
8
- *
9
- * Kamailio is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation; either version 2 of the License, or
12
- * (at your option) any later version
13
- *
14
- * Kamailio is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
- * GNU General Public License for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License
20
- * along with this program; if not, write to the Free Software
21
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
- *
23
- */
24
-
25
-#include "spi_gen.h"
26
-#include "spi_list.h"
27
-#include <pthread.h>
28
-#include "../../core/mem/shm_mem.h"
29
-
30
-typedef struct port_generator{
31
-	pthread_mutex_t	sport_mut;		// server port mutex
32
-	pthread_mutex_t	cport_mut;		// client port mutex
33
-	spi_list_t		used_sports;	// list with used server ports
34
-	spi_list_t		used_cports;	// list with used client ports
35
-	uint32_t		sport_val;		// the last acquired server port
36
-	uint32_t		cport_val;		// the last acquired client port
37
-	uint32_t		min_sport;
38
-	uint32_t		min_cport;
39
-	uint32_t		max_sport;
40
-	uint32_t		max_cport;
41
-} port_generator_t;
42
-
43
-port_generator_t* port_data = NULL;
44
-
45
-int init_port_gen(uint32_t sport_start_val, uint32_t cport_start_val, uint32_t range)
46
-{
47
-    if(sport_start_val < 1 || cport_start_val < 1){
48
-        return 1;
49
-    }
50
-
51
-    if((UINT32_MAX - range < sport_start_val) || (UINT32_MAX - range < cport_start_val)){
52
-        return 2;
53
-    }
54
-
55
-	if(port_data){
56
-		return 3;
57
-	}
58
-
59
-	port_data = shm_malloc(sizeof(port_generator_t));
60
-	if(port_data == NULL){
61
-		return 4;
62
-	}
63
-
64
-	if(pthread_mutex_init(&port_data->sport_mut, NULL)){
65
-		shm_free(port_data);
66
-		return 5;
67
-	}
68
-
69
-	if(pthread_mutex_init(&port_data->cport_mut, NULL)){
70
-		pthread_mutex_destroy(&port_data->sport_mut);
71
-		shm_free(port_data);
72
-		return 6;
73
-	}
74
-
75
-	port_data->used_sports = create_list();
76
-	port_data->used_cports = create_list();
77
-
78
-	port_data->sport_val = port_data->min_sport = sport_start_val;
79
-	port_data->cport_val = port_data->min_cport = cport_start_val;
80
-	port_data->max_sport = sport_start_val + range;
81
-	port_data->max_cport = cport_start_val + range;
82
-
83
-    return 0;
84
-}
85
-
86
-uint32_t acquire_port(spi_list_t* used_ports, pthread_mutex_t* port_mut, uint32_t* port_val, uint32_t min_port, uint32_t max_port)
87
-{
88
-	//save the initial value for the highly unlikely case where there are no free PORTs
89
-    uint32_t initial_val = *port_val;
90
-    uint32_t ret = 0; // by default return invalid port
91
-
92
-    if(pthread_mutex_lock(port_mut) != 0) {
93
-        return ret;
94
-    }
95
-
96
-    while(1){
97
-        if(spi_in_list(used_ports, *port_val) == 0) {
98
-            ret = *port_val;
99
-            (*port_val)++;
100
-
101
-			if(*port_val >= max_port) { //reached the top of the range - reset
102
-				*port_val = min_port;
103
-			}
104
-
105
-            break;
106
-        }
107
-
108
-        (*port_val)++; //the current server port is not available - increment
109
-
110
-        if(*port_val >= max_port) { //reached the top of the range - reset
111
-            *port_val = min_port;
112
-        }
113
-
114
-        if(*port_val == initial_val) { //there are no free server ports
115
-            pthread_mutex_unlock(port_mut);
116
-            return ret;
117
-        }
118
-    }
119
-
120
-    // found unused server port - add it to the used list
121
-    if(spi_add(used_ports, ret) != 0) {
122
-        ret = 0;
123
-    }
124
-
125
-    pthread_mutex_unlock(port_mut);
126
-    return ret;
127
-}
128
-
129
-uint32_t acquire_sport()
130
-{
131
-	if(!port_data){
132
-		return 0;
133
-	}
134
-
135
-	return acquire_port(&port_data->used_sports, &port_data->sport_mut, &port_data->sport_val, port_data->min_sport, port_data->max_sport);
136
-}
137
-
138
-uint32_t acquire_cport()
139
-{
140
-	if(!port_data){
141
-		return 0;
142
-	}
143
-
144
-	return acquire_port(&port_data->used_cports, &port_data->cport_mut, &port_data->cport_val, port_data->min_cport, port_data->max_cport);
145
-}
146
-
147
-int release_sport(uint32_t port)
148
-{
149
-	if(!port_data){
150
-		return 1;
151
-	}
152
-
153
-	if(pthread_mutex_lock(&port_data->sport_mut) != 0){
154
-        return 1;
155
-    }
156
-
157
-	spi_remove(&port_data->used_sports, port);
158
-
159
-	pthread_mutex_unlock(&port_data->sport_mut);
160
-    return 0;
161
-}
162
-
163
-int release_cport(uint32_t port)
164
-{
165
-	if(!port_data){
166
-		return 1;
167
-	}
168
-
169
-	if(pthread_mutex_lock(&port_data->cport_mut) != 0){
170
-        return 1;
171
-    }
172
-
173
-	spi_remove(&port_data->used_cports, port);
174
-
175
-	pthread_mutex_unlock(&port_data->cport_mut);
176
-    return 0;
177
-}
178