summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartijn van Duren <martijn@cvs.openbsd.org>2020-09-23 18:01:28 +0000
committerMartijn van Duren <martijn@cvs.openbsd.org>2020-09-23 18:01:28 +0000
commit5c037d976501f99425a662755a60e01e7990eaa4 (patch)
treee472f4e8b5640e4823242d8861ef6f7907269e33
parente1b56baa9e989c22b85335cae85f3f476897db26 (diff)
Add support for agentx to smtpd.
This is based around NETWORK-SERVICES-MIB from RFC2788 and MTA-MIB from RFC2789, but does not export the full spec. Hopefully this will expand in the future. People who want to use this against net-snmp (currently the only option known to me at the time of writing) may want to add -I -mta_sendmail to the flags, so net-snmp doesn't throw garbage into the mib-2.28 subtree.
-rw-r--r--usr.sbin/smtpd/control.c10
-rw-r--r--usr.sbin/smtpd/control_agentx.c235
-rw-r--r--usr.sbin/smtpd/parse.y91
-rw-r--r--usr.sbin/smtpd/smtpd.c32
-rw-r--r--usr.sbin/smtpd/smtpd.conf.531
-rw-r--r--usr.sbin/smtpd/smtpd.h25
-rw-r--r--usr.sbin/smtpd/smtpd/Makefile7
7 files changed, 417 insertions, 14 deletions
diff --git a/usr.sbin/smtpd/control.c b/usr.sbin/smtpd/control.c
index 6f9c9aca553..1a206e55b3b 100644
--- a/usr.sbin/smtpd/control.c
+++ b/usr.sbin/smtpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.123 2018/05/31 21:06:12 gilles Exp $ */
+/* $OpenBSD: control.c,v 1.124 2020/09/23 18:01:26 martijn Exp $ */
/*
* Copyright (c) 2012 Gilles Chehade <gilles@poolp.org>
@@ -73,7 +73,7 @@ extern const char *backend_stat;
static uint64_t connid = 0;
static struct tree ctl_conns;
static struct tree ctl_count;
-static struct stat_digest digest;
+struct stat_digest digest;
#define CONTROL_FD_RESERVE 5
#define CONTROL_MAXCONN_PER_CLIENT 32
@@ -157,6 +157,9 @@ control_imsg(struct mproc *p, struct imsg *imsg)
if (stat_backend)
stat_backend->set(key, &val);
return;
+ case IMSG_AGENTX_GETFD:
+ control_agentx_connect(imsg->fd);
+ return;
}
errx(1, "control_imsg: unexpected %s imsg",
@@ -253,6 +256,9 @@ control(void)
control_listen();
+ if (env->sc_agentx != NULL)
+ control_agentx();
+
if (pledge("stdio unix recvfd sendfd", NULL) == -1)
err(1, "pledge");
diff --git a/usr.sbin/smtpd/control_agentx.c b/usr.sbin/smtpd/control_agentx.c
new file mode 100644
index 00000000000..4db3dd74d63
--- /dev/null
+++ b/usr.sbin/smtpd/control_agentx.c
@@ -0,0 +1,235 @@
+/* $OpenBSD: control_agentx.c,v 1.1 2020/09/23 18:01:26 martijn Exp $ */
+
+/*
+ * Copyright (c) 2020 Martijn van Duren <martijn@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/socket.h>
+#include <sys/tree.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <event.h>
+#include <imsg.h>
+#include <limits.h>
+#include <stdio.h>
+#include <subagentx.h>
+
+#include "log.h"
+#include "smtpd.h"
+
+static void control_agentx_nofd(struct subagentx *, void *, int);
+static void control_agentx_tryconnect(int, short, void *);
+static void control_agentx_read(int, short, void *);
+static void control_agentx_appltable(struct subagentx_varbind *);
+static void control_agentx_mtatable(struct subagentx_varbind *);
+
+static struct subagentx *sa;
+static struct subagentx_session *sas;
+static struct subagentx_context *sac;
+static struct subagentx_region *application, *mta;
+static struct subagentx_index *applIndex;
+static struct subagentx_object *applName, *applDirectoryName;
+static struct subagentx_object *applVersion, *applUptime, *applOperStatus;
+static struct subagentx_object *applDescription, *applURL;
+static struct subagentx_object *mtaReceivedMessages, *mtaStoredMessages;
+static struct subagentx_object *mtaTransmittedMessages, *mtaLoopsDetected;
+static struct event connev, rev;
+
+extern struct stat_digest digest;
+
+#define APPLICATION SUBAGENTX_MIB2, 27
+#define APPLTABLE APPLICATION, 1
+#define APPLENTRY APPLTABLE, 1
+#define APPLINDEX APPLENTRY, 1
+#define APPLNAME APPLENTRY, 2
+#define APPLDIRECTORYNAME APPLENTRY, 3
+#define APPLVERSION APPLENTRY, 4
+#define APPLUPTIME APPLENTRY, 5
+#define APPLOPERSTATUS APPLENTRY, 6
+#define APPLLASTCHANGE APPLENTRY, 7
+#define APPLDESCRIPTION APPLENTRY, 16
+#define APPLURL APPLENTRY, 17
+#define MTA SUBAGENTX_MIB2, 28
+#define MTATABLE MTA, 1
+#define MTAENTRY MTATABLE, 1
+#define MTARECEIVEDMESSAGES MTAENTRY, 1
+#define MTASTOREDMESSAGES MTAENTRY, 2
+#define MTATRANSMITTEDMESSAGES MTAENTRY, 3
+#define MTALOOPSDETECTED MTAENTRY, 12
+
+#define APPLOPERSTATUS_UP 1
+#define APPLOPERSTATUS_DOWN 2
+#define APPLOPERSTATUS_HALTED 3
+#define APPLOPERSTATUS_CONGESTED 4
+#define APPLOPERSTATUS_RESTARTING 5
+#define APPLOPERSTATUS_QUIESCING 6
+
+void
+control_agentx(void)
+{
+ subagentx_log_fatal = fatalx;
+ subagentx_log_warn = log_warnx;
+ subagentx_log_info = log_info;
+ subagentx_log_debug = log_debug;
+
+ if ((sa = subagentx(control_agentx_nofd, NULL)) == NULL)
+ fatal("subagentx");
+ if ((sas = subagentx_session(sa, NULL, 0, "OpenSMTPd", 0)) == NULL)
+ fatal("subagentx_session");
+ if ((sac = subagentx_context(sas, env->sc_agentx->context)) == NULL)
+ fatal("subagentx_context");
+
+ if ((application = subagentx_region(sac,
+ SUBAGENTX_OID(APPLICATION), 0)) == NULL ||
+ (mta = subagentx_region(sac, SUBAGENTX_OID(MTA), 0)) == NULL)
+ fatal("subagentx_region");
+ switch (env->sc_agentx->applIndexType) {
+ case AGENTX_INDEX_TYPE_ANY:
+ if ((applIndex = subagentx_index_integer_any(application,
+ SUBAGENTX_OID(APPLINDEX))) == NULL)
+ fatal("subagentx_index_integer_any");
+ break;
+ case AGENTX_INDEX_TYPE_NEW:
+ if ((applIndex = subagentx_index_integer_new(application,
+ SUBAGENTX_OID(APPLINDEX))) == NULL)
+ fatal("subagentx_index_integer_new");
+ break;
+ case AGENTX_INDEX_TYPE_VALUE:
+ if ((applIndex = subagentx_index_integer_value(application,
+ SUBAGENTX_OID(APPLINDEX),
+ env->sc_agentx->applIndex)) == NULL)
+ fatal("subagentx_index_integer_value");
+ break;
+ case AGENTX_INDEX_TYPE_UNDEFINED:
+ fatalx("%s: How did I get here?", __func__);
+ }
+
+ if ((applName = subagentx_object(application, SUBAGENTX_OID(APPLNAME),
+ &applIndex, 1, 0, control_agentx_appltable)) == NULL ||
+ (applDirectoryName = subagentx_object(application,
+ SUBAGENTX_OID(APPLDIRECTORYNAME), &applIndex, 1,
+ 0, control_agentx_appltable)) == NULL ||
+ (applVersion = subagentx_object(application,
+ SUBAGENTX_OID(APPLVERSION), &applIndex, 1,
+ 0, control_agentx_appltable)) == NULL ||
+ (applUptime = subagentx_object(application,
+ SUBAGENTX_OID(APPLUPTIME), &applIndex, 1,
+ 0, control_agentx_appltable)) == NULL ||
+ (applOperStatus = subagentx_object(application,
+ SUBAGENTX_OID(APPLOPERSTATUS), &applIndex, 1,
+ 0, control_agentx_appltable)) == NULL ||
+ (applDescription = subagentx_object(application,
+ SUBAGENTX_OID(APPLDESCRIPTION), &applIndex, 1,
+ 0, control_agentx_appltable)) == NULL ||
+ (applURL = subagentx_object(application, SUBAGENTX_OID(APPLURL),
+ &applIndex, 1, 0, control_agentx_appltable)) == NULL ||
+ (mtaReceivedMessages = subagentx_object(mta,
+ SUBAGENTX_OID(MTARECEIVEDMESSAGES), &applIndex, 1,
+ 0, control_agentx_mtatable)) == NULL ||
+ (mtaStoredMessages = subagentx_object(mta,
+ SUBAGENTX_OID(MTASTOREDMESSAGES), &applIndex, 1,
+ 0, control_agentx_mtatable)) == NULL ||
+ (mtaTransmittedMessages = subagentx_object(mta,
+ SUBAGENTX_OID(MTATRANSMITTEDMESSAGES), &applIndex, 1,
+ 0, control_agentx_mtatable)) == NULL ||
+ (mtaLoopsDetected = subagentx_object(mta,
+ SUBAGENTX_OID(MTALOOPSDETECTED), &applIndex, 1,
+ 0, control_agentx_mtatable)) == NULL)
+ fatal("subagentx_object");
+
+}
+
+static void
+control_agentx_nofd(struct subagentx *unused, void *cookie, int close)
+{
+ event_del(&rev);
+ control_agentx_tryconnect(-1, 0, NULL);
+}
+
+static void
+control_agentx_tryconnect(int fd, short event, void *cookie)
+{
+ m_create(p_parent, IMSG_AGENTX_GETFD, 0, 0, -1);
+ m_close(p_parent);
+}
+
+static void
+control_agentx_read(int fd, short event, void *cookie)
+{
+ subagentx_read(sa);
+}
+
+void
+control_agentx_connect(int fd)
+{
+ struct timeval timeout = {3, 0};
+
+ if (fd == -1) {
+ evtimer_set(&connev, control_agentx_tryconnect, NULL);
+ evtimer_add(&connev, &timeout);
+ return;
+ }
+
+ subagentx_connect(sa, fd);
+
+ event_set(&rev, fd, EV_READ|EV_PERSIST, control_agentx_read, NULL);
+ event_add(&rev, NULL);
+}
+
+static void
+control_agentx_appltable(struct subagentx_varbind *vb)
+{
+ if (subagentx_varbind_get_object(vb) == applName)
+ subagentx_varbind_string(vb, "OpenSMTPd");
+ else if (subagentx_varbind_get_object(vb) == applDirectoryName)
+ subagentx_varbind_string(vb, "");
+ else if (subagentx_varbind_get_object(vb) == applVersion)
+ subagentx_varbind_string(vb, SMTPD_VERSION);
+ else if (subagentx_varbind_get_object(vb) == applUptime)
+ subagentx_varbind_timeticks(vb,
+ (uint32_t) ((time(NULL) - digest.startup) * 100));
+ else if (subagentx_varbind_get_object(vb) == applOperStatus)
+ subagentx_varbind_integer(vb,
+ env->sc_flags & SMTPD_SMTP_PAUSED ?
+ APPLOPERSTATUS_DOWN : APPLOPERSTATUS_UP);
+ else if (subagentx_varbind_get_object(vb) == applDescription)
+ subagentx_varbind_string(vb, "OpenSMTPD is a FREE "
+ "implementation of the server-side SMTP protocol as "
+ "defined by RFC 5321, with some additional standard "
+ "extensions. It allows ordinary machines to exchange "
+ "emails with other systems speaking the SMTP protocol.");
+ else if (subagentx_varbind_get_object(vb) == applURL)
+ subagentx_varbind_string(vb, "");
+ else
+ fatalx("%s: unexpected callback", __func__);
+}
+
+static void
+control_agentx_mtatable(struct subagentx_varbind *vb)
+{
+ if (subagentx_varbind_get_object(vb) == mtaReceivedMessages)
+ subagentx_varbind_counter32(vb, (uint32_t) digest.evp_enqueued);
+ else if (subagentx_varbind_get_object(vb) == mtaStoredMessages)
+ subagentx_varbind_counter32(vb,
+ (uint32_t) (digest.evp_enqueued - digest.evp_dequeued));
+ else if (subagentx_varbind_get_object(vb) == mtaTransmittedMessages)
+ subagentx_varbind_counter32(vb, digest.evp_dequeued);
+ else if (subagentx_varbind_get_object(vb) == mtaLoopsDetected)
+ subagentx_varbind_counter32(vb, digest.dlv_loop);
+ else
+ fatalx("%s: unexpected callback", __func__);
+}
diff --git a/usr.sbin/smtpd/parse.y b/usr.sbin/smtpd/parse.y
index 6a1f92f733b..85d58f1a449 100644
--- a/usr.sbin/smtpd/parse.y
+++ b/usr.sbin/smtpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.279 2020/09/16 11:19:42 martijn Exp $ */
+/* $OpenBSD: parse.y,v 1.280 2020/09/23 18:01:26 martijn Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -28,6 +28,7 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
+#include <sys/un.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -47,6 +48,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <subagentx.h>
#include <syslog.h>
#include <unistd.h>
#include <util.h>
@@ -173,9 +175,9 @@ typedef struct {
%}
-%token ACTION ADMD ALIAS ANY ARROW AUTH AUTH_OPTIONAL
+%token ACTION ADMD AGENTX ALIAS ANY APPLINDEX ARROW AUTH AUTH_OPTIONAL
%token BACKUP BOUNCE BYPASS
-%token CA CERT CHAIN CHROOT CIPHERS COMMIT COMPRESSION CONNECT
+%token CA CERT CHAIN CHROOT CIPHERS COMMIT COMPRESSION CONNECT CONTEXT
%token DATA DATA_LINE DHE DISCONNECT DOMAIN
%token EHLO ENABLE ENCRYPTION ERROR EXPAND_ONLY
%token FCRDNS FILTER FOR FORWARD_ONLY FROM
@@ -188,7 +190,7 @@ typedef struct {
%token MAIL_FROM MAILDIR MASK_SRC MASQUERADE MATCH MAX_MESSAGE_SIZE MAX_DEFERRED MBOX MDA MTA MX
%token NO_DSN NO_VERIFY NOOP
%token ON
-%token PHASE PKI PORT PROC PROC_EXEC PROXY_V2
+%token PATH PHASE PKI PORT PROC PROC_EXEC PROXY_V2
%token QUEUE QUIT
%token RCPT_TO RDNS RECIPIENT RECEIVEDAUTH REGEX RELAY REJECT REPORT REWRITE RSET
%token SCHEDULER SENDER SENDERS SMTP SMTP_IN SMTP_OUT SMTPS SOCKET SRC SRS SUB_ADDR_DELIM
@@ -224,6 +226,7 @@ grammar : /* empty */
| grammar dispatcher '\n'
| grammar match '\n'
| grammar filter '\n'
+ | grammar agentx '\n'
| grammar error '\n' { file->errors++; }
;
@@ -1960,6 +1963,82 @@ FILTER STRING CHAIN {
}
;
+agentxopt :
+CONTEXT STRING {
+ if (conf->sc_agentx->context != NULL) {
+ yyerror("redefinition of agentx context");
+ free($2);
+ YYERROR;
+ }
+ conf->sc_agentx->context = $2;
+}
+| PATH STRING {
+ if (strlen($2) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
+ yyerror("agentx path too large");
+ free($2);
+ YYERROR;
+ }
+ if ($2[0] != '/') {
+ yyerror("agentx path must be absolute");
+ free($2);
+ YYERROR;
+ }
+ if (conf->sc_agentx->path != NULL) {
+ yyerror("redefinition of agentx path");
+ free($2);
+ YYERROR;
+ }
+ conf->sc_agentx->path = $2;
+}
+| APPLINDEX STRING {
+ if (conf->sc_agentx->applIndexType != AGENTX_INDEX_TYPE_UNDEFINED) {
+ yyerror("redefinition of agentx applIndex");
+ YYERROR;
+ }
+
+ if (strcasecmp($2, "any") == 0)
+ conf->sc_agentx->applIndexType = AGENTX_INDEX_TYPE_ANY;
+ else if (strcasecmp($2, "new") == 0)
+ conf->sc_agentx->applIndexType = AGENTX_INDEX_TYPE_NEW;
+ else {
+ yyerror("invalid applIndex");
+ YYERROR;
+ }
+}
+| APPLINDEX NUMBER {
+ if (conf->sc_agentx->applIndexType != AGENTX_INDEX_TYPE_UNDEFINED) {
+ yyerror("redefinition of agentx applIndex");
+ YYERROR;
+ }
+ if ($2 > UINT32_MAX) {
+ yyerror("agentx applIndex too large");
+ YYERROR;
+ }
+ if ($2 < 1) {
+ yyerror("agentx applIndex too small");
+ YYERROR;
+ }
+
+ conf->sc_agentx->applIndexType = AGENTX_INDEX_TYPE_VALUE;
+ conf->sc_agentx->applIndex = (uint32_t) $2;
+}
+;
+
+agentxopts : /* empty */
+ | agentxopts agentxopt
+ ;
+
+agentx:
+AGENTX {
+ conf->sc_agentx = xcalloc(1, sizeof(*conf->sc_agentx));
+} agentxopts {
+ if (conf->sc_agentx->path == NULL)
+ conf->sc_agentx->path = SUBAGENTX_AGENTX_MASTER;
+ if (conf->sc_agentx->applIndexType == AGENTX_INDEX_TYPE_UNDEFINED)
+ conf->sc_agentx->applIndexType = AGENTX_INDEX_TYPE_ANY;
+}
+;
+
size : NUMBER {
if ($1 < 0) {
yyerror("invalid size: %" PRId64, $1);
@@ -2620,8 +2699,10 @@ lookup(char *s)
static const struct keywords keywords[] = {
{ "action", ACTION },
{ "admd", ADMD },
+ { "agentx", AGENTX },
{ "alias", ALIAS },
{ "any", ANY },
+ { "applIndex", APPLINDEX },
{ "auth", AUTH },
{ "auth-optional", AUTH_OPTIONAL },
{ "backup", BACKUP },
@@ -2635,6 +2716,7 @@ lookup(char *s)
{ "commit", COMMIT },
{ "compression", COMPRESSION },
{ "connect", CONNECT },
+ { "context", CONTEXT },
{ "data", DATA },
{ "data-line", DATA_LINE },
{ "dhe", DHE },
@@ -2678,6 +2760,7 @@ lookup(char *s)
{ "no-verify", NO_VERIFY },
{ "noop", NOOP },
{ "on", ON },
+ { "path", PATH },
{ "phase", PHASE },
{ "pki", PKI },
{ "port", PORT },
diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
index d0c67bab2af..6359c16ab3a 100644
--- a/usr.sbin/smtpd/smtpd.c
+++ b/usr.sbin/smtpd/smtpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.c,v 1.333 2020/05/06 16:03:30 millert Exp $ */
+/* $OpenBSD: smtpd.c,v 1.334 2020/09/23 18:01:27 martijn Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -25,6 +25,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/uio.h>
+#include <sys/un.h>
#include <sys/mman.h>
#include <bsd_auth.h>
@@ -57,6 +58,7 @@
#include "smtpd.h"
#include "log.h"
#include "ssl.h"
+#include "subagentx.h"
#define SMTPD_MAXARG 32
@@ -69,6 +71,7 @@ static void parent_send_config_lka(void);
static void parent_send_config_pony(void);
static void parent_send_config_ca(void);
static void parent_sig_handler(int, short, void *);
+static int parent_open_agentx(void);
static void forkmda(struct mproc *, uint64_t, struct deliver *);
static int parent_forward_open(char *, char *, uid_t, gid_t);
static struct child *child_add(pid_t, int, const char *);
@@ -267,6 +270,12 @@ parent_imsg(struct mproc *p, struct imsg *imsg)
m_add_string(p_lka, procname);
m_close(p_lka);
return;
+ case IMSG_AGENTX_GETFD:
+ fd = parent_open_agentx();
+
+ m_create(p_control, IMSG_AGENTX_GETFD, 0, 0, fd);
+ m_close(p_control);
+ return;
}
errx(1, "parent_imsg: unexpected %s imsg from %s",
@@ -473,6 +482,25 @@ parent_sig_handler(int sig, short event, void *p)
}
}
+static int
+parent_open_agentx(void)
+{
+ int fd;
+ struct sockaddr_un sun;
+
+ sun.sun_len = sizeof(sun);
+ sun.sun_family = AF_UNIX;
+ strlcpy(sun.sun_path, env->sc_agentx->path, sizeof(sun.sun_path));
+
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ||
+ connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
+ log_warn("agentx connect");
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
int
main(int argc, char *argv[])
{
@@ -2125,6 +2153,8 @@ imsg_to_str(int type)
CASE(IMSG_CA_RSA_PRIVENC);
CASE(IMSG_CA_RSA_PRIVDEC);
CASE(IMSG_CA_ECDSA_SIGN);
+
+ CASE(IMSG_AGENTX_GETFD);
default:
(void)snprintf(buf, sizeof(buf), "IMSG_??? (%d)", type);
diff --git a/usr.sbin/smtpd/smtpd.conf.5 b/usr.sbin/smtpd/smtpd.conf.5
index d117b3c4bb3..02d6ece4f70 100644
--- a/usr.sbin/smtpd/smtpd.conf.5
+++ b/usr.sbin/smtpd/smtpd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: smtpd.conf.5,v 1.253 2020/09/16 11:19:42 martijn Exp $
+.\" $OpenBSD: smtpd.conf.5,v 1.254 2020/09/23 18:01:27 martijn Exp $
.\"
.\" Copyright (c) 2008 Janne Johansson <jj@openbsd.org>
.\" Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
@@ -17,7 +17,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\"
-.Dd $Mdocdate: September 16 2020 $
+.Dd $Mdocdate: September 23 2020 $
.Dt SMTPD.CONF 5
.Os
.Sh NAME
@@ -326,6 +326,33 @@ The Administrative Management Domain this mailserver belongs to.
The authservid will be forwarded to filters using it to identify or mark
authentication-results headers.
If omitted it defaults to the server name.
+.It Ic agentx Oo Cm applIndex Ar index Oc Oo Cm context Ar context Oc Op Cm path Ar path
+Export NETWORK-SERVICES-MIB and MTA-MIB metrics via an agentx compatible
+.Pq snmp
+daemon by connecting to
+.Ar path .
+Metrics can be found under the application subtree
+.Pq mib-2.27
+and mta subtree
+.Pq mib-2.28 .
+The index in the applTable and mtaTable can be controlled via
+.Cm applIndex .
+For the first available index it can be set to
+.Cm any ,
+for a new unused entry it can be set to
+.Cm new ,
+and if a fixed position is desired it can be set to a number between 1 and
+4294967295.
+If an index collision occurs because of a fixed position the metrics will not be
+exported.
+The default is
+.Cm any .
+If
+.Ar path
+is omitted it will default to
+.Pa /var/agentx/master .
+.Ar Context
+is the SNMPv3 context and can usually be omitted.
.It Ic bounce Cm warn-interval Ar delay Op , Ar delay ...
Send warning messages to the envelope sender when temporary delivery
failures cause a message to remain on the queue for longer than
diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h
index c238cf1882f..1949e527b51 100644
--- a/usr.sbin/smtpd/smtpd.h
+++ b/usr.sbin/smtpd/smtpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtpd.h,v 1.657 2020/09/16 11:19:42 martijn Exp $ */
+/* $OpenBSD: smtpd.h,v 1.658 2020/09/23 18:01:27 martijn Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
@@ -163,7 +163,7 @@ union lookup {
* Bump IMSG_VERSION whenever a change is made to enum imsg_type.
* This will ensure that we can never use a wrong version of smtpctl with smtpd.
*/
-#define IMSG_VERSION 16
+#define IMSG_VERSION 17
enum imsg_type {
IMSG_NONE,
@@ -337,6 +337,8 @@ enum imsg_type {
IMSG_CA_RSA_PRIVENC,
IMSG_CA_RSA_PRIVDEC,
IMSG_CA_ECDSA_SIGN,
+
+ IMSG_AGENTX_GETFD,
};
enum smtp_proc_type {
@@ -626,6 +628,8 @@ struct smtpd {
int sc_srs_ttl;
char *sc_admd;
+
+ struct smtp_agentx *sc_agentx;
};
#define TRACE_DEBUG 0x0001
@@ -862,6 +866,20 @@ struct mta_envelope {
char status[LINE_MAX];
};
+enum agentx_index_type {
+ AGENTX_INDEX_TYPE_UNDEFINED,
+ AGENTX_INDEX_TYPE_ANY,
+ AGENTX_INDEX_TYPE_NEW,
+ AGENTX_INDEX_TYPE_VALUE,
+};
+
+struct smtp_agentx {
+ const char *path;
+ const char *context;
+ enum agentx_index_type applIndexType;
+ uint32_t applIndex;
+};
+
struct mta_task {
TAILQ_ENTRY(mta_task) entry;
struct mta_relay *relay;
@@ -1307,6 +1325,9 @@ void config_peer(enum smtp_proc_type);
int control(void);
int control_create_socket(void);
+/* control_agentx.c */
+void control_agentx(void);
+void control_agentx_connect(int);
/* crypto.c */
int crypto_setup(const char *, size_t);
diff --git a/usr.sbin/smtpd/smtpd/Makefile b/usr.sbin/smtpd/smtpd/Makefile
index 8a9474e30be..e0bd176ab1c 100644
--- a/usr.sbin/smtpd/smtpd/Makefile
+++ b/usr.sbin/smtpd/smtpd/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.107 2020/01/31 22:01:20 gilles Exp $
+# $OpenBSD: Makefile,v 1.108 2020/09/23 18:01:27 martijn Exp $
.PATH: ${.CURDIR}/..
@@ -11,6 +11,7 @@ SRCS+= cert.c
SRCS+= compress_backend.c
SRCS+= config.c
SRCS+= control.c
+SRCS+= control_agentx.c
SRCS+= crypto.c
SRCS+= dict.c
SRCS+= dns.c
@@ -82,8 +83,8 @@ SRCS+= stat_ramstat.c
MAN= sendmail.8 smtpd.8 smtpd.conf.5 table.5
BINDIR= /usr/sbin
-LDADD+= -levent -lutil -lssl -lcrypto -lm -lz
-DPADD+= ${LIBEVENT} ${LIBUTIL} ${LIBSSL} ${LIBCRYPTO} ${LIBM} ${LIBZ}
+LDADD+= -levent -lutil -lssl -lcrypto -lm -lz -lagentx
+DPADD+= ${LIBEVENT} ${LIBUTIL} ${LIBSSL} ${LIBCRYPTO} ${LIBM} ${LIBZ} ${LIBAGENTX}
CFLAGS+= -fstack-protector-all
CFLAGS+= -I${.CURDIR}/..