net-snmp 5.7
|
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 */