1 /* $OpenBSD: snmpd.h,v 1.106 2022/10/06 14:41:08 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(...) { { __VA_ARGS__ } } 219 #define MIBDECL(...) { { MIB_##__VA_ARGS__ } }, #__VA_ARGS__ 220 #define MIB(...) { { MIB_##__VA_ARGS__ } }, NULL 221 #define MIBEND { { 0 } }, NULL 222 223 /* 224 * daemon structures 225 */ 226 227 #define MSG_HAS_AUTH(m) (((m)->sm_flags & SNMP_MSGFLAG_AUTH) != 0) 228 #define MSG_HAS_PRIV(m) (((m)->sm_flags & SNMP_MSGFLAG_PRIV) != 0) 229 #define MSG_SECLEVEL(m) ((m)->sm_flags & SNMP_MSGFLAG_SECMASK) 230 #define MSG_REPORT(m) (((m)->sm_flags & SNMP_MSGFLAG_REPORT) != 0) 231 232 struct snmp_message { 233 int sm_sock; 234 struct sockaddr_storage sm_ss; 235 socklen_t sm_slen; 236 int sm_sock_tcp; 237 int sm_aflags; 238 enum snmp_pdutype sm_pdutype; 239 struct event sm_sockev; 240 char sm_host[HOST_NAME_MAX+1]; 241 in_port_t sm_port; 242 243 struct sockaddr_storage sm_local_ss; 244 socklen_t sm_local_slen; 245 246 struct ber sm_ber; 247 struct ber_element *sm_req; 248 struct ber_element *sm_resp; 249 250 u_int8_t sm_data[READ_BUF_SIZE]; 251 size_t sm_datalen; 252 253 uint32_t sm_transactionid; 254 255 u_int sm_version; 256 257 /* V1, V2c */ 258 char sm_community[SNMPD_MAXCOMMUNITYLEN]; 259 260 /* V3 */ 261 long long sm_msgid; 262 long long sm_max_msg_size; 263 u_int8_t sm_flags; 264 long long sm_secmodel; 265 u_int32_t sm_engine_boots; 266 u_int32_t sm_engine_time; 267 uint8_t sm_ctxengineid[SNMPD_MAXENGINEIDLEN]; 268 size_t sm_ctxengineid_len; 269 char sm_ctxname[SNMPD_MAXCONTEXNAMELEN+1]; 270 271 /* USM */ 272 char sm_username[SNMPD_MAXUSERNAMELEN+1]; 273 struct usmuser *sm_user; 274 size_t sm_digest_offs; 275 char sm_salt[SNMP_USM_SALTLEN]; 276 int sm_usmerr; 277 278 long long sm_request; 279 280 const char *sm_errstr; 281 long long sm_error; 282 #define sm_nonrepeaters sm_error 283 long long sm_errorindex; 284 #define sm_maxrepetitions sm_errorindex 285 286 struct ber_element *sm_pdu; 287 struct ber_element *sm_pduend; 288 289 struct ber_element *sm_varbind; 290 struct ber_element *sm_varbindresp; 291 292 RB_ENTRY(snmp_message) sm_entry; 293 }; 294 RB_HEAD(snmp_messages, snmp_message); 295 extern struct snmp_messages snmp_messages; 296 297 /* Defined in SNMPv2-MIB.txt (RFC 3418) */ 298 struct snmp_stats { 299 u_int32_t snmp_inpkts; 300 u_int32_t snmp_outpkts; 301 u_int32_t snmp_inbadversions; 302 u_int32_t snmp_inbadcommunitynames; 303 u_int32_t snmp_inbadcommunityuses; 304 u_int32_t snmp_inasnparseerrs; 305 u_int32_t snmp_intoobigs; 306 u_int32_t snmp_innosuchnames; 307 u_int32_t snmp_inbadvalues; 308 u_int32_t snmp_inreadonlys; 309 u_int32_t snmp_ingenerrs; 310 u_int32_t snmp_intotalreqvars; 311 u_int32_t snmp_intotalsetvars; 312 u_int32_t snmp_ingetrequests; 313 u_int32_t snmp_ingetnexts; 314 u_int32_t snmp_insetrequests; 315 u_int32_t snmp_ingetresponses; 316 u_int32_t snmp_intraps; 317 u_int32_t snmp_outtoobigs; 318 u_int32_t snmp_outnosuchnames; 319 u_int32_t snmp_outbadvalues; 320 u_int32_t snmp_outgenerrs; 321 u_int32_t snmp_outgetrequests; 322 u_int32_t snmp_outgetnexts; 323 u_int32_t snmp_outsetrequests; 324 u_int32_t snmp_outgetresponses; 325 u_int32_t snmp_outtraps; 326 int snmp_enableauthentraps; 327 u_int32_t snmp_silentdrops; 328 u_int32_t snmp_proxydrops; 329 330 /* USM stats (RFC 3414) */ 331 u_int32_t snmp_usmbadseclevel; 332 u_int32_t snmp_usmtimewindow; 333 u_int32_t snmp_usmnosuchuser; 334 u_int32_t snmp_usmnosuchengine; 335 u_int32_t snmp_usmwrongdigest; 336 u_int32_t snmp_usmdecrypterr; 337 }; 338 339 struct address { 340 struct sockaddr_storage ss; 341 in_port_t port; 342 int type; 343 int flags; 344 int fd; 345 struct event ev; 346 struct event evt; 347 348 TAILQ_ENTRY(address) entry; 349 }; 350 TAILQ_HEAD(addresslist, address); 351 352 struct agentx_master { 353 int axm_fd; 354 struct sockaddr_un axm_sun; 355 uid_t axm_owner; 356 gid_t axm_group; 357 mode_t axm_mode; 358 359 struct event axm_ev; 360 361 TAILQ_ENTRY(agentx_master) axm_entry; 362 }; 363 TAILQ_HEAD(axmasterlist, agentx_master); 364 365 #define ADDRESS_FLAG_READ 0x01 366 #define ADDRESS_FLAG_WRITE 0x02 367 #define ADDRESS_FLAG_NOTIFY 0x04 368 #define ADDRESS_FLAG_PERM \ 369 (ADDRESS_FLAG_READ | ADDRESS_FLAG_WRITE | ADDRESS_FLAG_NOTIFY) 370 #define ADDRESS_FLAG_SNMPV1 0x10 371 #define ADDRESS_FLAG_SNMPV2 0x20 372 #define ADDRESS_FLAG_SNMPV3 0x40 373 #define ADDRESS_FLAG_MPS \ 374 (ADDRESS_FLAG_SNMPV1 | ADDRESS_FLAG_SNMPV2 | ADDRESS_FLAG_SNMPV3) 375 376 struct trap_address { 377 struct sockaddr_storage ta_ss; 378 struct sockaddr_storage ta_sslocal; 379 int ta_version; 380 union { 381 char ta_community[SNMPD_MAXCOMMUNITYLEN]; 382 struct { 383 char *ta_usmusername; 384 struct usmuser *ta_usmuser; 385 int ta_seclevel; 386 }; 387 }; 388 struct ber_oid *ta_oid; 389 390 TAILQ_ENTRY(trap_address) entry; 391 }; 392 TAILQ_HEAD(trap_addresslist, trap_address); 393 394 enum usmauth { 395 AUTH_NONE = 0, 396 AUTH_MD5, /* HMAC-MD5-96, RFC3414 */ 397 AUTH_SHA1, /* HMAC-SHA-96, RFC3414 */ 398 AUTH_SHA224, /* usmHMAC128SHA224AuthProtocol. RFC7860 */ 399 AUTH_SHA256, /* usmHMAC192SHA256AuthProtocol. RFC7860 */ 400 AUTH_SHA384, /* usmHMAC256SHA384AuthProtocol. RFC7860 */ 401 AUTH_SHA512 /* usmHMAC384SHA512AuthProtocol. RFC7860 */ 402 }; 403 404 #define AUTH_DEFAULT AUTH_SHA1 /* Default digest */ 405 406 enum usmpriv { 407 PRIV_NONE = 0, 408 PRIV_DES, /* CBC-DES, RFC3414 */ 409 PRIV_AES /* CFB128-AES-128, RFC3826 */ 410 }; 411 412 #define PRIV_DEFAULT PRIV_AES /* Default cipher */ 413 414 struct usmuser { 415 char *uu_name; 416 int uu_seclevel; 417 418 enum usmauth uu_auth; 419 char *uu_authkey; 420 unsigned uu_authkeylen; 421 422 423 enum usmpriv uu_priv; 424 char *uu_privkey; 425 unsigned long long uu_salt; 426 427 SLIST_ENTRY(usmuser) uu_next; 428 }; 429 430 struct snmpd { 431 u_int8_t sc_flags; 432 #define SNMPD_F_VERBOSE 0x01 433 #define SNMPD_F_DEBUG 0x02 434 #define SNMPD_F_NONAMES 0x04 435 436 const char *sc_confpath; 437 struct addresslist sc_addresses; 438 struct axmasterlist sc_agentx_masters; 439 struct timeval sc_starttime; 440 u_int32_t sc_engine_boots; 441 442 char sc_rdcommunity[SNMPD_MAXCOMMUNITYLEN]; 443 char sc_rwcommunity[SNMPD_MAXCOMMUNITYLEN]; 444 char sc_trcommunity[SNMPD_MAXCOMMUNITYLEN]; 445 446 uint8_t sc_engineid[SNMPD_MAXENGINEIDLEN]; 447 size_t sc_engineid_len; 448 449 struct snmp_stats sc_stats; 450 451 struct trap_addresslist sc_trapreceivers; 452 453 struct ber_oid *sc_blocklist; 454 size_t sc_nblocklist; 455 int sc_rtfilter; 456 457 int sc_min_seclevel; 458 int sc_traphandler; 459 460 struct privsep sc_ps; 461 }; 462 463 struct trapcmd { 464 struct ber_oid *cmd_oid; 465 /* sideways return for intermediate lookups */ 466 struct trapcmd *cmd_maybe; 467 468 int cmd_argc; 469 char **cmd_argv; 470 471 RB_ENTRY(trapcmd) cmd_entry; 472 }; 473 RB_HEAD(trapcmd_tree, trapcmd); 474 extern struct trapcmd_tree trapcmd_tree; 475 476 extern struct snmpd *snmpd_env; 477 478 /* parse.y */ 479 struct snmpd *parse_config(const char *, u_int); 480 int cmdline_symset(char *); 481 482 /* snmpe.c */ 483 void snmpe(struct privsep *, struct privsep_proc *); 484 void snmpe_shutdown(void); 485 void snmpe_dispatchmsg(struct snmp_message *); 486 void snmpe_response(struct snmp_message *); 487 int snmp_messagecmp(struct snmp_message *, struct snmp_message *); 488 RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp) 489 490 /* trap.c */ 491 void trap_init(void); 492 int trap_imsg(struct imsgev *, pid_t); 493 int trap_send(struct ber_oid *, struct ber_element *); 494 495 /* mps.c */ 496 int mps_getreq(struct snmp_message *, struct ber_element *, 497 struct ber_oid *, u_int); 498 int mps_getnextreq(struct snmp_message *, struct ber_element *, 499 struct ber_oid *); 500 int mps_getbulkreq(struct snmp_message *, struct ber_element **, 501 struct ber_element **, struct ber_oid *, int); 502 int mps_set(struct ber_oid *, void *, long long); 503 int mps_getstr(struct oid *, struct ber_oid *, 504 struct ber_element **); 505 int mps_getint(struct oid *, struct ber_oid *, 506 struct ber_element **); 507 int mps_getts(struct oid *, struct ber_oid *, 508 struct ber_element **); 509 510 /* smi.c */ 511 int smi_init(void); 512 void smi_mibtree(struct oid *); 513 struct oid *smi_find(struct oid *); 514 struct oid *smi_nfind(struct oid *); 515 struct oid *smi_findkey(char *); 516 struct oid *smi_next(struct oid *); 517 struct oid *smi_foreach(struct oid *, u_int); 518 void smi_oidlen(struct ber_oid *); 519 void smi_scalar_oidlen(struct ber_oid *); 520 int smi_string2oid(const char *, struct ber_oid *); 521 void smi_delete(struct oid *); 522 int smi_insert(struct oid *); 523 int smi_oid_cmp(struct oid *, struct oid *); 524 int smi_key_cmp(struct oid *, struct oid *); 525 unsigned int smi_application(struct ber_element *); 526 void smi_debug_elements(struct ber_element *); 527 528 /* snmpd.c */ 529 int snmpd_socket_af(struct sockaddr_storage *, int); 530 u_long snmpd_engine_time(void); 531 532 /* usm.c */ 533 void usm_generate_keys(void); 534 struct usmuser *usm_newuser(char *name, const char **); 535 struct usmuser *usm_finduser(char *name); 536 int usm_checkuser(struct usmuser *, const char **); 537 struct ber_element *usm_decode(struct snmp_message *, struct ber_element *, 538 const char **); 539 struct ber_element *usm_encode(struct snmp_message *, struct ber_element *); 540 struct ber_element *usm_encrypt(struct snmp_message *, struct ber_element *); 541 void usm_finalize_digest(struct snmp_message *, char *, ssize_t); 542 void usm_make_report(struct snmp_message *); 543 const struct usmuser *usm_check_mincred(int, const char **); 544 545 /* proc.c */ 546 enum privsep_procid 547 proc_getid(struct privsep_proc *, unsigned int, const char *); 548 void proc_init(struct privsep *, struct privsep_proc *, unsigned int, int, 549 int, char **, enum privsep_procid); 550 void proc_kill(struct privsep *); 551 void proc_connect(struct privsep *); 552 void proc_dispatch(int, short event, void *); 553 void proc_run(struct privsep *, struct privsep_proc *, 554 struct privsep_proc *, u_int, 555 void (*)(struct privsep *, struct privsep_proc *, void *), void *); 556 void imsg_event_add(struct imsgev *); 557 int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, 558 pid_t, int, void *, u_int16_t); 559 int imsg_composev_event(struct imsgev *, u_int16_t, u_int32_t, 560 pid_t, int, const struct iovec *, int); 561 void proc_range(struct privsep *, enum privsep_procid, int *, int *); 562 int proc_compose_imsg(struct privsep *, enum privsep_procid, int, 563 u_int16_t, u_int32_t, int, void *, u_int16_t); 564 int proc_compose(struct privsep *, enum privsep_procid, 565 uint16_t, void *, uint16_t); 566 int proc_composev_imsg(struct privsep *, enum privsep_procid, int, 567 u_int16_t, u_int32_t, int, const struct iovec *, int); 568 int proc_composev(struct privsep *, enum privsep_procid, 569 uint16_t, const struct iovec *, int); 570 int proc_forward_imsg(struct privsep *, struct imsg *, 571 enum privsep_procid, int); 572 struct imsgbuf * 573 proc_ibuf(struct privsep *, enum privsep_procid, int); 574 struct imsgev * 575 proc_iev(struct privsep *, enum privsep_procid, int); 576 int proc_flush_imsg(struct privsep *, enum privsep_procid, int); 577 578 /* traphandler.c */ 579 int traphandler_parse(struct snmp_message *); 580 int traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *); 581 void trapcmd_free(struct trapcmd *); 582 int trapcmd_add(struct trapcmd *); 583 struct trapcmd * 584 trapcmd_lookup(struct ber_oid *); 585 586 /* util.c */ 587 ssize_t sendtofrom(int, void *, size_t, int, struct sockaddr *, 588 socklen_t, struct sockaddr *, socklen_t); 589 ssize_t recvfromto(int, void *, size_t, int, struct sockaddr *, 590 socklen_t *, struct sockaddr *, socklen_t *); 591 const char *print_host(struct sockaddr_storage *, char *, size_t); 592 char *tohexstr(u_int8_t *, int); 593 uint8_t *fromhexstr(uint8_t *, const char *, size_t); 594 595 #endif /* SNMPD_H */ 596