<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [

<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../docbook/entities.xml">
%docentities;

]>

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

<chapter>
	
	<title>&adminguide;</title>
	
	<section>
	<title>Overview</title>
	<para>
	This module contains all authentication related functions that can work
	with ephemeral credentials. This module can be used together with the
	<emphasis>auth</emphasis> module for digest authentication. Use this
	module if you want to use ephemeral credentials instead of ordinary
	usernames and passwords.
	</para>

	<section>
	<title>How ephemeral credentials work</title>
	<para>
	Ephemeral credentials are generated by a web-service and enforced on
	Kamailio. This use of ephemeral credentials ensures that access to
	Kamailio is controlled even if the credentials cannot be kept secret,
	as can be the case in WebRTC where the credentials may be specified in
	Javascript.
	</para>
	<para>
	The only interaction needed between the web-service and Kamailio is to
	share a secret key.
	</para>
	<para>
	Credentials will typically be requested from the web-service using an
	HTTP POST and provided in a HTTP response with a content-type of
	&quot;application/json&quot;. To prevent unauthorised use the HTTP
	requests can be ACLd by various means.
	</para>
	<para>
	This mechanism is based on draft-uberti-rtcweb-turn-rest.
	</para>
	<section>
	<title>Request</title>
	<para>
	The request to the web-service should contain the following parameters:
	<itemizedlist>
	<listitem>
	<para><emphasis>service</emphasis> - specifies the desired service
	(msrp, sip, etc)</para>
	</listitem>
	<listitem>
	<para><emphasis>username</emphasis> - an optional user identifier for
	the service (as would normally be found in the username parameter of an
	Authorization: or Proxy-Authorization: header)</para>
	</listitem>
	<listitem>
	<para><emphasis>key</emphasis> - an optional API key used for
	authentication</para>
	</listitem>
	</itemizedlist>
	</para>
	<example>
	<title>Request example</title>
	<programlisting format="linespecific">
POST /?service=sip&amp;username=foo@bar.com
</programlisting>
	</example>
	</section>
	<section>
	<title>Response</title>
	<para>
	The response should include the following parameters:
	<itemizedlist>
	<listitem>
	<para><emphasis>username</emphasis> - the username to use, which is a
	colon-delimited combination of the expiration timestamp and the username
	parameter from the request (if specified). When used with this module
	the timestamp must be a UNIX timestamp.</para>
	</listitem>
	<listitem>
	<para><emphasis>password</emphasis> - the password to use; this value is
	computed from the secret key and the returned username value, by
	performing base64(hmac-sha1(secret key, returned username)).</para>
	</listitem>
	<listitem>
	<para><emphasis>ttl</emphasis> - the duration for which the username and
	password are valid, in seconds.</para>
	</listitem>
	<listitem>
	<para><emphasis>uris</emphasis> - an array of URIs indicating servers
	that the username and password are valid for.</para>
	</listitem>
	</itemizedlist>
	</para>
	<example>
	<title>Response example</title>
	<programlisting format="linespecific">
{
  "username" : "1234567890:foo@bar.com",
  "password" : "asdfghjklauio=",
  "ttl" : 86400,
  "uris" : [
    "sip:1.2.3.4;transport=ws",
    "sip:5.6.7.8;transport=ws"
  ]
}
</programlisting>
	</example>
	</section>
	</section>
	</section>

	<section>
	<title>Dependencies</title>
	<section>
		<title>&kamailio; Modules</title>
		<para>
		The module must be loaded before this module:
		<itemizedlist>
		<listitem>
		<para><emphasis>auth</emphasis> (optional).</para>
		</listitem>
		</itemizedlist>
		</para>
	</section>

	<section>
		<title>External Libraries or Applications</title>
		<para>
		The following libraries must be installed before running
		&kamailio; with this module loaded:
		<itemizedlist>
		<listitem>
		<para><emphasis>OpenSSL</emphasis>.</para>
		</listitem>
		</itemizedlist>
		</para>
	</section>
	</section>

	<section id="auth_eph.parameters">
	<title>Parameters</title>
	<section id="auth_eph.p.secret">
		<title><varname>secret</varname> (string)</title>
		<para>
		The shared secret to use for generating credentials. This
		parameter can be set multiple times - this enables the secret
		used for new credentials to be changed without causing existing
		credentials to stop working. The last secret set is the first
		that will be tried.
		</para>
		<example>
		<title><varname>secret</varname> parameter usage</title>
		<programlisting format="linespecific">
