michael@18: UAC module authentication extention (contribution) michael@18: michael@18: Problem michael@18: michael@18: A problem involving SIP authentication has plagued OpenSIPS for years. michael@18: Because OpenSIPS is a proxy it may not manipulate the CSEQ of incoming michael@18: requests or responses. When a UAC sends a SIP message which triggers michael@18: an authentication challenge from another proxy or external UAS, OpenSIPS michael@18: may receive a SIP response message with a 401 or 407 code. michael@18: michael@18: The UAC module provides a function uac_auth() to allow OpenSIPS to michael@18: authenticate, however it is of limited utility because any SIP compliant michael@18: proxy, PBX, or UAS sending such authentication challenges expects the michael@18: CSEQ of the succeeding request to be different than the preceding one. michael@18: michael@18: Solution michael@18: michael@18: While somewhat of a hack, one solution to this problem is to forward michael@18: code 401 and 407 responses to the UAC which will formulate an michael@18: authorization header, insert it into the original request, and michael@18: send the message again after incrementing the CSEQ. OpenSIPS michael@18: receives the new request and passes it with success this time. michael@18: michael@18: This solution requires new hack logic to allow OpenSIPS to provide michael@18: the uac_auth() function inside of request routing blocks, whereas michael@18: the unmodified versions of OpenSIPS allow usage of uac_auth() only michael@18: in failure routes. michael@18: michael@18: Usage michael@18: michael@18: To use the new logic simply follow the instructions of uac_auth() usage michael@18: on incoming SIP requests (for example INVITE) inside a main or secondary michael@18: routing block like so: michael@18: michael@18: if (!load_gws()) { michael@18: send_reply("500", "Server Internal Error"); michael@18: exit; michael@18: } michael@18: if (!next_gw()) { michael@18: send_reply("503", "Service Unavailable"); michael@18: exit; michael@18: } michael@18: if ($avp(s:authuser) == "") { # this is in case no user exists michael@18: $avp(s:authuser) = $fU; # in the gw database table row michael@18: } michael@18: if ($hdr(P-hint) != "lcr applied") { michael@18: append_hf("P-hint: lcr applied\r\n"); michael@18: } michael@18: michael@18: # the following uac_auth avp parameters are filled in michael@18: # by the lcr itself, through a patch to its datatables michael@18: uac_auth(); # patched for use in request route as well michael@18: route(1); # forward to gateway provider michael@18: michael@18: Location michael@18: michael@18: http://scm.europalab.com/contrib/opensips/ michael@18: http://scm.europalab.com/contrib/file/tip/opensips/ michael@18: http://scm.europalab.com/contrib/file/tip/opensips/uac-reauth.txt michael@18: http://scm.europalab.com/contrib/file/tip/opensips/uac-reauth.diff michael@18: michael@18: Instructions michael@18: michael@18: To integrate this contributed logic into the source code tree of michael@18: a OpenSIPS distribution, download the unified diff and use the michael@18: patch(1) command: michael@18: michael@18: $ cd /tmp && mkdir uac-patch && cd uac-patch michael@18: $ wget http://scm.europalab.com/contrib/raw-file/tip/opensips/uac-reauth.diff michael@18: $ tar zxf /tmp/opensips--tls.tar.gz michael@18: $ cd opensips--tls michael@18: $ patch -p0 <../uac-reauth.diff michael@18: michael@18: Disclaimer michael@18: michael@18: This software contribution is based on source code from OpenSIPS SVN michael@18: revision 6590. The author makes no guarantees as to this contribution. michael@18: A user who downloads and executes it does so at his own risk. michael@18: michael@18: Michael Schloh von Bennewitz michael@18: http://michael.schloh.com/ michael@18: Wednsday, 10. February 2010