1 /* $OpenBSD: snmpd.h,v 1.110 2023/11/12 20:04:35 martijn 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/tree.h> 24 #include <sys/un.h> 25 26 #include <net/if.h> 27 #include <net/if_dl.h> 28 #include <netinet/in.h> 29 #include <netinet/if_ether.h> 30 #include <netinet/ip.h> 31 #include <arpa/inet.h> 32 #include <net/pfvar.h> 33 #include <net/route.h> 34 35 #include <ber.h> 36 #include <stdio.h> 37 #include <imsg.h> 38 39 #include "log.h" 40 #include "smi.h" 41 #include "snmp.h" 42 43 #ifndef nitems 44 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 45 #endif 46 47 /* 48 * common definitions for snmpd 49 */ 50 51 #define CONF_FILE "/etc/snmpd.conf" 52 #define SNMPD_BACKEND "/usr/libexec/snmpd" 53 #define SNMPD_USER "_snmpd" 54 #define SNMP_PORT "161" 55 #define SNMPTRAP_PORT "162" 56 57 #define AGENTX_MASTER_PATH "/var/agentx/master" 58 #define AGENTX_GROUP "_agentx" 59 60 #define SNMPD_MAXSTRLEN 484 61 #define SNMPD_MAXCOMMUNITYLEN SNMPD_MAXSTRLEN 62 #define SNMPD_MAXVARBIND 0x7fffffff 63 #define SNMPD_MAXVARBINDLEN 1210 64 #define SNMPD_MAXENGINEIDLEN 32 65 #define SNMPD_MAXUSERNAMELEN 32 66 #define SNMPD_MAXCONTEXNAMELEN 32 67 68 #define SNMP_USM_MAXDIGESTLEN 48 69 #define SNMP_USM_SALTLEN 8 70 #define SNMP_USM_KEYLEN 64 71 #define SNMP_CIPHER_KEYLEN 16 72 73 #define SMALL_READ_BUF_SIZE 1024 74 #define READ_BUF_SIZE 65535 75 #define RT_BUF_SIZE 16384 76 #define MAX_RTSOCK_BUF (2 * 1024 * 1024) 77 78 #define SNMP_ENGINEID_OLD 0x00 79 #define SNMP_ENGINEID_NEW 0x80 /* RFC3411 */ 80 81 #define SNMP_ENGINEID_FMT_IPv4 1 82 #define SNMP_ENGINEID_FMT_IPv6 2 83 #define SNMP_ENGINEID_FMT_MAC 3 84 #define SNMP_ENGINEID_FMT_TEXT 4 85 #define SNMP_ENGINEID_FMT_OCT 5 86 #define SNMP_ENGINEID_FMT_HH 129 87 88 #define PEN_OPENBSD 30155 89 90 enum imsg_type { 91 IMSG_NONE, 92 IMSG_CTL_VERBOSE, 93 IMSG_CTL_PROCFD, 94 IMSG_TRAP_EXEC, 95 IMSG_AX_FD 96 }; 97 98 struct imsgev { 99 struct imsgbuf ibuf; 100 void (*handler)(int, short, void *); 101 struct event ev; 102 struct privsep_proc *proc; 103 void *data; 104 short events; 105 const char *name; 106 }; 107 108 #define IMSG_SIZE_CHECK(imsg, p) do { \ 109 if (IMSG_DATA_SIZE(imsg) < sizeof(*p)) \ 110 fatalx("bad length imsg received"); \ 111 } while (0) 112 #define IMSG_DATA_SIZE(imsg) ((imsg)->hdr.len - IMSG_HEADER_SIZE) 113 114 enum privsep_procid { 115 PROC_PARENT, /* Parent process and application interface */ 116 PROC_SNMPE, /* SNMP engine */ 117 PROC_MAX 118 }; 119 120 extern enum privsep_procid privsep_process; 121 122 struct privsep_pipes { 123 int *pp_pipes[PROC_MAX]; 124 }; 125 126 struct privsep { 127 struct privsep_pipes *ps_pipes[PROC_MAX]; 128 struct privsep_pipes *ps_pp; 129 130 struct imsgev *ps_ievs[PROC_MAX]; 131 const char *ps_title[PROC_MAX]; 132 pid_t ps_pid[PROC_MAX]; 133 struct passwd *ps_pw; 134 135 u_int ps_instances[PROC_MAX]; 136 u_int ps_instance; 137 int ps_noaction; 138 139 /* Event and signal handlers */ 140 struct event ps_evsigint; 141 struct event ps_evsigterm; 142 struct event ps_evsigchld; 143 struct event ps_evsighup; 144 struct event ps_evsigpipe; 145 struct event ps_evsigusr1; 146 147 void *ps_env; 148 }; 149 150 struct privsep_proc { 151 const char *p_title; 152 enum privsep_procid p_id; 153 int (*p_cb)(int, struct privsep_proc *, 154 struct imsg *); 155 void (*p_init)(struct privsep *, 156 struct privsep_proc *); 157 void (*p_shutdown)(void); 158 const char *p_chroot; 159 struct privsep *p_ps; 160 struct passwd *p_pw; 161 }; 162 163 struct privsep_fd { 164 enum privsep_procid pf_procid; 165 unsigned int pf_instance; 166 }; 167 168 #define PROC_PARENT_SOCK_FILENO 3 169 #define PROC_MAX_INSTANCES 32 170 171 #if DEBUG 172 #define DPRINTF log_debug 173 #else 174 #define DPRINTF(x...) do {} while(0) 175 #endif 176 177 /* 178 * Message Processing Subsystem (mps) 179 */ 180 181 struct oid { 182 struct ber_oid o_id; 183 #define o_oid o_id.bo_id 184 #define o_oidlen o_id.bo_n 185 186 char *o_name; 187 188 u_int o_flags; 189 190 int (*o_get)(struct oid *, struct ber_oid *, 191 struct ber_element **); 192 struct ber_oid *(*o_table)(struct oid *, struct ber_oid *, 193 struct ber_oid *); 194 195 long long o_val; 196 void *o_data; 197 198 RB_ENTRY(oid) o_element; 199 RB_ENTRY(oid) o_keyword; 200 }; 201 202 #define OID_RD 0x01 203 #define OID_WR 0x02 204 #define OID_IFSET 0x04 /* only if user-specified value */ 205 #define OID_DYNAMIC 0x08 /* free allocated data */ 206 #define OID_TABLE 0x10 /* dynamic sub-elements */ 207 #define OID_MIB 0x20 /* root-OID of a supported MIB */ 208 #define OID_KEY 0x40 /* lookup tables */ 209 210 #define OID_RS (OID_RD|OID_IFSET) 211 212 #define OID_TRD (OID_RD|OID_TABLE) 213 214 #define OID_NOTSET(_oid) \ 215 (((_oid)->o_flags & OID_IFSET) && \ 216 ((_oid)->o_data == NULL) && ((_oid)->o_val == 0)) 217 218 #define OID(...) (struct ber_oid){ { __VA_ARGS__ }, \ 219 (sizeof((uint32_t []) { __VA_ARGS__ }) / sizeof(uint32_t)) } 220 #define MIBDECL(...) { { MIB_##__VA_ARGS__ } }, #__VA_ARGS__ 221 #define MIB(...) { { MIB_##__VA_ARGS__ } }, NULL 222 #define MIBEND { { 0 } }, NULL 223 224 /* 225 * daemon structures 226 */ 227 228 #define MSG_HAS_AUTH(m) (((m)->sm_flags & SNMP_MSGFLAG_AUTH) != 0) 229 #define MSG_HAS_PRIV(m) (((m)->sm_flags & SNMP_MSGFLAG_PRIV) != 0) 230 #define MSG_SECLEVEL(m) ((m)->sm_flags & SNMP_MSGFLAG_SECMASK) 231 #define MSG_REPORT(m) (((m)->sm_flags & SNMP_MSGFLAG_REPORT) != 0) 232 233 struct snmp_message { 234 int sm_sock; 235 struct sockaddr_storage sm_ss; 236 socklen_t sm_slen; 237 int sm_sock_tcp; 238 int sm_aflags; 239 enum snmp_pdutype sm_pdutype; 240 struct event sm_sockev; 241 char sm_host[HOST_NAME_MAX+1]; 242 in_port_t sm_port; 243 244 struct sockaddr_storage sm_local_ss; 245 socklen_t sm_local_slen; 246 247 struct ber sm_ber; 248 struct ber_element *sm_req; 249 struct ber_element *sm_resp; 250 251 u_int8_t sm_data[READ_BUF_SIZE]; 252 size_t sm_datalen; 253 254 uint32_t sm_transactionid; 255 256 u_int sm_version; 257 258 /* V1, V2c */ 259 char sm_community[SNMPD_MAXCOMMUNITYLEN]; 260 261 /* V3 */ 262 long long sm_msgid; 263 long long sm_max_msg_size; 264 u_int8_t sm_flags; 265 long long sm_secmodel; 266 u_int32_t sm_engine_boots; 267 u_int32_t sm_engine_time; 268 uint8_t sm_ctxengineid[SNMPD_MAXENGINEIDLEN]; 269 size_t sm_ctxengineid_len; 270 char sm_ctxname[SNMPD_MAXCONTEXNAMELEN+1]; 271 272 /* USM */ 273 char sm_username[SNMPD_MAXUSERNAMELEN+1]; 274 struct usmuser *sm_user; 275 size_t sm_digest_offs; 276 char sm_salt[SNMP_USM_SALTLEN]; 277 int sm_usmerr; 278 279 long long sm_request; 280 281 const char *sm_errstr; 282 long long sm_error; 283 #define sm_nonrepeaters sm_error 284 long long sm_errorindex; 285 #define sm_maxrepetitions sm_errorindex 286 287 struct ber_element *sm_pdu; 288 struct ber_element *sm_pduend; 289 290 struct ber_element *sm_varbind; 291 struct ber_element *sm_varbindresp; 292 293 RB_ENTRY(snmp_message) sm_entry; 294 }; 295 RB_HEAD(snmp_messages, snmp_message); 296 extern struct snmp_messages snmp_messages; 297 298 /* Defined in SNMPv2-MIB.txt (RFC 3418) */ 299 struct snmp_stats { 300 u_int32_t snmp_inpkts; 301 u_int32_t snmp_outpkts; 302 u_int32_t snmp_inbadversions; 303 u_int32_t snmp_inbadcommunitynames; 304 u_int32_t snmp_inbadcommunityuses; 305 u_int32_t snmp_inasnparseerrs; 306 u_int32_t snmp_intoobigs; 307 u_int32_t snmp_innosuchnames; 308 u_int32_t snmp_inbadvalues; 309 u_int32_t snmp_inreadonlys; 310 u_int32_t snmp_ingenerrs; 311 u_int32_t snmp_intotalreqvars; 312 u_int32_t snmp_intotalsetvars; 313 u_int32_t snmp_ingetrequests; 314 u_int32_t snmp_ingetnexts; 315 u_int32_t snmp_insetrequests; 316 u_int32_t snmp_ingetresponses; 317 u_int32_t snmp_intraps; 318 u_int32_t snmp_outtoobigs; 319 u_int32_t snmp_outnosuchnames; 320 u_int32_t snmp_outbadvalues; 321 u_int32_t snmp_outgenerrs; 322 u_int32_t snmp_outgetrequests; 323 u_int32_t snmp_outgetnexts; 324 u_int32_t snmp_outsetrequests; 325 u_int32_t snmp_outgetresponses; 326 u_int32_t snmp_outtraps; 327 int snmp_enableauthentraps; 328 u_int32_t snmp_silentdrops; 329 u_int32_t snmp_proxydrops; 330 331 /* USM stats (RFC 3414) */ 332 u_int32_t snmp_usmbadseclevel; 333 u_int32_t snmp_usmtimewindow; 334 u_int32_t snmp_usmnosuchuser; 335 u_int32_t snmp_usmnosuchengine; 336 u_int32_t snmp_usmwrongdigest; 337 u_int32_t snmp_usmdecrypterr; 338 }; 339 340 struct address { 341 struct sockaddr_storage ss; 342 in_port_t port; 343 int type; 344 int flags; 345 int fd; 346 struct event ev; 347 struct event evt; 348 349 TAILQ_ENTRY(address) entry; 350 }; 351 TAILQ_HEAD(addresslist, address); 352 353 struct agentx_master { 354 int axm_fd; 355 struct sockaddr_un axm_sun; 356 uid_t axm_owner; 357 gid_t axm_group; 358 mode_t axm_mode; 359 360 struct event axm_ev; 361 362 TAILQ_ENTRY(agentx_master) axm_entry; 363 }; 364 TAILQ_HEAD(axmasterlist, agentx_master); 365 366 #define ADDRESS_FLAG_READ 0x01 367 #define ADDRESS_FLAG_WRITE 0x02 368 #define ADDRESS_FLAG_NOTIFY 0x04 369 #define ADDRESS_FLAG_PERM \ 370 (ADDRESS_FLAG_READ | ADDRESS_FLAG_WRITE | ADDRESS_FLAG_NOTIFY) 371 #define ADDRESS_FLAG_SNMPV1 0x10 372 #define ADDRESS_FLAG_SNMPV2 0x20 373 #define ADDRESS_FLAG_SNMPV3 0x40 374 #define ADDRESS_FLAG_MPS \ 375 (ADDRESS_FLAG_SNMPV1 | ADDRESS_FLAG_SNMPV2 | ADDRESS_FLAG_SNMPV3) 376 377 struct trap_address { 378 struct sockaddr_storage ta_ss; 379 struct sockaddr_storage ta_sslocal; 380 int ta_version; 381 union { 382 char ta_community[SNMPD_MAXCOMMUNITYLEN]; 383 struct { 384 char *ta_usmusername; 385 struct usmuser *ta_usmuser; 386 int ta_seclevel; 387 }; 388 }; 389 struct ber_oid *ta_oid; 390 391 TAILQ_ENTRY(trap_address) entry; 392 }; 393 TAILQ_HEAD(trap_addresslist, trap_address); 394 395 enum usmauth { 396 AUTH_NONE = 0, 397 AUTH_MD5, /* HMAC-MD5-96, RFC3414 */ 398 AUTH_SHA1, /* HMAC-SHA-96, RFC3414 */ 399 AUTH_SHA224, /* usmHMAC128SHA224AuthProtocol. RFC7860 */ 400 AUTH_SHA256, /* usmHMAC192SHA256AuthProtocol. RFC7860 */ 401 AUTH_SHA384, /* usmHMAC256SHA384AuthProtocol. RFC7860 */ 402 AUTH_SHA512 /* usmHMAC384SHA512AuthProtocol. RFC7860 */ 403 }; 404 405 #define AUTH_DEFAULT AUTH_SHA1 /* Default digest */ 406 407 enum usmpriv { 408 PRIV_NONE = 0, 409 PRIV_DES, /* CBC-DES, RFC3414 */ 410 PRIV_AES /* CFB128-AES-128, RFC3826 */ 411 }; 412 413 #define PRIV_DEFAULT PRIV_AES /* Default cipher */ 414 415 struct usmuser { 416 char *uu_name; 417 int uu_seclevel; 418 419 enum usmauth uu_auth; 420 char *uu_authkey; 421 unsigned uu_authkeylen; 422 423 424 enum usmpriv uu_priv; 425 char *uu_privkey; 426 unsigned long long uu_salt; 427 428 SLIST_ENTRY(usmuser) uu_next; 429 }; 430 431 struct snmp_system { 432 char sys_descr[256]; 433 struct ber_oid sys_oid; 434 char sys_contact[256]; 435 char sys_name[256]; 436 char sys_location[256]; 437 int8_t sys_services; 438 }; 439 440 struct snmpd { 441 u_int8_t sc_flags; 442 #define SNMPD_F_VERBOSE 0x01 443 #define SNMPD_F_DEBUG 0x02 444 #define SNMPD_F_NONAMES 0x04 445 446 const char *sc_confpath; 447 struct addresslist sc_addresses; 448 struct axmasterlist sc_agentx_masters; 449 struct timeval sc_starttime; 450 u_int32_t sc_engine_boots; 451 452 char sc_rdcommunity[SNMPD_MAXCOMMUNITYLEN]; 453 char sc_rwcommunity[SNMPD_MAXCOMMUNITYLEN]; 454 char sc_trcommunity[SNMPD_MAXCOMMUNITYLEN]; 455 456 uint8_t sc_engineid[SNMPD_MAXENGINEIDLEN]; 457 size_t sc_engineid_len; 458 459 struct snmp_stats sc_stats; 460 struct snmp_system sc_system; 461 462 struct trap_addresslist sc_trapreceivers; 463 464 struct ber_oid *sc_blocklist; 465 size_t sc_nblocklist; 466 int sc_rtfilter; 467 468 int sc_min_seclevel; 469 int sc_traphandler; 470 471 struct privsep sc_ps; 472 }; 473 474 struct trapcmd { 475 struct ber_oid *cmd_oid; 476 /* sideways return for intermediate lookups */ 477 struct trapcmd *cmd_maybe; 478 479 int cmd_argc; 480 char **cmd_argv; 481 482 RB_ENTRY(trapcmd) cmd_entry; 483 }; 484 RB_HEAD(trapcmd_tree, trapcmd); 485 extern struct trapcmd_tree trapcmd_tree; 486 487 extern struct snmpd *snmpd_env; 488 489 /* parse.y */ 490 struct snmpd *parse_config(const char *, u_int); 491 int cmdline_symset(char *); 492 493 /* snmpe.c */ 494 void snmpe(struct privsep *, struct privsep_proc *); 495 void snmpe_shutdown(void); 496 void snmpe_dispatchmsg(struct snmp_message *); 497 void snmpe_response(struct snmp_message *); 498 int snmp_messagecmp(struct snmp_message *, struct snmp_message *); 499 RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp) 500 501 /* trap.c */ 502 void trap_init(void); 503 int trap_imsg(struct imsgev *, pid_t); 504 int trap_send(struct ber_oid *, struct ber_element *); 505 506 /* smi.c */ 507 int smi_init(void); 508 void smi_mibtree(struct oid *); 509 struct oid *smi_find(struct oid *); 510 struct oid *smi_nfind(struct oid *); 511 struct oid *smi_findkey(char *); 512 struct oid *smi_next(struct oid *); 513 struct oid *smi_foreach(struct oid *, u_int); 514 void smi_oidlen(struct ber_oid *); 515 void smi_scalar_oidlen(struct ber_oid *); 516 int smi_string2oid(const char *, struct ber_oid *); 517 void smi_delete(struct oid *); 518 const char *smi_insert(struct ber_oid *, const char *); 519 int smi_oid_cmp(struct oid *, struct oid *); 520 int smi_key_cmp(struct oid *, struct oid *); 521 unsigned int smi_application(struct ber_element *); 522 void smi_debug_elements(struct ber_element *); 523 524 /* snmpd.c */ 525 int snmpd_socket_af(struct sockaddr_storage *, int); 526 u_long snmpd_engine_time(void); 527 528 /* usm.c */ 529 void usm_generate_keys(void); 530 struct usmuser *usm_newuser(char *name, const char **); 531 struct usmuser *usm_finduser(char *name); 532 int usm_checkuser(struct usmuser *, const char **); 533 struct ber_element *usm_decode(struct snmp_message *, struct ber_element *, 534 const char **); 535 struct ber_element *usm_encode(struct snmp_message *, struct ber_element *); 536 struct ber_element *usm_encrypt(struct snmp_message *, struct ber_element *); 537 void usm_finalize_digest(struct snmp_message *, char *, ssize_t); 538 void usm_make_report(struct snmp_message *); 539 const struct usmuser *usm_check_mincred(int, const char **); 540 541 /* proc.c */ 542 enum privsep_procid 543 proc_getid(struct privsep_proc *, unsigned int, const char *); 544 void proc_init(struct privsep *, struct privsep_proc *, unsigned int, int, 545 int, char **, enum privsep_procid); 546 void proc_kill(struct privsep *); 547 void proc_connect(struct privsep *); 548 void proc_dispatch(int, short event, void *); 549 void proc_run(struct privsep *, struct privsep_proc *, 550 struct privsep_proc *, u_int, 551 void (*)(struct privsep *, struct privsep_proc *, void *), void *); 552 void imsg_event_add(struct imsgev *); 553 int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, 554 pid_t, int, void *, u_int16_t); 555 int imsg_composev_event(struct imsgev *, u_int16_t, u_int32_t, 556 pid_t, int, const struct iovec *, int); 557 void proc_range(struct privsep *, enum privsep_procid, int *, int *); 558 int proc_compose_imsg(struct privsep *, enum privsep_procid, int, 559 u_int16_t, u_int32_t, int, void *, u_int16_t); 560 int proc_compose(struct privsep *, enum privsep_procid, 561 uint16_t, void *, uint16_t); 562 int proc_composev_imsg(struct privsep *, enum privsep_procid, int, 563 u_int16_t, u_int32_t, int, const struct iovec *, int); 564 int proc_composev(struct privsep *, enum privsep_procid, 565 uint16_t, const struct iovec *, int); 566 int proc_forward_imsg(struct privsep *, struct imsg *, 567 enum privsep_procid, int); 568 struct imsgbuf * 569 proc_ibuf(struct privsep *, enum privsep_procid, int); 570 struct imsgev * 571 proc_iev(struct privsep *, enum privsep_procid, int); 572 int proc_flush_imsg(struct privsep *, enum privsep_procid, int); 573 574 /* traphandler.c */ 575 int traphandler_parse(struct snmp_message *); 576 int traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *); 577 void trapcmd_free(struct trapcmd *); 578 int trapcmd_add(struct trapcmd *); 579 struct trapcmd * 580 trapcmd_lookup(struct ber_oid *); 581 582 /* util.c */ 583 ssize_t sendtofrom(int, void *, size_t, int, struct sockaddr *, 584 socklen_t, struct sockaddr *, socklen_t); 585 ssize_t recvfromto(int, void *, size_t, int, struct sockaddr *, 586 socklen_t *, struct sockaddr *, socklen_t *); 587 const char *print_host(struct sockaddr_storage *, char *, size_t); 588 char *tohexstr(u_int8_t *, int); 589 uint8_t *fromhexstr(uint8_t *, const char *, size_t); 590 591 #endif /* SNMPD_H */ 592