...
modparam("auth_ephemeral", "secret", "kamailio_rules")
...
</programlisting>
		</example>
	</section>

	<section id="auth_eph.p.username_format">
		<title><varname>username_format</varname> (integer)</title>
		<para>
		The format of the username in the web-service response.
		</para>
		<para>
		<itemizedlist>
		<listitem>
			<para>0 (deprecated - pre IETF draft format) -
		&lt;username parameter from the request&gt;:&lt;timestamp&gt;
			</para>
		</listitem>
		<listitem>
			<para>1 (default - IETF draft format) -
		&lt;timestamp&gt;:&lt;username parameter from the request&gt;
			</para>
		</listitem>
		</itemizedlist>
		</para>
		<example>
		<title><varname>username_format</varname> parameter
		usage</title>
		<programlisting format="linespecific">
...
modparam("auth_ephemeral", "username_format", 0)
...
</programlisting>
		</example>
	</section>
	</section>

	<section id="auth_eph.functions">
	<title>Functions</title>
	<section id="auth_eph.f.autheph_proxy">
		<title>
			<function moreinfo="none">autheph_proxy(realm)</function>
		</title>
		<para>This function performs proxy authentication.</para>
		<note><para>This function can only be used when the
		<emphasis>auth</emphasis> module is loaded before this module.
		</para></note>
		<para>The meaning of the parameters are as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>realm</emphasis> - realm is an opaque
			string that the user agent should present to the user so
			that he can decide what username and password to use.
			Usually this is domain of the host the server is running
			on.
			</para>
			<para>
			It must not be an empty string <quote></quote>. Apart
			from a static string, a typical value is the From-URI
			domain (i.e., $fd).
			</para>
			<para>
			The string may contain pseudo variables.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title>autheph_proxy usage</title>
		<programlisting format="linespecific">
...
if (!autheph_proxy("$fd")) {
    auth_challenge("$fd", "1");
    exit;
}
...
</programlisting>
		</example>
	</section>

	<section id="auth_eph.f.autheph_www">
		<title>
			<function moreinfo="none">autheph_www(realm[, method])</function>
		</title>
		<para>This function performs WWW digest authentication.</para>
		<note><para>This function can only be used when the
		<emphasis>auth</emphasis> module is loaded before this module.
		</para></note>
		<para>The meaning of the parameters are as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>realm</emphasis> - realm is an opaque
			string that the user agent should present to the user so
			that he can decide what username and password to use.
			Usually this is domain of the host the server is running
			on.
			</para>
			<para>
			It must not be an empty string <quote></quote>. Apart
			from a static string, a typical value is the From-URI
			domain (i.e., $fd).
			</para>
			<para>
			The string may contain pseudo variables.
			</para>
		</listitem>
		<listitem>
			<para><emphasis>method</emphasis> - the method to be
			used for authentication. This parameter is optional and
			if not set the first "word" on the request-line is used.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title>autheph_www usage</title>
		<programlisting format="linespecific">
