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