<html>
<head>
    <base href="https://wiki.asterisk.org/wiki">
            <link rel="stylesheet" href="/wiki/s/2033/1/7/_/styles/combined.css?spaceKey=TOP&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://wiki.asterisk.org/wiki/display/TOP/Sip+Authentication+Hook">Sip Authentication Hook</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://wiki.asterisk.org/wiki/display/~mmichelson">Mark Michelson</a>
    </h4>
        <br/>
                         <h4>Changes (23)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h1. Intro <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >When it comes to authenticating SIP users, it&#39;s tough to define operations in such a way that suits all users. Authentication is heavily policy-based, and as such should be handled by code not included with Asterisk SCF. Since authentication is a decision point during the overall processing of a SIP message, it doesn&#39;t make sense that an entire separate component be designed for authentication. Instead, a user-defined hook could be used, with an extension point built into any SIP modules that might make use of the hook. <span class="diff-added-words"style="background-color: #dfd;">The hook will be called upon whenever it may be useful to require authentication for a user. The SIP component will provide information from the SIP request to the hook. It is the hook&#39;s job to decide whether authentication should be requested, and if so, supply information for the SIP component to use when creating the challenge to send to the client.</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br>h1. Authentication in SIP <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >h1. Presenting information to the User Hook <br> <br></td></tr>
            <tr><td class="diff-changed-lines" >What information will a user need in order to choose whether to challenge the client? Challenge decisions can be made for nearly any reason, but it seems wise to present the user with some information from the SIP message to aid in the decision. For this, we define the <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">{{AuthInfo}}</span> <span class="diff-added-words"style="background-color: #dfd;">{{RequestInfo}}</span> class: <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:language=slice} <br></td></tr>
            <tr><td class="diff-changed-lines" >class <span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">AuthInfo</span> <span class="diff-added-words"style="background-color: #dfd;">RequestInfo</span> <br></td></tr>
            <tr><td class="diff-unchanged" >{ <br>    // The SIP method the client is using <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >{code} <br> <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">Different request methods may have additional information to expose to the hook. For instance, when calling into the hook when a SUBSCRIBE is received, the event package may be included. This can be done by subclassing {{RequestInfo}}. <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h1. Receiving a challenge request from the User Hook <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >* algorithm - Hashing algorithm for the client to use when generating the digest response. <br> <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">So of this information, what is useful for a user hook to be able to generate? The realm and domain list are important for the user to generate. The nonce and opaque strings are not as important since it&#39;s quite possible for Asterisk SCF to generate these values on the user&#39;s behalf. Still, it makes sense to allow the user to generate these himself should he choose to. algorithm has a default value per RFC 2617, but again the user should have the ability to choose this information himself. The qop is optional, though RFC 2617 says that servers SHOULD provide qop options. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">So of this information, what is useful for a user hook to be able to generate? The {{realm}} and {{domain}} are important elements that the hook should provide. The {{nonce}} and {{opaque}} are completely unnecessary for the hook to provide; however, it could be argued that a user may want to be able to control this information, so it makes sense to be allowed to provide it if desired. The {{qop}} during the challenge is completely unnecessary for the user to provide. The {{algorithm}} may be useful for the user to set. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">So basically, it&#39;s reasonable to assume that a user would be interested in generating all of these himself, or possibly not. With this in mind, we define the following datatypes: <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">With all this in mind, we define the following datatypes: <br></td></tr>
            <tr><td class="diff-unchanged" > <br>{code:language=slice} <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">/** <br> * Used for strings that are optional <br> * to be set. Since Ice does not support <br> * the concept of null strings, tacking on <br> * an extra boolean ensures that there is <br> * no misinterpretation of empty strings <br> */ <br>class OptionalString <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">enum Algorithm <br></td></tr>
            <tr><td class="diff-unchanged" >{ <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">    bool isSet; <br>    string str; <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    MD5, <br>    MD5sess, <br>    AKAv1MD5, <br>    AKAv1MD5sess, <br>    AKAv2MD5, <br>    AKAv2MD5sess <br></td></tr>
            <tr><td class="diff-unchanged" >}; <br> <br>class DigestChallenge <br>{ <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    string username; <br>    string password; <br></td></tr>
            <tr><td class="diff-unchanged" >    bool doAuth; <br>    StringSeq domain; <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">    StringSeq qop; <br></td></tr>
            <tr><td class="diff-unchanged" >    string realm; <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">OptionalString</span> <span class="diff-added-words"style="background-color: #dfd;">StringSeq</span> nonce; <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">OptionalString</span> <span class="diff-added-words"style="background-color: #dfd;">StringSeq</span> opaque; <br></td></tr>
            <tr><td class="diff-changed-lines" ><span class="diff-deleted-words"style="color:#999;background-color:#fdd;text-decoration:line-through;">OptionalString</span> <span class="diff-added-words"style="background-color: #dfd;">Algorithm</span> algorithm; <br></td></tr>
            <tr><td class="diff-unchanged" >}; <br>{code} <br></td></tr>
            <tr><td class="diff-changed-lines" >The most important member is {{doAuth}}. If false, then the hook has indicated it does not want for Asterisk to send an authentication challenge to the client. If set true, then an authentication challenge should be sent. <span class="diff-added-words"style="background-color: #dfd;">Why are {{StringSeq}}s used for items which can only contain a single value? The reason is that they&#39;re all optional for the user to set. An empty sequence will be treated as like a null string. Any of the StringSeqs may be empty, although it is recommended that the user provides values for {{domain}}. If the {{nonce}} or {{opaque}} sequences are empty, then Asterisk SCF will create one on behalf of the user.</span> <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">All of the {{OptionalString}} parameters are, of course, optional for the user to set. If {{nonce}} or {{opaque}} is not set, then Asterisk SCF will generate them on behalf of the user. If {{algorithm}} is not set, then Asterisk SCF will assume an algorithm of &quot;md5&quot; as specified in RFC 2617. The {{qop}} sequence may be empty (although people won&#39;t really like you for that), but the {{domain}} sequence and {{realm}} strings must be set by the user. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">The {{username}} and {{password}} are provided so that Asterisk SCF will be able to properly authenticate the user once the authentication response is received from the client. Since this information is passed using Ice, it is recommended that this information is transferred over an encrypted transport so that the information is not in the clear on the wire. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h1. Authenticating a response <br> <br>Aside: Is this beyond the scope of what we&#39;re looking for at the moment? <br> <br>When the client receives an authentication challenge, it will respond by sending an authentication response. Asterisk SCF will provide the authentication information to the hook so that the hook can determine whether to authorize the SIP request. When asking the hook whether the user&#39;s response is correct, this is the information we will provide. <br> <br>{code:language=slice} <br>class AuthResponse <br>{ <br>    string username; <br>    OptionalString cnonce; <br>    int nonceCount; <br>    string digestURI; <br>    string qop; <br>    string response; <br>    DigestChallenge challenge; <br>}; <br>{code} <br> <br>The {{DigestChallenge}} is included so that the user hook will have all information that it needs in order to determine if the {{response}} is what it expects. One unfortunate aspect of having a hook used for client authentication is that the hook will have to contain the hashing logic to determine if the user response  <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h1. Registering a hook with Asterisk SCF <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >interface AuthHook <br>{ <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">    HookResult getChallenge(AuthInfo info, out Challenge challenge); <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">    HookResult getAuthChallenge(RequestInfo info, out DigestChallenge challenge); <br></td></tr>
            <tr><td class="diff-unchanged" >}; <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <div class='panelMacro'><table class='warningMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="/wiki/images/icons/emoticons/forbidden.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>This is a work in progress. Please refrain from making comments at this time</td></tr></table></div>