...
if (!autheph_www("$fd")) {
    auth_challenge("$fd", "1");
    exit;
}
...
</programlisting>
		</example>
	</section>

	<section id="auth_eph.f.autheph_check">
		<title>
			<function moreinfo="none">autheph_check(realm)</function>
		</title>
		<para>This function combines the functionalities of
		<function moreinfo="none">autheph_www</function> and
		<function moreinfo="none">autheph_proxy</function>, the first
		being exectuted if the SIP request is a REGISTER, the second for
		the rest.</para>
		<note><para>This function can only be used when the
		<emphasis>auth</emphasis> module is loaded before this module.
		</para></note>
		<para>The meaning of the parameters are as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>realm</emphasis> - realm is an opaque
			string that the user agent should present to the user so
			that he can decide what username and password to use.
			Usually this is domain of the host the server is running
			on.
			</para>
			<para>
			It must not be an empty string <quote></quote>. Apart
			from a static string, a typical value is the From-URI
			domain (i.e., $fd).
			</para>
			<para>
			The string may contain pseudo variables.
			</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title>autheph_check usage</title>
		<programlisting format="linespecific">
...
if (!autheph_check("$fd")) {
    auth_challenge("$fd", "1");
    exit;
}
...
</programlisting>
		</example>
	</section>

	<section id="auth_eph.f.autheph_authenticate">
		<title>
			<function moreinfo="none">autheph_authenticate(username, password)</function>
		</title>
		<para>This function performs non-digest ephemeral
		authentication. This may be used when digest authentication
		cannot. For example, during WebSocket handshake the username
		may be part of the requested URI and the password presented in
		a Cookie: header.</para>
		<note><para>This function may be used without loading the
		<emphasis>auth</emphasis> module.</para></note>
		<para>The meaning of the parameters are as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>username</emphasis> - the username
			returned in the response from the web-service.</para>
		</listitem>
		<listitem>
			<para><emphasis>password</emphasis> - the password
			returned in the response from the web-service.</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title>autheph_authenticate usage</title>
		<programlisting format="linespecific">
...
if (!autheph_authenticate("$var(username)", "$var(password)")) {
    sl_send_reply("403", "Forbidden");
    exit;
}
...
</programlisting>
		</example>
	</section>

	<section id="auth_eph.f.autheph_check_from">
		<title>
			<function moreinfo="none">autheph_check_from([username])</function>
		</title>
		<para>This function checks that the username (or username and
		domain) in the From: URI matches the credentials.</para>
		<para>When used without the <emphasis>username</emphasis>
		parameter it compares the From: URI with the credentials used
		to authenticate the request (in the Authorization: or
		Proxy-Authorization: headers).</para>
		<para>The <emphasis>username</emphasis> parameter can be used
		to check the From: when individual SIP requests are not
		authenticated (for example, when they are over WebSockets and
		the connection was authenticated during the handshake). In this
		scenario the username should be cached (perhaps in a hash-table)
		at the point the authentication occurs.</para>
		<note><para>This function must have the optional
		<emphasis>username</emphasis> parameter specified to use it
		without loading the <emphasis>auth</emphasis> module before this
		module.</para></note>
		<para>The meaning of the parameters are as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>username</emphasis> (optional) - the
			username returned in the response from the
			web-service.</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title>autheph_check_from usage</title>
		<programlisting format="linespecific">
...
if (!autheph_check_from()) {
    sl_send_reply("403", "Forbidden");
    exit;
}
...
</programlisting>
		</example>
	</section>

	<section id="auth_eph.f.autheph_check_to">
		<title>
			<function moreinfo="none">autheph_check_to([username])</function>
		</title>
		<para>This function checks that the username (or username and
		domain) in the To: URI matches the credentials.</para>
		<para>When used without the <emphasis>username</emphasis>
		parameter it compares the To: URI with the credentials used
		to authenticate the request (in the Authorization: or
		Proxy-Authorization: headers).</para>
		<para>The <emphasis>username</emphasis> parameter can be used
		to check the From: when individual SIP requests are not
		authenticated (for example, when they are over WebSockets and
		the connection was authenticated during the handshake). In this
		scenario the username should be cached (perhaps in a hash-table)
		at the point the authentication occurs.</para>
		<note><para>This function must have the optional
		<emphasis>username</emphasis> parameter specified to use it
		without loading the <emphasis>auth</emphasis> module before this
		module.</para></note>
		<para>The meaning of the parameters are as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>username</emphasis> (optional) - the
			username returned in the response from the
			web-service.</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title>autheph_check_to usage</title>
		<programlisting format="linespecific">
