Current File : //usr/share/doc/net-snmp/html/snmpksm_8c_source.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>net-snmp: snmpksm.c Source File</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />



</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">net-snmp
   &#160;<span id="projectnumber">5.4.1</span>
   </div>
   
  </td>
  
  
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.7.6.1 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li><a href="examples.html"><span>Examples</span></a></li>
    </ul>
  </div>
  <div id="navrow2" class="tabs2">
    <ul class="tablist">
      <li><a href="files.html"><span>File&#160;List</span></a></li>
      <li><a href="globals.html"><span>Globals</span></a></li>
    </ul>
  </div>
</div>
<div class="header">
  <div class="headertitle">
<div class="title">snmpksm.c</div>  </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"> * snmpksm.c</span>
<a name="l00003"></a>00003 <span class="comment"> *</span>
<a name="l00004"></a>00004 <span class="comment"> * This code implements the Kerberos Security Model (KSM) for SNMP.</span>
<a name="l00005"></a>00005 <span class="comment"> *</span>
<a name="l00006"></a>00006 <span class="comment"> * Security number - 2066432</span>
<a name="l00007"></a>00007 <span class="comment"> */</span>
<a name="l00008"></a>00008 
<a name="l00009"></a>00009 <span class="preprocessor">#include &lt;net-snmp/net-snmp-config.h&gt;</span>
<a name="l00010"></a>00010 
<a name="l00011"></a>00011 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
<a name="l00012"></a>00012 <span class="preprocessor">#if HAVE_WINSOCK_H</span>
<a name="l00013"></a>00013 <span class="preprocessor"></span><span class="preprocessor">#include &lt;winsock.h&gt;</span>
<a name="l00014"></a>00014 <span class="preprocessor">#endif</span>
<a name="l00015"></a>00015 <span class="preprocessor"></span><span class="preprocessor">#include &lt;stdio.h&gt;</span>
<a name="l00016"></a>00016 <span class="preprocessor">#ifdef HAVE_STDLIB_H</span>
<a name="l00017"></a>00017 <span class="preprocessor"></span><span class="preprocessor">#include &lt;stdlib.h&gt;</span>
<a name="l00018"></a>00018 <span class="preprocessor">#endif</span>
<a name="l00019"></a>00019 <span class="preprocessor"></span><span class="preprocessor">#if TIME_WITH_SYS_TIME</span>
<a name="l00020"></a>00020 <span class="preprocessor"></span><span class="preprocessor"># ifdef WIN32</span>
<a name="l00021"></a>00021 <span class="preprocessor"></span><span class="preprocessor">#  include &lt;sys/timeb.h&gt;</span>
<a name="l00022"></a>00022 <span class="preprocessor"># else</span>
<a name="l00023"></a>00023 <span class="preprocessor"></span><span class="preprocessor">#  include &lt;sys/time.h&gt;</span>
<a name="l00024"></a>00024 <span class="preprocessor"># endif</span>
<a name="l00025"></a>00025 <span class="preprocessor"></span><span class="preprocessor"># include &lt;time.h&gt;</span>
<a name="l00026"></a>00026 <span class="preprocessor">#else</span>
<a name="l00027"></a>00027 <span class="preprocessor"></span><span class="preprocessor"># if HAVE_SYS_TIME_H</span>
<a name="l00028"></a>00028 <span class="preprocessor"></span><span class="preprocessor">#  include &lt;sys/time.h&gt;</span>
<a name="l00029"></a>00029 <span class="preprocessor"># else</span>
<a name="l00030"></a>00030 <span class="preprocessor"></span><span class="preprocessor">#  include &lt;time.h&gt;</span>
<a name="l00031"></a>00031 <span class="preprocessor"># endif</span>
<a name="l00032"></a>00032 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l00033"></a>00033 <span class="preprocessor"></span><span class="preprocessor">#if HAVE_STRING_H</span>
<a name="l00034"></a>00034 <span class="preprocessor"></span><span class="preprocessor">#include &lt;string.h&gt;</span>
<a name="l00035"></a>00035 <span class="preprocessor">#else</span>
<a name="l00036"></a>00036 <span class="preprocessor"></span><span class="preprocessor">#include &lt;strings.h&gt;</span>
<a name="l00037"></a>00037 <span class="preprocessor">#endif</span>
<a name="l00038"></a>00038 <span class="preprocessor"></span><span class="preprocessor">#ifdef HAVE_NETINET_IN_H</span>
<a name="l00039"></a>00039 <span class="preprocessor"></span><span class="preprocessor">#include &lt;netinet/in.h&gt;</span>
<a name="l00040"></a>00040 <span class="preprocessor">#endif</span>
<a name="l00041"></a>00041 <span class="preprocessor"></span><span class="preprocessor">#include &lt;errno.h&gt;</span>
<a name="l00042"></a>00042 
<a name="l00043"></a>00043 
<a name="l00044"></a>00044 <span class="preprocessor">#if HAVE_DMALLOC_H</span>
<a name="l00045"></a>00045 <span class="preprocessor"></span><span class="preprocessor">#include &lt;dmalloc.h&gt;</span>
<a name="l00046"></a>00046 <span class="preprocessor">#endif</span>
<a name="l00047"></a>00047 <span class="preprocessor"></span>
<a name="l00048"></a>00048 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_HEIMDAL</span>
<a name="l00049"></a>00049 <span class="preprocessor"></span><span class="preprocessor">#ifndef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l00050"></a>00050 <span class="preprocessor"></span><span class="preprocessor">#define OLD_HEIMDAL</span>
<a name="l00051"></a>00051 <span class="preprocessor"></span><span class="preprocessor">#endif                          </span><span class="comment">/* ! NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00052"></a>00052 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l00053"></a>00053 
<a name="l00054"></a>00054 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_HEIMDAL</span>
<a name="l00055"></a>00055 <span class="preprocessor"></span><span class="preprocessor">#define oid heimdal_oid_renamed</span>
<a name="l00056"></a>00056 <span class="preprocessor"></span><span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l00057"></a>00057 <span class="preprocessor">#include &lt;krb5.h&gt;</span>
<a name="l00058"></a>00058 <span class="preprocessor">#include &lt;com_err.h&gt;</span>
<a name="l00059"></a>00059 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_HEIMDAL</span>
<a name="l00060"></a>00060 <span class="preprocessor"></span><span class="preprocessor">#undef oid</span>
<a name="l00061"></a>00061 <span class="preprocessor"></span><span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l00062"></a>00062 
<a name="l00063"></a>00063 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_HEIMDAL</span>
<a name="l00064"></a>00064 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_TYPE(x)        (x)-&gt;cksumtype</span>
<a name="l00065"></a>00065 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_CONTENTS(x)    ((char *)((x)-&gt;checksum.data))</span>
<a name="l00066"></a>00066 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_LENGTH(x)      (x)-&gt;checksum.length</span>
<a name="l00067"></a>00067 <span class="preprocessor"></span><span class="preprocessor">#define TICKET_CLIENT(x)        (x)-&gt;client</span>
<a name="l00068"></a>00068 <span class="preprocessor"></span><span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l00069"></a>00069 <span class="preprocessor">#define CHECKSUM_TYPE(x)        (x)-&gt;checksum_type</span>
<a name="l00070"></a>00070 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_CONTENTS(x)    (x)-&gt;contents</span>
<a name="l00071"></a>00071 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_LENGTH(x)      (x)-&gt;length</span>
<a name="l00072"></a>00072 <span class="preprocessor"></span><span class="preprocessor">#define TICKET_CLIENT(x)        (x)-&gt;enc_part2-&gt;client</span>
<a name="l00073"></a>00073 <span class="preprocessor"></span><span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l00074"></a>00074 
<a name="l00075"></a>00075 <span class="preprocessor">#include &lt;net-snmp/output_api.h&gt;</span>
<a name="l00076"></a>00076 <span class="preprocessor">#include &lt;net-snmp/config_api.h&gt;</span>
<a name="l00077"></a>00077 <span class="preprocessor">#include &lt;net-snmp/utilities.h&gt;</span>
<a name="l00078"></a>00078 
<a name="l00079"></a>00079 <span class="preprocessor">#include &lt;net-snmp/library/asn1.h&gt;</span>
<a name="l00080"></a>00080 <span class="preprocessor">#include &lt;net-snmp/library/snmp_api.h&gt;</span>
<a name="l00081"></a>00081 <span class="preprocessor">#include &lt;net-snmp/library/callback.h&gt;</span>
<a name="l00082"></a>00082 <span class="preprocessor">#include &lt;net-snmp/library/keytools.h&gt;</span>
<a name="l00083"></a>00083 <span class="preprocessor">#include &lt;net-snmp/library/snmpv3.h&gt;</span>
<a name="l00084"></a>00084 <span class="preprocessor">#include &lt;net-snmp/library/lcd_time.h&gt;</span>
<a name="l00085"></a>00085 <span class="preprocessor">#include &lt;net-snmp/library/scapi.h&gt;</span>
<a name="l00086"></a>00086 <span class="preprocessor">#include &lt;net-snmp/library/callback.h&gt;</span>
<a name="l00087"></a>00087 <span class="preprocessor">#include &lt;net-snmp/library/snmp_secmod.h&gt;</span>
<a name="l00088"></a>00088 <span class="preprocessor">#include &lt;net-snmp/library/snmpksm.h&gt;</span>
<a name="l00089"></a>00089 
<a name="l00090"></a>00090 <span class="keyword">static</span> krb5_context kcontext = NULL;
<a name="l00091"></a>00091 <span class="keyword">static</span> krb5_rcache rcache = NULL;
<a name="l00092"></a>00092 <span class="keyword">static</span> krb5_keytab keytab = NULL;
<a name="l00093"></a>00093 <span class="keyword">static</span> <span class="keywordtype">int</span> keytab_setup = 0;
<a name="l00094"></a>00094 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *service_name = NULL;
<a name="l00095"></a>00095 
<a name="l00096"></a>00096 <span class="keyword">static</span> <span class="keywordtype">int</span>      ksm_session_init(<a class="code" href="structsnmp__session.html" title="The snmp session structure.">netsnmp_session</a> *);
<a name="l00097"></a>00097 <span class="keyword">static</span> <span class="keywordtype">void</span>     ksm_free_state_ref(<span class="keywordtype">void</span> *);
<a name="l00098"></a>00098 <span class="keyword">static</span> <span class="keywordtype">int</span>      ksm_free_pdu(<a class="code" href="structsnmp__pdu.html" title="The snmp protocol data unit.">netsnmp_pdu</a> *);
<a name="l00099"></a>00099 <span class="keyword">static</span> <span class="keywordtype">int</span>      ksm_clone_pdu(<a class="code" href="structsnmp__pdu.html" title="The snmp protocol data unit.">netsnmp_pdu</a> *, <a class="code" href="structsnmp__pdu.html" title="The snmp protocol data unit.">netsnmp_pdu</a> *);
<a name="l00100"></a>00100 
<a name="l00101"></a>00101 <span class="keyword">static</span> <span class="keywordtype">int</span>      ksm_insert_cache(<span class="keywordtype">long</span>, krb5_auth_context, u_char *,
<a name="l00102"></a>00102                                  <span class="keywordtype">size_t</span>);
<a name="l00103"></a>00103 <span class="keyword">static</span> <span class="keywordtype">void</span>     ksm_decrement_ref_count(<span class="keywordtype">long</span>);
<a name="l00104"></a>00104 <span class="keyword">static</span> <span class="keywordtype">void</span>     ksm_increment_ref_count(<span class="keywordtype">long</span>);
<a name="l00105"></a>00105 <span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *ksm_get_cache(<span class="keywordtype">long</span>);
<a name="l00106"></a>00106 
<a name="l00107"></a>00107 <span class="preprocessor">#define HASHSIZE        64</span>
<a name="l00108"></a>00108 <span class="preprocessor"></span>
<a name="l00109"></a>00109 <span class="comment">/*</span>
<a name="l00110"></a>00110 <span class="comment"> * Our information stored for the response PDU.</span>
<a name="l00111"></a>00111 <span class="comment"> */</span>
<a name="l00112"></a>00112 
<a name="l00113"></a><a class="code" href="structksm__secStateRef.html">00113</a> <span class="keyword">struct </span><a class="code" href="structksm__secStateRef.html">ksm_secStateRef</a> {
<a name="l00114"></a>00114     krb5_auth_context auth_context;
<a name="l00115"></a>00115     krb5_cksumtype  cksumtype;
<a name="l00116"></a>00116 };
<a name="l00117"></a>00117 
<a name="l00118"></a>00118 <span class="comment">/*</span>
<a name="l00119"></a>00119 <span class="comment"> * A KSM outgoing pdu cache entry</span>
<a name="l00120"></a>00120 <span class="comment"> */</span>
<a name="l00121"></a>00121 
<a name="l00122"></a><a class="code" href="structksm__cache__entry.html">00122</a> <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> {
<a name="l00123"></a>00123     <span class="keywordtype">long</span>            msgid;
<a name="l00124"></a>00124     <span class="keywordtype">int</span>             refcount;
<a name="l00125"></a>00125     krb5_auth_context auth_context;
<a name="l00126"></a>00126     u_char         *secName;
<a name="l00127"></a>00127     <span class="keywordtype">size_t</span>          secNameLen;
<a name="l00128"></a>00128     <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *next;
<a name="l00129"></a>00129 };
<a name="l00130"></a>00130 
<a name="l00131"></a>00131 <span class="comment">/*</span>
<a name="l00132"></a>00132 <span class="comment"> * Poor man&#39;s hash table</span>
<a name="l00133"></a>00133 <span class="comment"> */</span>
<a name="l00134"></a>00134 
<a name="l00135"></a>00135 <span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *ksm_hash_table[HASHSIZE];
<a name="l00136"></a>00136 
<a name="l00137"></a>00137 <span class="comment">/*</span>
<a name="l00138"></a>00138 <span class="comment"> * Stuff to deal with config values</span>
<a name="l00139"></a>00139 <span class="comment"> * Note the conditionals that wrap these--i don&#39;t know if these are</span>
<a name="l00140"></a>00140 <span class="comment"> * needed, since i don&#39;t know how library initialization and callbacks</span>
<a name="l00141"></a>00141 <span class="comment"> * and stuff work</span>
<a name="l00142"></a>00142 <span class="comment"> */</span>
<a name="l00143"></a>00143 
<a name="l00144"></a>00144 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00145"></a>00145 init_snmpksm_post_config(<span class="keywordtype">int</span> majorid, <span class="keywordtype">int</span> minorid, <span class="keywordtype">void</span> *serverarg,
<a name="l00146"></a>00146                          <span class="keywordtype">void</span> *clientarg)
<a name="l00147"></a>00147 {
<a name="l00148"></a>00148 
<a name="l00149"></a>00149     <span class="keywordflow">if</span> (kcontext == NULL) {
<a name="l00150"></a>00150         <span class="comment">/* not reached, i&#39;d imagine */</span>
<a name="l00151"></a>00151         <span class="keywordflow">return</span> SNMPERR_KRB5;
<a name="l00152"></a>00152     }
<a name="l00153"></a>00153 
<a name="l00154"></a>00154     <span class="keywordflow">if</span> (service_name == NULL) {
<a name="l00155"></a>00155         <span class="comment">/* always reached, i&#39;d imagine */</span>
<a name="l00156"></a>00156         <span class="keywordtype">char</span> *c = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
<a name="l00157"></a>00157                                         NETSNMP_DS_LIB_KSM_SERVICE_NAME);
<a name="l00158"></a>00158         <span class="keywordflow">if</span> (c != NULL) {
<a name="l00159"></a>00159                 service_name = c;
<a name="l00160"></a>00160         }
<a name="l00161"></a>00161         <span class="keywordflow">else</span> {
<a name="l00162"></a>00162                 service_name = <span class="stringliteral">&quot;host&quot;</span>;
<a name="l00163"></a>00163         }
<a name="l00164"></a>00164     }
<a name="l00165"></a>00165 
<a name="l00166"></a>00166     <span class="keywordflow">if</span> (keytab_setup == 0) {
<a name="l00167"></a>00167         <span class="comment">/* always reached, i&#39;d imagine */</span>
<a name="l00168"></a>00168         <span class="keywordtype">char</span> *c = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
<a name="l00169"></a>00169                                         NETSNMP_DS_LIB_KSM_KEYTAB);
<a name="l00170"></a>00170         <span class="keywordflow">if</span> (c) {
<a name="l00171"></a>00171             krb5_error_code retval;
<a name="l00172"></a>00172             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Using keytab %s\n&quot;</span>, c));
<a name="l00173"></a>00173             retval = krb5_kt_resolve(kcontext, c, &amp;keytab);
<a name="l00174"></a>00174             <span class="keywordflow">if</span> (retval) {
<a name="l00175"></a>00175                 DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_kt_resolve(\&quot;%s\&quot;) failed. KSM &quot;</span>
<a name="l00176"></a>00176                             <span class="stringliteral">&quot;config callback failing\n&quot;</span>, error_message(retval)));
<a name="l00177"></a>00177                 <span class="keywordflow">return</span> SNMPERR_KRB5;
<a name="l00178"></a>00178             }
<a name="l00179"></a>00179         }
<a name="l00180"></a>00180         <span class="keywordflow">else</span> {
<a name="l00181"></a>00181             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Using default keytab\n&quot;</span>, c));
<a name="l00182"></a>00182         }
<a name="l00183"></a>00183         keytab_setup = 1;
<a name="l00184"></a>00184     }
<a name="l00185"></a>00185 
<a name="l00186"></a>00186     <span class="keywordflow">return</span> SNMPERR_SUCCESS;
<a name="l00187"></a>00187 }
<a name="l00188"></a>00188 
<a name="l00189"></a>00189 <span class="comment">/*</span>
<a name="l00190"></a>00190 <span class="comment"> * Initialize all of the state required for Kerberos (right now, just call</span>
<a name="l00191"></a>00191 <span class="comment"> * krb5_init_context).</span>
<a name="l00192"></a>00192 <span class="comment"> */</span>
<a name="l00193"></a>00193 
<a name="l00194"></a>00194 <span class="keywordtype">void</span>
<a name="l00195"></a>00195 init_ksm(<span class="keywordtype">void</span>)
<a name="l00196"></a>00196 {
<a name="l00197"></a>00197     krb5_error_code retval;
<a name="l00198"></a>00198     <span class="keyword">struct </span><a class="code" href="structsnmp__secmod__def.html">snmp_secmod_def</a> *def;
<a name="l00199"></a>00199     <span class="keywordtype">int</span>             i;
<a name="l00200"></a>00200 
<a name="l00201"></a>00201     netsnmp_ds_register_config(ASN_OCTET_STR, <span class="stringliteral">&quot;snmp&quot;</span>, <span class="stringliteral">&quot;defKSMKeytab&quot;</span>,
<a name="l00202"></a>00202                                NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_KSM_KEYTAB);
<a name="l00203"></a>00203     netsnmp_ds_register_config(ASN_OCTET_STR, <span class="stringliteral">&quot;snmp&quot;</span>, <span class="stringliteral">&quot;defKSMServiceName&quot;</span>,
<a name="l00204"></a>00204                                NETSNMP_DS_LIBRARY_ID,
<a name="l00205"></a>00205                                NETSNMP_DS_LIB_KSM_SERVICE_NAME);
<a name="l00206"></a>00206     <a class="code" href="group__callback.html#gaa74bcb0ea6a8b7270f5e26746ba1fff1" title="This function registers a generic callback function.">snmp_register_callback</a>(SNMP_CALLBACK_LIBRARY,
<a name="l00207"></a>00207                            SNMP_CALLBACK_POST_READ_CONFIG,
<a name="l00208"></a>00208                            init_snmpksm_post_config, NULL);
<a name="l00209"></a>00209 
<a name="l00210"></a>00210 
<a name="l00211"></a>00211     <span class="keywordflow">if</span> (kcontext == NULL) {
<a name="l00212"></a>00212         retval = krb5_init_context(&amp;kcontext);
<a name="l00213"></a>00213 
<a name="l00214"></a>00214         <span class="keywordflow">if</span> (retval) {
<a name="l00215"></a>00215             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_init_context failed (%s), not &quot;</span>
<a name="l00216"></a>00216                         <span class="stringliteral">&quot;registering KSM\n&quot;</span>, error_message(retval)));
<a name="l00217"></a>00217             <span class="keywordflow">return</span>;
<a name="l00218"></a>00218         }
<a name="l00219"></a>00219     }
<a name="l00220"></a>00220 
<a name="l00221"></a>00221     <span class="keywordflow">for</span> (i = 0; i &lt; HASHSIZE; i++)
<a name="l00222"></a>00222         ksm_hash_table[i] = NULL;
<a name="l00223"></a>00223 
<a name="l00224"></a>00224     def = <a class="code" href="group__util.html#ga6356941968481380ea6f4a646df4aaf9" title="Mallocs memory of sizeof(struct s), zeros it and returns a pointer to it.">SNMP_MALLOC_STRUCT</a>(<a class="code" href="structsnmp__secmod__def.html">snmp_secmod_def</a>);
<a name="l00225"></a>00225 
<a name="l00226"></a>00226     <span class="keywordflow">if</span> (!def) {
<a name="l00227"></a>00227         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to malloc snmp_secmod struct, not &quot;</span>
<a name="l00228"></a>00228                     <span class="stringliteral">&quot;registering KSM\n&quot;</span>));
<a name="l00229"></a>00229         <span class="keywordflow">return</span>;
<a name="l00230"></a>00230     }
<a name="l00231"></a>00231 
<a name="l00232"></a>00232     def-&gt;encode_reverse = ksm_rgenerate_out_msg;
<a name="l00233"></a>00233     def-&gt;decode = ksm_process_in_msg;
<a name="l00234"></a>00234     def-&gt;session_open = ksm_session_init;
<a name="l00235"></a>00235     def-&gt;pdu_free_state_ref = ksm_free_state_ref;
<a name="l00236"></a>00236     def-&gt;pdu_free = ksm_free_pdu;
<a name="l00237"></a>00237     def-&gt;pdu_clone = ksm_clone_pdu;
<a name="l00238"></a>00238 
<a name="l00239"></a>00239     register_sec_mod(NETSNMP_KSM_SECURITY_MODEL, <span class="stringliteral">&quot;ksm&quot;</span>, def);
<a name="l00240"></a>00240 }
<a name="l00241"></a>00241 
<a name="l00242"></a>00242 <span class="comment">/*</span>
<a name="l00243"></a>00243 <span class="comment"> * These routines implement a simple cache for information we need to</span>
<a name="l00244"></a>00244 <span class="comment"> * process responses.  When we send out a request, it contains an AP_REQ;</span>
<a name="l00245"></a>00245 <span class="comment"> * we get back an AP_REP, and we need the authorization context from the</span>
<a name="l00246"></a>00246 <span class="comment"> * AP_REQ to decrypt the AP_REP.  But because right now there&#39;s nothing</span>
<a name="l00247"></a>00247 <span class="comment"> * that gets preserved across calls to rgenerate_out_msg to process_in_msg,</span>
<a name="l00248"></a>00248 <span class="comment"> * we cache these internally based on the message ID (we also cache the</span>
<a name="l00249"></a>00249 <span class="comment"> * passed-in security name, for reasons that are mostly stupid).</span>
<a name="l00250"></a>00250 <span class="comment"> */</span>
<a name="l00251"></a>00251 
<a name="l00252"></a>00252 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00253"></a>00253 ksm_insert_cache(<span class="keywordtype">long</span> msgid, krb5_auth_context auth_context,
<a name="l00254"></a>00254                  u_char * secName, <span class="keywordtype">size_t</span> secNameLen)
<a name="l00255"></a>00255 {
<a name="l00256"></a>00256     <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *entry;
<a name="l00257"></a>00257     <span class="keywordtype">int</span>             bucket;
<a name="l00258"></a>00258     <span class="keywordtype">int</span>             retval;
<a name="l00259"></a>00259 
<a name="l00260"></a>00260     entry = <a class="code" href="group__util.html#ga6356941968481380ea6f4a646df4aaf9" title="Mallocs memory of sizeof(struct s), zeros it and returns a pointer to it.">SNMP_MALLOC_STRUCT</a>(<a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a>);
<a name="l00261"></a>00261 
<a name="l00262"></a>00262     <span class="keywordflow">if</span> (!entry)
<a name="l00263"></a>00263         <span class="keywordflow">return</span> SNMPERR_MALLOC;
<a name="l00264"></a>00264 
<a name="l00265"></a>00265     entry-&gt;msgid = msgid;
<a name="l00266"></a>00266     entry-&gt;auth_context = auth_context;
<a name="l00267"></a>00267     entry-&gt;refcount = 1;
<a name="l00268"></a>00268 
<a name="l00269"></a>00269     retval = <a class="code" href="group__util.html#ga623784b8aac0469fcd84e24ccdeda0bd" title="Duplicates a memory block.">memdup</a>(&amp;entry-&gt;secName, secName, secNameLen);
<a name="l00270"></a>00270 
<a name="l00271"></a>00271     <span class="keywordflow">if</span> (retval != SNMPERR_SUCCESS) {
<a name="l00272"></a>00272         free(entry);
<a name="l00273"></a>00273         <span class="keywordflow">return</span> retval;
<a name="l00274"></a>00274     }
<a name="l00275"></a>00275 
<a name="l00276"></a>00276     entry-&gt;secNameLen = secNameLen;
<a name="l00277"></a>00277 
<a name="l00278"></a>00278     bucket = msgid % HASHSIZE;
<a name="l00279"></a>00279 
<a name="l00280"></a>00280     entry-&gt;next = ksm_hash_table[bucket];
<a name="l00281"></a>00281     ksm_hash_table[bucket] = entry;
<a name="l00282"></a>00282 
<a name="l00283"></a>00283     <span class="keywordflow">return</span> SNMPERR_SUCCESS;
<a name="l00284"></a>00284 }
<a name="l00285"></a>00285 
<a name="l00286"></a>00286 <span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *
<a name="l00287"></a>00287 ksm_get_cache(<span class="keywordtype">long</span> msgid)
<a name="l00288"></a>00288 {
<a name="l00289"></a>00289     <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *entry;
<a name="l00290"></a>00290     <span class="keywordtype">int</span>             bucket;
<a name="l00291"></a>00291 
<a name="l00292"></a>00292     bucket = msgid % HASHSIZE;
<a name="l00293"></a>00293 
<a name="l00294"></a>00294     <span class="keywordflow">for</span> (entry = ksm_hash_table[bucket]; entry != NULL;
<a name="l00295"></a>00295          entry = entry-&gt;next)
<a name="l00296"></a>00296         <span class="keywordflow">if</span> (entry-&gt;msgid == msgid)
<a name="l00297"></a>00297             <span class="keywordflow">return</span> entry;
<a name="l00298"></a>00298 
<a name="l00299"></a>00299     <span class="keywordflow">return</span> NULL;
<a name="l00300"></a>00300 }
<a name="l00301"></a>00301 
<a name="l00302"></a>00302 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00303"></a>00303 ksm_decrement_ref_count(<span class="keywordtype">long</span> msgid)
<a name="l00304"></a>00304 {
<a name="l00305"></a>00305     <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *entry, *entry1;
<a name="l00306"></a>00306     <span class="keywordtype">int</span>             bucket;
<a name="l00307"></a>00307 
<a name="l00308"></a>00308     bucket = msgid % HASHSIZE;
<a name="l00309"></a>00309 
<a name="l00310"></a>00310     <span class="keywordflow">if</span> (ksm_hash_table[bucket] &amp;&amp; ksm_hash_table[bucket]-&gt;msgid == msgid) {
<a name="l00311"></a>00311         entry = ksm_hash_table[bucket];
<a name="l00312"></a>00312 
<a name="l00313"></a>00313         <span class="comment">/*</span>
<a name="l00314"></a>00314 <span class="comment">         * If the reference count is zero, then free it</span>
<a name="l00315"></a>00315 <span class="comment">         */</span>
<a name="l00316"></a>00316 
<a name="l00317"></a>00317         <span class="keywordflow">if</span> (--entry-&gt;refcount &lt;= 0) {
<a name="l00318"></a>00318             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Freeing entry for msgid %ld\n&quot;</span>, msgid));
<a name="l00319"></a>00319             krb5_auth_con_free(kcontext, entry-&gt;auth_context);
<a name="l00320"></a>00320             free(entry-&gt;secName);
<a name="l00321"></a>00321             ksm_hash_table[bucket] = entry-&gt;next;
<a name="l00322"></a>00322             free(entry);
<a name="l00323"></a>00323         }
<a name="l00324"></a>00324 
<a name="l00325"></a>00325         <span class="keywordflow">return</span>;
<a name="l00326"></a>00326 
<a name="l00327"></a>00327     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ksm_hash_table[bucket])
<a name="l00328"></a>00328         <span class="keywordflow">for</span> (entry1 = ksm_hash_table[bucket], entry = entry1-&gt;next;
<a name="l00329"></a>00329              entry != NULL; entry1 = entry, entry = entry-&gt;next)
<a name="l00330"></a>00330             <span class="keywordflow">if</span> (entry-&gt;msgid == msgid) {
<a name="l00331"></a>00331 
<a name="l00332"></a>00332                 <span class="keywordflow">if</span> (--entry-&gt;refcount &lt;= 0) {
<a name="l00333"></a>00333                     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Freeing entry for msgid %ld\n&quot;</span>,
<a name="l00334"></a>00334                                 msgid));
<a name="l00335"></a>00335                     krb5_auth_con_free(kcontext, entry-&gt;auth_context);
<a name="l00336"></a>00336                     free(entry-&gt;secName);
<a name="l00337"></a>00337                     entry1-&gt;next = entry-&gt;next;
<a name="l00338"></a>00338                     free(entry);
<a name="l00339"></a>00339                 }
<a name="l00340"></a>00340 
<a name="l00341"></a>00341                 <span class="keywordflow">return</span>;
<a name="l00342"></a>00342             }
<a name="l00343"></a>00343 
<a name="l00344"></a>00344     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l00345"></a>00345                 <span class="stringliteral">&quot;KSM: Unable to decrement cache entry for msgid %ld.\n&quot;</span>,
<a name="l00346"></a>00346                 msgid));
<a name="l00347"></a>00347 }
<a name="l00348"></a>00348 
<a name="l00349"></a>00349 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00350"></a>00350 ksm_increment_ref_count(<span class="keywordtype">long</span> msgid)
<a name="l00351"></a>00351 {
<a name="l00352"></a>00352     <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *entry = ksm_get_cache(msgid);
<a name="l00353"></a>00353 
<a name="l00354"></a>00354     <span class="keywordflow">if</span> (!entry) {
<a name="l00355"></a>00355         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to find cache entry for msgid %ld &quot;</span>
<a name="l00356"></a>00356                     <span class="stringliteral">&quot;for increment\n&quot;</span>, msgid));
<a name="l00357"></a>00357         <span class="keywordflow">return</span>;
<a name="l00358"></a>00358     }
<a name="l00359"></a>00359 
<a name="l00360"></a>00360     entry-&gt;refcount++;
<a name="l00361"></a>00361 }
<a name="l00362"></a>00362 
<a name="l00363"></a>00363 <span class="comment">/*</span>
<a name="l00364"></a>00364 <span class="comment"> * Initialize specific session information (right now, just set up things to</span>
<a name="l00365"></a>00365 <span class="comment"> * not do an engineID probe)</span>
<a name="l00366"></a>00366 <span class="comment"> */</span>
<a name="l00367"></a>00367 
<a name="l00368"></a>00368 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00369"></a>00369 ksm_session_init(<a class="code" href="structsnmp__session.html" title="The snmp session structure.">netsnmp_session</a> * sess)
<a name="l00370"></a>00370 {
<a name="l00371"></a>00371     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l00372"></a>00372                 <span class="stringliteral">&quot;KSM: Reached our session initialization callback\n&quot;</span>));
<a name="l00373"></a>00373 
<a name="l00374"></a>00374     sess-&gt;flags |= SNMP_FLAGS_DONT_PROBE;
<a name="l00375"></a>00375 
<a name="l00376"></a>00376     <span class="keywordflow">return</span> SNMPERR_SUCCESS;
<a name="l00377"></a>00377 }
<a name="l00378"></a>00378 
<a name="l00379"></a>00379 <span class="comment">/*</span>
<a name="l00380"></a>00380 <span class="comment"> * Free our state information (this is only done on the agent side)</span>
<a name="l00381"></a>00381 <span class="comment"> */</span>
<a name="l00382"></a>00382 
<a name="l00383"></a>00383 <span class="keyword">static</span> <span class="keywordtype">void</span>
<a name="l00384"></a>00384 ksm_free_state_ref(<span class="keywordtype">void</span> *ptr)
<a name="l00385"></a>00385 {
<a name="l00386"></a>00386     <span class="keyword">struct </span><a class="code" href="structksm__secStateRef.html">ksm_secStateRef</a> *ref = (<span class="keyword">struct </span><a class="code" href="structksm__secStateRef.html">ksm_secStateRef</a> *) ptr;
<a name="l00387"></a>00387 
<a name="l00388"></a>00388     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Freeing state reference\n&quot;</span>));
<a name="l00389"></a>00389 
<a name="l00390"></a>00390     krb5_auth_con_free(kcontext, ref-&gt;auth_context);
<a name="l00391"></a>00391 
<a name="l00392"></a>00392     free(ref);
<a name="l00393"></a>00393 }
<a name="l00394"></a>00394 
<a name="l00395"></a>00395 <span class="comment">/*</span>
<a name="l00396"></a>00396 <span class="comment"> * This is called when the PDU is freed; this will decrement reference counts</span>
<a name="l00397"></a>00397 <span class="comment"> * for entries in our state cache.</span>
<a name="l00398"></a>00398 <span class="comment"> */</span>
<a name="l00399"></a>00399 
<a name="l00400"></a>00400 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00401"></a>00401 ksm_free_pdu(<a class="code" href="structsnmp__pdu.html" title="The snmp protocol data unit.">netsnmp_pdu</a> *pdu)
<a name="l00402"></a>00402 {
<a name="l00403"></a>00403     ksm_decrement_ref_count(pdu-&gt;<a class="code" href="structsnmp__pdu.html#a528226bcca644a9d42d63392fb9e6676" title="Message id for V3 messages note: incremented for each retry.">msgid</a>);
<a name="l00404"></a>00404 
<a name="l00405"></a>00405     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Decrementing cache entry for PDU msgid %ld\n&quot;</span>,
<a name="l00406"></a>00406                 pdu-&gt;<a class="code" href="structsnmp__pdu.html#a528226bcca644a9d42d63392fb9e6676" title="Message id for V3 messages note: incremented for each retry.">msgid</a>));
<a name="l00407"></a>00407 
<a name="l00408"></a>00408     <span class="keywordflow">return</span> SNMPERR_SUCCESS;
<a name="l00409"></a>00409 }
<a name="l00410"></a>00410 
<a name="l00411"></a>00411 <span class="comment">/*</span>
<a name="l00412"></a>00412 <span class="comment"> * This is called when a PDU is cloned (to increase reference counts)</span>
<a name="l00413"></a>00413 <span class="comment"> */</span>
<a name="l00414"></a>00414 
<a name="l00415"></a>00415 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00416"></a>00416 ksm_clone_pdu(<a class="code" href="structsnmp__pdu.html" title="The snmp protocol data unit.">netsnmp_pdu</a> *pdu, <a class="code" href="structsnmp__pdu.html" title="The snmp protocol data unit.">netsnmp_pdu</a> *pdu2)
<a name="l00417"></a>00417 {
<a name="l00418"></a>00418     ksm_increment_ref_count(pdu-&gt;<a class="code" href="structsnmp__pdu.html#a528226bcca644a9d42d63392fb9e6676" title="Message id for V3 messages note: incremented for each retry.">msgid</a>);
<a name="l00419"></a>00419 
<a name="l00420"></a>00420     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Incrementing cache entry for PDU msgid %ld\n&quot;</span>,
<a name="l00421"></a>00421                 pdu-&gt;<a class="code" href="structsnmp__pdu.html#a528226bcca644a9d42d63392fb9e6676" title="Message id for V3 messages note: incremented for each retry.">msgid</a>));
<a name="l00422"></a>00422 
<a name="l00423"></a>00423     <span class="keywordflow">return</span> SNMPERR_SUCCESS;
<a name="l00424"></a>00424 }
<a name="l00425"></a>00425 
<a name="l00426"></a>00426 <span class="comment">/****************************************************************************</span>
<a name="l00427"></a>00427 <span class="comment"> *</span>
<a name="l00428"></a>00428 <span class="comment"> * ksm_generate_out_msg</span>
<a name="l00429"></a>00429 <span class="comment"> *</span>
<a name="l00430"></a>00430 <span class="comment"> * Parameters:</span>
<a name="l00431"></a>00431 <span class="comment"> *      (See list below...)</span>
<a name="l00432"></a>00432 <span class="comment"> *</span>
<a name="l00433"></a>00433 <span class="comment"> * Returns:</span>
<a name="l00434"></a>00434 <span class="comment"> *      SNMPERR_GENERIC                        On success.</span>
<a name="l00435"></a>00435 <span class="comment"> *      SNMPERR_KRB5</span>
<a name="l00436"></a>00436 <span class="comment"> *      ... and others</span>
<a name="l00437"></a>00437 <span class="comment"> *</span>
<a name="l00438"></a>00438 <span class="comment"> *</span>
<a name="l00439"></a>00439 <span class="comment"> * Generate an outgoing message.</span>
<a name="l00440"></a>00440 <span class="comment"> *</span>
<a name="l00441"></a>00441 <span class="comment"> ****************************************************************************/</span>
<a name="l00442"></a>00442 
<a name="l00443"></a>00443 <span class="keywordtype">int</span>
<a name="l00444"></a>00444 ksm_rgenerate_out_msg(<span class="keyword">struct</span> <a class="code" href="structsnmp__secmod__outgoing__params.html">snmp_secmod_outgoing_params</a> *parms)
<a name="l00445"></a>00445 {
<a name="l00446"></a>00446     krb5_auth_context auth_context = NULL;
<a name="l00447"></a>00447     krb5_error_code retcode;
<a name="l00448"></a>00448     krb5_ccache     cc = NULL;
<a name="l00449"></a>00449     <span class="keywordtype">int</span>             retval = SNMPERR_SUCCESS;
<a name="l00450"></a>00450     krb5_data       outdata, ivector;
<a name="l00451"></a>00451     krb5_keyblock  *subkey = NULL;
<a name="l00452"></a>00452 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l00453"></a>00453 <span class="preprocessor"></span>    krb5_data       input;
<a name="l00454"></a>00454     krb5_enc_data   output;
<a name="l00455"></a>00455     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>    numcksumtypes;
<a name="l00456"></a>00456     krb5_cksumtype  *cksumtype_array;
<a name="l00457"></a>00457 <span class="preprocessor">#elif defined OLD_HEIMDAL       </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00458"></a>00458     krb5_crypto heim_crypto = NULL;
<a name="l00459"></a>00459 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00460"></a>00460     krb5_encrypt_block eblock;
<a name="l00461"></a>00461 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00462"></a>00462     <span class="keywordtype">size_t</span>          blocksize, encrypted_length;
<a name="l00463"></a>00463     <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>  *encrypted_data = NULL;
<a name="l00464"></a>00464     <span class="keywordtype">int</span>             zero = 0, i;
<a name="l00465"></a>00465     u_char         *cksum_pointer, *endp = *parms-&gt;wholeMsg;
<a name="l00466"></a>00466     krb5_cksumtype  cksumtype;
<a name="l00467"></a>00467     krb5_checksum   pdu_checksum;
<a name="l00468"></a>00468     u_char         **wholeMsg = parms-&gt;wholeMsg;
<a name="l00469"></a>00469     <span class="keywordtype">size_t</span>         *offset = parms-&gt;wholeMsgOffset, seq_offset;
<a name="l00470"></a>00470     <span class="keyword">struct </span><a class="code" href="structksm__secStateRef.html">ksm_secStateRef</a> *ksm_state = (<span class="keyword">struct </span><a class="code" href="structksm__secStateRef.html">ksm_secStateRef</a> *)
<a name="l00471"></a>00471         parms-&gt;secStateRef;
<a name="l00472"></a>00472 #ifdef OLD_HEIMDAL
<a name="l00473"></a>00473     krb5_data encrypted_scoped_pdu;
<a name="l00474"></a>00474 #endif                          <span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00475"></a>00475     <span class="keywordtype">int</span> rc;
<a name="l00476"></a>00476     <span class="keywordtype">char</span> *colon = NULL;
<a name="l00477"></a>00477 
<a name="l00478"></a>00478     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Starting KSM processing\n&quot;</span>));
<a name="l00479"></a>00479 
<a name="l00480"></a>00480     outdata.length = 0;
<a name="l00481"></a>00481     outdata.data = NULL;
<a name="l00482"></a>00482     ivector.length = 0;
<a name="l00483"></a>00483     ivector.data = NULL;
<a name="l00484"></a>00484     CHECKSUM_CONTENTS(&amp;pdu_checksum) = NULL;
<a name="l00485"></a>00485 
<a name="l00486"></a>00486     <span class="keywordflow">if</span> (!ksm_state) {
<a name="l00487"></a>00487         <span class="comment">/*</span>
<a name="l00488"></a>00488 <span class="comment">         * If we&#39;ve got a port number as part of the &quot;peername&quot;, then</span>
<a name="l00489"></a>00489 <span class="comment">         * suppress this (temporarily) while we build the credential info.</span>
<a name="l00490"></a>00490 <span class="comment">         *   XXX - what about &quot;udp:host&quot; style addresses?</span>
<a name="l00491"></a>00491 <span class="comment">         */</span>
<a name="l00492"></a>00492         colon = strrchr(params-&gt;session-&gt;peername, <span class="charliteral">&#39;:&#39;</span>);
<a name="l00493"></a>00493         <span class="keywordflow">if</span> (colon != NULL) {
<a name="l00494"></a>00494             *colon=<span class="charliteral">&#39;\0&#39;</span>;
<a name="l00495"></a>00495         }
<a name="l00496"></a>00496 
<a name="l00497"></a>00497         <span class="comment">/*</span>
<a name="l00498"></a>00498 <span class="comment">         * If we don&#39;t have a ksm_state, then we&#39;re a request.  Get a</span>
<a name="l00499"></a>00499 <span class="comment">         * credential cache and build a ap_req.</span>
<a name="l00500"></a>00500 <span class="comment">         */</span>
<a name="l00501"></a>00501         retcode = krb5_cc_default(kcontext, &amp;cc);
<a name="l00502"></a>00502 
<a name="l00503"></a>00503         <span class="keywordflow">if</span> (retcode) {
<a name="l00504"></a>00504             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: krb5_cc_default failed: %s\n&quot;</span>,
<a name="l00505"></a>00505                         error_message(retcode)));
<a name="l00506"></a>00506             snmp_set_detail(error_message(retcode));
<a name="l00507"></a>00507             retval = SNMPERR_KRB5;
<a name="l00508"></a>00508             <span class="keywordflow">goto</span> error;
<a name="l00509"></a>00509         }
<a name="l00510"></a>00510 
<a name="l00511"></a>00511         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Set credential cache successfully\n&quot;</span>));
<a name="l00512"></a>00512 
<a name="l00513"></a>00513         <span class="comment">/*</span>
<a name="l00514"></a>00514 <span class="comment">         * This seems odd, since we don&#39;t need this until later (or earlier,</span>
<a name="l00515"></a>00515 <span class="comment">         * depending on how you look at it), but because the most likely</span>
<a name="l00516"></a>00516 <span class="comment">         * errors are Kerberos at this point, I&#39;ll get this now to save</span>
<a name="l00517"></a>00517 <span class="comment">         * time not encoding the rest of the packet.</span>
<a name="l00518"></a>00518 <span class="comment">         *</span>
<a name="l00519"></a>00519 <span class="comment">         * Also, we need the subkey to encrypt the PDU (if required).</span>
<a name="l00520"></a>00520 <span class="comment">         */</span>
<a name="l00521"></a>00521 
<a name="l00522"></a>00522         retcode =
<a name="l00523"></a>00523             krb5_mk_req(kcontext, &amp;auth_context,
<a name="l00524"></a>00524                         AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY,
<a name="l00525"></a>00525                         (<span class="keywordtype">char</span> *) service_name, parms-&gt;session-&gt;<a class="code" href="structsnmp__session.html#a6651007c1d156f67f99d54d84aac09b9" title="name or address of default peer (may include transport specifier and/or port number)">peername</a>, NULL,
<a name="l00526"></a>00526                         cc, &amp;outdata);
<a name="l00527"></a>00527 
<a name="l00528"></a>00528         <span class="keywordflow">if</span> (colon != NULL)
<a name="l00529"></a>00529             *colon=<span class="charliteral">&#39;:&#39;</span>;
<a name="l00530"></a>00530 
<a name="l00531"></a>00531         <span class="keywordflow">if</span> (retcode) {
<a name="l00532"></a>00532             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: krb5_mk_req failed: %s\n&quot;</span>,
<a name="l00533"></a>00533                         error_message(retcode)));
<a name="l00534"></a>00534             snmp_set_detail(error_message(retcode));
<a name="l00535"></a>00535             retval = SNMPERR_KRB5;
<a name="l00536"></a>00536             <span class="keywordflow">goto</span> error;
<a name="l00537"></a>00537         }
<a name="l00538"></a>00538 
<a name="l00539"></a>00539         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: ticket retrieved successfully for \&quot;%s/%s\&quot; &quot;</span>
<a name="l00540"></a>00540                     <span class="stringliteral">&quot;(may not be actual ticket sname)\n&quot;</span>, service_name,
<a name="l00541"></a>00541                     parms-&gt;session-&gt;<a class="code" href="structsnmp__session.html#a6651007c1d156f67f99d54d84aac09b9" title="name or address of default peer (may include transport specifier and/or port number)">peername</a>));
<a name="l00542"></a>00542 
<a name="l00543"></a>00543     } <span class="keywordflow">else</span> {
<a name="l00544"></a>00544 
<a name="l00545"></a>00545         <span class="comment">/*</span>
<a name="l00546"></a>00546 <span class="comment">         * Grab the auth_context from our security state reference</span>
<a name="l00547"></a>00547 <span class="comment">         */</span>
<a name="l00548"></a>00548 
<a name="l00549"></a>00549         auth_context = ksm_state-&gt;auth_context;
<a name="l00550"></a>00550 
<a name="l00551"></a>00551         <span class="comment">/*</span>
<a name="l00552"></a>00552 <span class="comment">         * Bundle up an AP_REP.  Note that we do this only when we</span>
<a name="l00553"></a>00553 <span class="comment">         * have a security state reference (which means we&#39;re in an agent</span>
<a name="l00554"></a>00554 <span class="comment">         * and we&#39;re sending a response).</span>
<a name="l00555"></a>00555 <span class="comment">         */</span>
<a name="l00556"></a>00556 
<a name="l00557"></a>00557         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Starting reply processing.\n&quot;</span>));
<a name="l00558"></a>00558 
<a name="l00559"></a>00559         retcode = krb5_mk_rep(kcontext, auth_context, &amp;outdata);
<a name="l00560"></a>00560 
<a name="l00561"></a>00561         <span class="keywordflow">if</span> (retcode) {
<a name="l00562"></a>00562             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: krb5_mk_rep failed: %s\n&quot;</span>,
<a name="l00563"></a>00563                         error_message(retcode)));
<a name="l00564"></a>00564             snmp_set_detail(error_message(retcode));
<a name="l00565"></a>00565             retval = SNMPERR_KRB5;
<a name="l00566"></a>00566             <span class="keywordflow">goto</span> error;
<a name="l00567"></a>00567         }
<a name="l00568"></a>00568 
<a name="l00569"></a>00569         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Finished with krb5_mk_rep()\n&quot;</span>));
<a name="l00570"></a>00570     }
<a name="l00571"></a>00571 
<a name="l00572"></a>00572     <span class="comment">/*</span>
<a name="l00573"></a>00573 <span class="comment">     * If we have to encrypt the PDU, do that now</span>
<a name="l00574"></a>00574 <span class="comment">     */</span>
<a name="l00575"></a>00575 
<a name="l00576"></a>00576     <span class="keywordflow">if</span> (parms-&gt;secLevel == SNMP_SEC_LEVEL_AUTHPRIV) {
<a name="l00577"></a>00577 
<a name="l00578"></a>00578         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Starting PDU encryption.\n&quot;</span>));
<a name="l00579"></a>00579 
<a name="l00580"></a>00580         <span class="comment">/*</span>
<a name="l00581"></a>00581 <span class="comment">         * It&#39;s weird -</span>
<a name="l00582"></a>00582 <span class="comment">         *</span>
<a name="l00583"></a>00583 <span class="comment">         * If we&#39;re on the manager, it&#39;s a local subkey (because that&#39;s in</span>
<a name="l00584"></a>00584 <span class="comment">         * our AP_REQ)</span>
<a name="l00585"></a>00585 <span class="comment">         *</span>
<a name="l00586"></a>00586 <span class="comment">         * If we&#39;re on the agent, it&#39;s a remote subkey (because that comes</span>
<a name="l00587"></a>00587 <span class="comment">         * FROM the received AP_REQ).</span>
<a name="l00588"></a>00588 <span class="comment">         */</span>
<a name="l00589"></a>00589 
<a name="l00590"></a>00590         <span class="keywordflow">if</span> (ksm_state)
<a name="l00591"></a>00591             retcode = krb5_auth_con_getremotesubkey(kcontext, auth_context,
<a name="l00592"></a>00592                                                     &amp;subkey);
<a name="l00593"></a>00593         <span class="keywordflow">else</span>
<a name="l00594"></a>00594             retcode = krb5_auth_con_getlocalsubkey(kcontext, auth_context,
<a name="l00595"></a>00595                                                    &amp;subkey);
<a name="l00596"></a>00596 
<a name="l00597"></a>00597         <span class="keywordflow">if</span> (retcode) {
<a name="l00598"></a>00598             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l00599"></a>00599                         <span class="stringliteral">&quot;KSM: krb5_auth_con_getlocalsubkey failed: %s\n&quot;</span>,
<a name="l00600"></a>00600                         error_message(retcode)));
<a name="l00601"></a>00601             snmp_set_detail(error_message(retcode));
<a name="l00602"></a>00602             retval = SNMPERR_KRB5;
<a name="l00603"></a>00603             <span class="keywordflow">goto</span> error;
<a name="l00604"></a>00604         }
<a name="l00605"></a>00605 
<a name="l00606"></a>00606         <span class="comment">/*</span>
<a name="l00607"></a>00607 <span class="comment">         * Note that here we need to handle different things between the</span>
<a name="l00608"></a>00608 <span class="comment">         * old and new crypto APIs.  First, we need to get the final encrypted</span>
<a name="l00609"></a>00609 <span class="comment">         * length of the PDU.</span>
<a name="l00610"></a>00610 <span class="comment">         */</span>
<a name="l00611"></a>00611 
<a name="l00612"></a>00612 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l00613"></a>00613 <span class="preprocessor"></span>        retcode = krb5_c_encrypt_length(kcontext, subkey-&gt;enctype,
<a name="l00614"></a>00614                                         parms-&gt;scopedPduLen,
<a name="l00615"></a>00615                                         &amp;encrypted_length);
<a name="l00616"></a>00616 
<a name="l00617"></a>00617         <span class="keywordflow">if</span> (retcode) {
<a name="l00618"></a>00618             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l00619"></a>00619                         <span class="stringliteral">&quot;Encryption length calculation failed: %s\n&quot;</span>,
<a name="l00620"></a>00620                         error_message(retcode)));
<a name="l00621"></a>00621             snmp_set_detail(error_message(retcode));
<a name="l00622"></a>00622             retval = SNMPERR_KRB5;
<a name="l00623"></a>00623             <span class="keywordflow">goto</span> error;
<a name="l00624"></a>00624         }
<a name="l00625"></a>00625 <span class="preprocessor">#elif defined OLD_HEIMDAL</span>
<a name="l00626"></a>00626 <span class="preprocessor"></span>        retcode = krb5_crypto_init(kcontext, subkey, 0, &amp;heim_crypto);
<a name="l00627"></a>00627         <span class="keywordflow">if</span> (retcode) {
<a name="l00628"></a>00628             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_crypto_init failed: %s\n&quot;</span>,
<a name="l00629"></a>00629                         error_message(retcode)));
<a name="l00630"></a>00630             snmp_set_detail(error_message(retcode));
<a name="l00631"></a>00631             retval = SNMPERR_KRB5;
<a name="l00632"></a>00632             <span class="keywordflow">goto</span> error;
<a name="l00633"></a>00633         }
<a name="l00634"></a>00634         encrypted_length = krb5_get_wrapped_length(kcontext, heim_crypto,
<a name="l00635"></a>00635                                                    parms-&gt;scopedPduLen);
<a name="l00636"></a>00636 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00637"></a>00637 
<a name="l00638"></a>00638         krb5_use_enctype(kcontext, &amp;eblock, subkey-&gt;enctype);
<a name="l00639"></a>00639         retcode = krb5_process_key(kcontext, &amp;eblock, subkey);
<a name="l00640"></a>00640 
<a name="l00641"></a>00641         <span class="keywordflow">if</span> (retcode) {
<a name="l00642"></a>00642             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_process_key failed: %s\n&quot;</span>,
<a name="l00643"></a>00643                         error_message(retcode)));
<a name="l00644"></a>00644             snmp_set_detail(error_message(retcode));
<a name="l00645"></a>00645             retval = SNMPERR_KRB5;
<a name="l00646"></a>00646             <span class="keywordflow">goto</span> error;
<a name="l00647"></a>00647         }
<a name="l00648"></a>00648 
<a name="l00649"></a>00649         encrypted_length = krb5_encrypt_size(parms-&gt;scopedPduLen,
<a name="l00650"></a>00650                                              eblock.crypto_entry);
<a name="l00651"></a>00651 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00652"></a>00652 
<a name="l00653"></a>00653 <span class="preprocessor">#ifndef OLD_HEIMDAL </span><span class="comment">/* since heimdal allocs the space for us */</span>
<a name="l00654"></a>00654         encrypted_data = malloc(encrypted_length);
<a name="l00655"></a>00655 
<a name="l00656"></a>00656         <span class="keywordflow">if</span> (!encrypted_data) {
<a name="l00657"></a>00657             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l00658"></a>00658                         <span class="stringliteral">&quot;KSM: Unable to malloc %d bytes for encrypt &quot;</span>
<a name="l00659"></a>00659                         <span class="stringliteral">&quot;buffer: %s\n&quot;</span>, parms-&gt;scopedPduLen,
<a name="l00660"></a>00660                         strerror(errno)));
<a name="l00661"></a>00661             retval = SNMPERR_MALLOC;
<a name="l00662"></a>00662 <span class="preprocessor">#ifndef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l00663"></a>00663 <span class="preprocessor"></span>            krb5_finish_key(kcontext, &amp;eblock);
<a name="l00664"></a>00664 <span class="preprocessor">#endif                          </span><span class="comment">/* ! NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00665"></a>00665 
<a name="l00666"></a>00666             <span class="keywordflow">goto</span> error;
<a name="l00667"></a>00667         }
<a name="l00668"></a>00668 <span class="preprocessor">#endif </span><span class="comment">/* ! OLD_HEIMDAL */</span>
<a name="l00669"></a>00669 
<a name="l00670"></a>00670         <span class="comment">/*</span>
<a name="l00671"></a>00671 <span class="comment">         * We need to set up a blank initialization vector for the encryption.</span>
<a name="l00672"></a>00672 <span class="comment">         * Use a block of all zero&#39;s (which is dependent on the block size</span>
<a name="l00673"></a>00673 <span class="comment">         * of the encryption method).</span>
<a name="l00674"></a>00674 <span class="comment">         */</span>
<a name="l00675"></a>00675 
<a name="l00676"></a>00676 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l00677"></a>00677 <span class="preprocessor"></span>
<a name="l00678"></a>00678         retcode = krb5_c_block_size(kcontext, subkey-&gt;enctype, &amp;blocksize);
<a name="l00679"></a>00679 
<a name="l00680"></a>00680         <span class="keywordflow">if</span> (retcode) {
<a name="l00681"></a>00681             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l00682"></a>00682                         <span class="stringliteral">&quot;Unable to determine crypto block size: %s\n&quot;</span>,
<a name="l00683"></a>00683                         error_message(retcode)));
<a name="l00684"></a>00684             snmp_set_detail(error_message(retcode));
<a name="l00685"></a>00685             retval = SNMPERR_KRB5;
<a name="l00686"></a>00686             <span class="keywordflow">goto</span> error;
<a name="l00687"></a>00687         }
<a name="l00688"></a>00688 <span class="preprocessor">#elif defined (OLD_HEIMDAL)     </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00689"></a>00689 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00690"></a>00690 
<a name="l00691"></a>00691         blocksize =
<a name="l00692"></a>00692             krb5_enctype_array[subkey-&gt;enctype]-&gt;system-&gt;block_length;
<a name="l00693"></a>00693 
<a name="l00694"></a>00694 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00695"></a>00695 
<a name="l00696"></a>00696 <span class="preprocessor">#ifndef OLD_HEIMDAL     </span><span class="comment">/* since allocs the space for us */</span>
<a name="l00697"></a>00697         ivector.data = malloc(blocksize);
<a name="l00698"></a>00698 
<a name="l00699"></a>00699         <span class="keywordflow">if</span> (!ivector.data) {
<a name="l00700"></a>00700             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to allocate %d bytes for ivector\n&quot;</span>,
<a name="l00701"></a>00701                         blocksize));
<a name="l00702"></a>00702             retval = SNMPERR_MALLOC;
<a name="l00703"></a>00703             <span class="keywordflow">goto</span> error;
<a name="l00704"></a>00704         }
<a name="l00705"></a>00705 
<a name="l00706"></a>00706         ivector.length = blocksize;
<a name="l00707"></a>00707         memset(ivector.data, 0, blocksize);
<a name="l00708"></a>00708 <span class="preprocessor">#endif </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00709"></a>00709 
<a name="l00710"></a>00710         <span class="comment">/*</span>
<a name="l00711"></a>00711 <span class="comment">         * Finally!  Do the encryption!</span>
<a name="l00712"></a>00712 <span class="comment">         */</span>
<a name="l00713"></a>00713 
<a name="l00714"></a>00714 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l00715"></a>00715 <span class="preprocessor"></span>
<a name="l00716"></a>00716         input.data = (<span class="keywordtype">char</span> *) parms-&gt;scopedPdu;
<a name="l00717"></a>00717         input.length = parms-&gt;scopedPduLen;
<a name="l00718"></a>00718         output.ciphertext.data = (<span class="keywordtype">char</span> *) encrypted_data;
<a name="l00719"></a>00719         output.ciphertext.length = encrypted_length;
<a name="l00720"></a>00720 
<a name="l00721"></a>00721         retcode =
<a name="l00722"></a>00722             krb5_c_encrypt(kcontext, subkey, KSM_KEY_USAGE_ENCRYPTION,
<a name="l00723"></a>00723                            &amp;ivector, &amp;input, &amp;output);
<a name="l00724"></a>00724 
<a name="l00725"></a>00725 <span class="preprocessor">#elif defined OLD_HEIMDAL </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00726"></a>00726 
<a name="l00727"></a>00727         krb5_data_zero(&amp;encrypted_scoped_pdu);
<a name="l00728"></a>00728         retcode = krb5_encrypt(kcontext, heim_crypto, KSM_KEY_USAGE_ENCRYPTION,
<a name="l00729"></a>00729                                parms-&gt;scopedPdu, parms-&gt;scopedPduLen,
<a name="l00730"></a>00730                                &amp;encrypted_scoped_pdu);
<a name="l00731"></a>00731         <span class="keywordflow">if</span> (retcode == 0) {
<a name="l00732"></a>00732                 encrypted_length = encrypted_scoped_pdu.length;
<a name="l00733"></a>00733                 encrypted_data = encrypted_scoped_pdu.data;
<a name="l00734"></a>00734                 krb5_data_zero(&amp;encrypted_scoped_pdu);
<a name="l00735"></a>00735         }
<a name="l00736"></a>00736 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00737"></a>00737 
<a name="l00738"></a>00738         retcode = krb5_encrypt(kcontext, (krb5_pointer) parms-&gt;scopedPdu,
<a name="l00739"></a>00739                                (krb5_pointer) encrypted_data,
<a name="l00740"></a>00740                                parms-&gt;scopedPduLen, &amp;eblock, ivector.data);
<a name="l00741"></a>00741 
<a name="l00742"></a>00742         krb5_finish_key(kcontext, &amp;eblock);
<a name="l00743"></a>00743 
<a name="l00744"></a>00744 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00745"></a>00745 
<a name="l00746"></a>00746         <span class="keywordflow">if</span> (retcode) {
<a name="l00747"></a>00747             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: krb5_encrypt failed: %s\n&quot;</span>,
<a name="l00748"></a>00748                         error_message(retcode)));
<a name="l00749"></a>00749             retval = SNMPERR_KRB5;
<a name="l00750"></a>00750             snmp_set_detail(error_message(retcode));
<a name="l00751"></a>00751             <span class="keywordflow">goto</span> error;
<a name="l00752"></a>00752         }
<a name="l00753"></a>00753 
<a name="l00754"></a>00754         *offset = 0;
<a name="l00755"></a>00755 
<a name="l00756"></a>00756         rc = asn_realloc_rbuild_string(wholeMsg, parms-&gt;wholeMsgLen,
<a name="l00757"></a>00757                                              offset, 1,
<a name="l00758"></a>00758                                              (u_char) (ASN_UNIVERSAL |
<a name="l00759"></a>00759                                                        ASN_PRIMITIVE |
<a name="l00760"></a>00760                                                        ASN_OCTET_STR),
<a name="l00761"></a>00761                                              encrypted_data,
<a name="l00762"></a>00762                                              encrypted_length);
<a name="l00763"></a>00763 
<a name="l00764"></a>00764         <span class="keywordflow">if</span> (rc == 0) {
<a name="l00765"></a>00765             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building encrypted payload failed.\n&quot;</span>));
<a name="l00766"></a>00766             retval = SNMPERR_TOO_LONG;
<a name="l00767"></a>00767             <span class="keywordflow">goto</span> error;
<a name="l00768"></a>00768         }
<a name="l00769"></a>00769 
<a name="l00770"></a>00770         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Encryption complete.\n&quot;</span>));
<a name="l00771"></a>00771 
<a name="l00772"></a>00772     } <span class="keywordflow">else</span> {
<a name="l00773"></a>00773         <span class="comment">/*</span>
<a name="l00774"></a>00774 <span class="comment">         * Plaintext PDU (not encrypted)</span>
<a name="l00775"></a>00775 <span class="comment">         */</span>
<a name="l00776"></a>00776 
<a name="l00777"></a>00777         <span class="keywordflow">if</span> (*parms-&gt;wholeMsgLen &lt; parms-&gt;scopedPduLen) {
<a name="l00778"></a>00778             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Not enough room for plaintext PDU.\n&quot;</span>));
<a name="l00779"></a>00779             retval = SNMPERR_TOO_LONG;
<a name="l00780"></a>00780             <span class="keywordflow">goto</span> error;
<a name="l00781"></a>00781         }
<a name="l00782"></a>00782     }
<a name="l00783"></a>00783 
<a name="l00784"></a>00784     <span class="comment">/*</span>
<a name="l00785"></a>00785 <span class="comment">     * Start encoding the msgSecurityParameters</span>
<a name="l00786"></a>00786 <span class="comment">     *</span>
<a name="l00787"></a>00787 <span class="comment">     * For now, use 0 for the response hint</span>
<a name="l00788"></a>00788 <span class="comment">     */</span>
<a name="l00789"></a>00789 
<a name="l00790"></a>00790     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: scopedPdu added to payload\n&quot;</span>));
<a name="l00791"></a>00791 
<a name="l00792"></a>00792     seq_offset = *offset;
<a name="l00793"></a>00793 
<a name="l00794"></a>00794     rc = asn_realloc_rbuild_int(wholeMsg, parms-&gt;wholeMsgLen,
<a name="l00795"></a>00795                                       offset, 1,
<a name="l00796"></a>00796                                       (u_char) (ASN_UNIVERSAL |
<a name="l00797"></a>00797                                                 ASN_PRIMITIVE |
<a name="l00798"></a>00798                                                 ASN_INTEGER),
<a name="l00799"></a>00799                                       (<span class="keywordtype">long</span> *) &amp;zero, <span class="keyword">sizeof</span>(zero));
<a name="l00800"></a>00800 
<a name="l00801"></a>00801     <span class="keywordflow">if</span> (rc == 0) {
<a name="l00802"></a>00802         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building ksm security parameters failed.\n&quot;</span>));
<a name="l00803"></a>00803         retval = SNMPERR_TOO_LONG;
<a name="l00804"></a>00804         <span class="keywordflow">goto</span> error;
<a name="l00805"></a>00805     }
<a name="l00806"></a>00806 
<a name="l00807"></a>00807     rc = asn_realloc_rbuild_string(wholeMsg, parms-&gt;wholeMsgLen,
<a name="l00808"></a>00808                                          offset, 1,
<a name="l00809"></a>00809                                          (u_char) (ASN_UNIVERSAL |
<a name="l00810"></a>00810                                                    ASN_PRIMITIVE |
<a name="l00811"></a>00811                                                    ASN_OCTET_STR),
<a name="l00812"></a>00812                                          (u_char *) outdata.data,
<a name="l00813"></a>00813                                          outdata.length);
<a name="l00814"></a>00814 
<a name="l00815"></a>00815     <span class="keywordflow">if</span> (rc == 0) {
<a name="l00816"></a>00816         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building ksm AP_REQ failed.\n&quot;</span>));
<a name="l00817"></a>00817         retval = SNMPERR_TOO_LONG;
<a name="l00818"></a>00818         <span class="keywordflow">goto</span> error;
<a name="l00819"></a>00819     }
<a name="l00820"></a>00820 
<a name="l00821"></a>00821     <span class="comment">/*</span>
<a name="l00822"></a>00822 <span class="comment">     * If we didn&#39;t encrypt the packet, we haven&#39;t yet got the subkey.</span>
<a name="l00823"></a>00823 <span class="comment">     * Get that now.</span>
<a name="l00824"></a>00824 <span class="comment">     */</span>
<a name="l00825"></a>00825 
<a name="l00826"></a>00826     <span class="keywordflow">if</span> (!subkey) {
<a name="l00827"></a>00827         <span class="keywordflow">if</span> (ksm_state)
<a name="l00828"></a>00828             retcode = krb5_auth_con_getremotesubkey(kcontext, auth_context,
<a name="l00829"></a>00829                                                     &amp;subkey);
<a name="l00830"></a>00830         <span class="keywordflow">else</span>
<a name="l00831"></a>00831             retcode = krb5_auth_con_getlocalsubkey(kcontext, auth_context,
<a name="l00832"></a>00832                                                    &amp;subkey);
<a name="l00833"></a>00833         <span class="keywordflow">if</span> (retcode) {
<a name="l00834"></a>00834             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_auth_con_getlocalsubkey failed: %s\n&quot;</span>,
<a name="l00835"></a>00835                         error_message(retcode)));
<a name="l00836"></a>00836             snmp_set_detail(error_message(retcode));
<a name="l00837"></a>00837             retval = SNMPERR_KRB5;
<a name="l00838"></a>00838             <span class="keywordflow">goto</span> error;
<a name="l00839"></a>00839         }
<a name="l00840"></a>00840 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l00841"></a>00841 <span class="preprocessor"></span>         retcode = krb5_crypto_init(kcontext, subkey, 0, &amp;heim_crypto);
<a name="l00842"></a>00842         <span class="keywordflow">if</span> (retcode) {
<a name="l00843"></a>00843             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_crypto_init failed: %s\n&quot;</span>,
<a name="l00844"></a>00844                         error_message(retcode)));
<a name="l00845"></a>00845             snmp_set_detail(error_message(retcode));
<a name="l00846"></a>00846             retval = SNMPERR_KRB5;
<a name="l00847"></a>00847             <span class="keywordflow">goto</span> error;
<a name="l00848"></a>00848         }
<a name="l00849"></a>00849 <span class="preprocessor">#endif                                  </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00850"></a>00850     }
<a name="l00851"></a>00851 
<a name="l00852"></a>00852     <span class="comment">/*</span>
<a name="l00853"></a>00853 <span class="comment">     * Now, we need to pick the &quot;right&quot; checksum algorithm.  For old</span>
<a name="l00854"></a>00854 <span class="comment">     * crypto, just pick CKSUMTYPE_RSA_MD5_DES; for new crypto, pick</span>
<a name="l00855"></a>00855 <span class="comment">     * one of the &quot;approved&quot; ones.</span>
<a name="l00856"></a>00856 <span class="comment">     */</span>
<a name="l00857"></a>00857 
<a name="l00858"></a>00858 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l00859"></a>00859 <span class="preprocessor"></span>    retcode = krb5_c_keyed_checksum_types(kcontext, subkey-&gt;enctype,
<a name="l00860"></a>00860                                           &amp;numcksumtypes, &amp;cksumtype_array);
<a name="l00861"></a>00861 
<a name="l00862"></a>00862     <span class="keywordflow">if</span> (retcode) {
<a name="l00863"></a>00863         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to find appropriate keyed checksum: %s\n&quot;</span>,
<a name="l00864"></a>00864                     error_message(retcode)));
<a name="l00865"></a>00865         snmp_set_detail(error_message(retcode));
<a name="l00866"></a>00866         retval = SNMPERR_KRB5;
<a name="l00867"></a>00867         <span class="keywordflow">goto</span> error;
<a name="l00868"></a>00868     }
<a name="l00869"></a>00869 
<a name="l00870"></a>00870     <span class="keywordflow">if</span> (numcksumtypes &lt;= 0) {
<a name="l00871"></a>00871         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;We received a list of zero cksumtypes for this &quot;</span>
<a name="l00872"></a>00872                     <span class="stringliteral">&quot;enctype (%d)\n&quot;</span>, subkey-&gt;enctype));
<a name="l00873"></a>00873         snmp_set_detail(<span class="stringliteral">&quot;No valid checksum type for this encryption type&quot;</span>);
<a name="l00874"></a>00874         retval = SNMPERR_KRB5;
<a name="l00875"></a>00875         <span class="keywordflow">goto</span> error;
<a name="l00876"></a>00876     }
<a name="l00877"></a>00877 
<a name="l00878"></a>00878     <span class="comment">/*</span>
<a name="l00879"></a>00879 <span class="comment">     * It&#39;s not clear to me from the API which checksum you&#39;re supposed</span>
<a name="l00880"></a>00880 <span class="comment">     * to support, so I&#39;m taking a guess at the first one</span>
<a name="l00881"></a>00881 <span class="comment">     */</span>
<a name="l00882"></a>00882 
<a name="l00883"></a>00883     cksumtype = cksumtype_array[0];
<a name="l00884"></a>00884 
<a name="l00885"></a>00885     krb5_free_cksumtypes(kcontext, cksumtype_array);
<a name="l00886"></a>00886 
<a name="l00887"></a>00887     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Choosing checksum type of %d (subkey type &quot;</span>
<a name="l00888"></a>00888                 <span class="stringliteral">&quot;of %d)\n&quot;</span>, cksumtype, subkey-&gt;enctype));
<a name="l00889"></a>00889 
<a name="l00890"></a>00890     retcode = krb5_c_checksum_length(kcontext, cksumtype, &amp;blocksize);
<a name="l00891"></a>00891 
<a name="l00892"></a>00892     <span class="keywordflow">if</span> (retcode) {
<a name="l00893"></a>00893         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to determine checksum length: %s\n&quot;</span>,
<a name="l00894"></a>00894                     error_message(retcode)));
<a name="l00895"></a>00895         snmp_set_detail(error_message(retcode));
<a name="l00896"></a>00896         retval = SNMPERR_KRB5;
<a name="l00897"></a>00897         <span class="keywordflow">goto</span> error;
<a name="l00898"></a>00898     }
<a name="l00899"></a>00899 
<a name="l00900"></a>00900     CHECKSUM_LENGTH(&amp;pdu_checksum) = blocksize;
<a name="l00901"></a>00901 
<a name="l00902"></a>00902 <span class="preprocessor">#else </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00903"></a>00903     <span class="keywordflow">if</span> (ksm_state)
<a name="l00904"></a>00904         cksumtype = ksm_state-&gt;cksumtype;
<a name="l00905"></a>00905     <span class="keywordflow">else</span>
<a name="l00906"></a>00906 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l00907"></a>00907 <span class="preprocessor"></span>    {
<a name="l00908"></a>00908             <span class="comment">/* no way to tell what kind of checksum to use without trying */</span>
<a name="l00909"></a>00909             retval = krb5_create_checksum(kcontext, heim_crypto, 
<a name="l00910"></a>00910                                           KSM_KEY_USAGE_CHECKSUM, 0,
<a name="l00911"></a>00911                                           parms-&gt;scopedPdu, parms-&gt;scopedPduLen,
<a name="l00912"></a>00912                                           &amp;pdu_checksum);
<a name="l00913"></a>00913             <span class="keywordflow">if</span> (retval) {
<a name="l00914"></a>00914                     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to create a checksum: %s\n&quot;</span>,
<a name="l00915"></a>00915                                 error_message(retval)));
<a name="l00916"></a>00916                     snmp_set_detail(error_message(retcode));
<a name="l00917"></a>00917                     retval = SNMPERR_KRB5;
<a name="l00918"></a>00918                     <span class="keywordflow">goto</span> error;
<a name="l00919"></a>00919             }
<a name="l00920"></a>00920             cksumtype = CHECKSUM_TYPE(&amp;pdu_checksum);
<a name="l00921"></a>00921     }
<a name="l00922"></a>00922 <span class="preprocessor">#else                                   </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00923"></a>00923         cksumtype = CKSUMTYPE_RSA_MD5_DES;
<a name="l00924"></a>00924 <span class="preprocessor">#endif                                  </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00925"></a>00925 
<a name="l00926"></a>00926 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l00927"></a>00927 <span class="preprocessor"></span>        <span class="keywordflow">if</span> (!krb5_checksum_is_keyed(kcontext, cksumtype)) {
<a name="l00928"></a>00928 <span class="preprocessor">#else                           </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00929"></a>00929     <span class="keywordflow">if</span> (!is_keyed_cksum(cksumtype)) {
<a name="l00930"></a>00930 <span class="preprocessor">#endif                          </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00931"></a>00931         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Checksum type %d is not a keyed checksum\n&quot;</span>,
<a name="l00932"></a>00932                     cksumtype));
<a name="l00933"></a>00933         snmp_set_detail(<span class="stringliteral">&quot;Checksum is not a keyed checksum&quot;</span>);
<a name="l00934"></a>00934         retval = SNMPERR_KRB5;
<a name="l00935"></a>00935         <span class="keywordflow">goto</span> error;
<a name="l00936"></a>00936     }
<a name="l00937"></a>00937 
<a name="l00938"></a>00938 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l00939"></a>00939 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (!krb5_checksum_is_collision_proof(kcontext, cksumtype)) {
<a name="l00940"></a>00940 <span class="preprocessor">#else                           </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00941"></a>00941     <span class="keywordflow">if</span> (!is_coll_proof_cksum(cksumtype)) {
<a name="l00942"></a>00942 <span class="preprocessor">#endif                          </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00943"></a>00943         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Checksum type %d is not a collision-proof &quot;</span>
<a name="l00944"></a>00944                     <span class="stringliteral">&quot;checksum\n&quot;</span>, cksumtype));
<a name="l00945"></a>00945         snmp_set_detail(<span class="stringliteral">&quot;Checksum is not a collision-proof checksum&quot;</span>);
<a name="l00946"></a>00946         retval = SNMPERR_KRB5;
<a name="l00947"></a>00947         <span class="keywordflow">goto</span> error;
<a name="l00948"></a>00948     }
<a name="l00949"></a>00949 
<a name="l00950"></a>00950 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l00951"></a>00951 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (CHECKSUM_CONTENTS(&amp;pdu_checksum) != NULL ) {
<a name="l00952"></a>00952         <span class="comment">/* we did the bogus checksum--don&#39;t need to ask for the size again</span>
<a name="l00953"></a>00953 <span class="comment">         * or initialize cksumtype; just free the bits */</span>
<a name="l00954"></a>00954         free(CHECKSUM_CONTENTS(&amp;pdu_checksum));
<a name="l00955"></a>00955         CHECKSUM_CONTENTS(&amp;pdu_checksum) = NULL;
<a name="l00956"></a>00956     }
<a name="l00957"></a>00957     <span class="keywordflow">else</span> {
<a name="l00958"></a>00958         retval = krb5_checksumsize(kcontext, cksumtype,
<a name="l00959"></a>00959                                    &amp;CHECKSUM_LENGTH(&amp;pdu_checksum));
<a name="l00960"></a>00960         <span class="keywordflow">if</span> (retval) {
<a name="l00961"></a>00961             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to determine checksum length: %s\n&quot;</span>,
<a name="l00962"></a>00962                         error_message(retval)));
<a name="l00963"></a>00963             snmp_set_detail(error_message(retcode));
<a name="l00964"></a>00964             retval = SNMPERR_KRB5;
<a name="l00965"></a>00965             <span class="keywordflow">goto</span> error;
<a name="l00966"></a>00966         }
<a name="l00967"></a>00967 <span class="preprocessor">#else                   </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00968"></a>00968     CHECKSUM_LENGTH(&amp;pdu_checksum) = krb5_checksum_size(kcontext, cksumtype);
<a name="l00969"></a>00969 <span class="preprocessor">#endif                  </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00970"></a>00970     CHECKSUM_TYPE(&amp;pdu_checksum) = cksumtype;
<a name="l00971"></a>00971 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l00972"></a>00972 <span class="preprocessor"></span>    }
<a name="l00973"></a>00973 <span class="preprocessor">#endif                  </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l00974"></a>00974 
<a name="l00975"></a>00975 <span class="preprocessor">#endif </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l00976"></a>00976 
<a name="l00977"></a>00977     <span class="comment">/*</span>
<a name="l00978"></a>00978 <span class="comment">     * Note that here, we&#39;re just leaving blank space for the checksum;</span>
<a name="l00979"></a>00979 <span class="comment">     * we remember where that is, and we&#39;ll fill it in later.</span>
<a name="l00980"></a>00980 <span class="comment">     */</span>
<a name="l00981"></a>00981 
<a name="l00982"></a>00982     *offset += CHECKSUM_LENGTH(&amp;pdu_checksum);
<a name="l00983"></a>00983     memset(*wholeMsg + *parms-&gt;wholeMsgLen - *offset, 0, CHECKSUM_LENGTH(&amp;pdu_checksum));
<a name="l00984"></a>00984 
<a name="l00985"></a>00985     cksum_pointer = *wholeMsg + *parms-&gt;wholeMsgLen - *offset;
<a name="l00986"></a>00986 
<a name="l00987"></a>00987     rc = asn_realloc_rbuild_header(wholeMsg, parms-&gt;wholeMsgLen,
<a name="l00988"></a>00988                                          parms-&gt;wholeMsgOffset, 1,
<a name="l00989"></a>00989                                          (u_char) (ASN_UNIVERSAL |
<a name="l00990"></a>00990                                                    ASN_PRIMITIVE |
<a name="l00991"></a>00991                                                    ASN_OCTET_STR),
<a name="l00992"></a>00992                                          CHECKSUM_LENGTH(&amp;pdu_checksum));
<a name="l00993"></a>00993 
<a name="l00994"></a>00994     <span class="keywordflow">if</span> (rc == 0) {
<a name="l00995"></a>00995         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building ksm security parameters failed.\n&quot;</span>));
<a name="l00996"></a>00996         retval = SNMPERR_TOO_LONG;
<a name="l00997"></a>00997         <span class="keywordflow">goto</span> error;
<a name="l00998"></a>00998     }
<a name="l00999"></a>00999 
<a name="l01000"></a>01000     rc = asn_realloc_rbuild_int(wholeMsg, parms-&gt;wholeMsgLen,
<a name="l01001"></a>01001                                       parms-&gt;wholeMsgOffset, 1,
<a name="l01002"></a>01002                                       (u_char) (ASN_UNIVERSAL |
<a name="l01003"></a>01003                                                 ASN_PRIMITIVE |
<a name="l01004"></a>01004                                                 ASN_OCTET_STR),
<a name="l01005"></a>01005                                       (<span class="keywordtype">long</span> *) &amp;cksumtype,
<a name="l01006"></a>01006                                       <span class="keyword">sizeof</span>(cksumtype));
<a name="l01007"></a>01007 
<a name="l01008"></a>01008     <span class="keywordflow">if</span> (rc == 0) {
<a name="l01009"></a>01009         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building ksm security parameters failed.\n&quot;</span>));
<a name="l01010"></a>01010         retval = SNMPERR_TOO_LONG;
<a name="l01011"></a>01011         <span class="keywordflow">goto</span> error;
<a name="l01012"></a>01012     }
<a name="l01013"></a>01013 
<a name="l01014"></a>01014     rc = asn_realloc_rbuild_sequence(wholeMsg, parms-&gt;wholeMsgLen,
<a name="l01015"></a>01015                                            parms-&gt;wholeMsgOffset, 1,
<a name="l01016"></a>01016                                            (u_char) (ASN_SEQUENCE |
<a name="l01017"></a>01017                                                      ASN_CONSTRUCTOR),
<a name="l01018"></a>01018                                            *offset - seq_offset);
<a name="l01019"></a>01019 
<a name="l01020"></a>01020     <span class="keywordflow">if</span> (rc == 0) {
<a name="l01021"></a>01021         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building ksm security parameters failed.\n&quot;</span>));
<a name="l01022"></a>01022         retval = SNMPERR_TOO_LONG;
<a name="l01023"></a>01023         <span class="keywordflow">goto</span> error;
<a name="l01024"></a>01024     }
<a name="l01025"></a>01025 
<a name="l01026"></a>01026     rc = asn_realloc_rbuild_header(wholeMsg, parms-&gt;wholeMsgLen,
<a name="l01027"></a>01027                                          parms-&gt;wholeMsgOffset, 1,
<a name="l01028"></a>01028                                          (u_char) (ASN_UNIVERSAL |
<a name="l01029"></a>01029                                                    ASN_PRIMITIVE |
<a name="l01030"></a>01030                                                    ASN_OCTET_STR),
<a name="l01031"></a>01031                                          *offset - seq_offset);
<a name="l01032"></a>01032 
<a name="l01033"></a>01033     <span class="keywordflow">if</span> (rc == 0) {
<a name="l01034"></a>01034         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building ksm security parameters failed.\n&quot;</span>));
<a name="l01035"></a>01035         retval = SNMPERR_TOO_LONG;
<a name="l01036"></a>01036         <span class="keywordflow">goto</span> error;
<a name="l01037"></a>01037     }
<a name="l01038"></a>01038 
<a name="l01039"></a>01039     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Security parameter encoding completed\n&quot;</span>));
<a name="l01040"></a>01040 
<a name="l01041"></a>01041     <span class="comment">/*</span>
<a name="l01042"></a>01042 <span class="comment">     * We&#39;re done with the KSM security parameters - now we do the global</span>
<a name="l01043"></a>01043 <span class="comment">     * header and wrap up the whole PDU.</span>
<a name="l01044"></a>01044 <span class="comment">     */</span>
<a name="l01045"></a>01045 
<a name="l01046"></a>01046     <span class="keywordflow">if</span> (*parms-&gt;wholeMsgLen &lt; parms-&gt;globalDataLen) {
<a name="l01047"></a>01047         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building global data failed.\n&quot;</span>));
<a name="l01048"></a>01048         retval = SNMPERR_TOO_LONG;
<a name="l01049"></a>01049         <span class="keywordflow">goto</span> error;
<a name="l01050"></a>01050     }
<a name="l01051"></a>01051 
<a name="l01052"></a>01052     *offset += parms-&gt;globalDataLen;
<a name="l01053"></a>01053     memcpy(*wholeMsg + *parms-&gt;wholeMsgLen - *offset,
<a name="l01054"></a>01054            parms-&gt;globalData, parms-&gt;globalDataLen);
<a name="l01055"></a>01055 
<a name="l01056"></a>01056     rc = asn_realloc_rbuild_sequence(wholeMsg, parms-&gt;wholeMsgLen,
<a name="l01057"></a>01057                                            offset, 1,
<a name="l01058"></a>01058                                            (u_char) (ASN_SEQUENCE |
<a name="l01059"></a>01059                                                      ASN_CONSTRUCTOR),
<a name="l01060"></a>01060                                            *offset);
<a name="l01061"></a>01061 
<a name="l01062"></a>01062     <span class="keywordflow">if</span> (rc == 0) {
<a name="l01063"></a>01063         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Building master packet sequence.\n&quot;</span>));
<a name="l01064"></a>01064         retval = SNMPERR_TOO_LONG;
<a name="l01065"></a>01065         <span class="keywordflow">goto</span> error;
<a name="l01066"></a>01066     }
<a name="l01067"></a>01067 
<a name="l01068"></a>01068     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: PDU master packet encoding complete.\n&quot;</span>));
<a name="l01069"></a>01069 
<a name="l01070"></a>01070     <span class="comment">/*</span>
<a name="l01071"></a>01071 <span class="comment">     * Now we need to checksum the entire PDU (since it&#39;s built).</span>
<a name="l01072"></a>01072 <span class="comment">     */</span>
<a name="l01073"></a>01073 
<a name="l01074"></a>01074 <span class="preprocessor">#ifndef OLD_HEIMDAL </span><span class="comment">/* since heimdal allocs the mem for us */</span>
<a name="l01075"></a>01075     CHECKSUM_CONTENTS(&amp;pdu_checksum) = malloc(CHECKSUM_LENGTH(&amp;pdu_checksum));
<a name="l01076"></a>01076 
<a name="l01077"></a>01077     <span class="keywordflow">if</span> (!CHECKSUM_CONTENTS(&amp;pdu_checksum)) {
<a name="l01078"></a>01078         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to malloc %d bytes for checksum\n&quot;</span>,
<a name="l01079"></a>01079                     CHECKSUM_LENGTH(&amp;pdu_checksum)));
<a name="l01080"></a>01080         retval = SNMPERR_MALLOC;
<a name="l01081"></a>01081         <span class="keywordflow">goto</span> error;
<a name="l01082"></a>01082     }
<a name="l01083"></a>01083 <span class="preprocessor">#endif                                  </span><span class="comment">/* ! OLD_HEIMDAL */</span>
<a name="l01084"></a>01084 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01085"></a>01085 <span class="preprocessor"></span>
<a name="l01086"></a>01086     input.data = (<span class="keywordtype">char</span> *) (*wholeMsg + *parms-&gt;wholeMsgLen - *offset);
<a name="l01087"></a>01087     input.length = *offset;
<a name="l01088"></a>01088         retcode = krb5_c_make_checksum(kcontext, cksumtype, subkey,
<a name="l01089"></a>01089                                        KSM_KEY_USAGE_CHECKSUM, &amp;input,
<a name="l01090"></a>01090                                        &amp;pdu_checksum);
<a name="l01091"></a>01091 
<a name="l01092"></a>01092 <span class="preprocessor">#elif defined(OLD_HEIMDAL)      </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01093"></a>01093 
<a name="l01094"></a>01094         retcode = krb5_create_checksum(kcontext, heim_crypto,
<a name="l01095"></a>01095                                        KSM_KEY_USAGE_CHECKSUM, cksumtype,
<a name="l01096"></a>01096                                        *wholeMsg + *parms-&gt;wholeMsgLen
<a name="l01097"></a>01097                                        - *offset, *offset, &amp;pdu_checksum);
<a name="l01098"></a>01098 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01099"></a>01099 
<a name="l01100"></a>01100     retcode = krb5_calculate_checksum(kcontext, cksumtype, *wholeMsg +
<a name="l01101"></a>01101                                       *parms-&gt;wholeMsgLen - *offset,
<a name="l01102"></a>01102                                       *offset,
<a name="l01103"></a>01103                                       (krb5_pointer) subkey-&gt;contents,
<a name="l01104"></a>01104                                       subkey-&gt;length, &amp;pdu_checksum);
<a name="l01105"></a>01105 
<a name="l01106"></a>01106 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01107"></a>01107 
<a name="l01108"></a>01108     <span class="keywordflow">if</span> (retcode) {
<a name="l01109"></a>01109         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Calculate checksum failed: %s\n&quot;</span>,
<a name="l01110"></a>01110                     error_message(retcode)));
<a name="l01111"></a>01111         retval = SNMPERR_KRB5;
<a name="l01112"></a>01112         snmp_set_detail(error_message(retcode));
<a name="l01113"></a>01113         <span class="keywordflow">goto</span> error;
<a name="l01114"></a>01114     }
<a name="l01115"></a>01115 
<a name="l01116"></a>01116     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Checksum calculation complete.\n&quot;</span>));
<a name="l01117"></a>01117 
<a name="l01118"></a>01118     memcpy(cksum_pointer, CHECKSUM_CONTENTS(&amp;pdu_checksum), CHECKSUM_LENGTH(&amp;pdu_checksum));
<a name="l01119"></a>01119 
<a name="l01120"></a>01120     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Writing checksum of %d bytes at offset %d\n&quot;</span>,
<a name="l01121"></a>01121                 CHECKSUM_LENGTH(&amp;pdu_checksum), cksum_pointer - (*wholeMsg + 1)));
<a name="l01122"></a>01122 
<a name="l01123"></a>01123     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: Checksum:&quot;</span>));
<a name="l01124"></a>01124 
<a name="l01125"></a>01125     <span class="keywordflow">for</span> (i = 0; i &lt; CHECKSUM_LENGTH(&amp;pdu_checksum); i++)
<a name="l01126"></a>01126         DEBUGMSG((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot; %02x&quot;</span>,
<a name="l01127"></a>01127                   (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>) CHECKSUM_CONTENTS(&amp;pdu_checksum)[i]));
<a name="l01128"></a>01128 
<a name="l01129"></a>01129     DEBUGMSG((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;\n&quot;</span>));
<a name="l01130"></a>01130 
<a name="l01131"></a>01131     <span class="comment">/*</span>
<a name="l01132"></a>01132 <span class="comment">     * If we&#39;re _not_ called as part of a response (null ksm_state),</span>
<a name="l01133"></a>01133 <span class="comment">     * then save the auth_context for later using our cache routines.</span>
<a name="l01134"></a>01134 <span class="comment">     */</span>
<a name="l01135"></a>01135 
<a name="l01136"></a>01136     <span class="keywordflow">if</span> (!ksm_state) {
<a name="l01137"></a>01137         <span class="keywordflow">if</span> ((retval = ksm_insert_cache(parms-&gt;pdu-&gt;<a class="code" href="structsnmp__pdu.html#a528226bcca644a9d42d63392fb9e6676" title="Message id for V3 messages note: incremented for each retry.">msgid</a>, auth_context,
<a name="l01138"></a>01138                                        (u_char *) parms-&gt;secName,
<a name="l01139"></a>01139                                        parms-&gt;secNameLen)) !=
<a name="l01140"></a>01140             SNMPERR_SUCCESS)
<a name="l01141"></a>01141             <span class="keywordflow">goto</span> error;
<a name="l01142"></a>01142         auth_context = NULL;
<a name="l01143"></a>01143     }
<a name="l01144"></a>01144 
<a name="l01145"></a>01145     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM processing complete!\n&quot;</span>));
<a name="l01146"></a>01146 
<a name="l01147"></a>01147   error:
<a name="l01148"></a>01148 
<a name="l01149"></a>01149     <span class="keywordflow">if</span> (CHECKSUM_CONTENTS(&amp;pdu_checksum))
<a name="l01150"></a>01150 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01151"></a>01151 <span class="preprocessor"></span>        krb5_free_checksum_contents(kcontext, &amp;pdu_checksum);
<a name="l01152"></a>01152 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01153"></a>01153         free(CHECKSUM_CONTENTS(&amp;pdu_checksum));
<a name="l01154"></a>01154 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01155"></a>01155 
<a name="l01156"></a>01156     <span class="keywordflow">if</span> (ivector.data)
<a name="l01157"></a>01157         free(ivector.data);
<a name="l01158"></a>01158 
<a name="l01159"></a>01159     <span class="keywordflow">if</span> (subkey)
<a name="l01160"></a>01160         krb5_free_keyblock(kcontext, subkey);
<a name="l01161"></a>01161 
<a name="l01162"></a>01162 <span class="preprocessor">#ifdef OLD_HEIMDAL </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01163"></a>01163     <span class="keywordflow">if</span> (heim_crypto)
<a name="l01164"></a>01164             krb5_crypto_destroy(kcontext, heim_crypto);
<a name="l01165"></a>01165 <span class="preprocessor">#endif </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01166"></a>01166 
<a name="l01167"></a>01167     <span class="keywordflow">if</span> (encrypted_data)
<a name="l01168"></a>01168         free(encrypted_data);
<a name="l01169"></a>01169 
<a name="l01170"></a>01170     <span class="keywordflow">if</span> (cc)
<a name="l01171"></a>01171         krb5_cc_close(kcontext, cc);
<a name="l01172"></a>01172 
<a name="l01173"></a>01173     <span class="keywordflow">if</span> (auth_context &amp;&amp; !ksm_state)
<a name="l01174"></a>01174         krb5_auth_con_free(kcontext, auth_context);
<a name="l01175"></a>01175 
<a name="l01176"></a>01176     <span class="keywordflow">return</span> retval;
<a name="l01177"></a>01177 }
<a name="l01178"></a>01178 
<a name="l01179"></a>01179 <span class="comment">/****************************************************************************</span>
<a name="l01180"></a>01180 <span class="comment"> *</span>
<a name="l01181"></a>01181 <span class="comment"> * ksm_process_in_msg</span>
<a name="l01182"></a>01182 <span class="comment"> *</span>
<a name="l01183"></a>01183 <span class="comment"> * Parameters:</span>
<a name="l01184"></a>01184 <span class="comment"> *      (See list below...)</span>
<a name="l01185"></a>01185 <span class="comment"> *</span>
<a name="l01186"></a>01186 <span class="comment"> * Returns:</span>
<a name="l01187"></a>01187 <span class="comment"> *      KSM_ERR_NO_ERROR                        On success.</span>
<a name="l01188"></a>01188 <span class="comment"> *      SNMPERR_KRB5</span>
<a name="l01189"></a>01189 <span class="comment"> *      KSM_ERR_GENERIC_ERROR</span>
<a name="l01190"></a>01190 <span class="comment"> *      KSM_ERR_UNSUPPORTED_SECURITY_LEVEL</span>
<a name="l01191"></a>01191 <span class="comment"> *</span>
<a name="l01192"></a>01192 <span class="comment"> *</span>
<a name="l01193"></a>01193 <span class="comment"> * Processes an incoming message.</span>
<a name="l01194"></a>01194 <span class="comment"> *</span>
<a name="l01195"></a>01195 <span class="comment"> ****************************************************************************/</span>
<a name="l01196"></a>01196 
<a name="l01197"></a>01197 <span class="keywordtype">int</span>
<a name="l01198"></a>01198 ksm_process_in_msg(<span class="keyword">struct</span> <a class="code" href="structsnmp__secmod__incoming__params.html">snmp_secmod_incoming_params</a> *parms)
<a name="l01199"></a>01199 {
<a name="l01200"></a>01200     <span class="keywordtype">long</span>            temp;
<a name="l01201"></a>01201     krb5_cksumtype  cksumtype;
<a name="l01202"></a>01202     krb5_auth_context auth_context = NULL;
<a name="l01203"></a>01203     krb5_error_code retcode;
<a name="l01204"></a>01204     krb5_checksum   checksum;
<a name="l01205"></a>01205     krb5_data       ap_req, ivector;
<a name="l01206"></a>01206     krb5_flags      flags;
<a name="l01207"></a>01207     krb5_keyblock  *subkey = NULL;
<a name="l01208"></a>01208 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01209"></a>01209 <span class="preprocessor"></span>    krb5_data       input, output;
<a name="l01210"></a>01210     krb5_boolean    valid;
<a name="l01211"></a>01211     krb5_enc_data   in_crypt;
<a name="l01212"></a>01212 <span class="preprocessor">#elif defined OLD_HEIMDAL       </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01213"></a>01213     krb5_data output;
<a name="l01214"></a>01214     krb5_crypto heim_crypto = NULL;
<a name="l01215"></a>01215 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01216"></a>01216     krb5_encrypt_block eblock;
<a name="l01217"></a>01217 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01218"></a>01218     krb5_ticket    *ticket = NULL;
<a name="l01219"></a>01219     <span class="keywordtype">int</span>             retval = SNMPERR_SUCCESS, response = 0;
<a name="l01220"></a>01220     <span class="keywordtype">size_t</span>          length =
<a name="l01221"></a>01221         parms-&gt;wholeMsgLen - (u_int) (parms-&gt;secParams - parms-&gt;wholeMsg);
<a name="l01222"></a>01222     u_char         *current = parms-&gt;secParams, type;
<a name="l01223"></a>01223     <span class="keywordtype">size_t</span>          cksumlength, blocksize;
<a name="l01224"></a>01224     <span class="keywordtype">long</span>            hint;
<a name="l01225"></a>01225     <span class="keywordtype">char</span>           *cname;
<a name="l01226"></a>01226     <span class="keyword">struct </span><a class="code" href="structksm__secStateRef.html">ksm_secStateRef</a> *ksm_state;
<a name="l01227"></a>01227     <span class="keyword">struct </span><a class="code" href="structksm__cache__entry.html">ksm_cache_entry</a> *entry;
<a name="l01228"></a>01228 
<a name="l01229"></a>01229     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Processing has begun\n&quot;</span>));
<a name="l01230"></a>01230 
<a name="l01231"></a>01231     CHECKSUM_CONTENTS(&amp;checksum) = NULL;
<a name="l01232"></a>01232     ap_req.data = NULL;
<a name="l01233"></a>01233     ivector.length = 0;
<a name="l01234"></a>01234     ivector.data = NULL;
<a name="l01235"></a>01235 
<a name="l01236"></a>01236     <span class="comment">/*</span>
<a name="l01237"></a>01237 <span class="comment">     * First, parse the security parameters (because we need the subkey inside</span>
<a name="l01238"></a>01238 <span class="comment">     * of the ticket to do anything</span>
<a name="l01239"></a>01239 <span class="comment">     */</span>
<a name="l01240"></a>01240 
<a name="l01241"></a>01241     <span class="keywordflow">if</span> ((current = asn_parse_sequence(current, &amp;length, &amp;type,
<a name="l01242"></a>01242                                       (ASN_UNIVERSAL | ASN_PRIMITIVE |
<a name="l01243"></a>01243                                        ASN_OCTET_STR),
<a name="l01244"></a>01244                                       <span class="stringliteral">&quot;ksm first octet&quot;</span>)) == NULL) {
<a name="l01245"></a>01245         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Initial security paramter parsing failed\n&quot;</span>));
<a name="l01246"></a>01246 
<a name="l01247"></a>01247         retval = SNMPERR_ASN_PARSE_ERR;
<a name="l01248"></a>01248         <span class="keywordflow">goto</span> error;
<a name="l01249"></a>01249     }
<a name="l01250"></a>01250 
<a name="l01251"></a>01251     <span class="keywordflow">if</span> ((current = asn_parse_sequence(current, &amp;length, &amp;type,
<a name="l01252"></a>01252                                       (ASN_SEQUENCE | ASN_CONSTRUCTOR),
<a name="l01253"></a>01253                                       <span class="stringliteral">&quot;ksm sequence&quot;</span>)) == NULL) {
<a name="l01254"></a>01254         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l01255"></a>01255                     <span class="stringliteral">&quot;Security parameter sequence parsing failed\n&quot;</span>));
<a name="l01256"></a>01256 
<a name="l01257"></a>01257         retval = SNMPERR_ASN_PARSE_ERR;
<a name="l01258"></a>01258         <span class="keywordflow">goto</span> error;
<a name="l01259"></a>01259     }
<a name="l01260"></a>01260 
<a name="l01261"></a>01261     <span class="keywordflow">if</span> ((current = asn_parse_int(current, &amp;length, &amp;type, &amp;temp,
<a name="l01262"></a>01262                                  <span class="keyword">sizeof</span>(temp))) == NULL) {
<a name="l01263"></a>01263         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Security parameter checksum type parsing&quot;</span>
<a name="l01264"></a>01264                     <span class="stringliteral">&quot;failed\n&quot;</span>));
<a name="l01265"></a>01265 
<a name="l01266"></a>01266         retval = SNMPERR_ASN_PARSE_ERR;
<a name="l01267"></a>01267         <span class="keywordflow">goto</span> error;
<a name="l01268"></a>01268     }
<a name="l01269"></a>01269 
<a name="l01270"></a>01270     cksumtype = temp;
<a name="l01271"></a>01271 
<a name="l01272"></a>01272 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01273"></a>01273 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (!krb5_c_valid_cksumtype(cksumtype)) {
<a name="l01274"></a>01274         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Invalid checksum type (%d)\n&quot;</span>, cksumtype));
<a name="l01275"></a>01275 
<a name="l01276"></a>01276         retval = SNMPERR_KRB5;
<a name="l01277"></a>01277         snmp_set_detail(<span class="stringliteral">&quot;Invalid checksum type&quot;</span>);
<a name="l01278"></a>01278         <span class="keywordflow">goto</span> error;
<a name="l01279"></a>01279     }
<a name="l01280"></a>01280 
<a name="l01281"></a>01281     <span class="keywordflow">if</span> (!krb5_c_is_keyed_cksum(cksumtype)) {
<a name="l01282"></a>01282         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Checksum type %d is not a keyed checksum\n&quot;</span>,
<a name="l01283"></a>01283                     cksumtype));
<a name="l01284"></a>01284         snmp_set_detail(<span class="stringliteral">&quot;Checksum is not a keyed checksum&quot;</span>);
<a name="l01285"></a>01285         retval = SNMPERR_KRB5;
<a name="l01286"></a>01286         <span class="keywordflow">goto</span> error;
<a name="l01287"></a>01287     }
<a name="l01288"></a>01288 
<a name="l01289"></a>01289     <span class="keywordflow">if</span> (!krb5_c_is_coll_proof_cksum(cksumtype)) {
<a name="l01290"></a>01290         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Checksum type %d is not a collision-proof &quot;</span>
<a name="l01291"></a>01291                     <span class="stringliteral">&quot;checksum\n&quot;</span>, cksumtype));
<a name="l01292"></a>01292         snmp_set_detail(<span class="stringliteral">&quot;Checksum is not a collision-proof checksum&quot;</span>);
<a name="l01293"></a>01293         retval = SNMPERR_KRB5;
<a name="l01294"></a>01294         <span class="keywordflow">goto</span> error;
<a name="l01295"></a>01295     }
<a name="l01296"></a>01296 <span class="preprocessor">#else </span><span class="comment">/* ! NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01297"></a>01297 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l01298"></a>01298 <span class="preprocessor"></span>    <span class="comment">/* kludge */</span>
<a name="l01299"></a>01299     <span class="keywordflow">if</span> (krb5_checksumsize(kcontext, cksumtype, &amp;cksumlength)) {
<a name="l01300"></a>01300 <span class="preprocessor">#else                                   </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01301"></a>01301     <span class="keywordflow">if</span> (!valid_cksumtype(cksumtype)) {
<a name="l01302"></a>01302 <span class="preprocessor">#endif                                  </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01303"></a>01303         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Invalid checksum type (%d)\n&quot;</span>, cksumtype));
<a name="l01304"></a>01304 
<a name="l01305"></a>01305         retval = SNMPERR_KRB5;
<a name="l01306"></a>01306         snmp_set_detail(<span class="stringliteral">&quot;Invalid checksum type&quot;</span>);
<a name="l01307"></a>01307         <span class="keywordflow">goto</span> error;
<a name="l01308"></a>01308     }
<a name="l01309"></a>01309 
<a name="l01310"></a>01310 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l01311"></a>01311 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (!krb5_checksum_is_keyed(kcontext, cksumtype)) {
<a name="l01312"></a>01312 <span class="preprocessor">#else                                   </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01313"></a>01313     <span class="keywordflow">if</span> (!is_keyed_cksum(cksumtype)) {
<a name="l01314"></a>01314 <span class="preprocessor">#endif                                  </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01315"></a>01315         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Checksum type %d is not a keyed checksum\n&quot;</span>,
<a name="l01316"></a>01316                     cksumtype));
<a name="l01317"></a>01317         snmp_set_detail(<span class="stringliteral">&quot;Checksum is not a keyed checksum&quot;</span>);
<a name="l01318"></a>01318         retval = SNMPERR_KRB5;
<a name="l01319"></a>01319         <span class="keywordflow">goto</span> error;
<a name="l01320"></a>01320     }
<a name="l01321"></a>01321 
<a name="l01322"></a>01322 <span class="preprocessor">#ifdef OLD_HEIMDAL</span>
<a name="l01323"></a>01323 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (!krb5_checksum_is_collision_proof(kcontext, cksumtype)) {
<a name="l01324"></a>01324 <span class="preprocessor">#else                                   </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01325"></a>01325     <span class="keywordflow">if</span> (!is_coll_proof_cksum(cksumtype)) {
<a name="l01326"></a>01326 <span class="preprocessor">#endif                                  </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01327"></a>01327         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Checksum type %d is not a collision-proof &quot;</span>
<a name="l01328"></a>01328                     <span class="stringliteral">&quot;checksum\n&quot;</span>, cksumtype));
<a name="l01329"></a>01329         snmp_set_detail(<span class="stringliteral">&quot;Checksum is not a collision-proof checksum&quot;</span>);
<a name="l01330"></a>01330         retval = SNMPERR_KRB5;
<a name="l01331"></a>01331         <span class="keywordflow">goto</span> error;
<a name="l01332"></a>01332     }
<a name="l01333"></a>01333 <span class="preprocessor">#endif </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01334"></a>01334 
<a name="l01335"></a>01335     CHECKSUM_TYPE(&amp;checksum) = cksumtype;
<a name="l01336"></a>01336 
<a name="l01337"></a>01337     cksumlength = length;
<a name="l01338"></a>01338 
<a name="l01339"></a>01339     <span class="keywordflow">if</span> ((current = asn_parse_sequence(current, &amp;cksumlength, &amp;type,
<a name="l01340"></a>01340                                       (ASN_UNIVERSAL | ASN_PRIMITIVE |
<a name="l01341"></a>01341                                        ASN_OCTET_STR), <span class="stringliteral">&quot;ksm checksum&quot;</span>)) ==
<a name="l01342"></a>01342         NULL) {
<a name="l01343"></a>01343         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l01344"></a>01344                     <span class="stringliteral">&quot;Security parameter checksum parsing failed\n&quot;</span>));
<a name="l01345"></a>01345 
<a name="l01346"></a>01346         retval = SNMPERR_ASN_PARSE_ERR;
<a name="l01347"></a>01347         <span class="keywordflow">goto</span> error;
<a name="l01348"></a>01348     }
<a name="l01349"></a>01349 
<a name="l01350"></a>01350     CHECKSUM_CONTENTS(&amp;checksum) = malloc(cksumlength);
<a name="l01351"></a>01351     <span class="keywordflow">if</span> (!CHECKSUM_CONTENTS(&amp;checksum)) {
<a name="l01352"></a>01352         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to malloc %d bytes for checksum.\n&quot;</span>,
<a name="l01353"></a>01353                     cksumlength));
<a name="l01354"></a>01354         retval = SNMPERR_MALLOC;
<a name="l01355"></a>01355         <span class="keywordflow">goto</span> error;
<a name="l01356"></a>01356     }
<a name="l01357"></a>01357 
<a name="l01358"></a>01358     memcpy(CHECKSUM_CONTENTS(&amp;checksum), current, cksumlength);
<a name="l01359"></a>01359 
<a name="l01360"></a>01360     CHECKSUM_LENGTH(&amp;checksum) = cksumlength;
<a name="l01361"></a>01361     CHECKSUM_TYPE(&amp;checksum) = cksumtype;
<a name="l01362"></a>01362 
<a name="l01363"></a>01363     <span class="comment">/*</span>
<a name="l01364"></a>01364 <span class="comment">     * Zero out the checksum so the validation works correctly</span>
<a name="l01365"></a>01365 <span class="comment">     */</span>
<a name="l01366"></a>01366 
<a name="l01367"></a>01367     memset(current, 0, cksumlength);
<a name="l01368"></a>01368 
<a name="l01369"></a>01369     current += cksumlength;
<a name="l01370"></a>01370     length = parms-&gt;wholeMsgLen - (u_int) (current - parms-&gt;wholeMsg);
<a name="l01371"></a>01371 
<a name="l01372"></a>01372     <span class="keywordflow">if</span> ((current = asn_parse_sequence(current, &amp;length, &amp;type,
<a name="l01373"></a>01373                                       (ASN_UNIVERSAL | ASN_PRIMITIVE |
<a name="l01374"></a>01374                                        ASN_OCTET_STR), <span class="stringliteral">&quot;ksm ap_req&quot;</span>)) ==
<a name="l01375"></a>01375         NULL) {
<a name="l01376"></a>01376         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM security parameter AP_REQ/REP parsing &quot;</span>
<a name="l01377"></a>01377                     <span class="stringliteral">&quot;failed\n&quot;</span>));
<a name="l01378"></a>01378 
<a name="l01379"></a>01379         retval = SNMPERR_ASN_PARSE_ERR;
<a name="l01380"></a>01380         <span class="keywordflow">goto</span> error;
<a name="l01381"></a>01381     }
<a name="l01382"></a>01382 
<a name="l01383"></a>01383     ap_req.length = length;
<a name="l01384"></a>01384     ap_req.data = malloc(length);
<a name="l01385"></a>01385     <span class="keywordflow">if</span> (!ap_req.data) {
<a name="l01386"></a>01386         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l01387"></a>01387                     <span class="stringliteral">&quot;KSM unable to malloc %d bytes for AP_REQ/REP.\n&quot;</span>,
<a name="l01388"></a>01388                     length));
<a name="l01389"></a>01389         retval = SNMPERR_MALLOC;
<a name="l01390"></a>01390         <span class="keywordflow">goto</span> error;
<a name="l01391"></a>01391     }
<a name="l01392"></a>01392 
<a name="l01393"></a>01393     memcpy(ap_req.data, current, length);
<a name="l01394"></a>01394 
<a name="l01395"></a>01395     current += length;
<a name="l01396"></a>01396     length = parms-&gt;wholeMsgLen - (u_int) (current - parms-&gt;wholeMsg);
<a name="l01397"></a>01397 
<a name="l01398"></a>01398     <span class="keywordflow">if</span> ((current = asn_parse_int(current, &amp;length, &amp;type, &amp;hint,
<a name="l01399"></a>01399                                  <span class="keyword">sizeof</span>(hint))) == NULL) {
<a name="l01400"></a>01400         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l01401"></a>01401                     <span class="stringliteral">&quot;KSM security parameter hint parsing failed\n&quot;</span>));
<a name="l01402"></a>01402 
<a name="l01403"></a>01403         retval = SNMPERR_ASN_PARSE_ERR;
<a name="l01404"></a>01404         <span class="keywordflow">goto</span> error;
<a name="l01405"></a>01405     }
<a name="l01406"></a>01406 
<a name="l01407"></a>01407     <span class="comment">/*</span>
<a name="l01408"></a>01408 <span class="comment">     * Okay!  We&#39;ve got it all!  Now try decoding the damn ticket.</span>
<a name="l01409"></a>01409 <span class="comment">     *</span>
<a name="l01410"></a>01410 <span class="comment">     * But of course there&#39;s a WRINKLE!  We need to figure out if we&#39;re</span>
<a name="l01411"></a>01411 <span class="comment">     * processing a AP_REQ or an AP_REP.  How do we do that?  We&#39;re going</span>
<a name="l01412"></a>01412 <span class="comment">     * to cheat, and look at the first couple of bytes (which is what</span>
<a name="l01413"></a>01413 <span class="comment">     * the Kerberos library routines do anyway).</span>
<a name="l01414"></a>01414 <span class="comment">     *</span>
<a name="l01415"></a>01415 <span class="comment">     * If there are ever new Kerberos message formats, we&#39;ll need to fix</span>
<a name="l01416"></a>01416 <span class="comment">     * this here.</span>
<a name="l01417"></a>01417 <span class="comment">     *</span>
<a name="l01418"></a>01418 <span class="comment">     * If it&#39;s a _response_, then we need to get the auth_context</span>
<a name="l01419"></a>01419 <span class="comment">     * from our cache.</span>
<a name="l01420"></a>01420 <span class="comment">     */</span>
<a name="l01421"></a>01421 
<a name="l01422"></a>01422     <span class="keywordflow">if</span> (ap_req.length
<a name="l01423"></a>01423 #ifndef NETSNMP_USE_KERBEROS_HEIMDAL
<a name="l01424"></a>01424         &amp;&amp; (ap_req.data[0] == 0x6e || ap_req.data[0] == 0x4e)) {
<a name="l01425"></a>01425 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l01426"></a>01426         &amp;&amp; (((<span class="keywordtype">char</span> *)ap_req.data)[0] == 0x6e || ((<span class="keywordtype">char</span> *)ap_req.data)[0] == 0x4e)) {
<a name="l01427"></a>01427 <span class="preprocessor">#endif</span>
<a name="l01428"></a>01428 <span class="preprocessor"></span>
<a name="l01429"></a>01429         <span class="comment">/*</span>
<a name="l01430"></a>01430 <span class="comment">         * We need to initalize the authorization context, and set the</span>
<a name="l01431"></a>01431 <span class="comment">         * replay cache in it (and initialize the replay cache if we</span>
<a name="l01432"></a>01432 <span class="comment">         * haven&#39;t already</span>
<a name="l01433"></a>01433 <span class="comment">         */</span>
<a name="l01434"></a>01434 
<a name="l01435"></a>01435         retcode = krb5_auth_con_init(kcontext, &amp;auth_context);
<a name="l01436"></a>01436 
<a name="l01437"></a>01437         <span class="keywordflow">if</span> (retcode) {
<a name="l01438"></a>01438             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_auth_con_init failed: %s\n&quot;</span>,
<a name="l01439"></a>01439                         error_message(retcode)));
<a name="l01440"></a>01440             retval = SNMPERR_KRB5;
<a name="l01441"></a>01441             snmp_set_detail(error_message(retcode));
<a name="l01442"></a>01442             <span class="keywordflow">goto</span> error;
<a name="l01443"></a>01443         }
<a name="l01444"></a>01444 
<a name="l01445"></a>01445         <span class="keywordflow">if</span> (!rcache) {
<a name="l01446"></a>01446             krb5_data       server;
<a name="l01447"></a>01447             server.data = <span class="stringliteral">&quot;host&quot;</span>;
<a name="l01448"></a>01448             server.length = strlen(server.data);
<a name="l01449"></a>01449 
<a name="l01450"></a>01450             retcode = krb5_get_server_rcache(kcontext, &amp;server, &amp;rcache);
<a name="l01451"></a>01451 
<a name="l01452"></a>01452             <span class="keywordflow">if</span> (retcode) {
<a name="l01453"></a>01453                 DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_get_server_rcache failed: %s\n&quot;</span>,
<a name="l01454"></a>01454                             error_message(retcode)));
<a name="l01455"></a>01455                 retval = SNMPERR_KRB5;
<a name="l01456"></a>01456                 snmp_set_detail(error_message(retcode));
<a name="l01457"></a>01457                 <span class="keywordflow">goto</span> error;
<a name="l01458"></a>01458             }
<a name="l01459"></a>01459         }
<a name="l01460"></a>01460 
<a name="l01461"></a>01461         retcode = krb5_auth_con_setrcache(kcontext, auth_context, rcache);
<a name="l01462"></a>01462 
<a name="l01463"></a>01463         <span class="keywordflow">if</span> (retcode) {
<a name="l01464"></a>01464             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_auth_con_setrcache failed: %s\n&quot;</span>,
<a name="l01465"></a>01465                         error_message(retcode)));
<a name="l01466"></a>01466             retval = SNMPERR_KRB5;
<a name="l01467"></a>01467             snmp_set_detail(error_message(retcode));
<a name="l01468"></a>01468             <span class="keywordflow">goto</span> error;
<a name="l01469"></a>01469         }
<a name="l01470"></a>01470 
<a name="l01471"></a>01471         retcode = krb5_rd_req(kcontext, &amp;auth_context, &amp;ap_req, NULL,
<a name="l01472"></a>01472                               keytab, &amp;flags, &amp;ticket);
<a name="l01473"></a>01473 
<a name="l01474"></a>01474         krb5_auth_con_setrcache(kcontext, auth_context, NULL);
<a name="l01475"></a>01475 
<a name="l01476"></a>01476         <span class="keywordflow">if</span> (retcode) {
<a name="l01477"></a>01477             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_rd_req() failed: %s\n&quot;</span>,
<a name="l01478"></a>01478                         error_message(retcode)));
<a name="l01479"></a>01479             retval = SNMPERR_KRB5;
<a name="l01480"></a>01480             snmp_set_detail(error_message(retcode));
<a name="l01481"></a>01481             <span class="keywordflow">goto</span> error;
<a name="l01482"></a>01482         }
<a name="l01483"></a>01483 
<a name="l01484"></a>01484         retcode =
<a name="l01485"></a>01485             krb5_unparse_name(kcontext, TICKET_CLIENT(ticket), &amp;cname);
<a name="l01486"></a>01486 
<a name="l01487"></a>01487         <span class="keywordflow">if</span> (retcode == 0) {
<a name="l01488"></a>01488             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM authenticated principal name: %s\n&quot;</span>,
<a name="l01489"></a>01489                         cname));
<a name="l01490"></a>01490             free(cname);
<a name="l01491"></a>01491         }
<a name="l01492"></a>01492 
<a name="l01493"></a>01493         <span class="comment">/*</span>
<a name="l01494"></a>01494 <span class="comment">         * Check to make sure AP_OPTS_MUTUAL_REQUIRED was set</span>
<a name="l01495"></a>01495 <span class="comment">         */</span>
<a name="l01496"></a>01496 
<a name="l01497"></a>01497         <span class="keywordflow">if</span> (!(flags &amp; AP_OPTS_MUTUAL_REQUIRED)) {
<a name="l01498"></a>01498             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l01499"></a>01499                         <span class="stringliteral">&quot;KSM MUTUAL_REQUIRED not set in request!\n&quot;</span>));
<a name="l01500"></a>01500             retval = SNMPERR_KRB5;
<a name="l01501"></a>01501             snmp_set_detail(<span class="stringliteral">&quot;MUTUAL_REQUIRED not set in message&quot;</span>);
<a name="l01502"></a>01502             <span class="keywordflow">goto</span> error;
<a name="l01503"></a>01503         }
<a name="l01504"></a>01504 
<a name="l01505"></a>01505         retcode =
<a name="l01506"></a>01506             krb5_auth_con_getremotesubkey(kcontext, auth_context, &amp;subkey);
<a name="l01507"></a>01507 
<a name="l01508"></a>01508         <span class="keywordflow">if</span> (retcode) {
<a name="l01509"></a>01509             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM remote subkey retrieval failed: %s\n&quot;</span>,
<a name="l01510"></a>01510                         error_message(retcode)));
<a name="l01511"></a>01511             retval = SNMPERR_KRB5;
<a name="l01512"></a>01512             snmp_set_detail(error_message(retcode));
<a name="l01513"></a>01513             <span class="keywordflow">goto</span> error;
<a name="l01514"></a>01514         }
<a name="l01515"></a>01515 
<a name="l01516"></a>01516 <span class="preprocessor">#ifndef NETSNMP_USE_KERBEROS_HEIMDAL</span>
<a name="l01517"></a>01517 <span class="preprocessor"></span>    } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ap_req.length &amp;&amp; (ap_req.data[0] == 0x6f ||
<a name="l01518"></a>01518                                  ap_req.data[0] == 0x4f)) {
<a name="l01519"></a>01519 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l01520"></a>01520     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ap_req.length &amp;&amp; (((<span class="keywordtype">char</span> *)ap_req.data)[0] == 0x6f ||
<a name="l01521"></a>01521                                  ((<span class="keywordtype">char</span> *)ap_req.data)[0] == 0x4f)) {
<a name="l01522"></a>01522 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l01523"></a>01523         <span class="comment">/*</span>
<a name="l01524"></a>01524 <span class="comment">         * Looks like a response; let&#39;s see if we&#39;ve got that auth_context</span>
<a name="l01525"></a>01525 <span class="comment">         * in our cache.</span>
<a name="l01526"></a>01526 <span class="comment">         */</span>
<a name="l01527"></a>01527 
<a name="l01528"></a>01528         krb5_ap_rep_enc_part *repl = NULL;
<a name="l01529"></a>01529 
<a name="l01530"></a>01530         response = 1;
<a name="l01531"></a>01531 
<a name="l01532"></a>01532         entry = ksm_get_cache(parms-&gt;pdu-&gt;<a class="code" href="structsnmp__pdu.html#a528226bcca644a9d42d63392fb9e6676" title="Message id for V3 messages note: incremented for each retry.">msgid</a>);
<a name="l01533"></a>01533 
<a name="l01534"></a>01534         <span class="keywordflow">if</span> (!entry) {
<a name="l01535"></a>01535             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l01536"></a>01536                         <span class="stringliteral">&quot;KSM: Unable to find auth_context for PDU with &quot;</span>
<a name="l01537"></a>01537                         <span class="stringliteral">&quot;message ID of %ld\n&quot;</span>, parms-&gt;pdu-&gt;<a class="code" href="structsnmp__pdu.html#a528226bcca644a9d42d63392fb9e6676" title="Message id for V3 messages note: incremented for each retry.">msgid</a>));
<a name="l01538"></a>01538             retval = SNMPERR_KRB5;
<a name="l01539"></a>01539             <span class="keywordflow">goto</span> error;
<a name="l01540"></a>01540         }
<a name="l01541"></a>01541 
<a name="l01542"></a>01542         auth_context = entry-&gt;auth_context;
<a name="l01543"></a>01543 
<a name="l01544"></a>01544         <span class="comment">/*</span>
<a name="l01545"></a>01545 <span class="comment">         * In that case, let&#39;s call the rd_rep function</span>
<a name="l01546"></a>01546 <span class="comment">         */</span>
<a name="l01547"></a>01547 
<a name="l01548"></a>01548         retcode = krb5_rd_rep(kcontext, auth_context, &amp;ap_req, &amp;repl);
<a name="l01549"></a>01549 
<a name="l01550"></a>01550         <span class="keywordflow">if</span> (repl)
<a name="l01551"></a>01551             krb5_free_ap_rep_enc_part(kcontext, repl);
<a name="l01552"></a>01552 
<a name="l01553"></a>01553         <span class="keywordflow">if</span> (retcode) {
<a name="l01554"></a>01554             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: krb5_rd_rep() failed: %s\n&quot;</span>,
<a name="l01555"></a>01555                         error_message(retcode)));
<a name="l01556"></a>01556             retval = SNMPERR_KRB5;
<a name="l01557"></a>01557             <span class="keywordflow">goto</span> error;
<a name="l01558"></a>01558         }
<a name="l01559"></a>01559 
<a name="l01560"></a>01560         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM: krb5_rd_rep() decoded successfully.\n&quot;</span>));
<a name="l01561"></a>01561 
<a name="l01562"></a>01562         retcode =
<a name="l01563"></a>01563             krb5_auth_con_getlocalsubkey(kcontext, auth_context, &amp;subkey);
<a name="l01564"></a>01564 
<a name="l01565"></a>01565         <span class="keywordflow">if</span> (retcode) {
<a name="l01566"></a>01566             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to retrieve local subkey: %s\n&quot;</span>,
<a name="l01567"></a>01567                         error_message(retcode)));
<a name="l01568"></a>01568             retval = SNMPERR_KRB5;
<a name="l01569"></a>01569             snmp_set_detail(<span class="stringliteral">&quot;Unable to retrieve local subkey&quot;</span>);
<a name="l01570"></a>01570             <span class="keywordflow">goto</span> error;
<a name="l01571"></a>01571         }
<a name="l01572"></a>01572 
<a name="l01573"></a>01573     } <span class="keywordflow">else</span> {
<a name="l01574"></a>01574 <span class="preprocessor">#ifndef NETSNMP_USE_KERBEROS_HEIMDAL</span>
<a name="l01575"></a>01575 <span class="preprocessor"></span>        DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unknown Kerberos message type (%02x)\n&quot;</span>,
<a name="l01576"></a>01576                     ap_req.data[0]));
<a name="l01577"></a>01577 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_HEIMDAL */</span>
<a name="l01578"></a>01578          DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unknown Kerberos message type (%02x)\n&quot;</span>,
<a name="l01579"></a>01579                     ((<span class="keywordtype">char</span> *)ap_req.data)[0]));
<a name="l01580"></a>01580 <span class="preprocessor">#endif</span>
<a name="l01581"></a>01581 <span class="preprocessor"></span>        retval = SNMPERR_KRB5;
<a name="l01582"></a>01582         snmp_set_detail(<span class="stringliteral">&quot;Unknown Kerberos message type&quot;</span>);
<a name="l01583"></a>01583         <span class="keywordflow">goto</span> error;
<a name="l01584"></a>01584     }
<a name="l01585"></a>01585 
<a name="l01586"></a>01586 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01587"></a>01587 <span class="preprocessor"></span>    input.data = (<span class="keywordtype">char</span> *) parms-&gt;wholeMsg;
<a name="l01588"></a>01588     input.length = parms-&gt;wholeMsgLen;
<a name="l01589"></a>01589 
<a name="l01590"></a>01590     retcode =
<a name="l01591"></a>01591         krb5_c_verify_checksum(kcontext, subkey, KSM_KEY_USAGE_CHECKSUM,
<a name="l01592"></a>01592                                &amp;input, &amp;checksum, &amp;valid);
<a name="l01593"></a>01593 <span class="preprocessor">#elif defined(OLD_HEIMDAL)      </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01594"></a>01594     retcode = krb5_crypto_init(kcontext, subkey, 0, &amp;heim_crypto);
<a name="l01595"></a>01595     <span class="keywordflow">if</span> (retcode) {
<a name="l01596"></a>01596             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;krb5_crypto_init failed: %s\n&quot;</span>,
<a name="l01597"></a>01597                         error_message(retcode)));
<a name="l01598"></a>01598             snmp_set_detail(error_message(retcode));
<a name="l01599"></a>01599             retval = SNMPERR_KRB5;
<a name="l01600"></a>01600             <span class="keywordflow">goto</span> error;
<a name="l01601"></a>01601     }
<a name="l01602"></a>01602     retcode = krb5_verify_checksum(kcontext, heim_crypto,
<a name="l01603"></a>01603                                    KSM_KEY_USAGE_CHECKSUM, parms-&gt;wholeMsg,
<a name="l01604"></a>01604                                    parms-&gt;wholeMsgLen, &amp;checksum);
<a name="l01605"></a>01605 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01606"></a>01606     retcode = krb5_verify_checksum(kcontext, cksumtype, &amp;checksum,
<a name="l01607"></a>01607                                    parms-&gt;wholeMsg, parms-&gt;wholeMsgLen,
<a name="l01608"></a>01608                                    (krb5_pointer) subkey-&gt;contents,
<a name="l01609"></a>01609                                    subkey-&gt;length);
<a name="l01610"></a>01610 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01611"></a>01611 
<a name="l01612"></a>01612     <span class="keywordflow">if</span> (retcode) {
<a name="l01613"></a>01613         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM checksum verification failed: %s\n&quot;</span>,
<a name="l01614"></a>01614                     error_message(retcode)));
<a name="l01615"></a>01615         retval = SNMPERR_KRB5;
<a name="l01616"></a>01616         snmp_set_detail(error_message(retcode));
<a name="l01617"></a>01617         <span class="keywordflow">goto</span> error;
<a name="l01618"></a>01618     }
<a name="l01619"></a>01619 
<a name="l01620"></a>01620     <span class="comment">/*</span>
<a name="l01621"></a>01621 <span class="comment">     * Don&#39;t ask me why they didn&#39;t simply return an error, but we have</span>
<a name="l01622"></a>01622 <span class="comment">     * to check to see if &quot;valid&quot; is false.</span>
<a name="l01623"></a>01623 <span class="comment">     */</span>
<a name="l01624"></a>01624 
<a name="l01625"></a>01625 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01626"></a>01626 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (!valid) {
<a name="l01627"></a>01627         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Computed checksum did not match supplied &quot;</span>
<a name="l01628"></a>01628                     <span class="stringliteral">&quot;checksum!\n&quot;</span>));
<a name="l01629"></a>01629         retval = SNMPERR_KRB5;
<a name="l01630"></a>01630         snmp_set_detail
<a name="l01631"></a>01631             (<span class="stringliteral">&quot;Computed checksum did not match supplied checksum&quot;</span>);
<a name="l01632"></a>01632         <span class="keywordflow">goto</span> error;
<a name="l01633"></a>01633     }
<a name="l01634"></a>01634 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01635"></a>01635 
<a name="l01636"></a>01636     <span class="comment">/*</span>
<a name="l01637"></a>01637 <span class="comment">     * Handle an encrypted PDU.  Note that it&#39;s an OCTET_STRING of the</span>
<a name="l01638"></a>01638 <span class="comment">     * output of whatever Kerberos cryptosystem you&#39;re using (defined by</span>
<a name="l01639"></a>01639 <span class="comment">     * the encryption type).  Note that this is NOT the EncryptedData</span>
<a name="l01640"></a>01640 <span class="comment">     * sequence - it&#39;s what goes in the &quot;cipher&quot; field of EncryptedData.</span>
<a name="l01641"></a>01641 <span class="comment">     */</span>
<a name="l01642"></a>01642 
<a name="l01643"></a>01643     <span class="keywordflow">if</span> (parms-&gt;secLevel == SNMP_SEC_LEVEL_AUTHPRIV) {
<a name="l01644"></a>01644 
<a name="l01645"></a>01645         <span class="keywordflow">if</span> ((current = asn_parse_sequence(current, &amp;length, &amp;type,
<a name="l01646"></a>01646                                           (ASN_UNIVERSAL | ASN_PRIMITIVE |
<a name="l01647"></a>01647                                            ASN_OCTET_STR), <span class="stringliteral">&quot;ksm pdu&quot;</span>)) ==
<a name="l01648"></a>01648             NULL) {
<a name="l01649"></a>01649             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM sPDU octet decoding failed\n&quot;</span>));
<a name="l01650"></a>01650             retval = SNMPERR_ASN_PARSE_ERR;
<a name="l01651"></a>01651             <span class="keywordflow">goto</span> error;
<a name="l01652"></a>01652         }
<a name="l01653"></a>01653 
<a name="l01654"></a>01654         <span class="comment">/*</span>
<a name="l01655"></a>01655 <span class="comment">         * The PDU is now pointed at by &quot;current&quot;, and the length is in</span>
<a name="l01656"></a>01656 <span class="comment">         * &quot;length&quot;.</span>
<a name="l01657"></a>01657 <span class="comment">         */</span>
<a name="l01658"></a>01658 
<a name="l01659"></a>01659         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM starting sPDU decode\n&quot;</span>));
<a name="l01660"></a>01660 
<a name="l01661"></a>01661         <span class="comment">/*</span>
<a name="l01662"></a>01662 <span class="comment">         * We need to set up a blank initialization vector for the decryption.</span>
<a name="l01663"></a>01663 <span class="comment">         * Use a block of all zero&#39;s (which is dependent on the block size</span>
<a name="l01664"></a>01664 <span class="comment">         * of the encryption method).</span>
<a name="l01665"></a>01665 <span class="comment">         */</span>
<a name="l01666"></a>01666 
<a name="l01667"></a>01667 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01668"></a>01668 <span class="preprocessor"></span>
<a name="l01669"></a>01669         retcode = krb5_c_block_size(kcontext, subkey-&gt;enctype, &amp;blocksize);
<a name="l01670"></a>01670 
<a name="l01671"></a>01671         <span class="keywordflow">if</span> (retcode) {
<a name="l01672"></a>01672             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l01673"></a>01673                         <span class="stringliteral">&quot;Unable to determine crypto block size: %s\n&quot;</span>,
<a name="l01674"></a>01674                         error_message(retcode)));
<a name="l01675"></a>01675             snmp_set_detail(error_message(retcode));
<a name="l01676"></a>01676             retval = SNMPERR_KRB5;
<a name="l01677"></a>01677             <span class="keywordflow">goto</span> error;
<a name="l01678"></a>01678         }
<a name="l01679"></a>01679 <span class="preprocessor">#elif defined(OLD_HEIMDAL)      </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01680"></a>01680 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01681"></a>01681 
<a name="l01682"></a>01682         blocksize =
<a name="l01683"></a>01683             krb5_enctype_array[subkey-&gt;enctype]-&gt;system-&gt;block_length;
<a name="l01684"></a>01684 
<a name="l01685"></a>01685 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01686"></a>01686 
<a name="l01687"></a>01687 <span class="preprocessor">#ifndef OLD_HEIMDAL</span>
<a name="l01688"></a>01688 <span class="preprocessor"></span>        ivector.data = malloc(blocksize);
<a name="l01689"></a>01689 
<a name="l01690"></a>01690         <span class="keywordflow">if</span> (!ivector.data) {
<a name="l01691"></a>01691             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Unable to allocate %d bytes for ivector\n&quot;</span>,
<a name="l01692"></a>01692                         blocksize));
<a name="l01693"></a>01693             retval = SNMPERR_MALLOC;
<a name="l01694"></a>01694             <span class="keywordflow">goto</span> error;
<a name="l01695"></a>01695         }
<a name="l01696"></a>01696 
<a name="l01697"></a>01697         ivector.length = blocksize;
<a name="l01698"></a>01698         memset(ivector.data, 0, blocksize);
<a name="l01699"></a>01699 
<a name="l01700"></a>01700 <span class="preprocessor">#ifndef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01701"></a>01701 <span class="preprocessor"></span>
<a name="l01702"></a>01702         krb5_use_enctype(kcontext, &amp;eblock, subkey-&gt;enctype);
<a name="l01703"></a>01703 
<a name="l01704"></a>01704         retcode = krb5_process_key(kcontext, &amp;eblock, subkey);
<a name="l01705"></a>01705 
<a name="l01706"></a>01706         <span class="keywordflow">if</span> (retcode) {
<a name="l01707"></a>01707             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM key post-processing failed: %s\n&quot;</span>,
<a name="l01708"></a>01708                         error_message(retcode)));
<a name="l01709"></a>01709             snmp_set_detail(error_message(retcode));
<a name="l01710"></a>01710             retval = SNMPERR_KRB5;
<a name="l01711"></a>01711             <span class="keywordflow">goto</span> error;
<a name="l01712"></a>01712         }
<a name="l01713"></a>01713 <span class="preprocessor">#endif                          </span><span class="comment">/* !NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01714"></a>01714 
<a name="l01715"></a>01715 <span class="preprocessor">#endif </span><span class="comment">/* ! OLD_HEIMDAL */</span>
<a name="l01716"></a>01716 
<a name="l01717"></a>01717         <span class="keywordflow">if</span> (length &gt; *parms-&gt;scopedPduLen) {
<a name="l01718"></a>01718             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM not enough room - have %d bytes to &quot;</span>
<a name="l01719"></a>01719                         <span class="stringliteral">&quot;decrypt but only %d bytes available\n&quot;</span>, length,
<a name="l01720"></a>01720                         *parms-&gt;scopedPduLen));
<a name="l01721"></a>01721             retval = SNMPERR_TOO_LONG;
<a name="l01722"></a>01722 <span class="preprocessor">#ifndef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01723"></a>01723 <span class="preprocessor"></span><span class="preprocessor">#ifndef OLD_HEIMDAL</span>
<a name="l01724"></a>01724 <span class="preprocessor"></span>            krb5_finish_key(kcontext, &amp;eblock);
<a name="l01725"></a>01725 <span class="preprocessor">#endif                          </span><span class="comment">/* ! OLD_HEIMDAL */</span>
<a name="l01726"></a>01726 <span class="preprocessor">#endif                          </span><span class="comment">/* ! NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01727"></a>01727             <span class="keywordflow">goto</span> error;
<a name="l01728"></a>01728         }
<a name="l01729"></a>01729 <span class="preprocessor">#ifdef NETSNMP_USE_KERBEROS_MIT</span>
<a name="l01730"></a>01730 <span class="preprocessor"></span>        in_crypt.ciphertext.data = (<span class="keywordtype">char</span> *) current;
<a name="l01731"></a>01731         in_crypt.ciphertext.length = length;
<a name="l01732"></a>01732         in_crypt.enctype = subkey-&gt;enctype;
<a name="l01733"></a>01733         output.data = (<span class="keywordtype">char</span> *) *parms-&gt;scopedPdu;
<a name="l01734"></a>01734         output.length = *parms-&gt;scopedPduLen;
<a name="l01735"></a>01735 
<a name="l01736"></a>01736         retcode =
<a name="l01737"></a>01737             krb5_c_decrypt(kcontext, subkey, KSM_KEY_USAGE_ENCRYPTION,
<a name="l01738"></a>01738                            &amp;ivector, &amp;in_crypt, &amp;output);
<a name="l01739"></a>01739 <span class="preprocessor">#elif defined (OLD_HEIMDAL)     </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01740"></a>01740         retcode = krb5_decrypt(kcontext, heim_crypto, KSM_KEY_USAGE_ENCRYPTION,
<a name="l01741"></a>01741                                current, length, &amp;output);
<a name="l01742"></a>01742         <span class="keywordflow">if</span> (retcode == 0) {
<a name="l01743"></a>01743                 *parms-&gt;scopedPdu = (<span class="keywordtype">char</span> *) output.data;
<a name="l01744"></a>01744                 *parms-&gt;scopedPduLen = output.length;
<a name="l01745"></a>01745                 krb5_data_zero(&amp;output);
<a name="l01746"></a>01746         }
<a name="l01747"></a>01747 <span class="preprocessor">#else                           </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01748"></a>01748 
<a name="l01749"></a>01749         retcode = krb5_decrypt(kcontext, (krb5_pointer) current,
<a name="l01750"></a>01750                                *parms-&gt;scopedPdu, length, &amp;eblock,
<a name="l01751"></a>01751                                ivector.data);
<a name="l01752"></a>01752 
<a name="l01753"></a>01753         krb5_finish_key(kcontext, &amp;eblock);
<a name="l01754"></a>01754 
<a name="l01755"></a>01755 <span class="preprocessor">#endif                          </span><span class="comment">/* NETSNMP_USE_KERBEROS_MIT */</span>
<a name="l01756"></a>01756 
<a name="l01757"></a>01757         <span class="keywordflow">if</span> (retcode) {
<a name="l01758"></a>01758             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Decryption failed: %s\n&quot;</span>,
<a name="l01759"></a>01759                         error_message(retcode)));
<a name="l01760"></a>01760             snmp_set_detail(error_message(retcode));
<a name="l01761"></a>01761             retval = SNMPERR_KRB5;
<a name="l01762"></a>01762             <span class="keywordflow">goto</span> error;
<a name="l01763"></a>01763         }
<a name="l01764"></a>01764 
<a name="l01765"></a>01765         *parms-&gt;scopedPduLen = length;
<a name="l01766"></a>01766 
<a name="l01767"></a>01767     } <span class="keywordflow">else</span> {
<a name="l01768"></a>01768         <span class="comment">/*</span>
<a name="l01769"></a>01769 <span class="comment">         * Clear PDU</span>
<a name="l01770"></a>01770 <span class="comment">         */</span>
<a name="l01771"></a>01771 
<a name="l01772"></a>01772         *parms-&gt;scopedPdu = current;
<a name="l01773"></a>01773         *parms-&gt;scopedPduLen =
<a name="l01774"></a>01774             parms-&gt;wholeMsgLen - (current - parms-&gt;wholeMsg);
<a name="l01775"></a>01775     }
<a name="l01776"></a>01776 
<a name="l01777"></a>01777     <span class="comment">/*</span>
<a name="l01778"></a>01778 <span class="comment">     * A HUGE GROSS HACK</span>
<a name="l01779"></a>01779 <span class="comment">     */</span>
<a name="l01780"></a>01780 
<a name="l01781"></a>01781     *parms-&gt;maxSizeResponse = parms-&gt;maxMsgSize - 200;
<a name="l01782"></a>01782 
<a name="l01783"></a>01783     DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM processing complete\n&quot;</span>));
<a name="l01784"></a>01784 
<a name="l01785"></a>01785     <span class="comment">/*</span>
<a name="l01786"></a>01786 <span class="comment">     * Set the secName to the right value (a hack for now).  But that&#39;s</span>
<a name="l01787"></a>01787 <span class="comment">     * only used for when we&#39;re processing a request, not a response.</span>
<a name="l01788"></a>01788 <span class="comment">     */</span>
<a name="l01789"></a>01789 
<a name="l01790"></a>01790     <span class="keywordflow">if</span> (!response) {
<a name="l01791"></a>01791 
<a name="l01792"></a>01792         retcode = krb5_unparse_name(kcontext, TICKET_CLIENT(ticket),
<a name="l01793"></a>01793                                     &amp;cname);
<a name="l01794"></a>01794 
<a name="l01795"></a>01795         <span class="keywordflow">if</span> (retcode) {
<a name="l01796"></a>01796             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM krb5_unparse_name failed: %s\n&quot;</span>,
<a name="l01797"></a>01797                         error_message(retcode)));
<a name="l01798"></a>01798             snmp_set_detail(error_message(retcode));
<a name="l01799"></a>01799             retval = SNMPERR_KRB5;
<a name="l01800"></a>01800             <span class="keywordflow">goto</span> error;
<a name="l01801"></a>01801         }
<a name="l01802"></a>01802 
<a name="l01803"></a>01803         <span class="keywordflow">if</span> (strlen(cname) &gt; *parms-&gt;secNameLen + 1) {
<a name="l01804"></a>01804             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>,
<a name="l01805"></a>01805                         <span class="stringliteral">&quot;KSM: Principal length (%d) is too long (%d)\n&quot;</span>,
<a name="l01806"></a>01806                         strlen(cname), parms-&gt;secNameLen));
<a name="l01807"></a>01807             retval = SNMPERR_TOO_LONG;
<a name="l01808"></a>01808             free(cname);
<a name="l01809"></a>01809             <span class="keywordflow">goto</span> error;
<a name="l01810"></a>01810         }
<a name="l01811"></a>01811 
<a name="l01812"></a>01812         strcpy(parms-&gt;secName, cname);
<a name="l01813"></a>01813         *parms-&gt;secNameLen = strlen(cname);
<a name="l01814"></a>01814 
<a name="l01815"></a>01815         free(cname);
<a name="l01816"></a>01816 
<a name="l01817"></a>01817         <span class="comment">/*</span>
<a name="l01818"></a>01818 <span class="comment">         * Also, if we&#39;re not a response, keep around our auth_context so we</span>
<a name="l01819"></a>01819 <span class="comment">         * can encode the reply message correctly</span>
<a name="l01820"></a>01820 <span class="comment">         */</span>
<a name="l01821"></a>01821 
<a name="l01822"></a>01822         ksm_state = <a class="code" href="group__util.html#ga6356941968481380ea6f4a646df4aaf9" title="Mallocs memory of sizeof(struct s), zeros it and returns a pointer to it.">SNMP_MALLOC_STRUCT</a>(<a class="code" href="structksm__secStateRef.html">ksm_secStateRef</a>);
<a name="l01823"></a>01823 
<a name="l01824"></a>01824         <span class="keywordflow">if</span> (!ksm_state) {
<a name="l01825"></a>01825             DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;KSM unable to malloc memory for &quot;</span>
<a name="l01826"></a>01826                         <span class="stringliteral">&quot;ksm_secStateRef\n&quot;</span>));
<a name="l01827"></a>01827             retval = SNMPERR_MALLOC;
<a name="l01828"></a>01828             <span class="keywordflow">goto</span> error;
<a name="l01829"></a>01829         }
<a name="l01830"></a>01830 
<a name="l01831"></a>01831         ksm_state-&gt;auth_context = auth_context;
<a name="l01832"></a>01832         auth_context = NULL;
<a name="l01833"></a>01833         ksm_state-&gt;cksumtype = cksumtype;
<a name="l01834"></a>01834 
<a name="l01835"></a>01835         *parms-&gt;secStateRef = ksm_state;
<a name="l01836"></a>01836     } <span class="keywordflow">else</span> {
<a name="l01837"></a>01837 
<a name="l01838"></a>01838         <span class="comment">/*</span>
<a name="l01839"></a>01839 <span class="comment">         * We _still_ have to set the secName in process_in_msg().  Do</span>
<a name="l01840"></a>01840 <span class="comment">         * that now with what we were passed in before (we cached it,</span>
<a name="l01841"></a>01841 <span class="comment">         * remember?)</span>
<a name="l01842"></a>01842 <span class="comment">         */</span>
<a name="l01843"></a>01843 
<a name="l01844"></a>01844         memcpy(parms-&gt;secName, entry-&gt;secName, entry-&gt;secNameLen);
<a name="l01845"></a>01845         *parms-&gt;secNameLen = entry-&gt;secNameLen;
<a name="l01846"></a>01846     }
<a name="l01847"></a>01847 
<a name="l01848"></a>01848     <span class="comment">/*</span>
<a name="l01849"></a>01849 <span class="comment">     * Just in case</span>
<a name="l01850"></a>01850 <span class="comment">     */</span>
<a name="l01851"></a>01851 
<a name="l01852"></a>01852     parms-&gt;secEngineID = (u_char *) <span class="stringliteral">&quot;&quot;</span>;
<a name="l01853"></a>01853     *parms-&gt;secEngineIDLen = 0;
<a name="l01854"></a>01854 
<a name="l01855"></a>01855     auth_context = NULL;        <span class="comment">/* So we don&#39;t try to free it on success */</span>
<a name="l01856"></a>01856 
<a name="l01857"></a>01857   error:
<a name="l01858"></a>01858     <span class="keywordflow">if</span> (retval == SNMPERR_ASN_PARSE_ERR &amp;&amp;
<a name="l01859"></a>01859         snmp_increment_statistic(STAT_SNMPINASNPARSEERRS) == 0)
<a name="l01860"></a>01860         DEBUGMSGTL((<span class="stringliteral">&quot;ksm&quot;</span>, <span class="stringliteral">&quot;Failed to increment statistics.\n&quot;</span>));
<a name="l01861"></a>01861 
<a name="l01862"></a>01862     <span class="keywordflow">if</span> (subkey)
<a name="l01863"></a>01863         krb5_free_keyblock(kcontext, subkey);
<a name="l01864"></a>01864 
<a name="l01865"></a>01865 <span class="preprocessor">#ifdef OLD_HEIMDAL </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01866"></a>01866     <span class="keywordflow">if</span> (heim_crypto)
<a name="l01867"></a>01867             krb5_crypto_destroy(kcontext, heim_crypto);
<a name="l01868"></a>01868 <span class="preprocessor">#endif </span><span class="comment">/* OLD_HEIMDAL */</span>
<a name="l01869"></a>01869 
<a name="l01870"></a>01870     <span class="keywordflow">if</span> (CHECKSUM_CONTENTS(&amp;checksum))
<a name="l01871"></a>01871         free(CHECKSUM_CONTENTS(&amp;checksum));
<a name="l01872"></a>01872 
<a name="l01873"></a>01873     <span class="keywordflow">if</span> (ivector.data)
<a name="l01874"></a>01874         free(ivector.data);
<a name="l01875"></a>01875 
<a name="l01876"></a>01876     <span class="keywordflow">if</span> (ticket)
<a name="l01877"></a>01877         krb5_free_ticket(kcontext, ticket);
<a name="l01878"></a>01878 
<a name="l01879"></a>01879     <span class="keywordflow">if</span> (!response &amp;&amp; auth_context)
<a name="l01880"></a>01880         krb5_auth_con_free(kcontext, auth_context);
<a name="l01881"></a>01881 
<a name="l01882"></a>01882     <span class="keywordflow">if</span> (ap_req.data)
<a name="l01883"></a>01883         free(ap_req.data);
<a name="l01884"></a>01884 
<a name="l01885"></a>01885     <span class="keywordflow">return</span> retval;
<a name="l01886"></a>01886 }
</pre></div></div><!-- contents -->


<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.7.6.1
</small></address>

</body>
</html>