<h1><a name="SipAuthenticationHook-Intro"></a>Intro</h1>

<p>When it comes to authenticating SIP users, it's tough to define operations in such a way that suits all users. Authentication is heavily policy-based, and as such should be handled by code not included with Asterisk SCF. Since authentication is a decision point during the overall processing of a SIP message, it doesn't make sense that an entire separate component be designed for authentication. Instead, a user-defined hook could be used, with an extension point built into any SIP modules that might make use of the hook. The hook will be called upon whenever it may be useful to require authentication for a user. The SIP component will provide information from the SIP request to the hook. It is the hook's job to decide whether authentication should be requested, and if so, supply information for the SIP component to use when creating the challenge to send to the client.</p>

<h1><a name="SipAuthenticationHook-AuthenticationinSIP"></a>Authentication in SIP</h1>

<p>Authentication in SIP is based off of HTTP authentication as defined in <a href="http://www.ietf.org/rfc/rfc2617.txt" class="external-link" rel="nofollow">RFC 2617</a>. In that document, the Basic and Digest authorization methods are defined. In <a href="http://www.ietf.org/rfc/rfc3261.txt" class="external-link" rel="nofollow">RFC 3261</a> it is expressly forbidden for servers to challenge using the Basic scheme, so this leaves just the Digest as an option. RFCs <a href="http://tools.ietf.org/rfc/rfc3310.txt" class="external-link" rel="nofollow">3310</a> and <a href="http://tools.ietf.org/rfc/rfc4169.txt" class="external-link" rel="nofollow">4169</a> define AKAv1 and AKAv2 extensions to Digest authentication, which are both supported by PJSIP.</p>