...
if (!autheph_check_to()) {
    sl_send_reply("403", "Forbidden");
    exit;
}
...
</programlisting>
		</example>
	</section>

	<section id="auth_eph.f.autheph_check_timestamp">
		<title>
			<function moreinfo="none">autheph_check_timestamp(username)</function>
		</title>
		<para>This function checks that the timestamp in the
		<emphasis>username</emphasis> parameter has not expired. The
		<emphasis>autheph_(check|proxy|www)</emphasis> functions all do
		this automatically, but in a scenario when individual SIP
		requests are not authenticated (for example, when they are over
		WebSockets and the connection was authenticated during the
		handshake) you may want to re-check for each new out-of-dialog
		request. In this scenario the username should be cached (perhaps
		in a hash-table) at the point authentication occurs.</para>
		<note><para>This function may be used without loading the
		<emphasis>auth</emphasis> module.</para></note>
		<para>The meaning of the parameters are as follows:</para>
		<itemizedlist>
		<listitem>
			<para><emphasis>username</emphasis> - the username
			returned in the response from the web-service.</para>
		</listitem>
		</itemizedlist>
		<para>
		This function can be used from REQUEST_ROUTE.
		</para>
		<example>
		<title>autheph_check_timestamp usage</title>
		<programlisting format="linespecific">
...
if (!autheph_check_timestamp("$var(username)")) {
    sl_send_reply("403", "Forbidden");
    exit;
}
...
</programlisting>
		</example>
	</section>
	</section>

	<section>
	<title>MI Commands</title>
	<section id="auth_eph.m.autheph.add_secret">
		<title><function moreinfo="none">autheph.add_secret</function></title>
		<para>Add a secret to the head of the shared secret list. The
		secret will be the first one tried during future authentication
		attempts. This MI command allows you to update the shared secret
		list without having to restart Kamailio.</para>
		<note><para>If you want your new shared secret list to persist
		across restarts you must add it to your Kamailio configuration
		file.</para></note>
		<para>Name: <emphasis>autheph.add_secret</emphasis></para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>secret</para>
			</listitem>
		</itemizedlist>
		<para>MI FIFO Command Format:</para>
		<programlisting  format="linespecific">
			:autheph.add_secret:fifo_reply
			kamailio_rules
			_empty_line_
</programlisting>
	</section>

	<section id="auth_eph.m.autheph.dump_secrets">
		<title><function moreinfo="none">autheph.dump_secrets</function></title>
		<para>Dump the set of shared secrets.</para>
		<para>Name: <emphasis>autheph.dump_secrets</emphasis></para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para><emphasis>none</emphasis></para>
			</listitem>
		</itemizedlist>
		<para>MI FIFO Command Format:</para>
		<programlisting  format="linespecific">
			:autheph.dump_secrets:fifo_reply
			_empty_line_
</programlisting>
	</section>

	<section id="auth_eph.m.autheph.rm_secret">
		<title><function moreinfo="none">autheph.rm_secret</function></title>
		<para>Remove the secret with the specified integer ID.  This MI
		command allows you to update the shared secret list without
		having to restart Kamailio.</para>
		<note><para>If you want your new shared secret list to persist
		across restarts you must add it to your Kamailio configuration
		file.</para></note>
		<para>Name: <emphasis>autheph.rm_secret</emphasis></para>
		<para>Parameters:</para>
		<itemizedlist>
			<listitem>
				<para>ID - the ID of the secret to remove</para>
			</listitem>
		</itemizedlist>
		<para>MI FIFO Command Format:</para>
		<programlisting  format="linespecific">
			:autheph.rm_secret:fifo_reply
			0
			_empty_line_
</programlisting>
	</section>

	</section>
</chapter>

