| 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
 <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 Page</span></a></li>
<li><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="annotated.html"><span>Data 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 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 <net-snmp/net-snmp-config.h></span>
<a name="l00010"></a>00010
<a name="l00011"></a>00011 <span class="preprocessor">#include <sys/types.h></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 <winsock.h></span>
<a name="l00014"></a>00014 <span class="preprocessor">#endif</span>
<a name="l00015"></a>00015 <span class="preprocessor"></span><span class="preprocessor">#include <stdio.h></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 <stdlib.h></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 <sys/timeb.h></span>
<a name="l00022"></a>00022 <span class="preprocessor"># else</span>
<a name="l00023"></a>00023 <span class="preprocessor"></span><span class="preprocessor"># include <sys/time.h></span>
<a name="l00024"></a>00024 <span class="preprocessor"># endif</span>
<a name="l00025"></a>00025 <span class="preprocessor"></span><span class="preprocessor"># include <time.h></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 <sys/time.h></span>
<a name="l00029"></a>00029 <span class="preprocessor"># else</span>
<a name="l00030"></a>00030 <span class="preprocessor"></span><span class="preprocessor"># include <time.h></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 <string.h></span>
<a name="l00035"></a>00035 <span class="preprocessor">#else</span>
<a name="l00036"></a>00036 <span class="preprocessor"></span><span class="preprocessor">#include <strings.h></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 <netinet/in.h></span>
<a name="l00040"></a>00040 <span class="preprocessor">#endif</span>
<a name="l00041"></a>00041 <span class="preprocessor"></span><span class="preprocessor">#include <errno.h></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 <dmalloc.h></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 <krb5.h></span>
<a name="l00058"></a>00058 <span class="preprocessor">#include <com_err.h></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)->cksumtype</span>
<a name="l00065"></a>00065 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_CONTENTS(x) ((char *)((x)->checksum.data))</span>
<a name="l00066"></a>00066 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_LENGTH(x) (x)->checksum.length</span>
<a name="l00067"></a>00067 <span class="preprocessor"></span><span class="preprocessor">#define TICKET_CLIENT(x) (x)->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)->checksum_type</span>
<a name="l00070"></a>00070 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_CONTENTS(x) (x)->contents</span>
<a name="l00071"></a>00071 <span class="preprocessor"></span><span class="preprocessor">#define CHECKSUM_LENGTH(x) (x)->length</span>
<a name="l00072"></a>00072 <span class="preprocessor"></span><span class="preprocessor">#define TICKET_CLIENT(x) (x)->enc_part2->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 <net-snmp/output_api.h></span>
<a name="l00076"></a>00076 <span class="preprocessor">#include <net-snmp/config_api.h></span>
<a name="l00077"></a>00077 <span class="preprocessor">#include <net-snmp/utilities.h></span>
<a name="l00078"></a>00078
<a name="l00079"></a>00079 <span class="preprocessor">#include <net-snmp/library/asn1.h></span>
<a name="l00080"></a>00080 <span class="preprocessor">#include <net-snmp/library/snmp_api.h></span>
<a name="l00081"></a>00081 <span class="preprocessor">#include <net-snmp/library/callback.h></span>
<a name="l00082"></a>00082 <span class="preprocessor">#include <net-snmp/library/keytools.h></span>
<a name="l00083"></a>00083 <span class="preprocessor">#include <net-snmp/library/snmpv3.h></span>
<a name="l00084"></a>00084 <span class="preprocessor">#include <net-snmp/library/lcd_time.h></span>
<a name="l00085"></a>00085 <span class="preprocessor">#include <net-snmp/library/scapi.h></span>
<a name="l00086"></a>00086 <span class="preprocessor">#include <net-snmp/library/callback.h></span>
<a name="l00087"></a>00087 <span class="preprocessor">#include <net-snmp/library/snmp_secmod.h></span>
<a name="l00088"></a>00088 <span class="preprocessor">#include <net-snmp/library/snmpksm.h></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'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't know if these are</span>
<a name="l00140"></a>00140 <span class="comment"> * needed, since i don'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'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'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">"host"</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'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">"ksm"</span>, <span class="stringliteral">"Using keytab %s\n"</span>, c));
<a name="l00173"></a>00173 retval = krb5_kt_resolve(kcontext, c, &keytab);
<a name="l00174"></a>00174 <span class="keywordflow">if</span> (retval) {
<a name="l00175"></a>00175 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"krb5_kt_resolve(\"%s\") failed. KSM "</span>
<a name="l00176"></a>00176 <span class="stringliteral">"config callback failing\n"</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">"ksm"</span>, <span class="stringliteral">"Using default keytab\n"</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">"snmp"</span>, <span class="stringliteral">"defKSMKeytab"</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">"snmp"</span>, <span class="stringliteral">"defKSMServiceName"</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(&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">"ksm"</span>, <span class="stringliteral">"krb5_init_context failed (%s), not "</span>
<a name="l00216"></a>00216 <span class="stringliteral">"registering KSM\n"</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 < 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">"ksm"</span>, <span class="stringliteral">"Unable to malloc snmp_secmod struct, not "</span>
<a name="l00228"></a>00228 <span class="stringliteral">"registering KSM\n"</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->encode_reverse = ksm_rgenerate_out_msg;
<a name="l00233"></a>00233 def->decode = ksm_process_in_msg;
<a name="l00234"></a>00234 def->session_open = ksm_session_init;
<a name="l00235"></a>00235 def->pdu_free_state_ref = ksm_free_state_ref;
<a name="l00236"></a>00236 def->pdu_free = ksm_free_pdu;
<a name="l00237"></a>00237 def->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">"ksm"</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'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->msgid = msgid;
<a name="l00266"></a>00266 entry->auth_context = auth_context;
<a name="l00267"></a>00267 entry->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>(&entry->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->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->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->next)
<a name="l00296"></a>00296 <span class="keywordflow">if</span> (entry->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] && ksm_hash_table[bucket]->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->refcount <= 0) {
<a name="l00318"></a>00318 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Freeing entry for msgid %ld\n"</span>, msgid));
<a name="l00319"></a>00319 krb5_auth_con_free(kcontext, entry->auth_context);
<a name="l00320"></a>00320 free(entry->secName);
<a name="l00321"></a>00321 ksm_hash_table[bucket] = entry->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->next;
<a name="l00329"></a>00329 entry != NULL; entry1 = entry, entry = entry->next)
<a name="l00330"></a>00330 <span class="keywordflow">if</span> (entry->msgid == msgid) {
<a name="l00331"></a>00331
<a name="l00332"></a>00332 <span class="keywordflow">if</span> (--entry->refcount <= 0) {
<a name="l00333"></a>00333 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Freeing entry for msgid %ld\n"</span>,
<a name="l00334"></a>00334 msgid));
<a name="l00335"></a>00335 krb5_auth_con_free(kcontext, entry->auth_context);
<a name="l00336"></a>00336 free(entry->secName);
<a name="l00337"></a>00337 entry1->next = entry->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">"ksm"</span>,
<a name="l00345"></a>00345 <span class="stringliteral">"KSM: Unable to decrement cache entry for msgid %ld.\n"</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">"ksm"</span>, <span class="stringliteral">"Unable to find cache entry for msgid %ld "</span>
<a name="l00356"></a>00356 <span class="stringliteral">"for increment\n"</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->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">"ksm"</span>,
<a name="l00372"></a>00372 <span class="stringliteral">"KSM: Reached our session initialization callback\n"</span>));
<a name="l00373"></a>00373
<a name="l00374"></a>00374 sess->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">"ksm"</span>, <span class="stringliteral">"KSM: Freeing state reference\n"</span>));
<a name="l00389"></a>00389
<a name="l00390"></a>00390 krb5_auth_con_free(kcontext, ref->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-><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">"ksm"</span>, <span class="stringliteral">"Decrementing cache entry for PDU msgid %ld\n"</span>,
<a name="l00406"></a>00406 pdu-><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-><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">"ksm"</span>, <span class="stringliteral">"Incrementing cache entry for PDU msgid %ld\n"</span>,
<a name="l00421"></a>00421 pdu-><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->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->wholeMsg;
<a name="l00469"></a>00469 <span class="keywordtype">size_t</span> *offset = parms->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->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">"ksm"</span>, <span class="stringliteral">"Starting KSM processing\n"</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(&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've got a port number as part of the "peername", 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 "udp:host" style addresses?</span>
<a name="l00491"></a>00491 <span class="comment"> */</span>
<a name="l00492"></a>00492 colon = strrchr(params->session->peername, <span class="charliteral">':'</span>);
<a name="l00493"></a>00493 <span class="keywordflow">if</span> (colon != NULL) {
<a name="l00494"></a>00494 *colon=<span class="charliteral">'\0'</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't have a ksm_state, then we'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, &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">"ksm"</span>, <span class="stringliteral">"KSM: krb5_cc_default failed: %s\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: Set credential cache successfully\n"</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'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'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, &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->session-><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, &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">':'</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">"ksm"</span>, <span class="stringliteral">"KSM: krb5_mk_req failed: %s\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: ticket retrieved successfully for \"%s/%s\" "</span>
<a name="l00540"></a>00540 <span class="stringliteral">"(may not be actual ticket sname)\n"</span>, service_name,
<a name="l00541"></a>00541 parms->session-><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->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're in an agent</span>
<a name="l00554"></a>00554 <span class="comment"> * and we'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">"ksm"</span>, <span class="stringliteral">"KSM: Starting reply processing.\n"</span>));
<a name="l00558"></a>00558
<a name="l00559"></a>00559 retcode = krb5_mk_rep(kcontext, auth_context, &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">"ksm"</span>, <span class="stringliteral">"KSM: krb5_mk_rep failed: %s\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: Finished with krb5_mk_rep()\n"</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->secLevel == SNMP_SEC_LEVEL_AUTHPRIV) {
<a name="l00577"></a>00577
<a name="l00578"></a>00578 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"KSM: Starting PDU encryption.\n"</span>));
<a name="l00579"></a>00579
<a name="l00580"></a>00580 <span class="comment">/*</span>
<a name="l00581"></a>00581 <span class="comment"> * It's weird -</span>
<a name="l00582"></a>00582 <span class="comment"> *</span>
<a name="l00583"></a>00583 <span class="comment"> * If we're on the manager, it's a local subkey (because that'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're on the agent, it'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 &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 &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">"ksm"</span>,
<a name="l00599"></a>00599 <span class="stringliteral">"KSM: krb5_auth_con_getlocalsubkey failed: %s\n"</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->enctype,
<a name="l00614"></a>00614 parms->scopedPduLen,
<a name="l00615"></a>00615 &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">"ksm"</span>,
<a name="l00619"></a>00619 <span class="stringliteral">"Encryption length calculation failed: %s\n"</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, &heim_crypto);
<a name="l00627"></a>00627 <span class="keywordflow">if</span> (retcode) {
<a name="l00628"></a>00628 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"krb5_crypto_init failed: %s\n"</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->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, &eblock, subkey->enctype);
<a name="l00639"></a>00639 retcode = krb5_process_key(kcontext, &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">"ksm"</span>, <span class="stringliteral">"krb5_process_key failed: %s\n"</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->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">"ksm"</span>,
<a name="l00658"></a>00658 <span class="stringliteral">"KSM: Unable to malloc %d bytes for encrypt "</span>
<a name="l00659"></a>00659 <span class="stringliteral">"buffer: %s\n"</span>, parms->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, &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'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->enctype, &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">"ksm"</span>,
<a name="l00682"></a>00682 <span class="stringliteral">"Unable to determine crypto block size: %s\n"</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->enctype]->system->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">"ksm"</span>, <span class="stringliteral">"Unable to allocate %d bytes for ivector\n"</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->scopedPdu;
<a name="l00717"></a>00717 input.length = parms->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 &ivector, &input, &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(&encrypted_scoped_pdu);
<a name="l00728"></a>00728 retcode = krb5_encrypt(kcontext, heim_crypto, KSM_KEY_USAGE_ENCRYPTION,
<a name="l00729"></a>00729 parms->scopedPdu, parms->scopedPduLen,
<a name="l00730"></a>00730 &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(&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->scopedPdu,
<a name="l00739"></a>00739 (krb5_pointer) encrypted_data,
<a name="l00740"></a>00740 parms->scopedPduLen, &eblock, ivector.data);
<a name="l00741"></a>00741
<a name="l00742"></a>00742 krb5_finish_key(kcontext, &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">"ksm"</span>, <span class="stringliteral">"KSM: krb5_encrypt failed: %s\n"</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->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">"ksm"</span>, <span class="stringliteral">"Building encrypted payload failed.\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: Encryption complete.\n"</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->wholeMsgLen < parms->scopedPduLen) {
<a name="l00778"></a>00778 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Not enough room for plaintext PDU.\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: scopedPdu added to payload\n"</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->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> *) &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">"ksm"</span>, <span class="stringliteral">"Building ksm security parameters failed.\n"</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->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">"ksm"</span>, <span class="stringliteral">"Building ksm AP_REQ failed.\n"</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't encrypt the packet, we haven'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 &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 &subkey);
<a name="l00833"></a>00833 <span class="keywordflow">if</span> (retcode) {
<a name="l00834"></a>00834 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"krb5_auth_con_getlocalsubkey failed: %s\n"</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, &heim_crypto);
<a name="l00842"></a>00842 <span class="keywordflow">if</span> (retcode) {
<a name="l00843"></a>00843 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"krb5_crypto_init failed: %s\n"</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 "right" 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 "approved" 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->enctype,
<a name="l00860"></a>00860 &numcksumtypes, &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">"ksm"</span>, <span class="stringliteral">"Unable to find appropriate keyed checksum: %s\n"</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 <= 0) {
<a name="l00871"></a>00871 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"We received a list of zero cksumtypes for this "</span>
<a name="l00872"></a>00872 <span class="stringliteral">"enctype (%d)\n"</span>, subkey->enctype));
<a name="l00873"></a>00873 snmp_set_detail(<span class="stringliteral">"No valid checksum type for this encryption type"</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's not clear to me from the API which checksum you're supposed</span>
<a name="l00880"></a>00880 <span class="comment"> * to support, so I'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">"ksm"</span>, <span class="stringliteral">"KSM: Choosing checksum type of %d (subkey type "</span>
<a name="l00888"></a>00888 <span class="stringliteral">"of %d)\n"</span>, cksumtype, subkey->enctype));
<a name="l00889"></a>00889
<a name="l00890"></a>00890 retcode = krb5_c_checksum_length(kcontext, cksumtype, &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">"ksm"</span>, <span class="stringliteral">"Unable to determine checksum length: %s\n"</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(&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->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->scopedPdu, parms->scopedPduLen,
<a name="l00912"></a>00912 &pdu_checksum);
<a name="l00913"></a>00913 <span class="keywordflow">if</span> (retval) {
<a name="l00914"></a>00914 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Unable to create a checksum: %s\n"</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(&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">"ksm"</span>, <span class="stringliteral">"Checksum type %d is not a keyed checksum\n"</span>,
<a name="l00932"></a>00932 cksumtype));
<a name="l00933"></a>00933 snmp_set_detail(<span class="stringliteral">"Checksum is not a keyed checksum"</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">"ksm"</span>, <span class="stringliteral">"Checksum type %d is not a collision-proof "</span>
<a name="l00944"></a>00944 <span class="stringliteral">"checksum\n"</span>, cksumtype));
<a name="l00945"></a>00945 snmp_set_detail(<span class="stringliteral">"Checksum is not a collision-proof checksum"</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(&pdu_checksum) != NULL ) {
<a name="l00952"></a>00952 <span class="comment">/* we did the bogus checksum--don'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(&pdu_checksum));
<a name="l00955"></a>00955 CHECKSUM_CONTENTS(&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 &CHECKSUM_LENGTH(&pdu_checksum));
<a name="l00960"></a>00960 <span class="keywordflow">if</span> (retval) {
<a name="l00961"></a>00961 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Unable to determine checksum length: %s\n"</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(&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(&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're just leaving blank space for the checksum;</span>
<a name="l00979"></a>00979 <span class="comment"> * we remember where that is, and we'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(&pdu_checksum);
<a name="l00983"></a>00983 memset(*wholeMsg + *parms->wholeMsgLen - *offset, 0, CHECKSUM_LENGTH(&pdu_checksum));
<a name="l00984"></a>00984
<a name="l00985"></a>00985 cksum_pointer = *wholeMsg + *parms->wholeMsgLen - *offset;
<a name="l00986"></a>00986
<a name="l00987"></a>00987 rc = asn_realloc_rbuild_header(wholeMsg, parms->wholeMsgLen,
<a name="l00988"></a>00988 parms->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(&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">"ksm"</span>, <span class="stringliteral">"Building ksm security parameters failed.\n"</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->wholeMsgLen,
<a name="l01001"></a>01001 parms->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> *) &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">"ksm"</span>, <span class="stringliteral">"Building ksm security parameters failed.\n"</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->wholeMsgLen,
<a name="l01015"></a>01015 parms->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">"ksm"</span>, <span class="stringliteral">"Building ksm security parameters failed.\n"</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->wholeMsgLen,
<a name="l01027"></a>01027 parms->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">"ksm"</span>, <span class="stringliteral">"Building ksm security parameters failed.\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: Security parameter encoding completed\n"</span>));
<a name="l01040"></a>01040
<a name="l01041"></a>01041 <span class="comment">/*</span>
<a name="l01042"></a>01042 <span class="comment"> * We'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->wholeMsgLen < parms->globalDataLen) {
<a name="l01047"></a>01047 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Building global data failed.\n"</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->globalDataLen;
<a name="l01053"></a>01053 memcpy(*wholeMsg + *parms->wholeMsgLen - *offset,
<a name="l01054"></a>01054 parms->globalData, parms->globalDataLen);
<a name="l01055"></a>01055
<a name="l01056"></a>01056 rc = asn_realloc_rbuild_sequence(wholeMsg, parms->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">"ksm"</span>, <span class="stringliteral">"Building master packet sequence.\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: PDU master packet encoding complete.\n"</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'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(&pdu_checksum) = malloc(CHECKSUM_LENGTH(&pdu_checksum));
<a name="l01076"></a>01076
<a name="l01077"></a>01077 <span class="keywordflow">if</span> (!CHECKSUM_CONTENTS(&pdu_checksum)) {
<a name="l01078"></a>01078 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Unable to malloc %d bytes for checksum\n"</span>,
<a name="l01079"></a>01079 CHECKSUM_LENGTH(&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->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, &input,
<a name="l01090"></a>01090 &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->wholeMsgLen
<a name="l01097"></a>01097 - *offset, *offset, &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->wholeMsgLen - *offset,
<a name="l01102"></a>01102 *offset,
<a name="l01103"></a>01103 (krb5_pointer) subkey->contents,
<a name="l01104"></a>01104 subkey->length, &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">"ksm"</span>, <span class="stringliteral">"Calculate checksum failed: %s\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: Checksum calculation complete.\n"</span>));
<a name="l01117"></a>01117
<a name="l01118"></a>01118 memcpy(cksum_pointer, CHECKSUM_CONTENTS(&pdu_checksum), CHECKSUM_LENGTH(&pdu_checksum));
<a name="l01119"></a>01119
<a name="l01120"></a>01120 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"KSM: Writing checksum of %d bytes at offset %d\n"</span>,
<a name="l01121"></a>01121 CHECKSUM_LENGTH(&pdu_checksum), cksum_pointer - (*wholeMsg + 1)));
<a name="l01122"></a>01122
<a name="l01123"></a>01123 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"KSM: Checksum:"</span>));
<a name="l01124"></a>01124
<a name="l01125"></a>01125 <span class="keywordflow">for</span> (i = 0; i < CHECKSUM_LENGTH(&pdu_checksum); i++)
<a name="l01126"></a>01126 DEBUGMSG((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">" %02x"</span>,
<a name="l01127"></a>01127 (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>) CHECKSUM_CONTENTS(&pdu_checksum)[i]));
<a name="l01128"></a>01128
<a name="l01129"></a>01129 DEBUGMSG((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"\n"</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'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->pdu-><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->secName,
<a name="l01139"></a>01139 parms->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">"ksm"</span>, <span class="stringliteral">"KSM processing complete!\n"</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(&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, &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(&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 && !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->wholeMsgLen - (u_int) (parms->secParams - parms->wholeMsg);
<a name="l01222"></a>01222 u_char *current = parms->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">"ksm"</span>, <span class="stringliteral">"Processing has begun\n"</span>));
<a name="l01230"></a>01230
<a name="l01231"></a>01231 CHECKSUM_CONTENTS(&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, &length, &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">"ksm first octet"</span>)) == NULL) {
<a name="l01245"></a>01245 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Initial security paramter parsing failed\n"</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, &length, &type,
<a name="l01252"></a>01252 (ASN_SEQUENCE | ASN_CONSTRUCTOR),
<a name="l01253"></a>01253 <span class="stringliteral">"ksm sequence"</span>)) == NULL) {
<a name="l01254"></a>01254 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>,
<a name="l01255"></a>01255 <span class="stringliteral">"Security parameter sequence parsing failed\n"</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, &length, &type, &temp,
<a name="l01262"></a>01262 <span class="keyword">sizeof</span>(temp))) == NULL) {
<a name="l01263"></a>01263 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Security parameter checksum type parsing"</span>
<a name="l01264"></a>01264 <span class="stringliteral">"failed\n"</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">"ksm"</span>, <span class="stringliteral">"Invalid checksum type (%d)\n"</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">"Invalid checksum type"</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">"ksm"</span>, <span class="stringliteral">"Checksum type %d is not a keyed checksum\n"</span>,
<a name="l01283"></a>01283 cksumtype));
<a name="l01284"></a>01284 snmp_set_detail(<span class="stringliteral">"Checksum is not a keyed checksum"</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">"ksm"</span>, <span class="stringliteral">"Checksum type %d is not a collision-proof "</span>
<a name="l01291"></a>01291 <span class="stringliteral">"checksum\n"</span>, cksumtype));
<a name="l01292"></a>01292 snmp_set_detail(<span class="stringliteral">"Checksum is not a collision-proof checksum"</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, &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">"ksm"</span>, <span class="stringliteral">"Invalid checksum type (%d)\n"</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">"Invalid checksum type"</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">"ksm"</span>, <span class="stringliteral">"Checksum type %d is not a keyed checksum\n"</span>,
<a name="l01316"></a>01316 cksumtype));
<a name="l01317"></a>01317 snmp_set_detail(<span class="stringliteral">"Checksum is not a keyed checksum"</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">"ksm"</span>, <span class="stringliteral">"Checksum type %d is not a collision-proof "</span>
<a name="l01328"></a>01328 <span class="stringliteral">"checksum\n"</span>, cksumtype));
<a name="l01329"></a>01329 snmp_set_detail(<span class="stringliteral">"Checksum is not a collision-proof checksum"</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(&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, &cksumlength, &type,
<a name="l01340"></a>01340 (ASN_UNIVERSAL | ASN_PRIMITIVE |
<a name="l01341"></a>01341 ASN_OCTET_STR), <span class="stringliteral">"ksm checksum"</span>)) ==
<a name="l01342"></a>01342 NULL) {
<a name="l01343"></a>01343 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>,
<a name="l01344"></a>01344 <span class="stringliteral">"Security parameter checksum parsing failed\n"</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(&checksum) = malloc(cksumlength);
<a name="l01351"></a>01351 <span class="keywordflow">if</span> (!CHECKSUM_CONTENTS(&checksum)) {
<a name="l01352"></a>01352 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Unable to malloc %d bytes for checksum.\n"</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(&checksum), current, cksumlength);
<a name="l01359"></a>01359
<a name="l01360"></a>01360 CHECKSUM_LENGTH(&checksum) = cksumlength;
<a name="l01361"></a>01361 CHECKSUM_TYPE(&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->wholeMsgLen - (u_int) (current - parms->wholeMsg);
<a name="l01371"></a>01371
<a name="l01372"></a>01372 <span class="keywordflow">if</span> ((current = asn_parse_sequence(current, &length, &type,
<a name="l01373"></a>01373 (ASN_UNIVERSAL | ASN_PRIMITIVE |
<a name="l01374"></a>01374 ASN_OCTET_STR), <span class="stringliteral">"ksm ap_req"</span>)) ==
<a name="l01375"></a>01375 NULL) {
<a name="l01376"></a>01376 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"KSM security parameter AP_REQ/REP parsing "</span>
<a name="l01377"></a>01377 <span class="stringliteral">"failed\n"</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">"ksm"</span>,
<a name="l01387"></a>01387 <span class="stringliteral">"KSM unable to malloc %d bytes for AP_REQ/REP.\n"</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->wholeMsgLen - (u_int) (current - parms->wholeMsg);
<a name="l01397"></a>01397
<a name="l01398"></a>01398 <span class="keywordflow">if</span> ((current = asn_parse_int(current, &length, &type, &hint,
<a name="l01399"></a>01399 <span class="keyword">sizeof</span>(hint))) == NULL) {
<a name="l01400"></a>01400 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>,
<a name="l01401"></a>01401 <span class="stringliteral">"KSM security parameter hint parsing failed\n"</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'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's a WRINKLE! We need to figure out if we're</span>
<a name="l01411"></a>01411 <span class="comment"> * processing a AP_REQ or an AP_REP. How do we do that? We'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'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'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 && (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 && (((<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'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, &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">"ksm"</span>, <span class="stringliteral">"krb5_auth_con_init failed: %s\n"</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">"host"</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, &server, &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">"ksm"</span>, <span class="stringliteral">"krb5_get_server_rcache failed: %s\n"</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">"ksm"</span>, <span class="stringliteral">"krb5_auth_con_setrcache failed: %s\n"</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, &auth_context, &ap_req, NULL,
<a name="l01472"></a>01472 keytab, &flags, &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">"ksm"</span>, <span class="stringliteral">"krb5_rd_req() failed: %s\n"</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), &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">"ksm"</span>, <span class="stringliteral">"KSM authenticated principal name: %s\n"</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 & AP_OPTS_MUTUAL_REQUIRED)) {
<a name="l01498"></a>01498 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>,
<a name="l01499"></a>01499 <span class="stringliteral">"KSM MUTUAL_REQUIRED not set in request!\n"</span>));
<a name="l01500"></a>01500 retval = SNMPERR_KRB5;
<a name="l01501"></a>01501 snmp_set_detail(<span class="stringliteral">"MUTUAL_REQUIRED not set in message"</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, &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">"ksm"</span>, <span class="stringliteral">"KSM remote subkey retrieval failed: %s\n"</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 && (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 && (((<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's see if we'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->pdu-><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">"ksm"</span>,
<a name="l01536"></a>01536 <span class="stringliteral">"KSM: Unable to find auth_context for PDU with "</span>
<a name="l01537"></a>01537 <span class="stringliteral">"message ID of %ld\n"</span>, parms->pdu-><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->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'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, &ap_req, &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">"ksm"</span>, <span class="stringliteral">"KSM: krb5_rd_rep() failed: %s\n"</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">"ksm"</span>, <span class="stringliteral">"KSM: krb5_rd_rep() decoded successfully.\n"</span>));
<a name="l01561"></a>01561
<a name="l01562"></a>01562 retcode =
<a name="l01563"></a>01563 krb5_auth_con_getlocalsubkey(kcontext, auth_context, &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">"ksm"</span>, <span class="stringliteral">"Unable to retrieve local subkey: %s\n"</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">"Unable to retrieve local subkey"</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">"ksm"</span>, <span class="stringliteral">"Unknown Kerberos message type (%02x)\n"</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">"ksm"</span>, <span class="stringliteral">"Unknown Kerberos message type (%02x)\n"</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">"Unknown Kerberos message type"</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->wholeMsg;
<a name="l01588"></a>01588 input.length = parms->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 &input, &checksum, &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, &heim_crypto);
<a name="l01595"></a>01595 <span class="keywordflow">if</span> (retcode) {
<a name="l01596"></a>01596 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"krb5_crypto_init failed: %s\n"</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->wholeMsg,
<a name="l01604"></a>01604 parms->wholeMsgLen, &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, &checksum,
<a name="l01607"></a>01607 parms->wholeMsg, parms->wholeMsgLen,
<a name="l01608"></a>01608 (krb5_pointer) subkey->contents,
<a name="l01609"></a>01609 subkey->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">"ksm"</span>, <span class="stringliteral">"KSM checksum verification failed: %s\n"</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't ask me why they didn't simply return an error, but we have</span>
<a name="l01622"></a>01622 <span class="comment"> * to check to see if "valid" 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">"ksm"</span>, <span class="stringliteral">"Computed checksum did not match supplied "</span>
<a name="l01628"></a>01628 <span class="stringliteral">"checksum!\n"</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">"Computed checksum did not match supplied checksum"</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's an OCTET_STRING of the</span>
<a name="l01638"></a>01638 <span class="comment"> * output of whatever Kerberos cryptosystem you'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's what goes in the "cipher" 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->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, &length, &type,
<a name="l01646"></a>01646 (ASN_UNIVERSAL | ASN_PRIMITIVE |
<a name="l01647"></a>01647 ASN_OCTET_STR), <span class="stringliteral">"ksm pdu"</span>)) ==
<a name="l01648"></a>01648 NULL) {
<a name="l01649"></a>01649 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"KSM sPDU octet decoding failed\n"</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 "current", and the length is in</span>
<a name="l01656"></a>01656 <span class="comment"> * "length".</span>
<a name="l01657"></a>01657 <span class="comment"> */</span>
<a name="l01658"></a>01658
<a name="l01659"></a>01659 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"KSM starting sPDU decode\n"</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'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->enctype, &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">"ksm"</span>,
<a name="l01673"></a>01673 <span class="stringliteral">"Unable to determine crypto block size: %s\n"</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->enctype]->system->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">"ksm"</span>, <span class="stringliteral">"Unable to allocate %d bytes for ivector\n"</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, &eblock, subkey->enctype);
<a name="l01703"></a>01703
<a name="l01704"></a>01704 retcode = krb5_process_key(kcontext, &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">"ksm"</span>, <span class="stringliteral">"KSM key post-processing failed: %s\n"</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 > *parms->scopedPduLen) {
<a name="l01718"></a>01718 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"KSM not enough room - have %d bytes to "</span>
<a name="l01719"></a>01719 <span class="stringliteral">"decrypt but only %d bytes available\n"</span>, length,
<a name="l01720"></a>01720 *parms->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, &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->enctype;
<a name="l01733"></a>01733 output.data = (<span class="keywordtype">char</span> *) *parms->scopedPdu;
<a name="l01734"></a>01734 output.length = *parms->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 &ivector, &in_crypt, &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, &output);
<a name="l01742"></a>01742 <span class="keywordflow">if</span> (retcode == 0) {
<a name="l01743"></a>01743 *parms->scopedPdu = (<span class="keywordtype">char</span> *) output.data;
<a name="l01744"></a>01744 *parms->scopedPduLen = output.length;
<a name="l01745"></a>01745 krb5_data_zero(&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->scopedPdu, length, &eblock,
<a name="l01751"></a>01751 ivector.data);
<a name="l01752"></a>01752
<a name="l01753"></a>01753 krb5_finish_key(kcontext, &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">"ksm"</span>, <span class="stringliteral">"Decryption failed: %s\n"</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->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->scopedPdu = current;
<a name="l01773"></a>01773 *parms->scopedPduLen =
<a name="l01774"></a>01774 parms->wholeMsgLen - (current - parms->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->maxSizeResponse = parms->maxMsgSize - 200;
<a name="l01782"></a>01782
<a name="l01783"></a>01783 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"KSM processing complete\n"</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's</span>
<a name="l01787"></a>01787 <span class="comment"> * only used for when we'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 &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">"ksm"</span>, <span class="stringliteral">"KSM krb5_unparse_name failed: %s\n"</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) > *parms->secNameLen + 1) {
<a name="l01804"></a>01804 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>,
<a name="l01805"></a>01805 <span class="stringliteral">"KSM: Principal length (%d) is too long (%d)\n"</span>,
<a name="l01806"></a>01806 strlen(cname), parms->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->secName, cname);
<a name="l01813"></a>01813 *parms->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'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">"ksm"</span>, <span class="stringliteral">"KSM unable to malloc memory for "</span>
<a name="l01826"></a>01826 <span class="stringliteral">"ksm_secStateRef\n"</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->auth_context = auth_context;
<a name="l01832"></a>01832 auth_context = NULL;
<a name="l01833"></a>01833 ksm_state->cksumtype = cksumtype;
<a name="l01834"></a>01834
<a name="l01835"></a>01835 *parms->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->secName, entry->secName, entry->secNameLen);
<a name="l01845"></a>01845 *parms->secNameLen = entry->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->secEngineID = (u_char *) <span class="stringliteral">""</span>;
<a name="l01853"></a>01853 *parms->secEngineIDLen = 0;
<a name="l01854"></a>01854
<a name="l01855"></a>01855 auth_context = NULL; <span class="comment">/* So we don'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 &&
<a name="l01859"></a>01859 snmp_increment_statistic(STAT_SNMPINASNPARSEERRS) == 0)
<a name="l01860"></a>01860 DEBUGMSGTL((<span class="stringliteral">"ksm"</span>, <span class="stringliteral">"Failed to increment statistics.\n"</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(&checksum))
<a name="l01871"></a>01871 free(CHECKSUM_CONTENTS(&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 && 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  <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>