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
89enum imsg_type {
90	IMSG_NONE,
91	IMSG_CTL_VERBOSE,
92	IMSG_CTL_PROCFD,
93	IMSG_TRAP_EXEC,
94	IMSG_AX_FD
95};
96
97struct 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
113enum privsep_procid {
114	PROC_PARENT,	/* Parent process and application interface */
115	PROC_SNMPE,	/* SNMP engine */
116	PROC_MAX
117};
118
119extern enum privsep_procid privsep_process;
120
121struct privsep_pipes {
122	int			*pp_pipes[PROC_MAX];
123};
124
125struct 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
149struct 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
162struct 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
188struct 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};
250RB_HEAD(snmp_messages, snmp_message);
251extern struct snmp_messages snmp_messages;
252
253/* Defined in SNMPv2-MIB.txt (RFC 3418) */
254struct 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
295struct 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};
306TAILQ_HEAD(addresslist, address);
307
308struct 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};
319TAILQ_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
332struct 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};
348TAILQ_HEAD(trap_addresslist, trap_address);
349
350enum 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
362enum 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
370struct 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
386struct 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
395struct 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
430struct 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};
440RB_HEAD(trapcmd_tree, trapcmd);
441extern	struct trapcmd_tree trapcmd_tree;
442
443extern struct snmpd *snmpd_env;
444
445/* parse.y */
446struct snmpd	*parse_config(const char *, u_int);
447int		 cmdline_symset(char *);
448
449/* snmpe.c */
450void		 snmpe(struct privsep *, struct privsep_proc *);
451void		 snmpe_shutdown(void);
452void		 snmpe_dispatchmsg(struct snmp_message *);
453void		 snmpe_response(struct snmp_message *);
454int		 snmp_messagecmp(struct snmp_message *, struct snmp_message *);
455RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp)
456
457/* trap.c */
458void		 trap_init(void);
459int		 trap_send(struct ber_oid *, struct ber_element *);
460
461/* smi.c */
462int		 smi_init(void);
463int		 smi_string2oid(const char *, struct ber_oid *);
464const char	*smi_insert(struct ber_oid *, const char *);
465unsigned int	 smi_application(struct ber_element *);
466void		 smi_debug_elements(struct ber_element *);
467
468/* snmpd.c */
469int		 snmpd_socket_af(struct sockaddr_storage *, int);
470u_long		 snmpd_engine_time(void);
471
472/* usm.c */
473void		 usm_generate_keys(void);
474struct usmuser	*usm_newuser(char *name, const char **);
475struct usmuser	*usm_finduser(char *name);
476int		 usm_checkuser(struct usmuser *, const char **);
477struct ber_element *usm_decode(struct snmp_message *, struct ber_element *,
478		    const char **);
479struct ber_element *usm_encode(struct snmp_message *, struct ber_element *);
480struct ber_element *usm_encrypt(struct snmp_message *, struct ber_element *);
481void		 usm_finalize_digest(struct snmp_message *, char *, ssize_t);
482void		 usm_make_report(struct snmp_message *);
483const struct usmuser *usm_check_mincred(int, const char **);
484
485/* proc.c */
486enum privsep_procid
487	    proc_getid(struct privsep_proc *, unsigned int, const char *);
488void	 proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
489	    int, char **, enum privsep_procid);
490void	 proc_kill(struct privsep *);
491void	 proc_connect(struct privsep *);
492void	 proc_dispatch(int, short event, void *);
493void	 proc_run(struct privsep *, struct privsep_proc *,
494	    struct privsep_proc *, u_int,
495	    void (*)(struct privsep *, struct privsep_proc *, void *), void *);
496void	 imsg_event_add(struct imsgev *);
497int	 imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t,
498	    pid_t, int, void *, u_int16_t);
499int	 imsg_composev_event(struct imsgev *, u_int16_t, u_int32_t,
500	    pid_t, int, const struct iovec *, int);
501void	 proc_range(struct privsep *, enum privsep_procid, int *, int *);
502int	 proc_compose_imsg(struct privsep *, enum privsep_procid, int,
503	    u_int16_t, u_int32_t, int, void *, u_int16_t);
504int	 proc_compose(struct privsep *, enum privsep_procid,
505	    uint16_t, void *, uint16_t);
506int	 proc_composev_imsg(struct privsep *, enum privsep_procid, int,
507	    u_int16_t, u_int32_t, int, const struct iovec *, int);
508int	 proc_composev(struct privsep *, enum privsep_procid,
509	    uint16_t, const struct iovec *, int);
510struct imsgbuf *
511	 proc_ibuf(struct privsep *, enum privsep_procid, int);
512struct imsgev *
513	 proc_iev(struct privsep *, enum privsep_procid, int);
514int	 proc_flush_imsg(struct privsep *, enum privsep_procid, int);
515
516/* traphandler.c */
517int	 traphandler_parse(struct snmp_message *);
518int	 traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *);
519void	 trapcmd_free(struct trapcmd *);
520int	 trapcmd_add(struct trapcmd *);
521struct trapcmd *
522	 trapcmd_lookup(struct ber_oid *);
523
524/* util.c */
525ssize_t	 sendtofrom(int, void *, size_t, int, struct sockaddr *,
526	    socklen_t, struct sockaddr *, socklen_t);
527ssize_t	 recvfromto(int, void *, size_t, int, struct sockaddr *,
528	    socklen_t *, struct sockaddr *, socklen_t *);
529const char *print_host(struct sockaddr_storage *, char *, size_t);
530char	*tohexstr(u_int8_t *, int);
531uint8_t *fromhexstr(uint8_t *, const char *, size_t);
532
533#endif /* SNMPD_H */
534