1 /*
2  * snmp_auth.c
3  *
4  * Community name parse/build routines.
5  */
6 /**********************************************************************
7     Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
8 
9 			 All Rights Reserved
10 
11 Permission to use, copy, modify, and distribute this software and its
12 documentation for any purpose and without fee is hereby granted,
13 provided that the above copyright notice appear in all copies and that
14 both that copyright notice and this permission notice appear in
15 supporting documentation, and that the name of CMU not be
16 used in advertising or publicity pertaining to distribution of the
17 software without specific, written prior permission.
18 
19 CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
20 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
21 CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
22 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25 SOFTWARE.
26 ******************************************************************/
27 
28 #include <net-snmp/net-snmp-config.h>
29 
30 #ifdef KINETICS
31 #include "gw.h"
32 #include "fp4/cmdmacro.h"
33 #endif
34 
35 #include <stdio.h>
36 #if HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif
39 #if HAVE_STRING_H
40 #include <string.h>
41 #else
42 #include <strings.h>
43 #endif
44 #include <sys/types.h>
45 #if TIME_WITH_SYS_TIME
46 # include <sys/time.h>
47 # include <time.h>
48 #else
49 # if HAVE_SYS_TIME_H
50 #  include <sys/time.h>
51 # else
52 #  include <time.h>
53 # endif
54 #endif
55 #if HAVE_SYS_SELECT_H
56 #include <sys/select.h>
57 #endif
58 #if HAVE_NETINET_IN_H
59 #include <netinet/in.h>
60 #endif
61 #if HAVE_ARPA_INET_H
62 #include <arpa/inet.h>
63 #endif
64 
65 #if HAVE_UNISTD_H
66 #include <unistd.h>
67 #endif
68 
69 #ifdef vms
70 #include <in.h>
71 #endif
72 
73 #include <net-snmp/types.h>
74 #include <net-snmp/output_api.h>
75 #include <net-snmp/utilities.h>
76 
77 #include <net-snmp/library/asn1.h>
78 #include <net-snmp/library/snmp_api.h>
79 #include <net-snmp/library/mib.h>
80 #include <net-snmp/library/md5.h>
81 #include <net-snmp/library/scapi.h>
82 
83 /*
84  * Globals.
85  */
86 
87 #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
88 /*******************************************************************-o-******
89  * snmp_comstr_parse
90  *
91  * Parameters:
92  *	*data		(I)   Message.
93  *	*length		(I/O) Bytes left in message.
94  *	*psid		(O)   Community string.
95  *	*slen		(O)   Length of community string.
96  *	*version	(O)   Message version.
97  *
98  * Returns:
99  *	Pointer to the remainder of data.
100  *
101  *
102  * Parse the header of a community string-based message such as that found
103  * in SNMPv1 and SNMPv2c.
104  */
105 u_char         *
snmp_comstr_parse(u_char * data,size_t * length,u_char * psid,size_t * slen,long * version)106 snmp_comstr_parse(u_char * data,
107                   size_t * length,
108                   u_char * psid, size_t * slen, long *version)
109 {
110     u_char          type;
111     long            ver;
112     size_t          origlen = *slen;
113 
114     /*
115      * Message is an ASN.1 SEQUENCE.
116      */
117     data = asn_parse_sequence(data, length, &type,
118                               (ASN_SEQUENCE | ASN_CONSTRUCTOR),
119                               "auth message");
120     if (data == NULL) {
121         return NULL;
122     }
123 
124     /*
125      * First field is the version.
126      */
127     DEBUGDUMPHEADER("recv", "SNMP version");
128     data = asn_parse_int(data, length, &type, &ver, sizeof(ver));
129     DEBUGINDENTLESS();
130     *version = ver;
131     if (data == NULL) {
132         ERROR_MSG("bad parse of version");
133         return NULL;
134     }
135 
136     /*
137      * second field is the community string for SNMPv1 & SNMPv2c
138      */
139     DEBUGDUMPHEADER("recv", "community string");
140     data = asn_parse_string(data, length, &type, psid, slen);
141     DEBUGINDENTLESS();
142     if (data == NULL) {
143         ERROR_MSG("bad parse of community");
144         return NULL;
145     }
146     psid[SNMP_MIN(*slen, origlen - 1)] = '\0';
147     return (u_char *) data;
148 
149 }                               /* end snmp_comstr_parse() */
150 
151 
152 
153 
154 /*******************************************************************-o-******
155  * snmp_comstr_build
156  *
157  * Parameters:
158  *	*data
159  *	*length
160  *	*psid
161  *	*slen
162  *	*version
163  *	 messagelen
164  *
165  * Returns:
166  *	Pointer into 'data' after built section.
167  *
168  *
169  * Build the header of a community string-based message such as that found
170  * in SNMPv1 and SNMPv2c.
171  *
172  * NOTE:	The length of the message will have to be inserted later,
173  *		if not known.
174  *
175  * NOTE:	Version is an 'int'.  (CMU had it as a long, but was passing
176  *		in a *int.  Grrr.)  Assign version to verfix and pass in
177  *		that to asn_build_int instead which expects a long.  -- WH
178  */
179 u_char         *
snmp_comstr_build(u_char * data,size_t * length,u_char * psid,size_t * slen,long * version,size_t messagelen)180 snmp_comstr_build(u_char * data,
181                   size_t * length,
182                   u_char * psid,
183                   size_t * slen, long *version, size_t messagelen)
184 {
185     long            verfix = *version;
186     u_char         *h1 = data;
187     u_char         *h1e;
188     size_t          hlength = *length;
189 
190 
191     /*
192      * Build the the message wrapper (note length will be inserted later).
193      */
194     data =
195         asn_build_sequence(data, length,
196                            (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 0);
197     if (data == NULL) {
198         return NULL;
199     }
200     h1e = data;
201 
202 
203     /*
204      * Store the version field.
205      */
206     data = asn_build_int(data, length,
207                          (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
208                                    ASN_INTEGER), &verfix, sizeof(verfix));
209     if (data == NULL) {
210         return NULL;
211     }
212 
213 
214     /*
215      * Store the community string.
216      */
217     data = asn_build_string(data, length,
218                             (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE |
219                                       ASN_OCTET_STR), psid,
220                             *(u_char *) slen);
221     if (data == NULL) {
222         return NULL;
223     }
224 
225 
226     /*
227      * Insert length.
228      */
229     asn_build_sequence(h1, &hlength,
230                        (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR),
231                        data - h1e + messagelen);
232 
233 
234     return data;
235 
236 }                               /* end snmp_comstr_build() */
237 #endif /* support for community based SNMP */
238