diff options
-rw-r--r-- | usr.sbin/snmpd/Makefile | 6 | ||||
-rw-r--r-- | usr.sbin/snmpd/agentx.c | 1130 | ||||
-rw-r--r-- | usr.sbin/snmpd/control.c | 686 | ||||
-rw-r--r-- | usr.sbin/snmpd/mps.c | 32 | ||||
-rw-r--r-- | usr.sbin/snmpd/parse.y | 47 | ||||
-rw-r--r-- | usr.sbin/snmpd/proc.c | 20 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmp.h | 299 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.conf.5 | 21 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.h | 31 | ||||
-rw-r--r-- | usr.sbin/snmpd/trap.c | 94 | ||||
-rw-r--r-- | usr.sbin/snmpd/util.c | 124 |
11 files changed, 14 insertions, 2476 deletions
diff --git a/usr.sbin/snmpd/Makefile b/usr.sbin/snmpd/Makefile index bc72fd96121..eb7b6c927d2 100644 --- a/usr.sbin/snmpd/Makefile +++ b/usr.sbin/snmpd/Makefile @@ -1,10 +1,10 @@ -# $OpenBSD: Makefile,v 1.16 2019/05/11 17:46:02 rob Exp $ +# $OpenBSD: Makefile,v 1.17 2020/06/30 17:11:49 martijn Exp $ PROG= snmpd MAN= snmpd.8 snmpd.conf.5 -SRCS= parse.y log.c control.c snmpe.c \ +SRCS= parse.y log.c snmpe.c \ mps.c trap.c mib.c smi.c kroute.c snmpd.c timer.c \ - pf.c proc.c usm.c agentx.c traphandler.c util.c + pf.c proc.c usm.c traphandler.c util.c LDADD= -levent -lutil -lkvm -lcrypto DPADD= ${LIBEVENT} ${LIBUTIL} diff --git a/usr.sbin/snmpd/agentx.c b/usr.sbin/snmpd/agentx.c deleted file mode 100644 index cc55eb71fd9..00000000000 --- a/usr.sbin/snmpd/agentx.c +++ /dev/null @@ -1,1130 +0,0 @@ -/* $OpenBSD: agentx.c,v 1.14 2020/06/05 19:50:59 denis Exp $ */ -/* - * Copyright (c) 2013,2014 Bret Stephen Lambert <blambert@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/queue.h> -#include <sys/un.h> - -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "snmp.h" - -int snmp_agentx_octetstring(struct agentx_pdu *, char *, int); -int snmp_agentx_buffercheck(struct agentx_pdu *, size_t); -int snmp_agentx_oid(struct agentx_pdu *, struct snmp_oid *); -int snmp_agentx_buffer_consume(struct agentx_pdu *, u_int); -int snmp_agentx_int(struct agentx_pdu *, uint32_t *); -int snmp_agentx_int64(struct agentx_pdu *, uint64_t *); -int snmp_agentx_do_read_raw(struct agentx_pdu *, void *, int, int); -void snmp_agentx_update_ids(struct agentx_handle *, struct agentx_pdu *); -struct agentx_pdu * - agentx_find_inflight(struct agentx_handle *, uint32_t, uint32_t); -int snmp_agentx_do_read_oid(struct agentx_pdu *, struct snmp_oid *, int *); - -#ifdef DEBUG -static void snmp_agentx_dump_hdr(struct agentx_hdr *); -#endif - -#define PDU_BUFLEN 256 - -/* snmpTrapOid.0 */ -struct snmp_oid trapoid_0 = { - .o_id = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }, - .o_n = 11 -}; - -/* - * AgentX handle allocation and management routines. - */ - -struct agentx_handle * -snmp_agentx_alloc(int s) -{ - struct agentx_handle *h; - - if ((h = calloc(1, sizeof(*h))) == NULL) - return (NULL); - - h->fd = s; - h->timeout = AGENTX_DEFAULT_TIMEOUT; - - TAILQ_INIT(&h->w); - TAILQ_INIT(&h->inflight); - - return (h); -} - -/* - * Synchronous open of unix socket path. - */ -struct agentx_handle * -snmp_agentx_open(const char *path, char *descr, struct snmp_oid *oid) -{ - struct sockaddr_un sun; - struct agentx_handle *h; - int s; - - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - return (NULL); - - bzero(&sun, sizeof(sun)); - sun.sun_family = AF_UNIX; - if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= - sizeof(sun.sun_path)) - goto fail; - - if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) == -1) - goto fail; - - if ((h = snmp_agentx_fdopen(s, descr, oid)) == NULL) - goto fail; - - return (h); - fail: - close(s); - return (NULL); -} - -/* - * Synchronous AgentX open operation over previously-opened socket. - */ -struct agentx_handle * -snmp_agentx_fdopen(int s, char *descr, struct snmp_oid *oid) -{ - struct agentx_handle *h; - struct agentx_pdu *pdu = NULL; - - if ((h = snmp_agentx_alloc(s)) == NULL) - return (NULL); - - if ((pdu = snmp_agentx_open_pdu(h, descr, oid)) == NULL || - (pdu = snmp_agentx_request(h, pdu)) == NULL || - snmp_agentx_open_response(h, pdu) == -1) { - if (pdu) - snmp_agentx_pdu_free(pdu); - snmp_agentx_free(h); - return (NULL); - } - - return (h); -} - -/* - * Synchronous close of agentx handle. - */ -int -snmp_agentx_close(struct agentx_handle *h, uint8_t reason) -{ - struct agentx_pdu *pdu; - int error = 0; - - if ((pdu = snmp_agentx_close_pdu(h, reason)) == NULL) - return (-1); - if ((pdu = snmp_agentx_request(h, pdu)) == NULL) - return (-1); - if (snmp_agentx_response(h, pdu) == -1) - error = -1; - - snmp_agentx_pdu_free(pdu); - - return (error); -} - -void -snmp_agentx_free(struct agentx_handle *h) -{ - struct agentx_pdu *pdu; - - if (h->fd != -1) - close(h->fd); - - while ((pdu = TAILQ_FIRST(&h->w))) { - TAILQ_REMOVE(&h->w, pdu, entry); - snmp_agentx_pdu_free(pdu); - } - while ((pdu = TAILQ_FIRST(&h->inflight))) { - TAILQ_REMOVE(&h->w, pdu, entry); - snmp_agentx_pdu_free(pdu); - } - if (h->r) - snmp_agentx_pdu_free(h->r); - - free(h); -} - -/* - * AgentX pdu allocation routines. - */ - -/* - * Allocate an AgentX PDU. - */ -struct agentx_pdu * -snmp_agentx_pdu_alloc(void) -{ - struct agentx_pdu *pdu; - - if ((pdu = calloc(1, sizeof(*pdu))) == NULL) - return (NULL); - if ((pdu->buffer = calloc(PDU_BUFLEN, sizeof(uint8_t))) == NULL) { - free(pdu); - return (NULL); - } - - pdu->buflen = PDU_BUFLEN; - - bzero(pdu->buffer, pdu->buflen); - pdu->ptr = pdu->buffer + sizeof(struct agentx_hdr); - pdu->ioptr = pdu->buffer; - pdu->hdr = (struct agentx_hdr *)pdu->buffer; - pdu->hdr->version = AGENTX_VERSION; - pdu->hdr->flags = AGENTX_LOCAL_BYTE_ORDER_FLAG; - pdu->hdr->reserved = 0; - pdu->hdr->length = 0; - pdu->datalen = sizeof(struct agentx_hdr); - - return (pdu); -} - -/* - * Read the response PDU for a generic operation. - */ -int -snmp_agentx_response(struct agentx_handle *h, struct agentx_pdu *pdu) -{ - struct agentx_response_data resp; - - if (snmp_agentx_read_raw(pdu, &resp, sizeof(resp)) == -1) - return (-1); - - if (!snmp_agentx_byteorder_native(pdu->hdr)) { - resp.error = snmp_agentx_int16_byteswap(resp.error); - resp.index = snmp_agentx_int16_byteswap(resp.index); - } - - h->error = resp.error; - if (resp.error != AGENTX_ERR_NONE) - return (-1); - - return (0); -} - -/* - * Read the response PDU for an open operation. - */ -int -snmp_agentx_open_response(struct agentx_handle *h, struct agentx_pdu *pdu) -{ - - if (snmp_agentx_response(h, pdu) == -1) - return (-1); - - h->sessionid = pdu->hdr->sessionid; - return (0); -} - -void -snmp_agentx_pdu_free(struct agentx_pdu *pdu) -{ - free(pdu->buffer); - free(pdu->request); - free(pdu); -} - -int -snmp_agentx_buffer_consume(struct agentx_pdu *b, u_int len) -{ - int padding; - - padding = ((len + 3) & ~0x03) - len; - - if (b->datalen < (len + padding)) - return (-1); - - b->datalen -= len + padding; - b->ptr += len + padding; - - return (0); -} - -/* - * Send an AgentX PDU. Flushes any already-enqueued PDUs. - */ -int -snmp_agentx_send(struct agentx_handle *h, struct agentx_pdu *pdu) -{ - ssize_t n; - - /* set the appropriate IDs in the protocol header */ - if (pdu != NULL && - (pdu->datalen == pdu->hdr->length + sizeof(struct agentx_hdr))) { - pdu->hdr->sessionid = h->sessionid; - - if (pdu->hdr->type != AGENTX_RESPONSE) { - ++h->transactid; - ++h->packetid; - } - - pdu->hdr->transactid = h->transactid; - pdu->hdr->packetid = h->packetid; - TAILQ_INSERT_TAIL(&h->w, pdu, entry); - } - - again: - if ((pdu = TAILQ_FIRST(&h->w)) == NULL) - return (0); - - if ((n = send(h->fd, pdu->ioptr, pdu->datalen, 0)) == -1) - return (-1); - - pdu->ioptr += n; - pdu->datalen -= n; - - if (pdu->datalen > 0) { - errno = EAGAIN; - return (-1); - } - -#ifdef DEBUG - snmp_agentx_dump_hdr(pdu->hdr); -#endif - - TAILQ_REMOVE(&h->w, pdu, entry); - TAILQ_INSERT_TAIL(&h->inflight, pdu, entry); - - goto again; -} - -/* - * Attempt to read a single AgentX PDU. - */ -struct agentx_pdu * -snmp_agentx_recv(struct agentx_handle *h) -{ - struct agentx_pdu *pdu, *match; - ssize_t n; - - h->error = AGENTX_ERR_NONE; - - if (h->r == NULL) { - if ((h->r = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - h->r->datalen = 0; /* XXX force this for receive buffers */ - } - pdu = h->r; - - if (snmp_agentx_buffercheck(pdu, sizeof(struct agentx_hdr)) == -1) - return (NULL); - - /* read header */ - if (pdu->datalen < sizeof(struct agentx_hdr)) { - n = recv(h->fd, pdu->ioptr, sizeof(struct agentx_hdr), 0); - - if (n == 0 || n == -1) - return (NULL); - - pdu->datalen += n; - pdu->ioptr += n; - - if (pdu->datalen < sizeof(struct agentx_hdr)) { - errno = EAGAIN; - return (NULL); - } - - if (pdu->hdr->version != AGENTX_VERSION) { - h->error = AGENTX_ERR_PARSE_ERROR; - return (NULL); - } - - if (snmp_agentx_buffercheck(pdu, pdu->hdr->length) == -1) - return (NULL); - } - - /* read body */ - if (pdu->hdr->length > 0) { - n = recv(h->fd, pdu->ioptr, pdu->hdr->length, 0); - - if (n == 0 || n == -1) - return (NULL); - - pdu->datalen += n; - pdu->ioptr += n; - } - - if (pdu->datalen < pdu->hdr->length + sizeof(struct agentx_hdr)) { - errno = EAGAIN; - return (NULL); - } - - if (pdu->hdr->version != AGENTX_VERSION) { - h->error = AGENTX_ERR_PARSE_ERROR; - goto fail; - } - - /* If this is an open on a new connection, fix it up */ - if (pdu->hdr->type == AGENTX_OPEN && h->sessionid == 0) { - pdu->hdr->sessionid = 0; /* ignored, per RFC */ - h->transactid = pdu->hdr->transactid; - h->packetid = pdu->hdr->packetid; - } - - if (pdu->hdr->type == AGENTX_RESPONSE) { - - match = agentx_find_inflight(h, pdu->hdr->transactid, - pdu->hdr->packetid); - if (match == NULL) { - errno = ESRCH; /* XXX */ - goto fail; - } - - TAILQ_REMOVE(&h->inflight, match, entry); - pdu->request = match; - h->r = NULL; - - } else { - if (pdu->hdr->sessionid != h->sessionid) { - h->error = AGENTX_ERR_NOT_OPEN; - goto fail; - } - - snmp_agentx_update_ids(h, pdu); /* XXX */ - - if (pdu->datalen != pdu->hdr->length + sizeof(*pdu->hdr)) { - h->error = AGENTX_ERR_PARSE_ERROR; - goto fail; - } - - if (pdu->hdr->flags & AGENTX_NON_DEFAULT_CONTEXT) { - pdu->context = snmp_agentx_read_octetstr(pdu, - &pdu->contextlen); - if (pdu->context == NULL) { - h->error = AGENTX_ERR_PARSE_ERROR; - goto fail; - } - } - } - -#ifdef DEBUG - snmp_agentx_dump_hdr(pdu->hdr); -#endif - h->r = NULL; - - return (pdu); - - fail: -#ifdef DEBUG - snmp_agentx_dump_hdr(pdu->hdr); -#endif - snmp_agentx_pdu_free(pdu); - h->r = NULL; - - return (NULL); -} - -/* - * Synchonous request and receipt of response. - */ -struct agentx_pdu * -snmp_agentx_request(struct agentx_handle *h, struct agentx_pdu *pdu) -{ - - if (snmp_agentx_send(h, pdu) == -1) { - if (errno != EAGAIN) - return (NULL); - } - while (snmp_agentx_send(h, NULL) == -1) { - if (errno != EAGAIN) - return (NULL); - } - while ((pdu = snmp_agentx_recv(h)) == NULL) { - if (errno != EAGAIN) - return (NULL); - } - h->error = AGENTX_ERR_NONE; - - return (pdu); -} - -struct agentx_pdu * -agentx_find_inflight(struct agentx_handle *h, uint32_t tid, uint32_t pid) -{ - struct agentx_pdu *pdu; - - TAILQ_FOREACH(pdu, &h->inflight, entry) - if (pdu->hdr->transactid == tid && pdu->hdr->packetid == pid) - break; - return (pdu); -} - -int -snmp_agentx_buffercheck(struct agentx_pdu *pdu, size_t len) -{ - uint8_t *newptr; - size_t newlen; - - if (pdu->buflen - pdu->datalen >= len) - return (0); - - newlen = pdu->buflen + len; - if (newlen < pdu->buflen || newlen < len) - return (-1); - - if ((newptr = realloc(pdu->buffer, newlen)) == NULL) - return (-1); - - pdu->buflen = newlen; - pdu->ioptr = &newptr[pdu->ioptr - pdu->buffer]; - pdu->buffer = newptr; - pdu->hdr = (struct agentx_hdr *)pdu->buffer; - pdu->ptr = &pdu->buffer[pdu->datalen]; - - return (0); -} - -/* - * Utility routines for initializing common AgentX PDUs. - */ - -struct agentx_pdu * -snmp_agentx_open_pdu(struct agentx_handle *h, char *descr, - struct snmp_oid *oid) -{ - struct agentx_open_timeout to; - struct snmp_oid nulloid; - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - - pdu->hdr->type = AGENTX_OPEN; - - if (oid == NULL) { - bzero(&nulloid, sizeof(nulloid)); - oid = &nulloid; - } - - bzero(&to, sizeof(to)); - to.timeout = AGENTX_DEFAULT_TIMEOUT; - - if (snmp_agentx_raw(pdu, &to, sizeof(to)) == -1 || - snmp_agentx_oid(pdu, oid) == -1 || - snmp_agentx_octetstring(pdu, descr, strlen(descr)) == -1) - goto fail; - - return (pdu); - fail: - snmp_agentx_pdu_free(pdu); - return (NULL); -} - -struct agentx_pdu * -snmp_agentx_close_pdu(struct agentx_handle *h, uint8_t reason) -{ - struct agentx_close_request_data req; - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - pdu->hdr->type = AGENTX_CLOSE; - - bzero(&req, sizeof(req)); - req.reason = reason; - - if (snmp_agentx_raw(pdu, &req, sizeof(req)) == -1) { - snmp_agentx_pdu_free(pdu); - return (NULL); - } - - return (pdu); -} - -struct agentx_pdu * -snmp_agentx_notify_pdu(struct snmp_oid *oid) -{ - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - pdu->hdr->type = AGENTX_NOTIFY; - - if (snmp_agentx_varbind(pdu, &trapoid_0, - AGENTX_OBJECT_IDENTIFIER, oid, sizeof(*oid)) == -1) { - snmp_agentx_pdu_free(pdu); - return (NULL); - } - - return (pdu); -} - -struct agentx_pdu * -snmp_agentx_response_pdu(int uptime, int error, int idx) -{ - struct agentx_response_data resp; - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - pdu->hdr->type = AGENTX_RESPONSE; - - resp.sysuptime = uptime; - resp.error = error; - resp.index = idx; - - if (snmp_agentx_raw(pdu, &resp, sizeof(resp)) == -1) { - snmp_agentx_pdu_free(pdu); - return (NULL); - } - - return (pdu); -} - -struct agentx_pdu * -snmp_agentx_ping_pdu(void) -{ - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - pdu->hdr->version = AGENTX_VERSION; - pdu->hdr->type = AGENTX_PING; - - return (pdu); -} - -struct agentx_pdu * -snmp_agentx_register_pdu(struct snmp_oid *oid, int timeout, int range_index, - int range_bound) -{ - struct agentx_register_hdr rhdr; - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - - pdu->hdr->version = AGENTX_VERSION; - pdu->hdr->type = AGENTX_REGISTER; - - rhdr.timeout = timeout; - rhdr.priority = AGENTX_REGISTER_PRIO_DEFAULT; - rhdr.subrange = range_index; - rhdr.reserved = 0; - - if (snmp_agentx_raw(pdu, &rhdr, sizeof(rhdr)) == -1 || - snmp_agentx_oid(pdu, oid) == -1 || - (range_index && snmp_agentx_int(pdu, &range_bound) == -1)) { - snmp_agentx_pdu_free(pdu); - return (NULL); - } - - return (pdu); -} - -struct agentx_pdu * -snmp_agentx_unregister_pdu(struct snmp_oid *oid, int range_index, - int range_bound) -{ - struct agentx_unregister_hdr uhdr; - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - - pdu->hdr->version = AGENTX_VERSION; - pdu->hdr->type = AGENTX_UNREGISTER; - - uhdr.reserved1 = 0; - uhdr.priority = AGENTX_REGISTER_PRIO_DEFAULT; - uhdr.subrange = range_index; - uhdr.reserved2 = 0; - - if (snmp_agentx_raw(pdu, &uhdr, sizeof(uhdr)) == -1 || - snmp_agentx_oid(pdu, oid) == -1 || - (range_index && snmp_agentx_int(pdu, &range_bound) == -1)) { - snmp_agentx_pdu_free(pdu); - return (NULL); - } - - return (pdu); -} - -struct agentx_pdu * -snmp_agentx_get_pdu(struct snmp_oid oid[], int noid) -{ - struct snmp_oid nulloid; - struct agentx_pdu *pdu; - int i; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - - pdu->hdr->version = AGENTX_VERSION; - pdu->hdr->type = AGENTX_GET; - - bzero(&nulloid, sizeof(nulloid)); - - for (i = 0; i < noid; i++) { - if (snmp_agentx_oid(pdu, &oid[i]) == -1 || - snmp_agentx_oid(pdu, &nulloid) == -1) { - snmp_agentx_pdu_free(pdu); - return (NULL); - } - } - - return (pdu); -} - -struct agentx_pdu * -snmp_agentx_getnext_pdu(struct snmp_oid oid[], int noid) -{ - struct snmp_oid nulloid; - struct agentx_pdu *pdu; - int i; - - if ((pdu = snmp_agentx_pdu_alloc()) == NULL) - return (NULL); - - pdu->hdr->version = AGENTX_VERSION; - pdu->hdr->type = AGENTX_GET_NEXT; - - bzero(&nulloid, sizeof(nulloid)); - - for (i = 0; i < noid; i++) { - if (snmp_agentx_oid(pdu, &oid[i]) == -1 || - snmp_agentx_oid(pdu, &nulloid) == -1) { - snmp_agentx_pdu_free(pdu); - return (NULL); - } - } - - return (pdu); -} - -/* - * AgentX PDU write routines. - */ - -int -snmp_agentx_raw(struct agentx_pdu *pdu, void *data, int len) -{ - - if (snmp_agentx_buffercheck(pdu, len) == -1) - return (-1); - - memcpy(pdu->ptr, data, len); - - pdu->hdr->length += len; - pdu->ptr += len; - pdu->datalen += len; - - return (0); -} - -int -snmp_agentx_int(struct agentx_pdu *pdu, uint32_t *i) -{ - return (snmp_agentx_raw(pdu, i, sizeof(*i))); -} - -int -snmp_agentx_int64(struct agentx_pdu *pdu, uint64_t *i) -{ - return (snmp_agentx_raw(pdu, i, sizeof(*i))); -} - -int -snmp_agentx_octetstring(struct agentx_pdu *pdu, char *str, int len) -{ - static uint8_t pad[4] = { 0, 0, 0, 0 }; - int padding; - uint32_t l; - - padding = ((len + 3) & ~0x03) - len; - - l = len; - if (snmp_agentx_int(pdu, &l) == -1 || - snmp_agentx_raw(pdu, str, len) == -1 || - snmp_agentx_raw(pdu, pad, padding) == -1) - return (-1); - - return (0); -} - -int -snmp_agentx_oid(struct agentx_pdu *pdu, struct snmp_oid *oid) -{ - struct agentx_oid_hdr ohdr; - u_int i, prefix; - - i = prefix = 0; - - if (oid->o_id[0] == 1 && oid->o_id[1] == 3 && - oid->o_id[2] == 6 && oid->o_id[3] == 1 && - oid->o_id[4] < 256) { - prefix = oid->o_id[4]; - i = 5; - } - - if (prefix) - ohdr.n_subid = oid->o_n - 5; - else - ohdr.n_subid = oid->o_n; - ohdr.prefix = prefix; - ohdr.include = 0; - ohdr.reserved = 0; - - if (snmp_agentx_raw(pdu, &ohdr, sizeof(ohdr)) == -1) - return (-1); - - for (; i < oid->o_n; i++) - if (snmp_agentx_int(pdu, &oid->o_id[i]) == -1) - return (-1); - - return (0); -} - -int -snmp_agentx_varbind(struct agentx_pdu *pdu, struct snmp_oid *oid, int type, - void *data, int len) -{ - struct agentx_varbind_hdr vbhdr; - - vbhdr.type = type; - vbhdr.reserved = 0; - if (snmp_agentx_raw(pdu, &vbhdr, sizeof(vbhdr)) == -1) - return (-1); - - if (snmp_agentx_oid(pdu, oid) == -1) - return (-1); - - switch (type) { - - case AGENTX_NO_SUCH_OBJECT: - case AGENTX_NO_SUCH_INSTANCE: - case AGENTX_END_OF_MIB_VIEW: - case AGENTX_NULL: - /* no data follows the OID */ - return (0); - - case AGENTX_IP_ADDRESS: - case AGENTX_OPAQUE: - case AGENTX_OCTET_STRING: - return (snmp_agentx_octetstring(pdu, data, len)); - - case AGENTX_OBJECT_IDENTIFIER: - return (snmp_agentx_oid(pdu, (struct snmp_oid *)data)); - - case AGENTX_INTEGER: - case AGENTX_COUNTER32: - case AGENTX_GAUGE32: - case AGENTX_TIME_TICKS: - return (snmp_agentx_int(pdu, (uint32_t *)data)); - - case AGENTX_COUNTER64: - return (snmp_agentx_int64(pdu, (uint64_t *)data)); - - default: - return (-1); - } - /* NOTREACHED */ -} - -/* - * AgentX PDU read routines. - */ - -int -snmp_agentx_read_vbhdr(struct agentx_pdu *pdu, - struct agentx_varbind_hdr *vbhdr) -{ - if (snmp_agentx_read_raw(pdu, vbhdr, sizeof(*vbhdr)) == -1) - return (-1); - if (!snmp_agentx_byteorder_native(pdu->hdr)) - vbhdr->type = snmp_agentx_int16_byteswap(vbhdr->type); - return (0); -} - -int -snmp_agentx_copy_raw(struct agentx_pdu *pdu, void *v, int len) -{ - return (snmp_agentx_do_read_raw(pdu, v, len, 0)); -} - -int -snmp_agentx_read_raw(struct agentx_pdu *pdu, void *v, int len) -{ - return (snmp_agentx_do_read_raw(pdu, v, len, 1)); -} - -int -snmp_agentx_do_read_raw(struct agentx_pdu *pdu, void *v, int len, int consume) -{ - void *ptr = pdu->ptr; - - if (consume) - if (snmp_agentx_buffer_consume(pdu, len) == -1) - return (-1); - - memcpy(v, ptr, len); - - return (0); -} - -int -snmp_agentx_read_int(struct agentx_pdu *pdu, uint32_t *i) -{ - if (snmp_agentx_read_raw(pdu, i, sizeof(*i)) == -1) - return (-1); - if (!snmp_agentx_byteorder_native(pdu->hdr)) - *i = snmp_agentx_int_byteswap(*i); - return (0); -} - -int -snmp_agentx_read_int64(struct agentx_pdu *pdu, uint64_t *i) -{ - if (snmp_agentx_read_raw(pdu, i, sizeof(*i)) == -1) - return (-1); - if (!snmp_agentx_byteorder_native(pdu->hdr)) - *i = snmp_agentx_int64_byteswap(*i); - return (0); -} - -int -snmp_agentx_read_oid(struct agentx_pdu *pdu, struct snmp_oid *oid) -{ - int dummy; - - return (snmp_agentx_do_read_oid(pdu, oid, &dummy)); -} - -int -snmp_agentx_do_read_oid(struct agentx_pdu *pdu, struct snmp_oid *oid, - int *include) -{ - struct agentx_oid_hdr ohdr; - int i = 0; - - if (snmp_agentx_read_raw(pdu, &ohdr, sizeof(ohdr)) == -1) - return (-1); - - bzero(oid, sizeof(*oid)); - - if (ohdr.prefix != 0) { - oid->o_id[0] = 1; - oid->o_id[1] = 3; - oid->o_id[2] = 6; - oid->o_id[3] = 1; - oid->o_id[4] = ohdr.prefix; - i = 5; - } - - while (ohdr.n_subid--) - if (snmp_agentx_read_int(pdu, &oid->o_id[i++]) == -1) - return (-1); - - oid->o_n = i; - *include = ohdr.include; - - return (0); -} - -int -snmp_agentx_read_searchrange(struct agentx_pdu *pdu, - struct agentx_search_range *sr) -{ - if (snmp_agentx_do_read_oid(pdu, &sr->start, &sr->include) == -1 || - snmp_agentx_read_oid(pdu, &sr->end) == -1) - return (-1); - - return (0); -} - -char * -snmp_agentx_read_octetstr(struct agentx_pdu *pdu, int *len) -{ - char *str; - uint32_t l; - - if (snmp_agentx_read_int(pdu, &l) == -1) - return (NULL); - - if ((str = malloc(l)) == NULL) - return (NULL); - - if (snmp_agentx_read_raw(pdu, str, l) == -1) { - free(str); - return (NULL); - } - *len = l; - - return (str); -} - -/* - * Synchronous AgentX calls. - */ - -int -snmp_agentx_ping(struct agentx_handle *h) -{ - struct agentx_pdu *pdu; - int error = 0; - - if ((pdu = snmp_agentx_ping_pdu()) == NULL) - return (-1); - - /* Attaches the pdu to the handle; will be released later */ - if ((pdu = snmp_agentx_request(h, pdu)) == NULL) - return (-1); - - if (snmp_agentx_response(h, pdu) == -1) - error = -1; - snmp_agentx_pdu_free(pdu); - - return (error); -} - -/* - * Internal utility functions. - */ - -void -snmp_agentx_update_ids(struct agentx_handle *h, struct agentx_pdu *pdu) -{ - /* XXX -- update to reflect the new queueing semantics */ - h->transactid = pdu->hdr->transactid; - h->packetid = pdu->hdr->packetid; -} - -char * -snmp_oid2string(struct snmp_oid *o, char *buf, size_t len) -{ - char str[256]; - size_t i; - - bzero(buf, len); - - for (i = 0; i < o->o_n; i++) { - snprintf(str, sizeof(str), "%u", o->o_id[i]); - strlcat(buf, str, len); - if (i < (o->o_n - 1)) - strlcat(buf, ".", len); - } - - return (buf); -} - -int -snmp_oid_cmp(struct snmp_oid *a, struct snmp_oid *b) -{ - size_t i; - - for (i = 0; i < SNMP_MAX_OID_LEN; i++) { - if (a->o_id[i] != 0) { - if (a->o_id[i] == b->o_id[i]) - continue; - else if (a->o_id[i] < b->o_id[i]) { - /* b is a successor of a */ - return (1); - } else { - /* b is a predecessor of a */ - return (-1); - } - } else if (b->o_id[i] != 0) { - /* b is larger, but a child of a */ - return (2); - } else - break; - } - - /* b and a are identical */ - return (0); -} - -void -snmp_oid_increment(struct snmp_oid *o) -{ - u_int i; - - for (i = o->o_n; i > 0; i--) { - o->o_id[i - 1]++; - if (o->o_id[i - 1] != 0) - break; - } -} - -char * -snmp_agentx_type2name(int type) -{ - static char *names[] = { - "AGENTX_OPEN", - "AGENTX_CLOSE", - "AGENTX_REGISTER", - "AGENTX_UNREGISTER", - "AGENTX_GET", - "AGENTX_GET_NEXT", - "AGENTX_GET_BULK", - "AGENTX_TEST_SET", - "AGENTX_COMMIT_SET", - "AGENTX_UNDO_SET", - "AGENTX_CLEANUP_SET", - "AGENTX_NOTIFY", - "AGENTX_PING", - "AGENTX_INDEX_ALLOCATE", - "AGENTX_INDEX_DEALLOCATE", - "AGENTX_ADD_AGENT_CAPS", - "AGENTX_REMOVE_AGENT_CAPS", - "AGENTX_RESPONSE" - }; - - if (type > 18) - return ("unknown"); - - return (names[type - 1]); -} - -#ifdef DEBUG -static void -snmp_agentx_dump_hdr(struct agentx_hdr *hdr) -{ - if (hdr == NULL) { - printf("NULL\n"); - return; - } - - fprintf(stderr, - "agentx: version %d type %s flags %d reserved %d" - " sessionid %d transactid %d packetid %d length %d", - hdr->version, snmp_agentx_type2name(hdr->type), hdr->flags, - hdr->reserved, hdr->sessionid, hdr->transactid, - hdr->packetid, hdr->length); - - if (hdr->type == AGENTX_RESPONSE) { - struct agentx_response *r = (struct agentx_response *)hdr; - - fprintf(stderr, " sysuptime %d error %d index %d", - r->data.sysuptime, r->data.error, r->data.index); - } - - fprintf(stderr, "\n"); -} -#endif diff --git a/usr.sbin/snmpd/control.c b/usr.sbin/snmpd/control.c deleted file mode 100644 index 4c54749358a..00000000000 --- a/usr.sbin/snmpd/control.c +++ /dev/null @@ -1,686 +0,0 @@ -/* $OpenBSD: control.c,v 1.45 2020/01/28 15:42:10 bket Exp $ */ - -/* - * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/queue.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/tree.h> - -#include <net/if.h> - -#include <errno.h> -#include <event.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> - -#include "snmpd.h" - -#define CONTROL_BACKLOG 5 - -struct ctl_connlist ctl_conns; - -static int agentx_sessionid = 1; - -void control_accept(int, short, void *); -void control_close(struct ctl_conn *, const char *, struct imsg *); -void control_dispatch_imsg(int, short, void *); -void control_dispatch_agentx(int, short, void *); -void control_imsg_forward(struct imsg *); -void control_event_add(struct ctl_conn *, int, int, struct timeval *); -ssize_t imsg_read_nofd(struct imsgbuf *); - -int -control_init(struct privsep *ps, struct control_sock *cs) -{ - struct snmpd *env = ps->ps_env; - struct sockaddr_un sun; - int fd; - mode_t old_umask, mode; - - if (cs->cs_name == NULL) - return (0); - - if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) { - log_warn("%s: socket", __func__); - return (-1); - } - - sun.sun_family = AF_UNIX; - if (strlcpy(sun.sun_path, cs->cs_name, - sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) { - log_warn("%s: %s name too long", __func__, cs->cs_name); - close(fd); - return (-1); - } - - if (unlink(cs->cs_name) == -1) - if (errno != ENOENT) { - log_warn("%s: unlink %s", __func__, cs->cs_name); - close(fd); - return (-1); - } - - if (cs->cs_restricted || cs->cs_agentx) { - old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH); - mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; - } else { - old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); - mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP; - } - - if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) { - log_warn("%s: bind: %s", __func__, cs->cs_name); - close(fd); - (void)umask(old_umask); - return (-1); - } - (void)umask(old_umask); - - if (chmod(cs->cs_name, mode) == -1) { - log_warn("%s: chmod", __func__); - close(fd); - (void)unlink(cs->cs_name); - return (-1); - } - - cs->cs_fd = fd; - cs->cs_env = env; - - return (0); -} - -int -control_listen(struct control_sock *cs) -{ - if (cs->cs_name == NULL) - return (0); - - if (listen(cs->cs_fd, CONTROL_BACKLOG) == -1) { - log_warn("%s: listen", __func__); - return (-1); - } - - event_set(&cs->cs_ev, cs->cs_fd, EV_READ, - control_accept, cs); - event_add(&cs->cs_ev, NULL); - evtimer_set(&cs->cs_evt, control_accept, cs); - - return (0); -} - -/* ARGSUSED */ -void -control_accept(int listenfd, short event, void *arg) -{ - struct control_sock *cs = arg; - int connfd; - socklen_t len; - struct sockaddr_un sun; - struct ctl_conn *c; - - event_add(&cs->cs_ev, NULL); - if ((event & EV_TIMEOUT)) - return; - - len = sizeof(sun); - if ((connfd = accept4(listenfd, - (struct sockaddr *)&sun, &len, SOCK_NONBLOCK)) == -1) { - /* - * Pause accept if we are out of file descriptors, or - * libevent will haunt us here too. - */ - if (errno == ENFILE || errno == EMFILE) { - struct timeval evtpause = { 1, 0 }; - - event_del(&cs->cs_ev); - evtimer_add(&cs->cs_evt, &evtpause); - } else if (errno != EWOULDBLOCK && errno != EINTR && - errno != ECONNABORTED) - log_warn("%s: accept", __func__); - return; - } - - if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) { - close(connfd); - log_warn("%s: calloc", __func__); - return; - } - - imsg_init(&c->iev.ibuf, connfd); - if (cs->cs_agentx) { - c->handle = snmp_agentx_alloc(c->iev.ibuf.fd); - if (c->handle == NULL) { - free(c); - log_warn("%s: agentx", __func__); - return; - } - c->flags |= CTL_CONN_LOCKED; - c->iev.handler = control_dispatch_agentx; - TAILQ_INIT(&c->oids); - } else - c->iev.handler = control_dispatch_imsg; - c->iev.events = EV_READ; - c->iev.data = c; - c->cs = cs; - event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events, - c->iev.handler, c->iev.data); - event_add(&c->iev.ev, NULL); - - TAILQ_INSERT_TAIL(&ctl_conns, c, entry); -} - -void -control_close(struct ctl_conn *c, const char *msg, struct imsg *imsg) -{ - struct control_sock *cs = c->cs; - - if (imsg) { - log_debug("%s: fd %d: %s, imsg %d datalen %zu", __func__, - c->iev.ibuf.fd, msg, imsg->hdr.type, IMSG_DATA_SIZE(imsg)); - imsg_free(imsg); - } else - log_debug("%s: fd %d: %s", __func__, c->iev.ibuf.fd, msg); - - msgbuf_clear(&c->iev.ibuf.w); - TAILQ_REMOVE(&ctl_conns, c, entry); - - event_del(&c->iev.ev); - close(c->iev.ibuf.fd); - - /* Some file descriptors are available again. */ - if (evtimer_pending(&cs->cs_evt, NULL)) { - evtimer_del(&cs->cs_evt); - event_add(&cs->cs_ev, NULL); - } - - free(c); -} - -/* ARGSUSED */ -void -control_dispatch_imsg(int fd, short event, void *arg) -{ - struct ctl_conn *c = arg; - struct control_sock *cs = c->cs; - struct snmpd *env = cs->cs_env; - struct imsg imsg; - int n, v, i; - - if (event & EV_READ) { - if (((n = imsg_read_nofd(&c->iev.ibuf)) == -1 && - errno != EAGAIN) || n == 0) { - control_close(c, "could not read imsg", NULL); - return; - } - } - if (event & EV_WRITE) { - if (msgbuf_write(&c->iev.ibuf.w) <= 0 && errno != EAGAIN) { - control_close(c, "could not write imsg", NULL); - return; - } - } - - for (;;) { - if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) { - control_close(c, "could not get imsg", NULL); - return; - } - - if (n == 0) - break; - - if (cs->cs_restricted || (c->flags & CTL_CONN_LOCKED)) { - switch (imsg.hdr.type) { - case IMSG_SNMP_AGENTX: - case IMSG_SNMP_ELEMENT: - case IMSG_SNMP_END: - case IMSG_SNMP_LOCK: - break; - default: - control_close(c, - "client requested restricted command", - &imsg); - return; - } - } - - control_imsg_forward(&imsg); - - switch (imsg.hdr.type) { - case IMSG_CTL_NOTIFY: - if (IMSG_DATA_SIZE(&imsg)) - return control_close(c, "invalid size", &imsg); - - if (c->flags & CTL_CONN_NOTIFY) { - log_debug("%s: " - "client requested notify more than once", - __func__); - imsg_compose_event(&c->iev, IMSG_CTL_FAIL, - 0, 0, -1, NULL, 0); - break; - } - c->flags |= CTL_CONN_NOTIFY; - break; - - case IMSG_SNMP_LOCK: - if (IMSG_DATA_SIZE(&imsg)) - return control_close(c, "invalid size", &imsg); - - /* enable restricted control mode */ - c->flags |= CTL_CONN_LOCKED; - break; - - case IMSG_SNMP_AGENTX: - if (IMSG_DATA_SIZE(&imsg)) - return control_close(c, "invalid size", &imsg); - - /* rendezvous with the client */ - imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - if (imsg_flush(&c->iev.ibuf) == -1) { - control_close(c, - "could not rendezvous with agentx client", - &imsg); - return; - } - - /* enable AgentX socket */ - c->handle = snmp_agentx_alloc(c->iev.ibuf.fd); - if (c->handle == NULL) { - control_close(c, - "could not allocate agentx socket", - &imsg); - return; - } - /* disable IMSG notifications */ - c->flags &= ~CTL_CONN_NOTIFY; - c->flags |= CTL_CONN_LOCKED; - c->iev.handler = control_dispatch_agentx; - break; - - case IMSG_CTL_VERBOSE: - if (IMSG_DATA_SIZE(&imsg) != sizeof(v)) - return control_close(c, "invalid size", &imsg); - - memcpy(&v, imsg.data, sizeof(v)); - log_setverbose(v); - - for (i = 0; i < PROC_MAX; i++) { - if (privsep_process == PROC_CONTROL) - continue; - proc_forward_imsg(&env->sc_ps, &imsg, i, -1); - } - break; - case IMSG_CTL_RELOAD: - if (IMSG_DATA_SIZE(&imsg)) - return control_close(c, "invalid size", &imsg); - proc_forward_imsg(&env->sc_ps, &imsg, PROC_PARENT, -1); - break; - default: - control_close(c, "invalid type", &imsg); - return; - } - - imsg_free(&imsg); - } - - imsg_event_add(&c->iev); -} - -static void -purge_registered_oids(struct oidlist *oids) -{ - struct oid *oid; - - while ((oid = TAILQ_FIRST(oids)) != NULL) { - if (!(oid->o_flags & OID_REGISTERED)) - fatalx("attempting to unregister a static mib"); - smi_delete(oid); - TAILQ_REMOVE(oids, oid, o_list); - } -} - -/* ARGSUSED */ -void -control_dispatch_agentx(int fd, short event, void *arg) -{ - struct ctl_conn *c = arg; - struct agentx_handle *h = c->handle; - struct agentx_pdu *pdu; - struct timeval tv; - struct agentx_open_timeout to; - struct ber_oid oid; - struct agentx_close_request_data clhdr; - int closing = 0; - int evflags = 0; - int timer = 0; - int error = AGENTX_ERR_NONE; - int idx = 0, vcpylen, dlen, uptime; - char *descr, *varcpy; - - varcpy = descr = NULL; - if (h->timeout != 0) - tv.tv_sec = h->timeout; - else - tv.tv_sec = AGENTX_DEFAULT_TIMEOUT; - tv.tv_usec = 0; - - if (event & EV_TIMEOUT) { - log_info("subagent session '%i' timed out after %i seconds", - h->sessionid, h->timeout); - goto teardown; - } - - if (event & EV_WRITE) { - if (snmp_agentx_send(h, NULL) == -1) { - if (errno != EAGAIN) - goto teardown; - - /* short write */ - evflags |= EV_WRITE; - timer = 1; - } - } - - if (event & EV_READ) { - if ((pdu = snmp_agentx_recv(h)) == NULL) { - if (h->error) { - error = h->error; - goto respond; - } - if (errno != EAGAIN) - goto teardown; - - /* short read */ - timer = 1; - goto done; - } - - switch (pdu->hdr->type) { - case AGENTX_OPEN: - if (snmp_agentx_read_raw(pdu, &to, sizeof(to)) == -1 || - snmp_agentx_read_oid(pdu, - (struct snmp_oid *)&oid) == -1 || - (descr = - snmp_agentx_read_octetstr(pdu, &dlen)) == NULL) { - error = AGENTX_ERR_PARSE_ERROR; - break; - } - - log_info("opening AgentX socket for '%.*s'", - dlen, descr); - - h->sessionid = pdu->hdr->sessionid = - agentx_sessionid++; - if (to.timeout != 0) - h->timeout = to.timeout; - else - h->timeout = AGENTX_DEFAULT_TIMEOUT; - break; - - case AGENTX_CLOSE: - if (snmp_agentx_read_raw(pdu, - &clhdr, sizeof(clhdr)) == -1) { - error = AGENTX_ERR_PARSE_ERROR; - break; - } - closing = 1; - break; - - case AGENTX_NOTIFY: - error = trap_agentx(h, pdu, &idx, &varcpy, &vcpylen); - break; - - case AGENTX_PING: - /* no processing, just an empty response */ - break; - - case AGENTX_REGISTER: { - struct agentx_register_hdr rhdr; - struct oidlist oids; - struct oid *miboid; - uint32_t ubound = 0; - - TAILQ_INIT(&oids); - - if (snmp_agentx_read_raw(pdu, - &rhdr, sizeof(rhdr)) == -1 || - snmp_agentx_read_oid(pdu, - (struct snmp_oid *)&oid) == -1) { - error = AGENTX_ERR_PARSE_ERROR; - break; - } - - do { - if ((miboid = calloc(1, sizeof(*miboid))) == NULL) { - purge_registered_oids(&oids); - error = AGENTX_ERR_PARSE_ERROR; - goto dodone; - } - bcopy(&oid, &miboid->o_id, sizeof(oid)); - miboid->o_flags = OID_RD|OID_WR|OID_REGISTERED; - miboid->o_session = c; - if (smi_insert(miboid) == -1) { - purge_registered_oids(&oids); - error = AGENTX_ERR_DUPLICATE_REGISTRATION; - goto dodone; - } - TAILQ_INSERT_TAIL(&oids, miboid, o_list); - } while (++oid.bo_id[rhdr.subrange] <= ubound); - - TAILQ_CONCAT(&c->oids, &oids, o_list); - dodone: - break; - } - - case AGENTX_UNREGISTER: { - struct agentx_unregister_hdr uhdr; - struct oid *miboid; - uint32_t ubound = 0; - - if (snmp_agentx_read_raw(pdu, - &uhdr, sizeof(uhdr)) == -1 || - snmp_agentx_read_oid(pdu, - (struct snmp_oid *)&oid) == -1) { - error = AGENTX_ERR_PARSE_ERROR; - break; - } - - do { - if ((miboid = smi_find((struct oid *)&oid)) == NULL) { - log_warnx("attempting to remove unregistered MIB"); - continue; - } - if (miboid->o_session != c) { - log_warnx("attempting to remove MIB registered by other session"); - continue; - } - smi_delete(miboid); - } while (++oid.bo_id[uhdr.subrange] <= ubound); - break; - } - - case AGENTX_RESPONSE: { - struct snmp_message *msg = pdu->request->cookie; - struct agentx_response_data resp; - struct agentx_varbind_hdr vbhdr; - struct ber_element **elm, **iter; - - if (snmp_agentx_read_raw(pdu, &resp, sizeof(resp)) == -1) { - msg->sm_error = SNMP_ERROR_GENERR; - goto dispatch; - } - - switch (resp.error) { - case AGENTX_ERR_NONE: - break; - - /* per RFC, resp.error may be an SNMP error value */ - case SNMP_ERROR_TOOBIG: - case SNMP_ERROR_NOSUCHNAME: - case SNMP_ERROR_BADVALUE: - case SNMP_ERROR_READONLY: - case SNMP_ERROR_GENERR: - case SNMP_ERROR_NOACCESS: - case SNMP_ERROR_WRONGTYPE: - case SNMP_ERROR_WRONGLENGTH: - case SNMP_ERROR_WRONGENC: - case SNMP_ERROR_WRONGVALUE: - case SNMP_ERROR_NOCREATION: - case SNMP_ERROR_INCONVALUE: - case SNMP_ERROR_RESUNAVAIL: - case SNMP_ERROR_COMMITFAILED: - case SNMP_ERROR_UNDOFAILED: - case SNMP_ERROR_AUTHERROR: - case SNMP_ERROR_NOTWRITABLE: - case SNMP_ERROR_INCONNAME: - msg->sm_error = resp.error; - msg->sm_errorindex = resp.index; - break; - - case AGENTX_ERR_INDEX_WRONG_TYPE: - case AGENTX_ERR_UNSUPPORTED_CONTEXT: - case AGENTX_ERR_PARSE_ERROR: - case AGENTX_ERR_REQUEST_DENIED: - case AGENTX_ERR_PROCESSING_ERROR: - default: - msg->sm_error = SNMP_ERROR_GENERR; - msg->sm_errorindex = resp.index; - break; - } - - iter = elm = &msg->sm_varbindresp; - - while (pdu->datalen > sizeof(struct agentx_hdr)) { - if (snmp_agentx_read_raw(pdu, &vbhdr, sizeof(vbhdr)) == -1 || - varbind_convert(pdu, &vbhdr, elm, iter) - != AGENTX_ERR_NONE) { - msg->sm_error = SNMP_ERROR_GENERR; - msg->sm_errorindex = msg->sm_i; - goto dispatch; - } - } - dispatch: - snmpe_dispatchmsg(msg); - break; - } - - /* unimplemented, but parse and accept for now */ - case AGENTX_ADD_AGENT_CAPS: - case AGENTX_REMOVE_AGENT_CAPS: - break; - - /* unimplemented */ - case AGENTX_GET: - case AGENTX_GET_NEXT: - case AGENTX_GET_BULK: - case AGENTX_TEST_SET: - case AGENTX_COMMIT_SET: - case AGENTX_UNDO_SET: - case AGENTX_CLEANUP_SET: - case AGENTX_INDEX_ALLOCATE: - case AGENTX_INDEX_DEALLOCATE: - error = AGENTX_ERR_REQUEST_DENIED; - break; - - /* NB: by RFC, this should precede all other checks. */ - default: - log_info("unknown AgentX type '%i'", pdu->hdr->type); - error = AGENTX_ERR_PARSE_ERROR; - break; - } - respond: - if (pdu) - snmp_agentx_pdu_free(pdu); - - uptime = smi_getticks(); - if ((pdu = snmp_agentx_response_pdu(uptime, error, idx)) == NULL) { - log_debug("failed to generate response"); - free(varcpy); - control_event_add(c, fd, EV_WRITE, NULL); /* XXX -- EV_WRITE? */ - return; - } - - if (varcpy) { - snmp_agentx_raw(pdu, varcpy, vcpylen); /* XXX */ - free(varcpy); - varcpy = NULL; - } - snmp_agentx_send(h, pdu); - - /* Request processed, now write out response */ - evflags |= EV_WRITE; - } - - if (closing) - goto teardown; - done: - control_event_add(c, fd, evflags, timer ? &tv : NULL); - return; - - teardown: - log_debug("subagent session '%i' destroyed", h->sessionid); - snmp_agentx_free(h); - purge_registered_oids(&c->oids); - free(varcpy); - control_close(c, "agentx teardown", NULL); -} - -void -control_imsg_forward(struct imsg *imsg) -{ - struct ctl_conn *c; - - TAILQ_FOREACH(c, &ctl_conns, entry) - if (c->flags & CTL_CONN_NOTIFY) - imsg_compose_event(&c->iev, imsg->hdr.type, - 0, imsg->hdr.pid, -1, imsg->data, - imsg->hdr.len - IMSG_HEADER_SIZE); -} - -void -control_event_add(struct ctl_conn *c, int fd, int wflag, struct timeval *tv) -{ - event_del(&c->iev.ev); - event_set(&c->iev.ev, fd, EV_READ|wflag, control_dispatch_agentx, c); - event_add(&c->iev.ev, tv); -} - -/* This should go into libutil, from smtpd/mproc.c */ -ssize_t -imsg_read_nofd(struct imsgbuf *ibuf) -{ - ssize_t n; - char *buf; - size_t len; - - buf = ibuf->r.buf + ibuf->r.wpos; - len = sizeof(ibuf->r.buf) - ibuf->r.wpos; - - while ((n = recv(ibuf->fd, buf, len, 0)) == -1) { - if (errno != EINTR) - return (n); - } - - ibuf->r.wpos += n; - return (n); -} diff --git a/usr.sbin/snmpd/mps.c b/usr.sbin/snmpd/mps.c index 7c6f2f18124..c602d630147 100644 --- a/usr.sbin/snmpd/mps.c +++ b/usr.sbin/snmpd/mps.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mps.c,v 1.28 2019/10/24 12:39:27 tb Exp $ */ +/* $OpenBSD: mps.c,v 1.29 2020/06/30 17:11:49 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -48,8 +48,6 @@ struct ber_oid * mps_table(struct oid *, struct ber_oid *, struct ber_oid *); -extern void control_event_add(struct ctl_conn *, int, int, struct timeval *); /* XXX */ - int mps_getstr(struct oid *oid, struct ber_oid *o, struct ber_element **elm) { @@ -131,20 +129,6 @@ mps_getreq(struct snmp_message *msg, struct ber_element *root, if (OID_NOTSET(value)) goto fail; - if (value->o_flags & OID_REGISTERED) { - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_get_pdu((struct snmp_oid *)o, 1)) == NULL) - return (-1); - pdu->cookie = msg; - if (snmp_agentx_send(value->o_session->handle, pdu) == -1) - return (-1); - - control_event_add(value->o_session, - value->o_session->handle->fd, EV_WRITE, NULL); - return (1); - } - if (value->o_get == NULL) goto fail; @@ -212,20 +196,6 @@ mps_getnextreq(struct snmp_message *msg, struct ber_element *root, if (value == NULL) goto fail; - if (value->o_flags & OID_REGISTERED) { - struct agentx_pdu *pdu; - - if ((pdu = snmp_agentx_getnext_pdu((struct snmp_oid *)o, 1)) == NULL) - return (-1); - pdu->cookie = msg; - if (snmp_agentx_send(value->o_session->handle, pdu) == -1) - return (-1); - - control_event_add(value->o_session, - value->o_session->handle->fd, EV_WRITE, NULL); - return (1); - } - if (value->o_flags & OID_TABLE) { /* Get the next table row for this column */ if (mps_table(value, o, &no) != NULL) { diff --git a/usr.sbin/snmpd/parse.y b/usr.sbin/snmpd/parse.y index e63a7bc121c..9d0c613eb55 100644 --- a/usr.sbin/snmpd/parse.y +++ b/usr.sbin/snmpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.57 2020/01/02 10:55:53 florian Exp $ */ +/* $OpenBSD: parse.y,v 1.58 2020/06/30 17:11:49 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -51,11 +51,6 @@ #include "snmpd.h" #include "mib.h" -enum socktype { - SOCK_TYPE_RESTRICTED = 1, - SOCK_TYPE_AGENTX = 2 -}; - TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); static struct file { TAILQ_ENTRY(file) entry; @@ -98,7 +93,6 @@ struct snmpd *conf = NULL; static int errors = 0; static struct addresslist *hlist; static struct usmuser *user = NULL; -static int nctlsocks = 0; struct address *host_v4(const char *); struct address *host_v6(const char *); @@ -133,12 +127,12 @@ typedef struct { %token SYSTEM CONTACT DESCR LOCATION NAME OBJECTID SERVICES RTFILTER %token READONLY READWRITE OCTETSTRING INTEGER COMMUNITY TRAP RECEIVER %token SECLEVEL NONE AUTH ENC USER AUTHKEY ENCKEY ERROR DISABLED -%token SOCKET RESTRICTED AGENTX HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER +%token HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER %token <v.string> STRING %token <v.number> NUMBER %type <v.string> hostcmn %type <v.string> srcaddr -%type <v.number> optwrite yesno seclevel socktype proto +%type <v.number> optwrite yesno seclevel proto %type <v.data> objtype cmd %type <v.oid> oid hostoid trapoid %type <v.auth> auth @@ -295,31 +289,6 @@ main : LISTEN ON STRING proto { } user = NULL; } - | SOCKET STRING socktype { - if ($3) { - struct control_sock *rcsock; - - rcsock = calloc(1, sizeof(*rcsock)); - if (rcsock == NULL) { - yyerror("calloc"); - YYERROR; - } - rcsock->cs_name = $2; - if ($3 == SOCK_TYPE_RESTRICTED) - rcsock->cs_restricted = 1; - else if ($3 == SOCK_TYPE_AGENTX) - rcsock->cs_agentx = 1; - TAILQ_INSERT_TAIL(&conf->sc_ps.ps_rcsocks, - rcsock, cs_entry); - } else { - if (++nctlsocks > 1) { - yyerror("multiple control " - "sockets specified"); - YYERROR; - } - conf->sc_ps.ps_csock.cs_name = $2; - } - } ; system : SYSTEM sysmib @@ -541,11 +510,6 @@ enc : STRING { } ; -socktype : RESTRICTED { $$ = SOCK_TYPE_RESTRICTED; } - | AGENTX { $$ = SOCK_TYPE_AGENTX; } - | /* nothing */ { $$ = 0; } - ; - proto : /* empty */ { $$ = IPPROTO_UDP; } | TCP { $$ = IPPROTO_TCP; } | UDP { $$ = IPPROTO_UDP; } @@ -631,7 +595,6 @@ lookup(char *s) { /* this has to be sorted always */ static const struct keywords keywords[] = { - { "agentx", AGENTX }, { "auth", AUTH }, { "authkey", AUTHKEY }, { "community", COMMUNITY }, @@ -655,10 +618,8 @@ lookup(char *s) { "read-only", READONLY }, { "read-write", READWRITE }, { "receiver", RECEIVER }, - { "restricted", RESTRICTED }, { "seclevel", SECLEVEL }, { "services", SERVICES }, - { "socket", SOCKET }, { "source-address", SRCADDR }, { "string", OCTETSTRING }, { "system", SYSTEM }, @@ -1037,8 +998,6 @@ parse_config(const char *filename, u_int flags) conf->sc_confpath = filename; TAILQ_INIT(&conf->sc_addresses); TAILQ_INIT(&conf->sc_sockets); - conf->sc_ps.ps_csock.cs_name = SNMPD_SOCKET; - TAILQ_INIT(&conf->sc_ps.ps_rcsocks); strlcpy(conf->sc_rdcommunity, "public", SNMPD_MAXCOMMUNITYLEN); strlcpy(conf->sc_rwcommunity, "private", SNMPD_MAXCOMMUNITYLEN); strlcpy(conf->sc_trcommunity, "public", SNMPD_MAXCOMMUNITYLEN); diff --git a/usr.sbin/snmpd/proc.c b/usr.sbin/snmpd/proc.c index d3701186821..fd76ac9720a 100644 --- a/usr.sbin/snmpd/proc.c +++ b/usr.sbin/snmpd/proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.c,v 1.26 2019/01/08 15:38:36 bluhm Exp $ */ +/* $OpenBSD: proc.c,v 1.27 2020/06/30 17:11:49 martijn Exp $ */ /* * Copyright (c) 2010 - 2016 Reyk Floeter <reyk@openbsd.org> @@ -525,21 +525,12 @@ proc_run(struct privsep *ps, struct privsep_proc *p, { struct passwd *pw; const char *root; - struct control_sock *rcs; log_procinit(p->p_title); /* Set the process group of the current process */ setpgid(0, 0); - if (p->p_id == PROC_CONTROL && ps->ps_instance == 0) { - if (control_init(ps, &ps->ps_csock) == -1) - fatalx("%s: control_init", __func__); - TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry) - if (control_init(ps, rcs) == -1) - fatalx("%s: control_init", __func__); - } - /* Use non-standard user */ if (p->p_pw != NULL) pw = p->p_pw; @@ -584,15 +575,6 @@ proc_run(struct privsep *ps, struct privsep_proc *p, proc_setup(ps, procs, nproc); proc_accept(ps, PROC_PARENT_SOCK_FILENO, PROC_PARENT, 0); - if (p->p_id == PROC_CONTROL && ps->ps_instance == 0) { - TAILQ_INIT(&ctl_conns); - if (control_listen(&ps->ps_csock) == -1) - fatalx("%s: control_listen", __func__); - TAILQ_FOREACH(rcs, &ps->ps_rcsocks, cs_entry) - if (control_listen(rcs) == -1) - fatalx("%s: control_listen", __func__); - } - DPRINTF("%s: %s %d/%d, pid %d", __func__, p->p_title, ps->ps_instance + 1, ps->ps_instances[p->p_id], getpid()); diff --git a/usr.sbin/snmpd/snmp.h b/usr.sbin/snmpd/snmp.h index 71261b4f5b5..fe4d4b10611 100644 --- a/usr.sbin/snmpd/snmp.h +++ b/usr.sbin/snmpd/snmp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: snmp.h,v 1.15 2018/06/17 18:19:59 rob Exp $ */ +/* $OpenBSD: snmp.h,v 1.16 2020/06/30 17:11:49 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -27,9 +27,6 @@ */ #define SNMP_MAX_OID_STRLEN 128 /* max size of the OID _string_ */ -#define SNMP_SOCKET "/var/run/snmpd.sock" -#define AGENTX_SOCKET "/var/run/agentx.sock" -#define SNMP_RESTRICTED_SOCKET "/var/run/snmpd.rsock" enum snmp_type { SNMP_IPADDR = 0, @@ -54,7 +51,6 @@ enum snmp_imsg_ctl { IMSG_SNMP_ELEMENT, IMSG_SNMP_END, IMSG_SNMP_LOCK, /* enable restricted mode */ - IMSG_SNMP_AGENTX }; struct snmp_imsg_hdr { @@ -156,297 +152,4 @@ enum snmp_security_model { #define SNMP_MAX_TIMEWINDOW 150 /* RFC3414 */ -#define SNMP_MIN_OID_LEN 2 /* OBJECT */ -#define SNMP_MAX_OID_LEN 32 /* OBJECT */ - -struct snmp_oid { - u_int32_t o_id[SNMP_MAX_OID_LEN + 1]; - size_t o_n; -}; - -/* AgentX protocol, as outlined in RFC 2741 */ - -/* version */ -#define AGENTX_VERSION 1 - -/* type */ -#define AGENTX_OPEN 1 -#define AGENTX_CLOSE 2 -#define AGENTX_REGISTER 3 -#define AGENTX_UNREGISTER 4 -#define AGENTX_GET 5 -#define AGENTX_GET_NEXT 6 -#define AGENTX_GET_BULK 7 -#define AGENTX_TEST_SET 8 -#define AGENTX_COMMIT_SET 9 -#define AGENTX_UNDO_SET 10 -#define AGENTX_CLEANUP_SET 11 -#define AGENTX_NOTIFY 12 -#define AGENTX_PING 13 -#define AGENTX_INDEX_ALLOCATE 14 -#define AGENTX_INDEX_DEALLOCATE 15 -#define AGENTX_ADD_AGENT_CAPS 16 -#define AGENTX_REMOVE_AGENT_CAPS 17 -#define AGENTX_RESPONSE 18 - -/* error return codes */ -#define AGENTX_ERR_NONE 0 -#define AGENTX_ERR_OPEN_FAILED 256 -#define AGENTX_ERR_NOT_OPEN 257 -#define AGENTX_ERR_INDEX_WRONG_TYPE 258 -#define AGENTX_ERR_INDEX_ALREADY_ALLOCATED 259 -#define AGENTX_ERR_INDEX_NONE_AVAILABLE 260 -#define AGENTX_ERR_INDEX_NOT_ALLOCATED 261 -#define AGENTX_ERR_UNSUPPORTED_CONTEXT 262 -#define AGENTX_ERR_DUPLICATE_REGISTRATION 263 -#define AGENTX_ERR_UNKNOWN_REGISTRATION 264 -#define AGENTX_ERR_UNKNOWN_AGENT_CAPS 265 -#define AGENTX_ERR_PARSE_ERROR 266 -#define AGENTX_ERR_REQUEST_DENIED 267 -#define AGENTX_ERR_PROCESSING_ERROR 268 - -/* flags */ -#define AGENTX_INSTANCE_REGISTRATION 0x01 -#define AGENTX_NEW_INDEX 0x02 -#define AGENTX_ANY_INDEX 0x04 -#define AGENTX_NON_DEFAULT_CONTEXT 0x08 -#define AGENTX_NETWORK_BYTE_ORDER 0x10 -#define AGENTX_FLAGS_MASK 0x1f - -/* encoded data types */ -#define AGENTX_INTEGER 2 -#define AGENTX_OCTET_STRING 4 -#define AGENTX_NULL 5 -#define AGENTX_OBJECT_IDENTIFIER 6 -#define AGENTX_IP_ADDRESS 64 -#define AGENTX_COUNTER32 65 -#define AGENTX_GAUGE32 66 -#define AGENTX_TIME_TICKS 67 -#define AGENTX_OPAQUE 68 -#define AGENTX_COUNTER64 70 -#define AGENTX_NO_SUCH_OBJECT 128 -#define AGENTX_NO_SUCH_INSTANCE 129 -#define AGENTX_END_OF_MIB_VIEW 130 - -/* for registered MIB overlap */ -#define AGENTX_REGISTER_PRIO_DEFAULT 127 - -/* reasons for request of close */ -#define AGENTX_CLOSE_OTHER 1 -#define AGENTX_CLOSE_PARSE_ERROR 2 -#define AGENTX_CLOSE_PROTOCOL_ERROR 3 -#define AGENTX_CLOSE_TIMEOUTS 4 -#define AGENTX_CLOSE_SHUTDOWN 5 -#define AGENTX_CLOSE_BY_MANAGER 6 - -#define AGENTX_DEFAULT_TIMEOUT 3 - -#define MIN_OID_LEN 2 /* OBJECT */ -#define MAX_OID_LEN 32 /* OBJECT */ - -/* - * Protocol header prefixed to all messages - */ -struct agentx_hdr { - uint8_t version; - uint8_t type; - uint8_t flags; - uint8_t reserved; - uint32_t sessionid; /* chosen by agent */ - uint32_t transactid; /* chosen by subagent */ - uint32_t packetid; /* per-request id */ - uint32_t length; -} __packed; - -/* - * Prefixed to a series of 4-byte values indicating the OID - */ -struct agentx_oid_hdr { - uint8_t n_subid; /* # of oid elements (named in RFC) */ - uint8_t prefix; /* if not 0, OID is 1.3.6.1.<prefix> */ - uint8_t include; /* is OID included in search range */ - uint8_t reserved; /* always 0 */ -} __packed; - -struct agentx_response_data { - uint32_t sysuptime; /* uptime of SNMP context */ - uint16_t error; /* status of request */ - uint16_t index; /* index of failed variable binding */ -} __packed; - -struct agentx_open_timeout { - uint8_t timeout; - uint8_t reserved[3]; -} __packed; - -struct agentx_register_hdr { - uint8_t timeout; - uint8_t priority; - uint8_t subrange; - uint8_t reserved; -} __packed; - -struct agentx_unregister_hdr { - uint8_t reserved1; - uint8_t priority; - uint8_t subrange; - uint8_t reserved2; -} __packed; - -struct agentx_null_oid { - uint8_t padding[4]; -} __packed; - -#define AGENTX_NULL_OID { 0, 0, 0, 0 } - -struct agentx_varbind_hdr { - uint16_t type; - uint16_t reserved; -} __packed; - -struct agentx_response { - struct agentx_hdr hdr; - struct agentx_response_data data; -} __packed; - -struct agentx_close_request_data { - uint8_t reason; - uint8_t padding[3]; -} __packed; - -struct agentx_close_request { - struct agentx_hdr hdr; - struct agentx_close_request_data data; -} __packed; - -struct agentx_getbulk_repeaters { - uint16_t nonrepeaters; - uint16_t maxrepetitions; -} __packed; - -struct agentx_pdu { - uint8_t *buffer; - uint8_t *ptr; - uint8_t *ioptr; - size_t buflen; - size_t datalen; - struct agentx_hdr *hdr; - - char *context; - uint32_t contextlen; - - void *cookie; - struct agentx_pdu *request; /* request this is a response to */ - TAILQ_ENTRY(agentx_pdu) entry; -}; -TAILQ_HEAD(agentx_pdulist, agentx_pdu); - -struct agentx_handle { - int fd; - uint32_t sessionid; - uint32_t transactid; - uint32_t packetid; - int timeout; /* in seconds */ - int error; - int erridx; - - struct agentx_pdulist w; - struct agentx_pdulist inflight; - - struct agentx_pdu *r; -}; - -struct agentx_search_range { - struct snmp_oid start; - struct snmp_oid end; - int include; /* is start oid included in search range */ -}; - -struct agentx_handle * - snmp_agentx_alloc(int); -struct agentx_handle * - snmp_agentx_open(const char *, char *, struct snmp_oid *); -struct agentx_handle * - snmp_agentx_fdopen(int, char *, struct snmp_oid *); -int snmp_agentx_response(struct agentx_handle *, struct agentx_pdu *); -int snmp_agentx_open_response(struct agentx_handle *, struct agentx_pdu *); -struct agentx_pdu * - snmp_agentx_open_pdu(struct agentx_handle *, char *descr, - struct snmp_oid *); -struct agentx_pdu * - snmp_agentx_close_pdu(struct agentx_handle *, uint8_t); -int snmp_agentx_close(struct agentx_handle *, uint8_t); -void snmp_agentx_free(struct agentx_handle *); -int snmp_agentx_ping(struct agentx_handle *); -struct agentx_pdu * - snmp_agentx_ping_pdu(void); -struct agentx_pdu * - snmp_agentx_notify_pdu(struct snmp_oid *); -struct agentx_pdu * - snmp_agentx_request(struct agentx_handle *, struct agentx_pdu *); -int snmp_agentx_varbind(struct agentx_pdu *, struct snmp_oid *, int, - void *, int); -int snmp_agentx_send(struct agentx_handle *, struct agentx_pdu *); -int snmp_agentx_enqueue(struct agentx_handle *, struct agentx_pdu *); -int snmp_agentx_flush(struct agentx_handle *); -struct agentx_pdu * - snmp_agentx_recv(struct agentx_handle *); -struct agentx_pdu * - snmp_agentx_response_pdu(int, int, int); -struct agentx_pdu * - snmp_agentx_register_pdu(struct snmp_oid *, int, int, int); -struct agentx_pdu * - snmp_agentx_unregister_pdu(struct snmp_oid *, int, int); -struct agentx_pdu * - snmp_agentx_get_pdu(struct snmp_oid *, int); -struct agentx_pdu * - snmp_agentx_getnext_pdu(struct snmp_oid *, int); -char *snmp_agentx_read_octetstr(struct agentx_pdu *, int *); -int snmp_agentx_read_oid(struct agentx_pdu *, struct snmp_oid *); -int snmp_agentx_read_searchrange(struct agentx_pdu *, - struct agentx_search_range *); -int snmp_agentx_read_raw(struct agentx_pdu *, void *, int); -int snmp_agentx_copy_raw(struct agentx_pdu *, void *, int); -char *snmp_agentx_type2name(int); -int snmp_agentx_read_int(struct agentx_pdu *, uint32_t *); -int snmp_agentx_read_int64(struct agentx_pdu *, uint64_t *); -int snmp_agentx_raw(struct agentx_pdu *, void *, int); -int snmp_agentx_read_vbhdr(struct agentx_pdu *, struct - agentx_varbind_hdr *); -struct agentx_pdu *snmp_agentx_pdu_alloc(void); -void snmp_agentx_pdu_free(struct agentx_pdu *); -char *snmp_oid2string(struct snmp_oid *, char *, size_t); -int snmp_oid_cmp(struct snmp_oid *, struct snmp_oid *); -void snmp_oid_increment(struct snmp_oid *); - -#if BYTE_ORDER == BIG_ENDIAN - -static __inline int -snmp_agentx_byteorder_native(struct agentx_hdr *h) -{ - return ((h->flags & AGENTX_NETWORK_BYTE_ORDER) != 0); -} - -#define AGENTX_LOCAL_BYTE_ORDER_FLAG AGENTX_NETWORK_BYTE_ORDER -#define snmp_agentx_int_byteswap(_i) htole32(_i) -#define snmp_agentx_int16_byteswap(_i) htole16(_i) -#define snmp_agentx_int64_byteswap(_i) htole64(_i) - -#elif BYTE_ORDER == LITTLE_ENDIAN - -static __inline int -snmp_agentx_byteorder_native(struct agentx_hdr *h) -{ - return ((h->flags & AGENTX_NETWORK_BYTE_ORDER) == 0); -} - -#define AGENTX_LOCAL_BYTE_ORDER_FLAG 0 -#define snmp_agentx_int_byteswap(_i) htobe32(_i) -#define snmp_agentx_int16_byteswap(_i) htobe16(_i) -#define snmp_agentx_int64_byteswap(_i) htobe64(_i) - -#else -#error "Unknown host byte order" -#endif - #endif /* SNMPD_SNMP_H */ diff --git a/usr.sbin/snmpd/snmpd.conf.5 b/usr.sbin/snmpd/snmpd.conf.5 index 6e4f37084f0..a9a5ba71d53 100644 --- a/usr.sbin/snmpd/snmpd.conf.5 +++ b/usr.sbin/snmpd/snmpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: snmpd.conf.5,v 1.42 2020/02/10 13:18:22 schwarze Exp $ +.\" $OpenBSD: snmpd.conf.5,v 1.43 2020/06/30 17:11:49 martijn Exp $ .\" .\" Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: February 10 2020 $ +.Dd $Mdocdate: June 30 2020 $ .Dt SNMPD.CONF 5 .Os .Sh NAME @@ -133,23 +133,6 @@ If the chosen value is different from .Xr snmpd 8 will accept only SNMPv3 requests since older versions neither support authentication nor encryption. -.It Ic socket Qo Ar path Qc Op Ic restricted | agentx -Create a control socket at -.Ar path . -If -.Ic restricted -is specified, a restricted control socket will be created. -If -.Ic agentx -is specified, a socket which speaks the AgentX protocol will be created. -Multiple -.Ic restricted -and -.Ic agentx -sockets may be created. -By default -.Pa /var/run/snmpd.sock -is created and no other sockets are created. .It Ic system contact Ar string Specify the name or description of the system contact, typically a name or an email address. diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h index 6a6f845deb5..c5ff348d316 100644 --- a/usr.sbin/snmpd/snmpd.h +++ b/usr.sbin/snmpd/snmpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: snmpd.h,v 1.86 2020/01/02 10:55:53 florian Exp $ */ +/* $OpenBSD: snmpd.h,v 1.87 2020/06/30 17:11:49 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -107,20 +107,6 @@ struct imsgev { } while (0) #define IMSG_DATA_SIZE(imsg) ((imsg)->hdr.len - IMSG_HEADER_SIZE) -/* initially control.h */ -struct control_sock { - const char *cs_name; - struct event cs_ev; - struct event cs_evt; - int cs_fd; - int cs_restricted; - int cs_agentx; - void *cs_env; - - TAILQ_ENTRY(control_sock) cs_entry; -}; -TAILQ_HEAD(control_socks, control_sock); - enum privsep_procid { PROC_PARENT, /* Parent process and application interface */ PROC_SNMPE, /* SNMP engine */ @@ -150,9 +136,6 @@ struct privsep { u_int ps_instance; int ps_noaction; - struct control_sock ps_csock; - struct control_socks ps_rcsocks; - /* Event and signal handlers */ struct event ps_evsigint; struct event ps_evsigterm; @@ -359,12 +342,8 @@ struct ctl_conn { #define CTL_CONN_NOTIFY 0x01 #define CTL_CONN_LOCKED 0x02 /* restricted mode */ struct imsgev iev; - struct control_sock *cs; - struct agentx_handle *handle; struct oidlist oids; }; -TAILQ_HEAD(ctl_connlist, ctl_conn); -extern struct ctl_connlist ctl_conns; /* * pf @@ -617,10 +596,6 @@ extern struct trapcmd_tree trapcmd_tree; extern struct snmpd *snmpd_env; -/* control.c */ -int control_init(struct privsep *, struct control_sock *); -int control_listen(struct control_sock *); - /* parse.y */ struct snmpd *parse_config(const char *, u_int); int cmdline_symset(char *); @@ -675,8 +650,6 @@ void snmpe_dispatchmsg(struct snmp_message *); /* trap.c */ void trap_init(void); int trap_imsg(struct imsgev *, pid_t); -int trap_agentx(struct agentx_handle *, struct agentx_pdu *, - int *, char **, int *); int trap_send(struct ber_oid *, struct ber_element *); /* mps.c */ @@ -808,8 +781,6 @@ struct trapcmd * trapcmd_lookup(struct ber_oid *); /* util.c */ -int varbind_convert(struct agentx_pdu *, struct agentx_varbind_hdr *, - struct ber_element **, struct ber_element **); ssize_t sendtofrom(int, void *, size_t, int, struct sockaddr *, socklen_t, struct sockaddr *, socklen_t); ssize_t recvfromto(int, void *, size_t, int, struct sockaddr *, diff --git a/usr.sbin/snmpd/trap.c b/usr.sbin/snmpd/trap.c index 721722051fd..95c68030d90 100644 --- a/usr.sbin/snmpd/trap.c +++ b/usr.sbin/snmpd/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.34 2019/12/09 16:51:10 martijn Exp $ */ +/* $OpenBSD: trap.c,v 1.35 2020/06/30 17:11:49 martijn Exp $ */ /* * Copyright (c) 2008 Reyk Floeter <reyk@openbsd.org> @@ -52,98 +52,6 @@ trap_init(void) } int -trap_agentx(struct agentx_handle *h, struct agentx_pdu *pdu, int *idx, - char **varcpy, int *vcpylen) -{ - struct agentx_varbind_hdr vbhdr; - u_int32_t d; - struct ber_oid o, oid; - struct ber_oid uptime = OID(MIB_sysUpTime); - struct ber_oid trapoid = OID(MIB_snmpTrapOID); - struct ber_element *varbind, *iter; - int x = 0, state = 0; - int ret = AGENTX_ERR_NONE; - int seensysuptime, seentrapoid; - size_t len = 0; - char *v = NULL; - - *varcpy = NULL; - varbind = NULL; - iter = NULL; - seensysuptime = seentrapoid = 0; - - if (pdu->hdr->flags & AGENTX_NON_DEFAULT_CONTEXT) { - ret = AGENTX_ERR_UNSUPPORTED_CONTEXT; - goto done; - } - - if ((v = malloc(pdu->hdr->length)) == NULL || - snmp_agentx_copy_raw(pdu, v, pdu->hdr->length) == -1) { - ret = AGENTX_ERR_PROCESSING_ERROR; - goto done; - } - - smi_scalar_oidlen(&uptime); - smi_scalar_oidlen(&trapoid); - while (pdu->datalen > sizeof(struct agentx_hdr)) { - x++; - - if (snmp_agentx_read_vbhdr(pdu, &vbhdr) == -1) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - - if (state < 2) { - if (snmp_agentx_read_oid(pdu, (struct snmp_oid *)&oid) == -1) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - if (state == 0 && ober_oid_cmp(&oid, &uptime) == 0) { - if (snmp_agentx_read_int(pdu, &d) == -1) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - state = 1; - continue; - } else if (ober_oid_cmp(&oid, &trapoid) == 0) { - if (snmp_agentx_read_oid(pdu, - (struct snmp_oid *)&o) == -1) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - state = 2; - continue; - } else { - ret = AGENTX_ERR_PROCESSING_ERROR; - goto done; - } - } - - ret = varbind_convert(pdu, &vbhdr, &varbind, &iter); - if (ret != AGENTX_ERR_NONE) - goto done; - } - - if (varbind != NULL) - len = ober_calc_len(varbind); - log_debug("trap_agentx: from packetid %d len %zu elements %d", - pdu->hdr->packetid, len, x); - - trap_send(&o, varbind); - - *varcpy = v; - *vcpylen = pdu->hdr->length; - - return (AGENTX_ERR_NONE); - done: - if (varbind != NULL) - ober_free_elements(varbind); - free(v); - *idx = x; - return (ret); -} - -int trap_send(struct ber_oid *oid, struct ber_element *elm) { int ret = 0, s; diff --git a/usr.sbin/snmpd/util.c b/usr.sbin/snmpd/util.c index 9944fafc840..26a83bec459 100644 --- a/usr.sbin/snmpd/util.c +++ b/usr.sbin/snmpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.9 2019/10/24 12:39:27 tb Exp $ */ +/* $OpenBSD: util.c,v 1.10 2020/06/30 17:11:49 martijn Exp $ */ /* * Copyright (c) 2014 Bret Stephen Lambert <blambert@openbsd.org> * @@ -30,128 +30,6 @@ #include "snmp.h" #include "snmpd.h" -/* - * Convert variable bindings from AgentX to SNMP dialect. - */ -int -varbind_convert(struct agentx_pdu *pdu, struct agentx_varbind_hdr *vbhdr, - struct ber_element **varbind, struct ber_element **iter) -{ - struct ber_oid oid; - u_int32_t d; - u_int64_t l; - int slen; - char *str; - struct ber_element *a; - int ret = AGENTX_ERR_NONE; - - if (snmp_agentx_read_oid(pdu, (struct snmp_oid *)&oid) == -1) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - - *iter = ober_add_sequence(*iter); - if (*varbind == NULL) - *varbind = *iter; - - a = ober_add_oid(*iter, &oid); - - switch (vbhdr->type) { - case AGENTX_NO_SUCH_OBJECT: - case AGENTX_NO_SUCH_INSTANCE: - case AGENTX_END_OF_MIB_VIEW: - case AGENTX_NULL: - a = ober_add_null(a); - break; - - case AGENTX_IP_ADDRESS: - case AGENTX_OPAQUE: - case AGENTX_OCTET_STRING: - str = snmp_agentx_read_octetstr(pdu, &slen); - if (str == NULL) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - a = ober_add_nstring(a, str, slen); - break; - - case AGENTX_OBJECT_IDENTIFIER: - if (snmp_agentx_read_oid(pdu, - (struct snmp_oid *)&oid) == -1) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - a = ober_add_oid(a, &oid); - break; - - case AGENTX_INTEGER: - case AGENTX_COUNTER32: - case AGENTX_GAUGE32: - case AGENTX_TIME_TICKS: - if (snmp_agentx_read_int(pdu, &d) == -1) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - a = ober_add_integer(a, d); - break; - - case AGENTX_COUNTER64: - if (snmp_agentx_read_int64(pdu, &l) == -1) { - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - a = ober_add_integer(a, l); - break; - - default: - log_debug("unknown data type '%i'", vbhdr->type); - ret = AGENTX_ERR_PARSE_ERROR; - goto done; - } - - /* AgentX types correspond to BER types */ - switch (vbhdr->type) { - case BER_TYPE_INTEGER: - case BER_TYPE_BITSTRING: - case BER_TYPE_OCTETSTRING: - case BER_TYPE_NULL: - case BER_TYPE_OBJECT: - /* universal types */ - break; - - /* Convert AgentX error types to SNMP error types */ - case AGENTX_NO_SUCH_OBJECT: - ober_set_header(a, BER_CLASS_CONTEXT, 0); - break; - case AGENTX_NO_SUCH_INSTANCE: - ober_set_header(a, BER_CLASS_CONTEXT, 1); - break; - - case AGENTX_COUNTER32: - ober_set_header(a, BER_CLASS_APPLICATION, SNMP_COUNTER32); - break; - - case AGENTX_GAUGE32: - ober_set_header(a, BER_CLASS_APPLICATION, SNMP_GAUGE32); - break; - - case AGENTX_COUNTER64: - ober_set_header(a, BER_CLASS_APPLICATION, SNMP_COUNTER64); - break; - - case AGENTX_IP_ADDRESS: - /* application 0 implicit 4-byte octet string per SNMPv2-SMI */ - break; - - default: - /* application-specific types */ - ober_set_header(a, BER_CLASS_APPLICATION, vbhdr->type); - break; - } - done: - return (ret); -} - ssize_t sendtofrom(int s, void *buf, size_t len, int flags, struct sockaddr *to, socklen_t tolen, struct sockaddr *from, socklen_t fromlen) |