<!-- Module User's Guide -->

<chapter>
	
	<title>&adminguide;</title>

	<section id="overview" xreflabel="Overview">
	<title>Overview</title>
	<para>This module adds support for SIP Identity (see RFC 4474).</para>
    </section>
    <section id="dependencies" xreflabel="Dependencies">
	<title>Dependencies</title>
	<section>
	    <title>&osips; Modules</title>
	    <para>
		The following modules must be loaded before this module:
	    	<itemizedlist>
		    <listitem>
			<para>
			    <emphasis>No dependencies on other &osips; modules</emphasis>.
			</para>
		    </listitem>
	    	</itemizedlist>
	    </para>
	</section>
	<section>
	    <title>External Libraries or Applications</title>
	    <para>
		The following libraries or applications must be installed before running
		&osips; with this module loaded:
	    	<itemizedlist>
		    <listitem>
			<para>
			    <emphasis>openssl (libssl)</emphasis>.
			</para>
		    </listitem>
	    	</itemizedlist>
	    </para>
	</section>
    </section>
    <section id="exported_parameters" xreflabel="Exported Parameters">
	<title>Exported Parameters</title>
	
	
	
	<section id="param_privKey" xreflabel="privKey">
	    <title><varname>privKey</varname> (string)</title>
	    <para>
		Filename of private RSA-key of authentication service. This file must be in PEM format.
	    </para>
	    
	    <example>
		<title>Set <varname>privKey</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("identity", "privKey", "/etc/openser/privkey.pem")
...
</programlisting>
	    </example>
	</section>

	
		
	<section id="param_authCert" xreflabel="authCert">
	    <title><varname>authCert</varname> (string)</title>
	    <para>
		Filename of certificate which belongs to <varname>privKey</varname>. This file must be in PEM format.
	    </para>
	    
	    <example>
		<title>Set <varname>authCert</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("identity", "authCert", "/etc/openser/cert.pem")
...
</programlisting>
	    </example>
	</section>
	
	
	<section id="param_certUri" xreflabel="certUri">
	    <title><varname>certUri</varname> (string)</title>
	    <para>
		URI from which the certificate of the authentication service can be acquired. This string will be placed in the Identity-Info header.
	    </para>
	    
	    <example>
		<title>Set <varname>certUri</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("identity", "certUri", "http://www.myserver.com/cert.pem")
...
</programlisting>
	    </example>
	</section>
	
	
	<section id="param_verCert" xreflabel="verCert">
	    <title><varname>verCert</varname> (string)</title>
	    <para>
		Path containing certificates for the verifier. Certificates must be in PEM format. The URI in the Identity-Info header field is used to find the corresponding certificate for the request. For this purpose the verifier replaces every character which is not alphanumeric, no <quote>_</quote> and no <quote>.</quote> with a <quote>-</quote>. A <quote>.</quote> at the beginning of the URI is forbidden. If the URI is <quote>http://www.test.com/cert.pem</quote> the verifier will look for the file <quote>http---www.test.com-cert.pem</quote>, for example.
		It is also possible to store a whole certificate chain in a file. In this case certificates must be in right order, end certificate first.
	    </para>
	    
	    <example>
		<title>Set <varname>verCert</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("identity", "verCert", "/etc/openser/verCert/")
...
</programlisting>
	    </example>
	</section>
	
	
	<section id="param_caList" xreflabel="caList">
	    <title><varname>caList</varname> (string)</title>
	    <para>
		File containing all trusted (root) certificates for the verifier. Certificates must be in PEM format.
	    </para>
	    
	    <example>
		<title>Set <varname>caList</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("identity", "caList", "/etc/openser/caList.pem")
...
</programlisting>
	    </example>
	</section>

	
	<section id="param_crlList" xreflabel="crlList">
	    <title><varname>crlList</varname> (string)</title>
	    <para>
		File containing certificate revocation lists (crls) for the verifier. Setting this parameter is only necessary if <varname>useCrls</varname> is set to <quote>1</quote>.
	    </para>
	    
	    <example>
		<title>Set <varname>crlList</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("identity", "crlList", "/etc/openser/crls.pem")
...
</programlisting>
	    </example>
	</section>	
	
	
	<section id="param_useCrls" xreflabel="useCrls">
	    <title><varname>useCrls</varname> (integer)</title>
	    <para>
		Switch to decide whether to use revocation lists (<quote>1</quote>) or not (<quote>0</quote>).
	    </para>
	    <para>
		<emphasis>
		    Default value is <quote>0</quote>.
		</emphasis>
	    </para>
	    
	    <example>
		<title>Set <varname>privKey</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("identity", "useCrls", 1)
...
</programlisting>
	    </example>
	</section>
	
	
    </section>
    <section id="exported_functions" xreflabel="exported_functions">
	<title>Exported Functions</title>
	
	<section id="func_authservice" xreflabel="authservice()">
	    <title>
		<function moreinfo="none">authservice()</function>
	    </title>
		<para>
		This function performs the steps of an authentication service. Before you call this function, you have to ensure
		that 
		</para>
		<itemizedlist>
		<listitem>
		    <para>the server is responsible for this request (from URI matches local SIP domain)
		    </para>
		</listitem>
		<listitem>
		    <para>the sender of the request is authorized to claim the identity given in the From header field.
		    </para>
		</listitem>
	    </itemizedlist>
	    
	    This function returns the following values:
	    <itemizedlist>
		<listitem>
		    <para>-3: Date header field does not match validity period of cert. Identity header has not been added.
			</para>	
		</listitem>
		<listitem>
		    <para>-2: message out of time (e.g. message to old), Identity header has not been added.
		    </para>
		</listitem>
		<listitem>
		    <para>-1: An error occurred.
		    </para>
		</listitem>
		<listitem>
		    <para>1: everything OK, Identity header has been added.
		    </para>
		</listitem>
	    </itemizedlist>
	     This function can be used from REQUEST_ROUTE.
	    <example>
		<title><function>authservice()</function> usage</title>
		<programlisting format="linespecific">
