diff options
author | Martijn van Duren <martijn@cvs.openbsd.org> | 2020-06-30 17:11:50 +0000 |
---|---|---|
committer | Martijn van Duren <martijn@cvs.openbsd.org> | 2020-06-30 17:11:50 +0000 |
commit | d22f77e554dc90e2671789cc39465575294a3e52 (patch) | |
tree | 85eb5e6060c829bfd8def925576fdfda6ac6e270 /usr.sbin | |
parent | 8e9a1f4a984e391d34de7c154c8caebff78ac414 (diff) |
Remove agentx and control socket support.
snmpctl has been removed two releases ago, which makes the control
interface obsolete.
agentx support has always been quirky at best, but got completely broken
with the BER_MAX_OID_LEN increase in ber.h. This change resulted in the
oid length on the snmp side being left uninitialized because of size
difference, resulting in weird behaviour. No one reported the breakage,
even after 6.7 was released.
This change requires users to remove the socket keyword from their
snmpd.conf.
OK denis@
Diffstat (limited to 'usr.sbin')
-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) |