-
Notifications
You must be signed in to change notification settings - Fork 74
Description
Hi @sobomax,
I wanted to add the sip realm in the authentication radius request (without perform digest authentication), and I've been looking through RadiusAuthorization; there is an extra_attributes parameter in the do_auth method which is not used anywhere and got me thinking.
Similarly to pass_headers parameters it would be nice to have an option to define a sip header from which b2bua will get specific radius attributes and add them to the Authentication request (via the extra_attributes property)
So I've modified the b2bua a bit to support exactly that. The patch adds an -x option, from which the user can add a sip header for b2bua to read radius attributes.
So for example, opensips might do something like:
append_hf('X-Test-Header: h323-ivr-out=SomeProperty=1\r\n');
$du = 'b2bua.ip'
route(RELAY);
sippy would have to run with -x x-test-header parameter and in the authentication request the header contents is added to the radius request. Obviously it's up to the administrator/ matching dictionary to supply valid radius key/ value pairs for this to work.
I am providing the patch in this comment, I don't know if you would be willing to add it to the b2bua source code. If you are, I'd be happy to supply you with a PR
Index: sippy/b2bua_radius.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- sippy/b2bua_radius.py (revision f1c375b3454445b66b88c4b3cdc365306bb0ef18)
+++ sippy/b2bua_radius.py (date 1603809097780)
@@ -119,11 +119,12 @@
rtp_proxy_session = None
huntstop_scodes = None
pass_headers = None
+ extra_attributes = None
auth_proc = None
proxied = False
challenge = None
- def __init__(self, remote_ip, source, global_config, pass_headers):
+ def __init__(self, remote_ip, source, global_config, pass_headers, extra_attributes):
self.id = CallController.id
CallController.id += 1
self.global_config = global_config
@@ -137,6 +138,7 @@
self.remote_ip = remote_ip
self.source = source
self.pass_headers = pass_headers
+ self.extra_attributes = extra_attributes
def recvEvent(self, event, ua):
if ua == self.uaA:
@@ -191,11 +193,12 @@
elif auth == None or auth.username == None or len(auth.username) == 0:
self.username = self.remote_ip
self.auth_proc = self.global_config['_radius_client'].do_auth(self.remote_ip, self.cli, self.cld, self.cGUID, \
- self.cId, self.remote_ip, self.rDone)
+ self.cId, self.remote_ip, self.rDone, extra_attributes=self.extra_attributes)
else:
self.username = auth.username
self.auth_proc = self.global_config['_radius_client'].do_auth(auth.username, self.cli, self.cld, self.cGUID,
- self.cId, self.remote_ip, self.rDone, auth.realm, auth.nonce, auth.uri, auth.response)
+ self.cId, self.remote_ip, self.rDone, auth.realm, auth.nonce, auth.uri, auth.response,
+ extra_attributes=self.extra_attributes)
return
if self.state not in (CCStateARComplete, CCStateConnected, CCStateDisconnecting) or self.uaO == None:
return
@@ -465,7 +468,27 @@
hfs = req.getHFs(header)
if len(hfs) > 0:
pass_headers.extend(hfs)
- cc = CallController(remote_ip, source, self.global_config, pass_headers)
+
+ extra_attributes = None
+
+ if 'auth_extra_header' in self.global_config:
+ header = self.global_config['auth_extra_header']
+
+ hfs = req.getHFs(header)
+
+ if len(hfs) > 0:
+ extra_attributes = []
+
+ for header in hfs:
+ kvPairs = header.body.body.split(';')
+
+ for pair in kvPairs:
+ [key, _, value] = pair.partition("=")
+
+ if value != '':
+ extra_attributes.append((key, value))
+
+ cc = CallController(remote_ip, source, self.global_config, pass_headers, extra_attributes)
cc.challenge = challenge
rval = cc.uaA.recvRequest(req, sip_t)
self.ccmap.append(cc)
@@ -668,7 +691,7 @@
global_config['_orig_argv'] = sys.argv[:]
global_config['_orig_cwd'] = os.getcwd()
try:
- opts, args = getopt.getopt(sys.argv[1:], 'fDl:p:d:P:L:s:a:t:T:k:m:A:ur:F:R:h:c:M:HC:W:',
+ opts, args = getopt.getopt(sys.argv[1:], 'fDl:p:d:P:L:s:a:t:T:k:m:A:ur:F:R:h:c:M:HC:W:x:',
global_config.get_longopts())
except getopt.GetoptError:
usage(global_config)
@@ -759,6 +782,9 @@
if o == '-h':
for a in a.split(','):
global_config.check_and_set('pass_header', a)
+ continue
+ if o == '-x':
+ global_config.check_and_set('auth_extra_header', a)
continue
if o == '-c':
global_config.check_and_set('b2bua_socket', a)
Index: sippy/MyConfigParser.py
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- sippy/MyConfigParser.py (revision f1c375b3454445b66b88c4b3cdc365306bb0ef18)
+++ sippy/MyConfigParser.py (date 1603808883519)
@@ -98,6 +98,8 @@
'and "SUBSCRIBE" messages. Address in the format ' \
'"host[:port]"'),
'nat_traversal': ('B', 'enable NAT traversal for signalling'), \
+ 'auth_extra_header': ('S', 'sip header containing radius parameters to pass ' \
+ 'to authentication request'), \
'xmpp_b2bua_id': ('I', 'ID passed to the XMPP socket server')}
class MyConfigParser(RawConfigParser):