...
# CANCEL and ACK cannot be challenged
if (($rm=="CANCEL") || ($rm"ACK"))
{
    route(1); # forward
    exit;
}

# some clients (e.g. Kphone) do not answer, when a BYE is challenged
if ($rm=="BYE")
{
    route(1); # forward
    exit;
}

### Authentication Service ###

# check whether I am authoritative
if($fd!="mysipdomain.de")
{
    route(1); # forward
    exit;
}

if(!proxy_authorize("mysipdomain.de","subscriber"))
{
    proxy_challenge("mysipdomain.de",0);
    exit;
}

if ($au!=$fU)
{
    sl_send_reply(403, "Use From=ID");
    exit;
}
consume_credentials();
        
authservice();
switch($retcode)
{
    case -3:
        xlog("L_DBG" ,"authservice: Date header field does not match validity period of cert\n");
        break;
    case -2:
        xlog("L_DBG" ,"authservice: msg out of time (max. +- 10 minutes allowed)\n");
        break;
    case -1:
        xlog("L_DBG" ,"authservice: ERROR, returnvalue: -1\n");
        break;
    case 1:
        xlog("L_DBG" ,"authservice: everything OK\n");
        break;
    default:
        xlog("L_DBG" ,"unknown returnvalue of authservice\n");
        
}

route(1); #forward with ($retcode=1) or without ($retcode!=1) Identity header
...
</programlisting>
	    </example>
	</section>
	
	
	<section id="func_verifier" xreflabel="verifier()">
	    <title>
		<function moreinfo="none">verifier()</function>
	    </title>
	    <para>
		This function performs the steps of an verifier. The returned code tells you the result of the verification:
		</para>
		<itemizedlist>
		<listitem>
		    <para> -438: Signature does not correspond to the message. 438-response should be send.
		    </para>
		</listitem>
		<listitem>
		    <para>-437: Certificate cannot be validated. 437-response should be send.
		    </para>
		</listitem>
		<listitem>
		    <para>-436: Certificate is not available. 436-response should be send.
		    </para>
		</listitem>
		<listitem>
		    <para>-428: Message does not have an Identity header. 428-response should be send.
		    </para>
		</listitem>
		<listitem>
		    <para>-3: Error verifying Date header field.
		    </para>
		</listitem>
		<listitem>
		    <para>-2: Authentication service is not authoritative.
		    </para>
		</listitem>
		<listitem>
		    <para>-1: An unknown error occurred.
		    </para>
		</listitem>
		<listitem>
		    <para>1: verification OK
		    </para>
		</listitem>
	    </itemizedlist>
	     This function can be used from REQUEST_ROUTE.
	    <example>
		<title><function>verifier()</function> usage</title>
		<programlisting format="linespecific">
...
# we have to define the same exceptions as we did for the authentication service
if (($rm=="CANCEL") || ($rm"ACK")) 
{ 
    route(1); # forward
    exit;
}
    
if ($rm=="BYE")
{
    route(1); # forward
    exit;
}
   
verifier();
switch($retcode)
{
    case -438:
        xlog("L_DBG" ,"verifier: returnvalue: -438\n");
        sl_send_reply(438, "Invalid Identity Header");
        exit;
        break;
    case -437:
        xlog("L_DBG" ,"verifier: returnvalue: -437\n");
        sl_send_reply(437, "Unsupported Certificate");
        exit;
        break;
    case -436:
        xlog("L_DBG" ,"verifier: returnvalue: -436\n");
        sl_send_reply(436, "Bad Identity-Info");
        exit;
        break;
    case -428:
        xlog("L_DBG" ,"verifier: returnvalue: -428\n");
        sl_send_reply(428, "Use Identity Header");
        exit;
        break;
    case -3:
        xlog("L_DBG" ,"verifier: error verifying Date header field\n");
        exit;
        break;
    case -2:
        xlog("L_DBG" ,"verifier: authentication service is not authoritative\n");
        exit;
        break;
    case -1:
        xlog("L_DBG" ,"verifier: ERROR, returnvalue: -1\n");
        exit;
        break;
    case 1:
        xlog("L_DBG" ,"verifier: verification OK\n");
        route(1); # forward
        exit;
        break;
    default:
        xlog("L_DBG" ,"unknown returnvalue of verifier\n");
        exit;
}
exit;
...
</programlisting>
	    </example>
	</section>
	
	
    </section>
    <section>
	<title>Known Limitations</title>
	<para>
	
	<itemizedlist>
		<listitem>
		    <para> Certificates are not downloaded. They have to be stored locally.
		    </para>
		</listitem>
		<listitem>
		    <para>Call-IDs of valid requests containing an Identity header are not recorded. 
				Hence the verifier does not provide full replay protection.
		    </para>
		</listitem>
		<listitem>
		    <para>Authentication service and verifier use the original request. Changes resulting from message processing in OpenSER script are ignored. 
		    </para>
		</listitem>
		</itemizedlist>
	
	</para>
    </section>
</chapter>

