net-snmp 5.7
snmp_auth.c
00001 /*
00002  * snmp_auth.c
00003  *
00004  * Community name parse/build routines.
00005  */
00006 /**********************************************************************
00007     Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
00008 
00009                          All Rights Reserved
00010 
00011 Permission to use, copy, modify, and distribute this software and its
00012 documentation for any purpose and without fee is hereby granted,
00013 provided that the above copyright notice appear in all copies and that
00014 both that copyright notice and this permission notice appear in
00015 supporting documentation, and that the name of CMU not be
00016 used in advertising or publicity pertaining to distribution of the
00017 software without specific, written prior permission.
00018 
00019 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
00020 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
00021 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
00022 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00023 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
00024 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00025 SOFTWARE.
00026 ******************************************************************/
00027 
00028 #include <net-snmp/net-snmp-config.h>
00029 
00030 #ifdef KINETICS
00031 #include "gw.h"
00032 #include "fp4/cmdmacro.h"
00033 #endif
00034 
00035 #include <stdio.h>
00036 #if HAVE_STDLIB_H
00037 #include <stdlib.h>
00038 #endif
00039 #if HAVE_STRING_H
00040 #include <string.h>
00041 #else
00042 #include <strings.h>
00043 #endif
00044 #include <sys/types.h>
00045 #if TIME_WITH_SYS_TIME
00046 # include <sys/time.h>
00047 # include <time.h>
00048 #else
00049 # if HAVE_SYS_TIME_H
00050 #  include <sys/time.h>
00051 # else
00052 #  include <time.h>
00053 # endif
00054 #endif
00055 #if HAVE_SYS_SELECT_H
00056 #include <sys/select.h>
00057 #endif
00058 #if HAVE_NETINET_IN_H
00059 #include <netinet/in.h>
00060 #endif
00061 #if HAVE_ARPA_INET_H
00062 #include <arpa/inet.h>
00063 #endif
00064 
00065 #if HAVE_UNISTD_H
00066 #include <unistd.h>
00067 #endif
00068 #if HAVE_DMALLOC_H
00069 #include <dmalloc.h>
00070 #endif
00071 
00072 #ifdef vms
00073 #include <in.h>
00074 #endif
00075 
00076 #include <net-snmp/types.h>
00077 #include <net-snmp/output_api.h>
00078 #include <net-snmp/utilities.h>
00079 
00080 #include <net-snmp/library/asn1.h>
00081 #include <net-snmp/library/snmp_api.h>
00082 #include <net-snmp/library/mib.h>
00083 #include <net-snmp/library/md5.h>
00084 #include <net-snmp/library/scapi.h>
00085 
00086 /*
00087  * Globals.
00088  */
00089 
00090 #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
00091 /*******************************************************************-o-******
00092  * snmp_comstr_parse
00093  *
00094  * Parameters:
00095  *      *data           (I)   Message.
00096  *      *length         (I/O) Bytes left in message.
00097  *      *psid           (O)   Community string.
00098  *      *slen           (O)   Length of community string.
00099  *      *version        (O)   Message version.
00100  *      
00101  * Returns:
00102  *      Pointer to the remainder of data.
00103  *
00104  *
00105  * Parse the header of a community string-based message such as that found
00106  * in SNMPv1 and SNMPv2c.
00107  */
00108 u_char         *
00109 snmp_comstr_parse(u_char * data,
00110                   size_t * length,
00111                   u_char * psid, size_t * slen, long *version)
00112 {
00113     u_char          type;
00114     long            ver;
00115     size_t          origlen = *slen;
00116 
00117     /*
00118      * Message is an ASN.1 SEQUENCE.
00119      */
00120     data = asn_parse_sequence(data, length, &type,
00121                               (ASN_SEQUENCE | ASN_CONSTRUCTOR),
00122                               "auth message");
00123     if (data == NULL) {
00124         return NULL;
00125     }
00126 
00127     /*
00128      * First field is the version.
00129      */
00130     DEBUGDUMPHEADER("recv", "SNMP version");
00131     data = asn_parse_int(data, length, &type, &ver, sizeof(ver));
00132     DEBUGINDENTLESS();
00133     *version = ver;
00134     if (data == NULL) {
00135         ERROR_MSG("bad parse of version");
00136         return NULL;
00137     }
00138 
00139     /*
00140      * second field is the community string for SNMPv1 & SNMPv2c 
00141      */
00142     DEBUGDUMPHEADER("recv", "community string");
00143     data = asn_parse_string(data, length, &type, psid, slen);
00144     DEBUGINDENTLESS();
00145     if (data == NULL) {
00146         ERROR_MSG("bad parse of community");
00147         return NULL;
00148     }
00149     psid[SNMP_MIN(*slen, origlen - 1)] = '\0';
00150     return (u_char *) data;
00151 
00152 }                               /* end snmp_comstr_parse() */
00153 
00154 
00155 
00156 
00157 /*******************************************************************-o-******
00158  * snmp_comstr_build
00159  *
00160  * Parameters:
00161  *      *data
00162  *      *length
00163  *      *psid
00164  *      *slen
00165  *      *version
00166  *       messagelen
00167  *      
00168  * Returns:
00169  *      Pointer into 'data' after built section.
00170  *
00171  *
00172  * Build the header of a community string-based message such as that found
00173  * in SNMPv1 and SNMPv2c.
00174  *
00175  * NOTE:        The length of the message will have to be inserted later,
00176  *              if not known.
00177  *
00178  * NOTE:        Version is an 'int'.  (CMU had it as a long, but was passing
00179  *              in a *int.  Grrr.)  Assign version to verfix and pass in
00180  *              that to asn_build_int instead which expects a long.  -- WH
00181  */
00182 u_char         *
00183 snmp_comstr_build(u_char * data,
00184                   size_t * length,
00185                   u_char * psid,
00186                   size_t * slen, long *version, size_t messagelen)
00187 {
00188     long            verfix = *version;
00189     u_char         *h1 = data;
00190     u_char         *h1e;
00191     size_t          hlength = *length;
00192 
00193 
00194     /*
00195      * Build the the message wrapper (note length will be inserted later).
00196      */
00197     data =
00198         asn_build_sequence(data, length,
00199                            (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 0);
00200     if (data == NULL) {
00201         return NULL;
00202     }
00203     h1e = data;
00204 
00205 
00206     /*
00207      * Store the version field.
00208      */
00209     data = asn_build_int(data, length,
00210                          (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
00211                                    ASN_INTEGER), &verfix, sizeof(verfix));
00212     if (data == NULL) {
00213         return NULL;
00214     }
00215 
00216 
00217     /*
00218      * Store the community string.
00219      */
00220     data = asn_build_string(data, length,
00221                             (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
00222                                       ASN_OCTET_STR), psid,
00223                             *(u_char *) slen);
00224     if (data == NULL) {
00225         return NULL;
00226     }
00227 
00228 
00229     /*
00230      * Insert length.
00231      */
00232     asn_build_sequence(h1, &hlength,
00233                        (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
00234                        data - h1e + messagelen);
00235 
00236 
00237     return data;
00238 
00239 }                               /* end snmp_comstr_build() */
00240 #endif /* support for community based SNMP */