xref: /openbsd/usr.sbin/snmpd/snmpd.h (revision ce7279d8)
1 /*	$OpenBSD: snmpd.h,v 1.120 2024/05/21 05:00:48 jsg Exp $	*/
2 
3 /*
4  * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
5  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef SNMPD_H
21 #define SNMPD_H
22 
23 #include <sys/queue.h>
24 #include <sys/socket.h>
25 #include <sys/time.h>
26 #include <sys/tree.h>
27 #include <sys/types.h>
28 #include <sys/un.h>
29 
30 #include <netinet/in.h>
31 
32 #include <ber.h>
33 #include <event.h>
34 #include <limits.h>
35 #include <imsg.h>
36 #include <stddef.h>
37 #include <stdint.h>
38 
39 #include "mib.h"
40 #include "snmp.h"
41 
42 #ifndef nitems
43 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
44 #endif
45 
46 /*
47  * common definitions for snmpd
48  */
49 
50 #define CONF_FILE		"/etc/snmpd.conf"
51 #define SNMPD_BACKEND		"/usr/libexec/snmpd"
52 #define SNMPD_USER		"_snmpd"
53 #define SNMP_PORT		"161"
54 #define SNMPTRAP_PORT		"162"
55 
56 #define AGENTX_MASTER_PATH	"/var/agentx/master"
57 #define AGENTX_GROUP		"_agentx"
58 
59 #define SNMPD_MAXSTRLEN		484
60 #define SNMPD_MAXCOMMUNITYLEN	SNMPD_MAXSTRLEN
61 #define SNMPD_MAXVARBIND	0x7fffffff
62 #define SNMPD_MAXVARBINDLEN	1210
63 #define SNMPD_MAXENGINEIDLEN	32
64 #define SNMPD_MAXUSERNAMELEN	32
65 #define SNMPD_MAXCONTEXNAMELEN	32
66 
67 #define SNMP_USM_MAXDIGESTLEN	48
68 #define SNMP_USM_SALTLEN	8
69 #define SNMP_USM_KEYLEN		64
70 #define SNMP_CIPHER_KEYLEN	16
71 
72 #define SMALL_READ_BUF_SIZE	1024
73 #define READ_BUF_SIZE		65535
74 #define	RT_BUF_SIZE		16384
75 #define	MAX_RTSOCK_BUF		(2 * 1024 * 1024)
76 
77 #define SNMP_ENGINEID_OLD	0x00
78 #define SNMP_ENGINEID_NEW	0x80	/* RFC3411 */
79 
80 #define SNMP_ENGINEID_FMT_IPv4	1
81 #define SNMP_ENGINEID_FMT_IPv6	2
82 #define SNMP_ENGINEID_FMT_MAC	3
83 #define SNMP_ENGINEID_FMT_TEXT	4
84 #define SNMP_ENGINEID_FMT_OCT	5
85 #define SNMP_ENGINEID_FMT_HH	129
86 
87 #define PEN_OPENBSD		30155
88 
89 enum imsg_type {
90 	IMSG_NONE,
91 	IMSG_CTL_VERBOSE,
92 	IMSG_CTL_PROCFD,
93 	IMSG_TRAP_EXEC,
94 	IMSG_AX_FD
95 };
96 
97 struct imsgev {
98 	struct imsgbuf		 ibuf;
99 	void			(*handler)(int, short, void *);
100 	struct event		 ev;
101 	struct privsep_proc	*proc;
102 	void			*data;
103 	short			 events;
104 	const char		*name;
105 };
106 
107 #define IMSG_SIZE_CHECK(imsg, p) do {				\
108 	if (IMSG_DATA_SIZE(imsg) < sizeof(*p))			\
109 		fatalx("bad length imsg received");		\
110 } while (0)
111 #define IMSG_DATA_SIZE(imsg)	((imsg)->hdr.len - IMSG_HEADER_SIZE)
112 
113 enum privsep_procid {
114 	PROC_PARENT,	/* Parent process and application interface */
115 	PROC_SNMPE,	/* SNMP engine */
116 	PROC_MAX
117 };
118 
119 extern enum privsep_procid privsep_process;
120 
121 struct privsep_pipes {
122 	int			*pp_pipes[PROC_MAX];
123 };
124 
125 struct privsep {
126 	struct privsep_pipes	*ps_pipes[PROC_MAX];
127 	struct privsep_pipes	*ps_pp;
128 
129 	struct imsgev		*ps_ievs[PROC_MAX];
130 	const char		*ps_title[PROC_MAX];
131 	pid_t			 ps_pid[PROC_MAX];
132 	struct passwd		*ps_pw;
133 
134 	u_int			 ps_instances[PROC_MAX];
135 	u_int			 ps_instance;
136 	int			 ps_noaction;
137 
138 	/* Event and signal handlers */
139 	struct event		 ps_evsigint;
140 	struct event		 ps_evsigterm;
141 	struct event		 ps_evsigchld;
142 	struct event		 ps_evsighup;
143 	struct event		 ps_evsigpipe;
144 	struct event		 ps_evsigusr1;
145 
146 	void			*ps_env;
147 };
148 
149 struct privsep_proc {
150 	const char		*p_title;
151 	enum privsep_procid	 p_id;
152 	int			(*p_cb)(int, struct privsep_proc *,
153 				    struct imsg *);
154 	void			(*p_init)(struct privsep *,
155 				    struct privsep_proc *);
156 	void			(*p_shutdown)(void);
157 	const char		*p_chroot;
158 	struct privsep		*p_ps;
159 	struct passwd		*p_pw;
160 };
161 
162 struct privsep_fd {
163 	enum privsep_procid		 pf_procid;
164 	unsigned int			 pf_instance;
165 };
166 
167 #define PROC_PARENT_SOCK_FILENO	3
168 #define PROC_MAX_INSTANCES	32
169 
170 #if DEBUG
171 #define DPRINTF		log_debug
172 #else
173 #define DPRINTF(x...)	do {} while(0)
174 #endif
175 
176 #define OID(...)		(struct ber_oid){ { __VA_ARGS__ },	\
177     (sizeof((uint32_t []) { __VA_ARGS__ }) / sizeof(uint32_t)) }
178 
179 /*
180  * daemon structures
181  */
182 
183 #define MSG_HAS_AUTH(m)		(((m)->sm_flags & SNMP_MSGFLAG_AUTH) != 0)
184 #define MSG_HAS_PRIV(m)		(((m)->sm_flags & SNMP_MSGFLAG_PRIV) != 0)
185 #define MSG_SECLEVEL(m)		((m)->sm_flags & SNMP_MSGFLAG_SECMASK)
186 #define MSG_REPORT(m)		(((m)->sm_flags & SNMP_MSGFLAG_REPORT) != 0)
187 
188 struct snmp_message {
189 	int			 sm_sock;
190 	struct sockaddr_storage	 sm_ss;
191 	socklen_t		 sm_slen;
192 	int			 sm_sock_tcp;
193 	int			 sm_aflags;
194 	enum snmp_pdutype	 sm_pdutype;
195 	struct event		 sm_sockev;
196 	char			 sm_host[HOST_NAME_MAX+1];
197 	in_port_t		 sm_port;
198 
199 	struct sockaddr_storage	 sm_local_ss;
200 	socklen_t		 sm_local_slen;
201 
202 	struct ber		 sm_ber;
203 	struct ber_element	*sm_req;
204 	struct ber_element	*sm_resp;
205 
206 	u_int8_t		 sm_data[READ_BUF_SIZE];
207 	size_t			 sm_datalen;
208 
209 	uint32_t		 sm_transactionid;
210 
211 	u_int			 sm_version;
212 
213 	/* V1, V2c */
214 	char			 sm_community[SNMPD_MAXCOMMUNITYLEN];
215 
216 	/* V3 */
217 	long long		 sm_msgid;
218 	long long		 sm_max_msg_size;
219 	u_int8_t		 sm_flags;
220 	long long		 sm_secmodel;
221 	u_int32_t		 sm_engine_boots;
222 	u_int32_t		 sm_engine_time;
223 	uint8_t			 sm_ctxengineid[SNMPD_MAXENGINEIDLEN];
224 	size_t			 sm_ctxengineid_len;
225 	char			 sm_ctxname[SNMPD_MAXCONTEXNAMELEN+1];
226 
227 	/* USM */
228 	char			 sm_username[SNMPD_MAXUSERNAMELEN+1];
229 	struct usmuser		*sm_user;
230 	size_t			 sm_digest_offs;
231 	char			 sm_salt[SNMP_USM_SALTLEN];
232 	int			 sm_usmerr;
233 
234 	long long		 sm_request;
235 
236 	const char		*sm_errstr;
237 	long long		 sm_error;
238 #define sm_nonrepeaters		 sm_error
239 	long long		 sm_errorindex;
240 #define sm_maxrepetitions	 sm_errorindex
241 
242 	struct ber_element	*sm_pdu;
243 	struct ber_element	*sm_pduend;
244 
245 	struct ber_element	*sm_varbind;
246 	struct ber_element	*sm_varbindresp;
247 
248 	RB_ENTRY(snmp_message)	 sm_entry;
249 };
250 RB_HEAD(snmp_messages, snmp_message);
251 extern struct snmp_messages snmp_messages;
252 
253 /* Defined in SNMPv2-MIB.txt (RFC 3418) */
254 struct snmp_stats {
255 	u_int32_t		snmp_inpkts;
256 	u_int32_t		snmp_outpkts;
257 	u_int32_t		snmp_inbadversions;
258 	u_int32_t		snmp_inbadcommunitynames;
259 	u_int32_t		snmp_inbadcommunityuses;
260 	u_int32_t		snmp_inasnparseerrs;
261 	u_int32_t		snmp_intoobigs;
262 	u_int32_t		snmp_innosuchnames;
263 	u_int32_t		snmp_inbadvalues;
264 	u_int32_t		snmp_inreadonlys;
265 	u_int32_t		snmp_ingenerrs;
266 	u_int32_t		snmp_intotalreqvars;
267 	u_int32_t		snmp_intotalsetvars;
268 	u_int32_t		snmp_ingetrequests;
269 	u_int32_t		snmp_ingetnexts;
270 	u_int32_t		snmp_insetrequests;
271 	u_int32_t		snmp_ingetresponses;
272 	u_int32_t		snmp_intraps;
273 	u_int32_t		snmp_outtoobigs;
274 	u_int32_t		snmp_outnosuchnames;
275 	u_int32_t		snmp_outbadvalues;
276 	u_int32_t		snmp_outgenerrs;
277 	u_int32_t		snmp_outgetrequests;
278 	u_int32_t		snmp_outgetnexts;
279 	u_int32_t		snmp_outsetrequests;
280 	u_int32_t		snmp_outgetresponses;
281 	u_int32_t		snmp_outtraps;
282 	int			snmp_enableauthentraps;
283 	u_int32_t		snmp_silentdrops;
284 	u_int32_t		snmp_proxydrops;
285 
286 	/* USM stats (RFC 3414) */
287 	u_int32_t		snmp_usmbadseclevel;
288 	u_int32_t		snmp_usmtimewindow;
289 	u_int32_t		snmp_usmnosuchuser;
290 	u_int32_t		snmp_usmnosuchengine;
291 	u_int32_t		snmp_usmwrongdigest;
292 	u_int32_t		snmp_usmdecrypterr;
293 };
294 
295 struct address {
296 	struct sockaddr_storage	 ss;
297 	in_port_t		 port;
298 	int			 type;
299 	int			 flags;
300 	int			 fd;
301 	struct event		 ev;
302 	struct event		 evt;
303 
304 	TAILQ_ENTRY(address)	 entry;
305 };
306 TAILQ_HEAD(addresslist, address);
307 
308 struct agentx_master {
309 	int			axm_fd;
310 	struct sockaddr_un	axm_sun;
311 	uid_t			axm_owner;
312 	gid_t			axm_group;
313 	mode_t			axm_mode;
314 
315 	struct event		axm_ev;
316 
317 	TAILQ_ENTRY(agentx_master) axm_entry;
318 };
319 TAILQ_HEAD(axmasterlist, agentx_master);
320 
321 #define ADDRESS_FLAG_READ	0x01
322 #define ADDRESS_FLAG_WRITE	0x02
323 #define ADDRESS_FLAG_NOTIFY	0x04
324 #define ADDRESS_FLAG_PERM	\
325     (ADDRESS_FLAG_READ | ADDRESS_FLAG_WRITE | ADDRESS_FLAG_NOTIFY)
326 #define ADDRESS_FLAG_SNMPV1	0x10
327 #define ADDRESS_FLAG_SNMPV2	0x20
328 #define ADDRESS_FLAG_SNMPV3	0x40
329 #define ADDRESS_FLAG_MPS	\
330     (ADDRESS_FLAG_SNMPV1 | ADDRESS_FLAG_SNMPV2 | ADDRESS_FLAG_SNMPV3)
331 
332 struct trap_address {
333 	struct sockaddr_storage	 ta_ss;
334 	struct sockaddr_storage	 ta_sslocal;
335 	int			 ta_version;
336 	union {
337 		char		 ta_community[SNMPD_MAXCOMMUNITYLEN];
338 		struct {
339 			char		*ta_usmusername;
340 			struct usmuser	*ta_usmuser;
341 			int		 ta_seclevel;
342 		};
343 	};
344 	struct ber_oid		 ta_oid;
345 
346 	TAILQ_ENTRY(trap_address) entry;
347 };
348 TAILQ_HEAD(trap_addresslist, trap_address);
349 
350 enum usmauth {
351 	AUTH_NONE = 0,
352 	AUTH_MD5,	/* HMAC-MD5-96, RFC3414 */
353 	AUTH_SHA1,	/* HMAC-SHA-96, RFC3414 */
354 	AUTH_SHA224,	/* usmHMAC128SHA224AuthProtocol. RFC7860 */
355 	AUTH_SHA256,	/* usmHMAC192SHA256AuthProtocol. RFC7860 */
356 	AUTH_SHA384,	/* usmHMAC256SHA384AuthProtocol. RFC7860 */
357 	AUTH_SHA512	/* usmHMAC384SHA512AuthProtocol. RFC7860 */
358 };
359 
360 #define AUTH_DEFAULT	AUTH_SHA1	/* Default digest */
361 
362 enum usmpriv {
363 	PRIV_NONE = 0,
364 	PRIV_DES,	/* CBC-DES, RFC3414 */
365 	PRIV_AES	/* CFB128-AES-128, RFC3826 */
366 };
367 
368 #define PRIV_DEFAULT	PRIV_AES	/* Default cipher */
369 
370 struct usmuser {
371 	char			*uu_name;
372 	int			 uu_seclevel;
373 
374 	enum usmauth		 uu_auth;
375 	char			*uu_authkey;
376 	unsigned		 uu_authkeylen;
377 
378 
379 	enum usmpriv		 uu_priv;
380 	char			*uu_privkey;
381 	unsigned long long	 uu_salt;
382 
383 	SLIST_ENTRY(usmuser)	 uu_next;
384 };
385 
386 struct snmp_system {
387 	char			 sys_descr[256];
388 	struct ber_oid		 sys_oid;
389 	char			 sys_contact[256];
390 	char			 sys_name[256];
391 	char			 sys_location[256];
392 	int8_t			 sys_services;
393 };
394 
395 struct snmpd {
396 	u_int8_t		 sc_flags;
397 #define SNMPD_F_VERBOSE		 0x01
398 #define SNMPD_F_DEBUG		 0x02
399 #define SNMPD_F_NONAMES		 0x04
400 	enum mib_oidfmt		 sc_oidfmt;
401 
402 	const char		*sc_confpath;
403 	struct addresslist	 sc_addresses;
404 	struct axmasterlist	 sc_agentx_masters;
405 	struct timeval		 sc_starttime;
406 	u_int32_t		 sc_engine_boots;
407 
408 	char			 sc_rdcommunity[SNMPD_MAXCOMMUNITYLEN];
409 	char			 sc_rwcommunity[SNMPD_MAXCOMMUNITYLEN];
410 	char			 sc_trcommunity[SNMPD_MAXCOMMUNITYLEN];
411 
412 	uint8_t			 sc_engineid[SNMPD_MAXENGINEIDLEN];
413 	size_t			 sc_engineid_len;
414 
415 	struct snmp_stats	 sc_stats;
416 	struct snmp_system	 sc_system;
417 
418 	struct trap_addresslist	 sc_trapreceivers;
419 
420 	struct ber_oid		*sc_blocklist;
421 	size_t			 sc_nblocklist;
422 	int			 sc_rtfilter;
423 
424 	int			 sc_min_seclevel;
425 	int			 sc_traphandler;
426 
427 	struct privsep		 sc_ps;
428 };
429 
430 struct trapcmd {
431 	struct ber_oid		 cmd_oid;
432 		/* sideways return for intermediate lookups */
433 	struct trapcmd		*cmd_maybe;
434 
435 	int			 cmd_argc;
436 	char			**cmd_argv;
437 
438 	RB_ENTRY(trapcmd)	 cmd_entry;
439 };
440 RB_HEAD(trapcmd_tree, trapcmd);
441 extern	struct trapcmd_tree trapcmd_tree;
442 
443 extern struct snmpd *snmpd_env;
444 
445 /* parse.y */
446 struct snmpd	*parse_config(const char *, u_int);
447 int		 cmdline_symset(char *);
448 
449 /* snmpe.c */
450 void		 snmpe(struct privsep *, struct privsep_proc *);
451 void		 snmpe_shutdown(void);
452 void		 snmpe_dispatchmsg(struct snmp_message *);
453 void		 snmpe_response(struct snmp_message *);
454 int		 snmp_messagecmp(struct snmp_message *, struct snmp_message *);
455 RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp)
456 
457 /* trap.c */
458 void		 trap_init(void);
459 int		 trap_send(struct ber_oid *, struct ber_element *);
460 
461 /* smi.c */
462 int		 smi_init(void);
463 int		 smi_string2oid(const char *, struct ber_oid *);
464 const char	*smi_insert(struct ber_oid *, const char *);
465 unsigned int	 smi_application(struct ber_element *);
466 void		 smi_debug_elements(struct ber_element *);
467 
468 /* snmpd.c */
469 int		 snmpd_socket_af(struct sockaddr_storage *, int);
470 u_long		 snmpd_engine_time(void);
471 
472 /* usm.c */
473 void		 usm_generate_keys(void);
474 struct usmuser	*usm_newuser(char *name, const char **);
475 struct usmuser	*usm_finduser(char *name);
476 int		 usm_checkuser(struct usmuser *, const char **);
477 struct ber_element *usm_decode(struct snmp_message *, struct ber_element *,
478 		    const char **);
479 struct ber_element *usm_encode(struct snmp_message *, struct ber_element *);
480 struct ber_element *usm_encrypt(struct snmp_message *, struct ber_element *);
481 void		 usm_finalize_digest(struct snmp_message *, char *, ssize_t);
482 void		 usm_make_report(struct snmp_message *);
483 const struct usmuser *usm_check_mincred(int, const char **);
484 
485 /* proc.c */
486 enum privsep_procid
487 	    proc_getid(struct privsep_proc *, unsigned int, const char *);
488 void	 proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
489 	    int, char **, enum privsep_procid);
490 void	 proc_kill(struct privsep *);
491 void	 proc_connect(struct privsep *);
492 void	 proc_dispatch(int, short event, void *);
493 void	 proc_run(struct privsep *, struct privsep_proc *,
494 	    struct privsep_proc *, u_int,
495 	    void (*)(struct privsep *, struct privsep_proc *, void *), void *);
496 void	 imsg_event_add(struct imsgev *);
497 int	 imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t,
498 	    pid_t, int, void *, u_int16_t);
499 int	 imsg_composev_event(struct imsgev *, u_int16_t, u_int32_t,
500 	    pid_t, int, const struct iovec *, int);
501 void	 proc_range(struct privsep *, enum privsep_procid, int *, int *);
502 int	 proc_compose_imsg(struct privsep *, enum privsep_procid, int,
503 	    u_int16_t, u_int32_t, int, void *, u_int16_t);
504 int	 proc_compose(struct privsep *, enum privsep_procid,
505 	    uint16_t, void *, uint16_t);
506 int	 proc_composev_imsg(struct privsep *, enum privsep_procid, int,
507 	    u_int16_t, u_int32_t, int, const struct iovec *, int);
508 int	 proc_composev(struct privsep *, enum privsep_procid,
509 	    uint16_t, const struct iovec *, int);
510 struct imsgbuf *
511 	 proc_ibuf(struct privsep *, enum privsep_procid, int);
512 struct imsgev *
513 	 proc_iev(struct privsep *, enum privsep_procid, int);
514 int	 proc_flush_imsg(struct privsep *, enum privsep_procid, int);
515 
516 /* traphandler.c */
517 int	 traphandler_parse(struct snmp_message *);
518 int	 traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *);
519 void	 trapcmd_free(struct trapcmd *);
520 int	 trapcmd_add(struct trapcmd *);
521 struct trapcmd *
522 	 trapcmd_lookup(struct ber_oid *);
523 
524 /* util.c */
525 ssize_t	 sendtofrom(int, void *, size_t, int, struct sockaddr *,
526 	    socklen_t, struct sockaddr *, socklen_t);
527 ssize_t	 recvfromto(int, void *, size_t, int, struct sockaddr *,
528 	    socklen_t *, struct sockaddr *, socklen_t *);
529 const char *print_host(struct sockaddr_storage *, char *, size_t);
530 char	*tohexstr(u_int8_t *, int);
531 uint8_t *fromhexstr(uint8_t *, const char *, size_t);
532 
533 #endif /* SNMPD_H */
534