net-snmp
5.4.1
|
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 # ifdef WIN32 00047 # include <sys/timeb.h> 00048 # else 00049 # include <sys/time.h> 00050 # endif 00051 # include <time.h> 00052 #else 00053 # if HAVE_SYS_TIME_H 00054 # include <sys/time.h> 00055 # else 00056 # include <time.h> 00057 # endif 00058 #endif 00059 #if HAVE_SYS_SELECT_H 00060 #include <sys/select.h> 00061 #endif 00062 #if HAVE_NETINET_IN_H 00063 #include <netinet/in.h> 00064 #endif 00065 #if HAVE_ARPA_INET_H 00066 #include <arpa/inet.h> 00067 #endif 00068 00069 #if HAVE_DMALLOC_H 00070 #include <dmalloc.h> 00071 #endif 00072 00073 #if HAVE_WINSOCK_H 00074 #include <winsock.h> 00075 #endif 00076 00077 #ifdef vms 00078 #include <in.h> 00079 #endif 00080 00081 #include <net-snmp/types.h> 00082 #include <net-snmp/output_api.h> 00083 #include <net-snmp/utilities.h> 00084 00085 #include <net-snmp/library/asn1.h> 00086 #include <net-snmp/library/snmp_api.h> 00087 #include <net-snmp/library/mib.h> 00088 #include <net-snmp/library/md5.h> 00089 #include <net-snmp/library/scapi.h> 00090 00091 /* 00092 * Globals. 00093 */ 00094 00095 #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C) 00096 /*******************************************************************-o-****** 00097 * snmp_comstr_parse 00098 * 00099 * Parameters: 00100 * *data (I) Message. 00101 * *length (I/O) Bytes left in message. 00102 * *psid (O) Community string. 00103 * *slen (O) Length of community string. 00104 * *version (O) Message version. 00105 * 00106 * Returns: 00107 * Pointer to the remainder of data. 00108 * 00109 * 00110 * Parse the header of a community string-based message such as that found 00111 * in SNMPv1 and SNMPv2c. 00112 */ 00113 u_char * 00114 snmp_comstr_parse(u_char * data, 00115 size_t * length, 00116 u_char * psid, size_t * slen, long *version) 00117 { 00118 u_char type; 00119 long ver; 00120 size_t origlen = *slen; 00121 00122 /* 00123 * Message is an ASN.1 SEQUENCE. 00124 */ 00125 data = asn_parse_sequence(data, length, &type, 00126 (ASN_SEQUENCE | ASN_CONSTRUCTOR), 00127 "auth message"); 00128 if (data == NULL) { 00129 return NULL; 00130 } 00131 00132 /* 00133 * First field is the version. 00134 */ 00135 DEBUGDUMPHEADER("recv", "SNMP version"); 00136 data = asn_parse_int(data, length, &type, &ver, sizeof(ver)); 00137 DEBUGINDENTLESS(); 00138 *version = ver; 00139 if (data == NULL) { 00140 ERROR_MSG("bad parse of version"); 00141 return NULL; 00142 } 00143 00144 /* 00145 * second field is the community string for SNMPv1 & SNMPv2c 00146 */ 00147 DEBUGDUMPHEADER("recv", "community string"); 00148 data = asn_parse_string(data, length, &type, psid, slen); 00149 DEBUGINDENTLESS(); 00150 if (data == NULL) { 00151 ERROR_MSG("bad parse of community"); 00152 return NULL; 00153 } 00154 psid[SNMP_MIN(*slen, origlen - 1)] = '\0'; 00155 return (u_char *) data; 00156 00157 } /* end snmp_comstr_parse() */ 00158 00159 00160 00161 00162 /*******************************************************************-o-****** 00163 * snmp_comstr_build 00164 * 00165 * Parameters: 00166 * *data 00167 * *length 00168 * *psid 00169 * *slen 00170 * *version 00171 * messagelen 00172 * 00173 * Returns: 00174 * Pointer into 'data' after built section. 00175 * 00176 * 00177 * Build the header of a community string-based message such as that found 00178 * in SNMPv1 and SNMPv2c. 00179 * 00180 * NOTE: The length of the message will have to be inserted later, 00181 * if not known. 00182 * 00183 * NOTE: Version is an 'int'. (CMU had it as a long, but was passing 00184 * in a *int. Grrr.) Assign version to verfix and pass in 00185 * that to asn_build_int instead which expects a long. -- WH 00186 */ 00187 u_char * 00188 snmp_comstr_build(u_char * data, 00189 size_t * length, 00190 u_char * psid, 00191 size_t * slen, long *version, size_t messagelen) 00192 { 00193 long verfix = *version; 00194 u_char *h1 = data; 00195 u_char *h1e; 00196 size_t hlength = *length; 00197 00198 00199 /* 00200 * Build the the message wrapper (note length will be inserted later). 00201 */ 00202 data = 00203 asn_build_sequence(data, length, 00204 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 0); 00205 if (data == NULL) { 00206 return NULL; 00207 } 00208 h1e = data; 00209 00210 00211 /* 00212 * Store the version field. 00213 */ 00214 data = asn_build_int(data, length, 00215 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | 00216 ASN_INTEGER), &verfix, sizeof(verfix)); 00217 if (data == NULL) { 00218 return NULL; 00219 } 00220 00221 00222 /* 00223 * Store the community string. 00224 */ 00225 data = asn_build_string(data, length, 00226 (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | 00227 ASN_OCTET_STR), psid, 00228 *(u_char *) slen); 00229 if (data == NULL) { 00230 return NULL; 00231 } 00232 00233 00234 /* 00235 * Insert length. 00236 */ 00237 asn_build_sequence(h1, &hlength, 00238 (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 00239 data - h1e + messagelen); 00240 00241 00242 return data; 00243 00244 } /* end snmp_comstr_build() */ 00245 #endif /* support for community based SNMP */