Merge "sip_to_pjsip: Write local_net, contact_acl, contact_deny, and contact_permit."
[asterisk/asterisk.git] / contrib / scripts / sip_to_pjsip / sip_to_pjsip.py
index 9f6919a..a4f03b5 100755 (executable)
@@ -54,10 +54,11 @@ def set_value(key=None, val=None, section=None, pjsip=None,
 
 
 def merge_value(key=None, val=None, section=None, pjsip=None,
-                nmapped=None, type='endpoint', section_to=None):
+                nmapped=None, type='endpoint', section_to=None,
+                key_to=None):
     """Merge values from the given section with those from the default."""
     def _merge_value(k, v, s, r, n):
-        merge_value(key if key else k, v, s, r, n, type, section_to)
+        merge_value(key if key else k, v, s, r, n, type, section_to, key_to)
 
     # if no value or section return the merge_value
     # function with the enclosed key and type
@@ -71,7 +72,8 @@ def merge_value(key=None, val=None, section=None, pjsip=None,
         sect = sip.default(section)[0]
     # for each merged value add it to pjsip.conf
     for i in sect.get_merged(key):
-        set_value(key, i, section_to if section_to else section,
+        set_value(key_to if key_to else key, i,
+                  section_to if section_to else section,
                   pjsip, nmapped, type)
 
 
@@ -133,11 +135,14 @@ def set_timers(key, val, section, pjsip, nmapped):
     found in sip.conf.
     """
     # pjsip.conf values can be yes/no, required, always
+    # 'required' is a new feature of chan_pjsip, which rejects
+    #            all SIP clients not supporting Session Timers
+    # 'Accept' is the default value of chan_sip and maps to 'yes'
+    # chan_sip ignores the case, for example 'session-timers=Refuse'
+    val = val.lower()
     if val == 'originate':
         set_value('timers', 'always', section, pjsip, nmapped)
-    elif val == 'accept':
-        set_value('timers', 'required', section, pjsip, nmapped)
-    elif val == 'never':
+    elif val == 'refuse':
         set_value('timers', 'no', section, pjsip, nmapped)
     else:
         set_value('timers', 'yes', section, pjsip, nmapped)
@@ -396,7 +401,7 @@ peer_map = [
     ['trustpid',           set_value('trust_id_inbound')],
     ['sendrpid',           from_sendrpid],       # send_pai, send_rpid
     ['send_diversion',     set_value],
-    ['encrpytion',         set_media_encryption],
+    ['encryption',         set_media_encryption],
     ['avpf',               set_value('use_avpf')],
     ['recordonfeature',    set_record_on_feature],  # automixon
     ['recordofffeature',   set_record_off_feature],  # automixon
@@ -440,6 +445,9 @@ peer_map = [
 
     ['host',               from_host],           # contact, max_contacts
     ['qualifyfreq',        set_value('qualify_frequency', type='aor')],
+    ['maxexpiry',          set_value('maximum_expiration', type='aor')],
+    ['minexpiry',          set_value('minimum_expiration', type='aor')],
+    ['defaultexpiry',      set_value('default_expiration', type='aor')],
 
 ############################# maps to auth#####################################
 #        type = auth
@@ -454,9 +462,9 @@ peer_map = [
     ['permit',             merge_value(type='acl', section_to='acl')],
     ['deny',               merge_value(type='acl', section_to='acl')],
     ['acl',                merge_value(type='acl', section_to='acl')],
-    ['contactpermit',      merge_value('contact_permit', type='acl', section_to='acl')],
-    ['contactdeny',        merge_value('contact_deny', type='acl', section_to='acl')],
-    ['contactacl',         merge_value('contact_acl', type='acl', section_to='acl')],
+    ['contactpermit',      merge_value(type='acl', section_to='acl', key_to='contact_permit')],
+    ['contactdeny',        merge_value(type='acl', section_to='acl', key_to='contact_deny')],
+    ['contactacl',         merge_value(type='acl', section_to='acl', key_to='contact_acl')],
 
 ########################### maps to transport #################################
 #        type = transport
@@ -464,6 +472,7 @@ peer_map = [
 #        bind
 #        async_operations
 #        ca_list_file
+#        ca_list_path
 #        cert_file
 #        privkey_file
 #        password
@@ -499,21 +508,6 @@ peer_map = [
 ]
 
 
-def add_localnet(section, pjsip, nmapped):
-    """
-    Adds localnet values from sip.conf's general section to a transport in
-    pjsip.conf. Ideally, we would have just created a template with the
-    localnet sections, but because this is a script, it's not hard to add
-    the same thing on to every transport.
-    """
-    try:
-        merge_value('local_net', sip.get('general', 'localnet')[0], 'general',
-                    pjsip, nmapped, 'transport', section)
-    except LookupError:
-        # No localnet options configured. No biggie!
-        pass
-
-
 def set_transport_common(section, pjsip, nmapped):
     """
     sip.conf has several global settings that in pjsip.conf apply to individual
@@ -527,8 +521,8 @@ def set_transport_common(section, pjsip, nmapped):
     """
 
     try:
-        merge_value('local_net', sip.get('general', 'localnet')[0], 'general',
-                    pjsip, nmapped, 'transport', section)
+        merge_value('localnet', sip.get('general', 'localnet')[0], 'general',
+                    pjsip, nmapped, 'transport', section, "local_net")
     except LookupError:
         # No localnet options configured. Move on.
         pass
@@ -697,6 +691,12 @@ def set_tls_bindaddr(val, pjsip, nmapped):
     set_value('bind', bind, 'transport-tls', pjsip, nmapped, 'transport')
 
 
+def set_tls_cert_file(val, pjsip, section, nmapped):
+    """Sets cert_file based on sip.conf tlscertfile"""
+    set_value('cert_file', val, section, pjsip, nmapped,
+              'transport')
+
+
 def set_tls_private_key(val, pjsip, nmapped):
     """Sets privkey_file based on sip.conf tlsprivatekey or sslprivatekey"""
     set_value('priv_key_file', val, 'transport-tls', pjsip, nmapped,
@@ -714,6 +714,12 @@ def set_tls_cafile(val, pjsip, nmapped):
               'transport')
 
 
+def set_tls_capath(val, pjsip, nmapped):
+    """Sets ca_list_path based on sip.conf tlscapath"""
+    set_value('ca_list_path', val, 'transport-tls', pjsip, nmapped,
+              'transport')
+
+
 def set_tls_verifyclient(val, pjsip, nmapped):
     """Sets verify_client based on sip.conf tlsverifyclient"""
     set_value('verify_client', val, 'transport-tls', pjsip, nmapped,
@@ -731,11 +737,6 @@ def set_tls_verifyserver(val, pjsip, nmapped):
                   'transport')
 
 
-def set_tls_method(val, pjsip, nmapped):
-    """Sets method based on sip.conf tlsclientmethod or sslclientmethod"""
-    set_value('method', val, 'transport-tls', pjsip, nmapped, 'transport')
-
-
 def create_tls(sip, pjsip, nmapped):
     """
     Creates a 'transport-tls' section in pjsip.conf based on the following
@@ -755,12 +756,13 @@ def create_tls(sip, pjsip, nmapped):
 
     tls_map = [
         (['tlsbindaddr', 'sslbindaddr'], set_tls_bindaddr),
+        (['tlscertfile', 'sslcert', 'tlscert'], set_tls_cert_file),
         (['tlsprivatekey', 'sslprivatekey'], set_tls_private_key),
         (['tlscipher', 'sslcipher'], set_tls_cipher),
         (['tlscafile'], set_tls_cafile),
+        (['tlscapath', 'tlscadir'], set_tls_capath),
         (['tlsverifyclient'], set_tls_verifyclient),
-        (['tlsdontverifyserver'], set_tls_verifyserver),
-        (['tlsclientmethod', 'sslclientmethod'], set_tls_method)
+        (['tlsdontverifyserver'], set_tls_verifyserver)
     ]
 
     try:
@@ -780,6 +782,23 @@ def create_tls(sip, pjsip, nmapped):
         except LookupError:
             pass
 
+    try:
+        method = sip.multi_get('general', ['tlsclientmethod', 'sslclientmethod'])[0]
+        print 'In chan_sip, you specified the TLS version. With chan_sip, this was just for outbound client connections. In chan_pjsip, this value is for client and server. Instead, consider not to specify \'tlsclientmethod\' for chan_sip and \'method = sslv23\' for chan_pjsip.'
+    except LookupError:
+        """
+        OpenSSL emerged during the 90s. SSLv2 and SSLv3 were the only
+        existing methods at that time. The OpenSSL project continued. And as
+        of today (OpenSSL 1.0.2) this does not start SSLv2 and SSLv3 anymore
+        but TLSv1.0 and v1.2. Or stated differently: This method should
+        have been called 'method = secure' or 'method = automatic' back in
+        the 90s. The PJProject did not realize this and uses 'tlsv1' as
+        default when unspecified, which disables TLSv1.2. chan_sip used
+        'sslv23' as default when unspecified, which gives TLSv1.0 and v1.2.
+        """
+        method = 'sslv23'
+    set_value('method', val, 'transport-tls', pjsip, nmapped, 'transport')
+
     set_transport_common('transport-tls', pjsip, nmapped)
     try:
         extern_addr = sip.multi_get('general', ['externaddr', 'externip',
@@ -981,9 +1000,8 @@ class Registration:
         if hasattr(self, 'secret') and self.secret:
             set_value('password', self.secret, auth_section, pjsip, nmapped,
                       'auth')
-            if hasattr(self, 'authuser'):
-                set_value('username', self.authuser or self.user, auth_section,
-                          pjsip, nmapped, 'auth')
+            set_value('username', self.authuser if hasattr(self, 'authuser')
+                      else self.user, auth_section, pjsip, nmapped, 'auth')
             set_value('outbound_auth', auth_section, section, pjsip, nmapped,
                       'registration')