<h1><a name="SipAuthenticationHook-PresentinginformationtotheUserHook"></a>Presenting information to the User Hook</h1>

<p>What information will a user need in order to choose whether to challenge the client? Challenge decisions can be made for nearly any reason, but it seems wise to present the user with some information from the SIP message to aid in the decision. For this, we define the <tt>RequestInfo</tt> class:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
class RequestInfo
{
    // The SIP method the client is using
    string method;
    // The display name in the From header
    string fromName;
    // The URI in the from header
    string fromURI;
    // The display name in the To header
    string toName;
    // The URI in teh To header
    string toURI;
    // The request URI
    string requestURI;
}
]]></script>
</div></div>

<p>Different request methods may have additional information to expose to the hook. For instance, when calling into the hook when a SUBSCRIBE is received, the event package may be included. This can be done by subclassing <tt>RequestInfo</tt>.</p>

<h1><a name="SipAuthenticationHook-ReceivingachallengerequestfromtheUserHook"></a>Receiving a challenge request from the User Hook</h1>

<p>A challenge sent by a server contains the following information for the client:</p>
<ul>
        <li>realm - A string used so that the client can know which credentials to use when authenticating</li>
        <li>domain - A list of URIs that define the protection space. This is a bit confusing when reading RFC 3261, because they specifically say that with SIP, the protection space is defined solely by the realm.</li>
        <li>nonce - A string re-generated for each challenge sent.</li>
        <li>opaque - A string generated by the server and used by the client when authenticating to any URI in the protection space.</li>
        <li>qop - Quality of protection: List of supported values, each of which causes slight variations to hashing algorithms used.</li>
        <li>algorithm - Hashing algorithm for the client to use when generating the digest response.</li>
</ul>


<p>So of this information, what is useful for a user hook to be able to generate? The <tt>realm</tt> and <tt>domain</tt> are important elements that the hook should provide. The <tt>nonce</tt> and <tt>opaque</tt> are completely unnecessary for the hook to provide; however, it could be argued that a user may want to be able to control this information, so it makes sense to be allowed to provide it if desired. The <tt>qop</tt> during the challenge is completely unnecessary for the user to provide. The <tt>algorithm</tt> may be useful for the user to set.</p>

<p>With all this in mind, we define the following datatypes:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
enum Algorithm
{
    MD5,
    MD5sess,
    AKAv1MD5,
    AKAv1MD5sess,
    AKAv2MD5,
    AKAv2MD5sess
};

class DigestChallenge
{
    string username;
    string password;
    bool doAuth;
    StringSeq domain;
    string realm;
    StringSeq nonce;
    StringSeq opaque;
    Algorithm algorithm;
};
]]></script>
</div></div>
<p>The most important member is <tt>doAuth</tt>. If false, then the hook has indicated it does not want for Asterisk to send an authentication challenge to the client. If set true, then an authentication challenge should be sent. Why are <tt>StringSeq}}s used for items which can only contain a single value? The reason is that they're all optional for the user to set. An empty sequence will be treated as like a null string. Any of the StringSeqs may be empty, although it is recommended that the user provides values for {{domain</tt>. If the <tt>nonce</tt> or <tt>opaque</tt> sequences are empty, then Asterisk SCF will create one on behalf of the user.</p>

<p>The <tt>username</tt> and <tt>password</tt> are provided so that Asterisk SCF will be able to properly authenticate the user once the authentication response is received from the client. Since this information is passed using Ice, it is recommended that this information is transferred over an encrypted transport so that the information is not in the clear on the wire.</p>

<h1><a name="SipAuthenticationHook-RegisteringahookwithAsteriskSCF"></a>Registering a hook with Asterisk SCF</h1>

<p>The SIP component of Asterisk will expose an interface similar to the one defined <a href="/wiki/display/TOP/Extension+Points+and+Hooks" title="Extension Points and Hooks">Extension Points and Hooks</a>.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="toolbar: false; theme: Confluence; brush: java; gutter: false"><![CDATA[
interface AuthHook
{
    HookResult getAuthChallenge(RequestInfo info, out DigestChallenge challenge);
};

interface SipExtensionPoints
{
    void addAuthHook(HookId id, AuthHook *hook);
    void removeAuthHook(HookId id);
    void clearAuthHooks();
};
]]></script>
</div></div>

<p><tt>HookId</tt> and <tt>HookResult</tt> are defined in the page linked to above.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://wiki.asterisk.org/wiki/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Sip+Authentication+Hook">View Online</a>
        |
        <a href="https://wiki.asterisk.org/wiki/pages/diffpagesbyversion.action?pageId=10650199&revisedVersion=2&originalVersion=1">View Changes</a>
                |
        <a href="https://wiki.asterisk.org/wiki/display/TOP/Sip+Authentication+Hook?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>