snmpd - improve trap handle documentation

2021-03-03 Thread Martijn van Duren
When moving the traphandler code to snpme I overlooked some text in the
"trap handle" section. This diff tries to rectify that. While here, try
to be a little more clear in the "listen on" segment as well.

OK?

martijn@

Index: snmpd.conf.5
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.conf.5,v
retrieving revision 1.46
diff -u -p -r1.46 snmpd.conf.5
--- snmpd.conf.522 Jan 2021 06:33:26 -  1.46
+++ snmpd.conf.53 Mar 2021 16:02:16 -
@@ -116,9 +116,12 @@ The default protocol is
 .Ic udp.
 The default
 .Ar port
-is 161, unless the only listen flags contains
+is 161, unless
 .Ic notify
-which sets it to 162.
+is the only listen flags
+which sets the
+.Ar port
+to 162.
 If no flags are specified it defaults to
 .Dq Ic read Ic write ,
 or
@@ -126,6 +129,11 @@ or
 when
 .Ar port
 is 162.
+Having
+.Ic notify
+set requires at least one
+.Ic trap handle
+statement.
 .It Ic read-only community Ar string
 Specify the name of the read-only community.
 The default value is
@@ -217,9 +225,12 @@ the resolved hostname of the host sendin
 the IP address of the host sending the trap,
 and any variable bindings contained in the trap
 (the OID followed by the value, separated by a single space).
-Traps will be accepted on all
+This option requires at least one
 .Ic listen on
-UDP addresses.
+statement with a
+.Ic notify
+flag set.
+Traps over SNMPv3 are currently unsupported.
 .It Xo
 .Ic trap receiver Ar string
 .Op Ic oid Ar oid-string




snmp(1) Fix some ranges and types

2021-03-02 Thread Martijn van Duren
Live and learn. While working on a regress test I found that I
misunderstood some types when I wrote this code. According to RFC2578:
- timeticks is a 32 bit unsigned int
- counter32 is a 32 bit unsigned int
- unsigned is "indistinguishable from Gauge32"
- integer is a 32 bit integer

OK?

martijn@

Index: snmp.1
===
RCS file: /cvs/src/usr.bin/snmp/snmp.1,v
retrieving revision 1.15
diff -u -p -r1.15 snmp.1
--- snmp.1  14 Sep 2020 15:12:27 -  1.15
+++ snmp.1  2 Mar 2021 21:48:35 -
@@ -524,7 +524,6 @@ A regular string.
 Timeticks in centiseconds.
 .It Cm u
 Unsigned integer.
-Actually a normal integer for compatibility with netsnmp.
 .It Cm x
 A hex string.
 Similar to a decimal string, but in hexadecimal format.
Index: snmpc.c
===
RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
retrieving revision 1.31
diff -u -p -r1.31 snmpc.c
--- snmpc.c 2 Dec 2020 15:45:51 -   1.31
+++ snmpc.c 2 Mar 2021 21:48:35 -
@@ -801,7 +801,7 @@ snmpc_trap(int argc, char *argv[])
if (clock_gettime(CLOCK_UPTIME, ) == -1)
err(1, "clock_gettime");
} else {
-   lval = strtonum(argv[1], 0, LLONG_MAX, );
+   lval = strtonum(argv[1], 0, UINT32_MAX, );
if (errstr != NULL)
errx(1, "Bad value notation (%s)", argv[1]);
ts.tv_sec = lval / 100;
@@ -1439,7 +1439,7 @@ snmpc_varbindparse(int argc, char *argv[
 */
goto pastestring;
case 'c':
-   lval = strtonum(argv[i + 2], INT32_MIN, INT32_MAX,
+   lval = strtonum(argv[i + 2], 0, UINT32_MAX,
);
if (errstr != NULL)
errx(1, "%s: Bad value notation (%s)", argv[i],
@@ -1472,9 +1472,8 @@ snmpc_varbindparse(int argc, char *argv[
tmpstr = endstr + 1;
} while (endstr[0] != '\0');
goto pastestring;
-   case 'u':
case 'i':
-   lval = strtonum(argv[i + 2], LLONG_MIN, LLONG_MAX,
+   lval = strtonum(argv[i + 2], INT32_MIN, INT32_MAX,
);
if (errstr != NULL)
errx(1, "%s: Bad value notation (%s)", argv[i],
@@ -1508,7 +1507,7 @@ pastestring:
free(str);
break;
case 't':
-   lval = strtonum(argv[i + 2], LLONG_MIN, LLONG_MAX,
+   lval = strtonum(argv[i + 2], 0, UINT32_MAX,
);
if (errstr != NULL)
errx(1, "%s: Bad value notation (%s)", argv[i],
@@ -1516,6 +1515,17 @@ pastestring:
if ((varbind = ober_printf_elements(varbind, "{Oit}",
, lval, BER_CLASS_APPLICATION,
SNMP_T_TIMETICKS)) == NULL)
+   err(1, "ober_printf_elements");
+   break;
+   case 'u':
+   lval = strtonum(argv[i + 2], 0, UINT32_MAX,
+   );
+   if (errstr != NULL)
+   errx(1, "%s: Bad value notation (%s)", argv[i],
+   argv[i + 2]);
+   if ((varbind = ober_printf_elements(varbind, "{Oit}",
+   , lval, BER_CLASS_APPLICATION,
+   SNMP_T_GAUGE32)) == NULL)
err(1, "ober_printf_elements");
break;
case 'x':




Re: systat(1) sticky help

2021-02-28 Thread Martijn van Duren
On Sun, 2021-02-28 at 23:03 -0800, Anindya Mukherjee wrote:
> Hi,
> 
> Thanks for the feedback. I see your point. Perhaps it would be better to
> have a separate "stickiness" toggle and not tie it to the help or the
> view name display functions. For example, pressing 't' could toggle it
> on and then pressing 'h' or Ctrl-G would make the display stick.
> Pressing 't' again would toggle it off, and then the display would get
> cleared normally.

Something like that seems better, but keep in mind that the single key
bindings within systat is a mess: 't' might already be allocated by one
of the views. When submitting your followup, try to make sure that you
considered all possible issues, including the keybindings, and show
how you came to your conclusion.
> 
> Regards,
> Anindya
> 
> On Mon, Mar 01, 2021 at 07:49:49AM +0100, Martijn van Duren wrote:
> > Although the feature *might* be useful (just woken up, so haven't given
> > it too much thought), the bindings have some problems and need to be
> > reworked if we decide to get this in. Problems that I see from just a
> > few short tests (so there might be others):
> > - Entering sticky: H, which also enters help, which is annoying if I
> >   want sticky ^G.
> > - Clearing sticky: h, which also displays help, which if I come from
> >   ^G is not what I want and if I'm in help is confusing, because I want
> >   to get rid of it.
> > 
> > martijn@
> > 
> > On Sun, 2021-02-28 at 19:40 -0800, Anindya Mukherjee wrote:
> > > Hi,
> > > 
> > > I tend to keep systat(1) running in interactive mode, and find it very
> > > useful to have the help line displayed permanently, i.e., not disappear
> > > if a key is pressed or after a command is executed. The same goes for
> > > the Ctrl-G display. For example, it tells me what modes are adjacent to
> > > the currently active one when pressing left or right arrow keys.
> > > 
> > > The attached diff adds this feature. It is off by default. I noticed
> > > that the 'h' key was not documented in the man page, so I took the
> > > liberty of adding a line describing it.
> > > 
> > > Hope it is useful. Please have a look, thanks!
> > > 
> > > Regards,
> > > Anindya
> > > 
> > > Index: engine.c
> > > ===
> > > RCS file: /cvs/src/usr.bin/systat/engine.c,v
> > > retrieving revision 1.27
> > > diff -u -p -r1.27 engine.c
> > > --- engine.c6 Feb 2021 06:19:28 -   1.27
> > > +++ engine.c1 Mar 2021 03:20:41 -
> > > @@ -70,6 +70,8 @@ volatile sig_atomic_t gotsig_alarm = 0;
> > >  int need_update = 0;
> > >  int need_sort = 0;
> > >  int separate_thousands = 0;
> > > +int viewmode = 0;
> > > +int sticky = 0;
> > >  
> > >  SCREEN *screen;
> > >  
> > > @@ -1139,7 +1141,9 @@ command_set(struct command *cmd, const c
> > > cmdbuf[0] = 0;
> > > }
> > > }
> > > -   message_set(NULL);
> > > +
> > > +   if (!sticky)
> > > +   message_set(NULL);
> > > curr_cmd = cmd;
> > > need_update = 1;
> > > return prev;
> > > @@ -1234,7 +1238,7 @@ keyboard(void)
> > > return;
> > >  
> > > if (curr_message != NULL) {
> > > -   if (ch > 0) {
> > > +   if (ch > 0 && !sticky) {
> > > message_set(NULL);
> > > need_update = 1;
> > > }
> > > @@ -1359,8 +1363,15 @@ engine_loop(int countmax)
> > > if (need_update) {
> > > erase();
> > > if (!averageonly ||
> > > -   (averageonly && count == countmax - 1))
> > > +   (averageonly && count == countmax - 1)) {
> > > disp_update();
> > > +   if (interactive && sticky) {
> > > +   if (viewmode)
> > > +   show_view();
> > > +   else
> > > +   show_help();
> > > +   }
> > > +   }
> > &g

Re: systat(1) sticky help

2021-02-28 Thread Martijn van Duren
Although the feature *might* be useful (just woken up, so haven't given
it too much thought), the bindings have some problems and need to be
reworked if we decide to get this in. Problems that I see from just a
few short tests (so there might be others):
- Entering sticky: H, which also enters help, which is annoying if I
  want sticky ^G.
- Clearing sticky: h, which also displays help, which if I come from
  ^G is not what I want and if I'm in help is confusing, because I want
  to get rid of it.

martijn@

On Sun, 2021-02-28 at 19:40 -0800, Anindya Mukherjee wrote:
> Hi,
> 
> I tend to keep systat(1) running in interactive mode, and find it very
> useful to have the help line displayed permanently, i.e., not disappear
> if a key is pressed or after a command is executed. The same goes for
> the Ctrl-G display. For example, it tells me what modes are adjacent to
> the currently active one when pressing left or right arrow keys.
> 
> The attached diff adds this feature. It is off by default. I noticed
> that the 'h' key was not documented in the man page, so I took the
> liberty of adding a line describing it.
> 
> Hope it is useful. Please have a look, thanks!
> 
> Regards,
> Anindya
> 
> Index: engine.c
> ===
> RCS file: /cvs/src/usr.bin/systat/engine.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 engine.c
> --- engine.c6 Feb 2021 06:19:28 -   1.27
> +++ engine.c1 Mar 2021 03:20:41 -
> @@ -70,6 +70,8 @@ volatile sig_atomic_t gotsig_alarm = 0;
>  int need_update = 0;
>  int need_sort = 0;
>  int separate_thousands = 0;
> +int viewmode = 0;
> +int sticky = 0;
>  
>  SCREEN *screen;
>  
> @@ -1139,7 +1141,9 @@ command_set(struct command *cmd, const c
> cmdbuf[0] = 0;
> }
> }
> -   message_set(NULL);
> +
> +   if (!sticky)
> +   message_set(NULL);
> curr_cmd = cmd;
> need_update = 1;
> return prev;
> @@ -1234,7 +1238,7 @@ keyboard(void)
> return;
>  
> if (curr_message != NULL) {
> -   if (ch > 0) {
> +   if (ch > 0 && !sticky) {
> message_set(NULL);
> need_update = 1;
> }
> @@ -1359,8 +1363,15 @@ engine_loop(int countmax)
> if (need_update) {
> erase();
> if (!averageonly ||
> -   (averageonly && count == countmax - 1))
> +   (averageonly && count == countmax - 1)) {
> disp_update();
> +   if (interactive && sticky) {
> +   if (viewmode)
> +   show_view();
> +   else
> +   show_help();
> +   }
> +   }
> end_page();
> need_update = 0;
> if (countmax && ++count >= countmax)
> Index: engine.h
> ===
> RCS file: /cvs/src/usr.bin/systat/engine.h,v
> retrieving revision 1.12
> diff -u -p -r1.12 engine.h
> --- engine.h12 Jan 2020 20:51:08 -  1.12
> +++ engine.h1 Mar 2021 03:20:41 -
> @@ -144,6 +144,8 @@ struct command *command_set(struct comma
>  const char *message_set(const char *msg);
>  
>  void foreach_view(void (*callback)(field_view *));
> +void show_help(void);
> +void show_view(void);
>  
>  extern int sortdir;
>  extern useconds_t udelay;
> @@ -160,6 +162,8 @@ extern int columns, lines;
>  extern int need_update;
>  extern int need_sort;
>  extern int separate_thousands;
> +extern int viewmode;
> +extern int sticky;
>  
>  extern volatile sig_atomic_t gotsig_close;
>  extern volatile sig_atomic_t gotsig_resize;
> Index: main.c
> ===
> RCS file: /cvs/src/usr.bin/systat/main.c,v
> retrieving revision 1.73
> diff -u -p -r1.73 main.c
> --- main.c  30 Jan 2021 08:44:42 -  1.73
> +++ main.c  1 Mar 2021 03:20:41 -
> @@ -285,6 +285,14 @@ cmd_compat(const char *buf)
>  
> if (strcasecmp(buf, "help") == 0) {
> show_help();
> +   sticky = 0;
> +   need_update = 1;
> +   return;
> +   }
> +   if (strcasecmp(buf, "stickyhelp") == 0) {
> +   show_help();
> +   sticky = 1;
> +   viewmode = 0;
> need_update = 1;
> return;
> }
> @@ -359,10 +367,18 @@ keyboard_callback(int ch)
> /* FALLTHROUGH */
> case 'h':
> show_help();
> +   sticky = 0;
> +   need_update = 1;
> +   break;
> +   case 'H':

ober_get_string.3: s/byte/character

2021-02-22 Thread Martijn van Duren
As pointed out by claudio@, it makes more sense to talk about characters
for fmt instead of bytes.

The .Bl line already was >80 columns, but I don't know how to remedy
this situation, so this diff makes that a little worse.

martijn@

Index: ober_get_string.3
===
RCS file: /cvs/src/lib/libutil/ober_get_string.3,v
retrieving revision 1.4
diff -u -p -r1.4 ober_get_string.3
--- ober_get_string.3   22 Feb 2021 17:15:02 -  1.4
+++ ober_get_string.3   22 Feb 2021 22:08:32 -
@@ -87,15 +87,15 @@ to return a valid
 .Fn ober_scanf_elements
 retrieves the values from zero or more elements starting at
 .Fa root .
-For each byte in
+For each character in
 .Fa fmt ,
 arguments of the types given in the following table are consumed
 and passed to the function listed, processing one
 .Vt ber_element
-per byte.
-The following bytes are valid:
-.Bl -column -offset indent bytes ober_get_enumerated() "1: struct ber_element 
**"
-.It Sy byte Ta Sy function Ta Sy arguments
+per character.
+The following characters are valid:
+.Bl -column -offset indent characters ober_get_enumerated() "1: struct 
ber_element **"
+.It Sy character Ta Sy function Ta Sy arguments
 .It $ Ta see below  Ta 0
 .It B Ta Fn ober_get_bitstring  Ta 2: Vt void ** , size_t *
 .It b Ta Fn ober_get_booleanTa 1: Vt int *




Re: snmpd: Add end of sequence tests

2021-02-12 Thread Martijn van Duren
On Fri, 2021-02-12 at 11:02 +0100, Claudio Jeker wrote:
> On Fri, Feb 12, 2021 at 10:03:21AM +0100, Martijn van Duren wrote:
> > ping
> > 
> > On Sun, 2021-01-31 at 11:57 +0100, Martijn van Duren wrote:
> > > Now that ober_scanf_elements supports '$' lets use it.
> > > 
> > > Here's a first stab by adding it to snmpd.
> > > Passing regress and a few manual checks.
> > > 
> > > 'e' still doesn't consume the element, but I've talked it over with
> > > rob@, who said that shouldn't get in the way of using this new feature.
> > > 
> > > OK?
> 
> Looks reasonable and I guess you verified the layout of all those ASN.1
> messages to ensure the $ is at the right place.

To the best of my knowledge in both reading and testing.
If I somehow did screw it up, it should be easy enough to fix and loud
enough to notice.
> 
> Side note: I wonder why does } not imply the $? At least now with S it
> would be possible to enforce this.

} does nothing more then dropping down from the current sequence level.
This comes in handy if for instance when parsing a PDU. The varbindlist
is of undefined length, so I wouldn't know how many Ss I'd need. See line
snmpe.c:380.
The parsing and verifying of the varbindlist happens on snmpe.c:439.

> I like that you closed a lot of open { format strings. What about these:
> 
> > > -   if (ober_scanf_elements(usm, "{xiixpxx", , ,
> > > +   if (ober_scanf_elements(usm, "{xiixpxx$", , ,
> 
> Wouldn't it be better to use "{xiixpxx$}" here?
> 
I treat } as dropping down from the current sequence level. In that case
it doesn't matter. It might be more estatically pleasing. I can add it if
you want, but doesn't add anything.

Updated diff, since I just now noticed how mangled that thing was.

Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.69
diff -u -p -r1.69 snmpe.c
--- snmpe.c 5 Feb 2021 10:30:45 -   1.69
+++ snmpe.c 12 Feb 2021 10:34:32 -
@@ -227,7 +227,7 @@ snmpe_parse(struct snmp_message *msg)
case SNMP_V2:
if (env->sc_min_seclevel != 0)
goto badversion;
-   if (ober_scanf_elements(a, "se", , >sm_pdu) != 0)
+   if (ober_scanf_elements(a, "seS$", , >sm_pdu) != 0)
goto parsefail;
if (strlcpy(msg->sm_community, comn,
sizeof(msg->sm_community)) >= sizeof(msg->sm_community)) {
@@ -237,7 +237,7 @@ snmpe_parse(struct snmp_message *msg)
}
break;
case SNMP_V3:
-   if (ober_scanf_elements(a, "{iisi}e",
+   if (ober_scanf_elements(a, "{iisi$}e",
>sm_msgid, >sm_max_msg_size, ,
>sm_secmodel, ) != 0)
goto parsefail;
@@ -255,7 +255,7 @@ snmpe_parse(struct snmp_message *msg)
goto parsefail;
}
 
-   if (ober_scanf_elements(a, "{xxe",
+   if (ober_scanf_elements(a, "{xxeS$}$",
>sm_ctxengineid, >sm_ctxengineid_len,
, , >sm_pdu) != 0)
goto parsefail;
@@ -377,7 +377,7 @@ snmpe_parse(struct snmp_message *msg)
}
 
/* SNMP PDU */
-   if (ober_scanf_elements(a, "iiie{et",
+   if (ober_scanf_elements(a, "iiie{et}$",
, , , >sm_pduend,
>sm_varbind, , ) != 0) {
stats->snmp_silentdrops++;
@@ -436,7 +436,7 @@ snmpe_parsevarbinds(struct snmp_message 
 
for (i = 1; varbind != NULL && i < SNMPD_MAXVARBIND;
varbind = varbind->be_next, i++) {
-   if (ober_scanf_elements(varbind, "{oe}", , ) == -1) {
+   if (ober_scanf_elements(varbind, "{oeS$}", , ) == -1) {
stats->snmp_inasnparseerrs++;
msg->sm_errstr = "invalid varbind";
goto varfail;
Index: traphandler.c
===
RCS file: /cvs/src/usr.sbin/snmpd/traphandler.c,v
retrieving revision 1.20
diff -u -p -r1.20 traphandler.c
--- traphandler.c   22 Jan 2021 06:33:27 -  1.20
+++ traphandler.c   12 Feb 2021 10:34:32 -
@@ -67,7 +67,7 @@ traphandler_parse(struct snmp_message *m
struct privsep  *ps = _env->sc_ps;
struct snmp_stats   *stats = _env->sc_stats;
struct ber   ber = {0};
-   struct ber_element  *vblist = NULL, *elm, *elm2;
+   struct ber_element  *vblist = NULL, *elm;

Re: snmpd: Add end of sequence tests

2021-02-12 Thread Martijn van Duren
ping

On Sun, 2021-01-31 at 11:57 +0100, Martijn van Duren wrote:
> Now that ober_scanf_elements supports '$' lets use it.
> 
> Here's a first stab by adding it to snmpd.
> Passing regress and a few manual checks.
> 
> 'e' still doesn't consume the element, but I've talked it over with
> rob@, who said that shouldn't get in the way of using this new feature.
> 
> OK?
> 
> martijn@
> 
> Index: snmpe.c
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
> retrieving revision 1.68
> diff -u -p -r1.68 snmpe.c
> --- snmpe.c 22 Jan 2021 06:33:27 -  1.68
> +++ snmpe.c 31 Jan 2021 10:55:49 -
> @@ -220,7 +220,7 @@ snmpe_parse(struct snmp_message *msg)
> case SNMP_V2:
> if (env->sc_min_seclevel != 0)
> goto badversion;
> -   if (ober_scanf_elements(a, "se", , >sm_pdu) != 0)
> +   if (ober_scanf_elements(a, "seS$", , >sm_pdu) != 0)
> goto parsefail;
> if (strlcpy(msg->sm_community, comn,
>     sizeof(msg->sm_community)) >= sizeof(msg->sm_community)) {
> @@ -230,7 +230,7 @@ snmpe_parse(st? tm_udp.c
> Index: snmpe.c
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
> retrieving revision 1.68
> diff -u -p -r1.68 snmpe.c
> --- snmpe.c 22 Jan 2021 06:33:27 -  1.68
> +++ snmpe.c 31 Jan 2021 10:55:49 -
> @@ -220,7 +220,7 @@ snmpe_parse(struct snmp_message *msg)
> case SNMP_V2:
> if (env->sc_min_seclevel != 0)
> goto badversion;
> -   if (ober_scanf_elements(a, "se", , >sm_pdu) != 0)
> +   if (ober_scanf_elements(a, "seS$", , >sm_pdu) != 0)
> goto parsefail;
> if (strlcpy(msg->sm_community, comn,
>     sizeof(msg->sm_community)) >= sizeof(msg->sm_community)) {
> @@ -230,7 +230,7 @@ snmpe_parse(struct snmp_message *msg)
> }
> break;
> case SNMP_V3:
> -   if (ober_scanf_elements(a, "{iisi}e",
> +   if (ober_scanf_elements(a, "{iisi$}e",
>     >sm_msgid, >sm_max_msg_size, ,
>     >sm_secmodel, ) != 0)
> goto parsefail;
> @@ -248,7 +248,7 @@ snmpe_parse(struct snmp_message *msg)
> goto parsefail;
> }
>  
> -   if (ober_scanf_elements(a, "{xxe",
> +   if (ober_scanf_elements(a, "{xxeS$}$",
>     >sm_ctxengineid, >sm_ctxengineid_len,
>     , , >sm_pdu) != 0)
> goto parsefail;
> @@ -370,7 +370,7 @@ snmpe_parse(struct snmp_message *msg)
> }
>  
> /* SNMP PDU */
> -   if (ober_scanf_elements(a, "iiie{et",
> +   if (ober_scanf_elements(a, "iiie{etS$}$",
>     , , , >sm_pduend,
>     >sm_varbind, , ) != 0) {
> stats->snmp_silentdrops++;
> @@ -429,7 +429,7 @@ snmpe_parsevarbinds(struct snmp_message 
>  
> for (i = 1; varbind != NULL && i < SNMPD_MAXVARBIND;
>     varbind = varbind->be_next, i++) {
> -   if (ober_scanf_elements(varbind, "{oe}", , ) == -1) {
> +   if (ober_scanf_elements(varbind, "{oeS$}", , ) == -1) 
> {
> stats->snmp_inasnparseerrs++;
> msg->sm_errstr = "invalid varbind";
> goto varfail;
> Index: traphandler.c
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/traphandler.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 traphandler.c
> --- traphandler.c   22 Jan 2021 06:33:27 -  1.20
> +++ traphandler.c   31 Jan 2021 10:55:49 -
> @@ -67,7 +67,7 @@ traphandler_parse(struct snmp_message *m
> struct privsep  *ps = _env->sc_ps;
> struct snmp_stats   *stats = _env->sc_stats;
> struct ber   ber = {0};
> -   struct ber_element  *vblist = NULL, *elm, *elm2;
> +   struct ber_element  *vblist = NULL, *elm;
> struct ber_oid   o1, o2, snmpTrapOIDOID;
> struct ber_oid   snmpTrapOID, sysUpTimeOID;
> int  sysUpTime;
> @@ -82,7 +82,7 @@ traphandler_parse(struct snmp_message *m
> 

snmpd: add transaction id to snmp_message

2021-02-02 Thread Martijn van Duren
Carefully taking some first looks into readding agentx master support to
snmpd. One of the things we're going to need is a transaction id as per
RFC2741 section 6.1 subsection h.transactionID:
The transaction ID uniquely identifies, for a given session,
the single SNMP management request (and single SNMP PDU)
with which an AgentX PDU is associated.  If a single SNMP
management request results in multiple AgentX PDUs being
sent by the master agent with the same session ID, each of
these AgentX PDUs must contain the same transaction ID;
conversely, AgentX PDUs sent during a particular session,
that result from distinct SNMP management requests, must
have distinct transaction IDs within the limits of the 32-
bit field).

Note that the transaction ID is not the same as the SNMP
PDU's request-id (as described in section 4.1 of RFC 1905
[13], nor is it the same as the SNMP Message's msgID (as
described in section 6.2 of RFC 2572 [11]), nor can it be,
since a master agent might receive SNMP requests with the
same request-ids or msgIDs from different managers.

The transaction ID has no significance and no defined value
in AgentX administrative PDUs, i.e., AgentX PDUs that are
not associated with an SNMP management request.

Our previous implementation took the transaction id from the agentx
context and incremented it by one for every request, which is just
plain wrong.

OK?

martijn@

Index: snmpd.h
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
retrieving revision 1.93
diff -u -p -r1.93 snmpd.h
--- snmpd.h 28 Jan 2021 20:45:14 -  1.93
+++ snmpd.h 2 Feb 2021 12:23:37 -
@@ -399,6 +399,8 @@ struct snmp_message {
u_int8_t sm_data[READ_BUF_SIZE];
size_t   sm_datalen;
 
+   uint32_t sm_transactionid;
+
u_intsm_version;
 
/* V1, V2c */
@@ -436,7 +438,11 @@ struct snmp_message {
 
struct ber_element  *sm_varbind;
struct ber_element  *sm_varbindresp;
+
+   RB_ENTRY(snmp_message)   sm_entry;
 };
+RB_HEAD(snmp_messages, snmp_message);
+extern struct snmp_messages snmp_messages;
 
 /* Defined in SNMPv2-MIB.txt (RFC 3418) */
 struct snmp_stats {
@@ -642,6 +648,8 @@ struct kif_arp  *karp_getaddr(struct sock
 voidsnmpe(struct privsep *, struct privsep_proc *);
 voidsnmpe_shutdown(void);
 voidsnmpe_dispatchmsg(struct snmp_message *);
+int snmp_messagecmp(struct snmp_message *, struct snmp_message *);
+RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp)
 
 /* trap.c */
 voidtrap_init(void);
Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.68
diff -u -p -r1.68 snmpe.c
--- snmpe.c 22 Jan 2021 06:33:27 -  1.68
+++ snmpe.c 2 Feb 2021 12:23:37 -
@@ -58,6 +58,8 @@ void   snmp_msgfree(struct snmp_message *
 struct imsgev  *iev_parent;
 static const struct timevalsnmpe_tcp_timeout = { 10, 0 }; /* 10s */
 
+struct snmp_messages snmp_messages = RB_INITIALIZER(_messages);
+
 static struct privsep_proc procs[] = {
{ "parent", PROC_PARENT }
 };
@@ -210,6 +212,11 @@ snmpe_parse(struct snmp_message *msg)
 
msg->sm_errstr = "invalid message";
 
+   do {
+   msg->sm_transactionid = arc4random();
+   } while (msg->sm_transactionid == 0 ||
+   RB_FIND(snmp_messages, _messages, msg) != NULL);
+
if (ober_scanf_elements(root, "{ie", , ) != 0)
goto parsefail;
 
@@ -834,6 +841,8 @@ snmpe_response(struct snmp_message *msg)
 void
 snmp_msgfree(struct snmp_message *msg)
 {
+   if (msg->sm_transactionid != 0)
+   RB_REMOVE(snmp_messages, _messages, msg);
event_del(>sm_sockev);
ober_free(>sm_ber);
if (msg->sm_req != NULL)
@@ -896,3 +905,12 @@ snmpe_encode(struct snmp_message *msg)
 #endif
return 0;
 }
+
+int
+snmp_messagecmp(struct snmp_message *m1, struct snmp_message *m2)
+{
+   return (m1->sm_transactionid < m2->sm_transactionid ? -1 :
+   m1->sm_transactionid > m2->sm_transactionid);
+}
+
+RB_GENERATE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp)




snmpd: Add end of sequence tests

2021-01-31 Thread Martijn van Duren
Now that ober_scanf_elements supports '$' lets use it.

Here's a first stab by adding it to snmpd.
Passing regress and a few manual checks.

'e' still doesn't consume the element, but I've talked it over with
rob@, who said that shouldn't get in the way of using this new feature.

OK?

martijn@

Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.68
diff -u -p -r1.68 snmpe.c
--- snmpe.c 22 Jan 2021 06:33:27 -  1.68
+++ snmpe.c 31 Jan 2021 10:55:49 -
@@ -220,7 +220,7 @@ snmpe_parse(struct snmp_message *msg)
case SNMP_V2:
if (env->sc_min_seclevel != 0)
goto badversion;
-   if (ober_scanf_elements(a, "se", , >sm_pdu) != 0)
+   if (ober_scanf_elements(a, "seS$", , >sm_pdu) != 0)
goto parsefail;
if (strlcpy(msg->sm_community, comn,
sizeof(msg->sm_community)) >= sizeof(msg->sm_community)) {
@@ -230,7 +230,7 @@ snmpe_parse(st? tm_udp.c
Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.68
diff -u -p -r1.68 snmpe.c
--- snmpe.c 22 Jan 2021 06:33:27 -  1.68
+++ snmpe.c 31 Jan 2021 10:55:49 -
@@ -220,7 +220,7 @@ snmpe_parse(struct snmp_message *msg)
case SNMP_V2:
if (env->sc_min_seclevel != 0)
goto badversion;
-   if (ober_scanf_elements(a, "se", , >sm_pdu) != 0)
+   if (ober_scanf_elements(a, "seS$", , >sm_pdu) != 0)
goto parsefail;
if (strlcpy(msg->sm_community, comn,
sizeof(msg->sm_community)) >= sizeof(msg->sm_community)) {
@@ -230,7 +230,7 @@ snmpe_parse(struct snmp_message *msg)
}
break;
case SNMP_V3:
-   if (ober_scanf_elements(a, "{iisi}e",
+   if (ober_scanf_elements(a, "{iisi$}e",
>sm_msgid, >sm_max_msg_size, ,
>sm_secmodel, ) != 0)
goto parsefail;
@@ -248,7 +248,7 @@ snmpe_parse(struct snmp_message *msg)
goto parsefail;
}
 
-   if (ober_scanf_elements(a, "{xxe",
+   if (ober_scanf_elements(a, "{xxeS$}$",
>sm_ctxengineid, >sm_ctxengineid_len,
, , >sm_pdu) != 0)
goto parsefail;
@@ -370,7 +370,7 @@ snmpe_parse(struct snmp_message *msg)
}
 
/* SNMP PDU */
-   if (ober_scanf_elements(a, "iiie{et",
+   if (ober_scanf_elements(a, "iiie{etS$}$",
, , , >sm_pduend,
>sm_varbind, , ) != 0) {
stats->snmp_silentdrops++;
@@ -429,7 +429,7 @@ snmpe_parsevarbinds(struct snmp_message 
 
for (i = 1; varbind != NULL && i < SNMPD_MAXVARBIND;
varbind = varbind->be_next, i++) {
-   if (ober_scanf_elements(varbind, "{oe}", , ) == -1) {
+   if (ober_scanf_elements(varbind, "{oeS$}", , ) == -1) {
stats->snmp_inasnparseerrs++;
msg->sm_errstr = "invalid varbind";
goto varfail;
Index: traphandler.c
===
RCS file: /cvs/src/usr.sbin/snmpd/traphandler.c,v
retrieving revision 1.20
diff -u -p -r1.20 traphandler.c
--- traphandler.c   22 Jan 2021 06:33:27 -  1.20
+++ traphandler.c   31 Jan 2021 10:55:49 -
@@ -67,7 +67,7 @@ traphandler_parse(struct snmp_message *m
struct privsep  *ps = _env->sc_ps;
struct snmp_stats   *stats = _env->sc_stats;
struct ber   ber = {0};
-   struct ber_element  *vblist = NULL, *elm, *elm2;
+   struct ber_element  *vblist = NULL, *elm;
struct ber_oid   o1, o2, snmpTrapOIDOID;
struct ber_oid   snmpTrapOID, sysUpTimeOID;
int  sysUpTime;
@@ -82,7 +82,7 @@ traphandler_parse(struct snmp_message *m
goto done;
break;
case SNMP_C_TRAPV2:
-   if (ober_scanf_elements(msg->sm_pdu, "{SSe}", ) == -1) {
+   if (ober_scanf_elements(msg->sm_pdu, "{SSe}$", ) == -1) {
stats->snmp_inasnparseerrs++;
goto done;
}
@@ -98,7 +98,7 @@ traphandler_parse(struct snmp_message *m
 
(void)ober_string2oid("1.3.6.1.2.1.1.3.0", );
(void)ober_string2oid("1.3.6.1.6.3.1.1.4.1.0", );
-   if (ober_scanf_elements(vblist, "{{od}{oo}", , , ,
+   if (ober_scanf_elements(vblist, "{{od$}{oo$}", , , ,
) == -1 ||
ober_oid_cmp(, ) != 0 ||
ober_oid_cmp(, ) != 0) {
@@ -107,8 +107,7 @@ traphandler_parse(struct snmp_message *m
}

Re: snmpd: remove print_{verbose,debug}

2021-01-28 Thread Martijn van Duren
ping

On Sun, 2021-01-24 at 14:48 +0100, Martijn van Duren wrote:
> Nothing seems to use them and I see no reason in the forseeable future
> to start using them.
> 
> OK?
> 
> martijn@
> 
> Index: snmpd.h
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
> retrieving revision 1.91
> diff -u -p -r1.91 snmpd.h
> --- snmpd.h 22 Jan 2021 06:33:26 -  1.91
> +++ snmpd.h 24 Jan 2021 13:48:15 -
> @@ -780,8 +780,6 @@ ssize_t  sendtofrom(int, void *, size_t,
>     socklen_t, struct sockaddr *, socklen_t);
>  ssize_t recvfromto(int, void *, size_t, int, struct sockaddr *,
>     socklen_t *, struct sockaddr *, socklen_t *);
> -void    print_debug(const char *, ...);
> -void    print_verbose(const char *, ...);
>  const char *log_in6addr(const struct in6_addr *);
>  const char *print_host(struct sockaddr_storage *, char *, size_t);
>  
> Index: util.c
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/util.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 util.c
> --- util.c  30 Jun 2020 17:11:49 -  1.10
> +++ util.c  24 Jan 2021 13:48:15 -
> @@ -152,30 +152,6 @@ recvfromto(int s, void *buf, size_t len,
> return (ret);
>  }
>  
> -void
> -print_debug(const char *emsg, ...)
> -{
> -   va_list  ap;
> -
> -   if (log_getverbose() > 2) {
> -   va_start(ap, emsg);
> -   vfprintf(stderr, emsg, ap);
> -   va_end(ap);
> -   }
> -}
> -
> -void
> -print_verbose(const char *emsg, ...)
> -{
> -   va_list  ap;
> -
> -   if (log_getverbose()) {
> -   va_start(ap, emsg);
> -   vfprintf(stderr, emsg, ap);
> -   va_end(ap);
> -   }
> -}
> -
>  const char *
>  log_in6addr(const struct in6_addr *addr)
>  {
> 
> 




Re: systat(1): improve parsing of delay value

2021-01-28 Thread Martijn van Duren
On Tue, 2021-01-26 at 16:40 +0100, Alexander Bluhm wrote:
> On Mon, Jan 25, 2021 at 11:17:04AM +0100, Martijn van Duren wrote:
> > if (argc == 1) {
> > -   double del = atof(argv[0]);
> > -   if (del == 0)
> > +   delay = strtodnum(argv[0], 0, UINT32_MAX / 100, 
> > );
> > +   if (errstr != NULL)
> > viewstr = argv[0];
> > -   else
> > -   delay = del;
> 
> You need the else.  delay should only be changed if parsing was successful.
> 
> > } else if (argc == 2) {
> > viewstr = argv[0];
> > -   delay = atof(argv[1]);
> > -   if (delay <= 0)
> > -   delay = 5;
> > +   delay = strtodnum(optarg, 0, UINT32_MAX / 100, );
> 
> This should be argv[1] instead of optarg.
> 
> > +   if (errstr != NULL)
> > +   errx(1, "-s \"%s\": delay value is %s", optarg, 
> > errstr);
> > }
> 
> The -s in the error message is wrong.  Here delay was passed as argument.
> 
> bluhm
> 
Thanks for checking. Should be fixed below.

Index: main.c
===
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.72
diff -u -p -r1.72 main.c
--- main.c  12 Jan 2020 20:51:08 -  1.72
+++ main.c  28 Jan 2021 20:05:30 -
@@ -40,9 +40,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -73,6 +75,7 @@ char  uloadbuf[TIMEPOS];
 
 int  ucount(void);
 void usage(void);
+double strtodnum(const char *, double, double, const char **);
 
 /* command prompt */
 
@@ -323,9 +326,14 @@ void
 cmd_delay(const char *buf)
 {
double del;
-   del = atof(buf);
+   const char *errstr;
 
-   if (del > 0) {
+   if (buf[0] == '\0')
+   return;
+   del = strtodnum(buf, 0, UINT32_MAX / 100, );
+   if (errstr != NULL)
+   error("s: \"%s\": delay value is %s", buf, errstr);
+   else {
udelay = (useconds_t)(del * 100);
gotsig_alarm = 1;
naptime = del;
@@ -414,6 +422,48 @@ gethz(void)
hz = cinf.hz;
 }
 
+#defineINVALID 1
+#defineTOOSMALL2
+#defineTOOLARGE3
+
+double
+strtodnum(const char *nptr, double minval, double maxval, const char **errstrp)
+{
+   double d = 0;
+   int error = 0;
+   char *ep;
+   struct errval {
+   const char *errstr;
+   int err;
+   } ev[4] = {
+   { NULL, 0 },
+   { "invalid",EINVAL },
+   { "too small",  ERANGE },
+   { "too large",  ERANGE },
+   };
+
+   ev[0].err = errno;
+   errno = 0;
+   if (minval > maxval) {
+   error = INVALID;
+   } else {
+   d = strtod(nptr, );
+   if (nptr == ep || *ep != '\0')
+   error = INVALID;
+   else if ((d == -HUGE_VAL && errno == ERANGE) || d < minval)
+   error = TOOSMALL;
+   else if ((d == HUGE_VAL && errno == ERANGE) || d > maxval)
+   error = TOOLARGE;
+   }
+   if (errstrp != NULL)
+   *errstrp = ev[error].errstr;
+   errno = ev[error].err;
+   if (error)
+   d = 0;
+
+   return (d);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -421,7 +471,7 @@ main(int argc, char *argv[])
const char *errstr;
extern char *optarg;
extern int optind;
-   double delay = 5;
+   double delay = 5, del;
 
char *viewstr = NULL;
 
@@ -475,9 +525,11 @@ main(int argc, char *argv[])
nflag = 1;
break;
case 's':
-   delay = atof(optarg);
-   if (delay <= 0)
-   delay = 5;
+   delay = strtodnum(optarg, 0, UINT32_MAX / 100,
+   );
+   if (errstr != NULL)
+   errx(1, "-s \"%s\": delay value is %s", optarg,
+   errstr);
break;
case 'w':
rawwidth = strtonum(optarg, 1, MAX_LINE_BUF-1, );
@@ -497,16 +549,16 @@ main(int argc, char *argv[])
argv += optind;
 
if (argc == 1) {
-   double del = atof(argv[0]);
-   if (del == 0)
+   del = strtodnum(argv[0], 0, UINT32_MAX / 100, );
+   if (errstr != NULL

Re: systat(1): improve parsing of delay value

2021-01-25 Thread Martijn van Duren
On Mon, 2021-01-25 at 10:50 +0100, Martijn van Duren wrote:
> On Mon, 2021-01-25 at 08:15 +, Nick Gasson wrote:
> > Hi,
> > 
> > I incorrectly ran "systat netstat -N" instead of "systat -N netstat" and
> > got confused why it wasn't resolving host names. The -N gets parsed with
> > atof to a 0s delay that is then clamped to 5s. The patch below instead
> > prints an error if the delay cannot be parsed. I think the <= 0 case
> > should also produce an error but I left the existing behaviour of
> > setting it to 5s.
> 
> Your diff fails for the simple case of "systat", because of your added
> else case. It's also not completely clear to the end user why things
> fail.
> 
> I agree that failing loud on unparseable strings and just defaulting
> back to the 5s is just stupid. So here's an updated diff that just
> blatantly steals^Wborrows from strtonum.
> 
> OK?
> 
> martijn@
> 
That one was a little too rushed... It overlooked the internal "s"
command and some minor additional testing shows that currently
large delays are accepted and completely broken because of useconds_t
overflow. I couldn't find something like USECONDS_MAX, so I took the
next best thing: UINT32_MAX, where useconds_t is based on.

This change limits delays to 4294 seconds, which already is the
only reasonable value that would work for systat.

martijn@

Index: main.c
===
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.72
diff -u -p -r1.72 main.c
--- main.c  12 Jan 2020 20:51:08 -  1.72
+++ main.c  25 Jan 2021 10:16:34 -
@@ -40,9 +40,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -73,6 +75,7 @@ char  uloadbuf[TIMEPOS];
 
 int  ucount(void);
 void usage(void);
+double strtodnum(const char *, double, double, const char **);
 
 /* command prompt */
 
@@ -323,9 +326,14 @@ void
 cmd_delay(const char *buf)
 {
double del;
-   del = atof(buf);
+   const char *errstr;
 
-   if (del > 0) {
+   if (buf[0] == '\0')
+   return;
+   del = strtodnum(buf, 0, UINT32_MAX / 100, );
+   if (errstr != NULL)
+   error("s: \"%s\": delay value is %s", buf, errstr);
+   else {
udelay = (useconds_t)(del * 100);
gotsig_alarm = 1;
naptime = del;
@@ -414,6 +422,48 @@ gethz(void)
hz = cinf.hz;
 }
 
+#defineINVALID 1
+#defineTOOSMALL2
+#defineTOOLARGE3
+
+double
+strtodnum(const char *nptr, double minval, double maxval, const char **errstrp)
+{
+   double d = 0;
+   int error = 0;
+   char *ep;
+   struct errval {
+   const char *errstr;
+   int err;
+   } ev[4] = {
+   { NULL, 0 },
+   { "invalid",EINVAL },
+   { "too small",  ERANGE },
+   { "too large",  ERANGE },
+   };
+
+   ev[0].err = errno;
+   errno = 0;
+   if (minval > maxval) {
+   error = INVALID;
+   } else {
+   d = strtod(nptr, );
+   if (nptr == ep || *ep != '\0')
+   error = INVALID;
+   else if ((d == -HUGE_VAL && errno == ERANGE) || d < minval)
+   error = TOOSMALL;
+   else if ((d == HUGE_VAL && errno == ERANGE) || d > maxval)
+   error = TOOLARGE;
+   }
+   if (errstrp != NULL)
+   *errstrp = ev[error].errstr;
+   errno = ev[error].err;
+   if (error)
+   d = 0;
+
+   return (d);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -475,9 +525,11 @@ main(int argc, char *argv[])
nflag = 1;
break;
case 's':
-   delay = atof(optarg);
-   if (delay <= 0)
-   delay = 5;
+   delay = strtodnum(optarg, 0, UINT32_MAX / 100,
+   );
+   if (errstr != NULL)
+   errx(1, "-s \"%s\": delay value is %s", optarg,
+   errstr);
break;
case 'w':
rawwidth = strtonum(optarg, 1, MAX_LINE_BUF-1, );
@@ -497,16 +549,14 @@ main(int argc, char *argv[])
argv += optind;
 
if (argc == 1) {
-   double del = atof(argv[0]);
-   if (del == 0)
+   delay = strtodnum(argv[0], 0, UINT32_MAX / 100, );
+   if (errstr != NULL)
viewstr = argv[0];
-   else
-

Re: systat(1): improve parsing of delay value

2021-01-25 Thread Martijn van Duren
On Mon, 2021-01-25 at 08:15 +, Nick Gasson wrote:
> Hi,
> 
> I incorrectly ran "systat netstat -N" instead of "systat -N netstat" and
> got confused why it wasn't resolving host names. The -N gets parsed with
> atof to a 0s delay that is then clamped to 5s. The patch below instead
> prints an error if the delay cannot be parsed. I think the <= 0 case
> should also produce an error but I left the existing behaviour of
> setting it to 5s.

Your diff fails for the simple case of "systat", because of your added
else case. It's also not completely clear to the end user why things
fail.

I agree that failing loud on unparseable strings and just defaulting
back to the 5s is just stupid. So here's an updated diff that just
blatantly steals^Wborrows from strtonum.

OK?

martijn@

Index: main.c
===
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.72
diff -u -p -r1.72 main.c
--- main.c  12 Jan 2020 20:51:08 -  1.72
+++ main.c  25 Jan 2021 09:48:44 -
@@ -40,6 +40,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -414,6 +415,48 @@ gethz(void)
hz = cinf.hz;
 }
 
+#defineINVALID 1
+#defineTOOSMALL2
+#defineTOOLARGE3
+
+double
+strtodnum(const char *nptr, double minval, double maxval, const char **errstrp)
+{
+   double d = 0;
+   int error = 0;
+   char *ep;
+   struct errval {
+   const char *errstr;
+   int err;
+   } ev[4] = {
+   { NULL, 0 },
+   { "invalid",EINVAL },
+   { "too small",  ERANGE },
+   { "too large",  ERANGE },
+   };
+
+   ev[0].err = errno;
+   errno = 0;
+   if (minval > maxval) {
+   error = INVALID;
+   } else {
+   d = strtod(nptr, );
+   if (nptr == ep || *ep != '\0')
+   error = INVALID;
+   else if ((d == -HUGE_VAL && errno == ERANGE) || d < minval)
+   error = TOOSMALL;
+   else if ((d == HUGE_VAL && errno == ERANGE) || d > maxval)
+   error = TOOLARGE;
+   }
+   if (errstrp != NULL)
+   *errstrp = ev[error].errstr;
+   errno = ev[error].err;
+   if (error)
+   d = 0;
+
+   return (d);
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -475,9 +518,9 @@ main(int argc, char *argv[])
nflag = 1;
break;
case 's':
-   delay = atof(optarg);
-   if (delay <= 0)
-   delay = 5;
+   delay = strtodnum(optarg, 0, HUGE_VAL, );
+   if (errstr != NULL)
+   errx(1, "-s %s: delay value is %s", optarg, 
errstr);
break;
case 'w':
rawwidth = strtonum(optarg, 1, MAX_LINE_BUF-1, );
@@ -497,16 +540,14 @@ main(int argc, char *argv[])
argv += optind;
 
if (argc == 1) {
-   double del = atof(argv[0]);
-   if (del == 0)
+   delay = strtodnum(argv[0], 0, HUGE_VAL, );
+   if (errstr != NULL)
viewstr = argv[0];
-   else
-   delay = del;
} else if (argc == 2) {
viewstr = argv[0];
-   delay = atof(argv[1]);
-   if (delay <= 0)
-   delay = 5;
+   delay = strtodnum(optarg, 0, HUGE_VAL, );
+   if (errstr != NULL)
+   errx(1, "-s %s: delay value is %s", optarg, errstr);
}
 
udelay = (useconds_t)(delay * 100.0);




snmpd: remove print_{verbose,debug}

2021-01-24 Thread Martijn van Duren
Nothing seems to use them and I see no reason in the forseeable future
to start using them.

OK?

martijn@

Index: snmpd.h
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
retrieving revision 1.91
diff -u -p -r1.91 snmpd.h
--- snmpd.h 22 Jan 2021 06:33:26 -  1.91
+++ snmpd.h 24 Jan 2021 13:48:15 -
@@ -780,8 +780,6 @@ ssize_t  sendtofrom(int, void *, size_t,
socklen_t, struct sockaddr *, socklen_t);
 ssize_t recvfromto(int, void *, size_t, int, struct sockaddr *,
socklen_t *, struct sockaddr *, socklen_t *);
-voidprint_debug(const char *, ...);
-voidprint_verbose(const char *, ...);
 const char *log_in6addr(const struct in6_addr *);
 const char *print_host(struct sockaddr_storage *, char *, size_t);
 
Index: util.c
===
RCS file: /cvs/src/usr.sbin/snmpd/util.c,v
retrieving revision 1.10
diff -u -p -r1.10 util.c
--- util.c  30 Jun 2020 17:11:49 -  1.10
+++ util.c  24 Jan 2021 13:48:15 -
@@ -152,30 +152,6 @@ recvfromto(int s, void *buf, size_t len,
return (ret);
 }
 
-void
-print_debug(const char *emsg, ...)
-{
-   va_list  ap;
-
-   if (log_getverbose() > 2) {
-   va_start(ap, emsg);
-   vfprintf(stderr, emsg, ap);
-   va_end(ap);
-   }
-}
-
-void
-print_verbose(const char *emsg, ...)
-{
-   va_list  ap;
-
-   if (log_getverbose()) {
-   va_start(ap, emsg);
-   vfprintf(stderr, emsg, ap);
-   va_end(ap);
-   }
-}
-
 const char *
 log_in6addr(const struct in6_addr *addr)
 {




Re: snmpd(8): Remove traphandler process attempt 2

2021-01-18 Thread Martijn van Duren
ping

On Tue, 2021-01-05 at 22:24 +0100, Martijn van Duren wrote:
> With the traphandler code beaten into submission I was able to keep the
> traphandler process removal diff more manageable. This diff does a
> couple things.
> - "listen on" now accepts any combination of read, write and notify.
>   This combination removes the traphandler dependency on the generic
>   listen on statement, which allows an admin to run snmpd in
>   traphandler-only mode. This will break existing traphandler setups,
>   but considering the benefit of not having the two functionalities
>   mixed is worth it to me and is fully intentional.
>   The names are choosen based on viewType names from RFC 3415 (VACM)
> - The traphandler process is gone, resulting in a single dispatcher
>   responsible for the initial parsing of the packets, which allows for
>   better msg checking in the future. The current traphandler process
>   does nothing more then what snmpe already does, but a lot crappier:
>   the pledge was also too wide.
> - We now check incoming trap packets against "trap community". The
>   current code does no community verification.
> - trap parsing errors are now shown in a similar fashion to the read
>   and write requests.
> - traphandler now support tcp!!!
> - Minus 65 LoC
> 
> With this change regress requires the following diff:
> Index: snmpd.sh
> ===
> RCS file: /cvs/src/regress/usr.sbin/snmpd/snmpd.sh,v
> retrieving revision 1.12
> diff -u -p -r1.12 snmpd.sh
> --- snmpd.sh8 Aug 2020 11:06:40 -   1.12
> +++ snmpd.sh5 Jan 2021 20:46:19 -
> @@ -65,6 +65,7 @@ cat > ${OBJDIR}/snmpd.conf <  # This is config template (1) for snmpd regression testing
>  # Restrict daemon to listen on localhost only
>  listen on 127.0.0.1
> +listen on 127.0.0.1 notify
>  listen on ::1
>  
>  # Specify a number of trap receivers
> 
> OK?
> 
> martijn@
> 
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
> retrieving revision 1.62
> diff -u -p -r1.62 parse.y
> --- parse.y 30 Oct 2020 07:43:48 -  1.62
> +++ parse.y 5 Jan 2021 21:22:12 -
> @@ -94,11 +94,10 @@ char*symget(const char *);
>  struct snmpd   *conf = NULL;
>  static int  errors = 0;
>  static struct usmuser  *user = NULL;
> -static char*snmpd_port = SNMPD_PORT;
>  
>  int host(const char *, const char *, int,
>     struct sockaddr_storage *, int);
> -int listen_add(struct sockaddr_storage *, int);
> +int listen_add(struct sockaddr_storage *, int, int);
>  
>  typedef struct {
> union {
> @@ -121,7 +120,7 @@ typedef struct {
>  %}
>  
>  %token INCLUDE
> -%token  LISTEN ON
> +%token  LISTEN ON READ WRITE NOTIFY
>  %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
> @@ -130,7 +129,7 @@ typedef struct {
>  %token   NUMBER
>  %typehostcmn
>  %typesrcaddr port
> -%typeoptwrite yesno seclevel
> +%typeoptwrite yesno seclevel listenopt listenopts
>  %type  objtype cmd
>  %type   oid hostoid trapoid
>  %type  auth
> @@ -281,54 +280,74 @@ listenproto   : UDP listen_udp
> | TCP listen_tcp
> | listen_udp
>  
> -listen_udp : STRING port   {
> +listenopts : /* empty */ { $$ = 0; }
> +   | listenopts listenopt { $$ |= $2; }
> +   ;
> +
> +listenopt  : READ { $$ = ADDRESS_FLAG_READ; }
> +   | WRITE { $$ = ADDRESS_FLAG_WRITE; }
> +   | NOTIFY { $$ = ADDRESS_FLAG_NOTIFY; }
> +   ;
> +
> +listen_udp : STRING port listenopts{
> struct sockaddr_storage ss[16];
> int nhosts, i;
> +   char *port = $2;
> +
> +   if (port == NULL) {
> +   if ($3 == ADDRESS_FLAG_NOTIFY)
> +   port = SNMPTRAP_PORT;
> +   else
> +   port = SNMP_PORT;
> +   }
>  
> -   nhosts = host($1, $2, SOCK_DGRAM, ss, nitems(ss));
> +   nhosts = host($1, port, SOCK_DGRAM, ss, nitems(ss));
&

ber: mandate end of sequence/set

2021-01-08 Thread Martijn van Duren
Right now we don't check for end of sequence or set in most ber places.
This means that valid ber, but invalid ASN1 could be passed down the
codepath.

Since most of the parsing is done with ober_scanf_elements I think it
would be a good idea to add a sequence limiter. rob@ likes the idea and
suggested '$'.

This allows for the following syntax (e.g. varbind parsing):
for (; elm != NULL; elm = elm->be_next) {
if (ober_scanf_elements(elm, "{oe$}", , ) == -1)
goto fail;
}

OK?

martijn@

Index: ber.c
===
RCS file: /cvs/src/lib/libutil/ber.c,v
retrieving revision 1.17
diff -u -p -r1.17 ber.c
--- ber.c   3 Sep 2020 19:09:57 -   1.17
+++ ber.c   8 Jan 2021 15:22:50 -
@@ -684,9 +684,14 @@ ober_scanf_elements(struct ber_element *
 
va_start(ap, fmt);
while (*fmt) {
-   if (ber == NULL && *fmt != '}' && *fmt != ')')
+   if (ber == NULL && *fmt != '$' && *fmt != '}' && *fmt != ')')
goto fail;
switch (*fmt++) {
+   case '$':
+   if (ber != NULL)
+   goto fail;
+   ret++;
+   continue;
case 'B':
ptr = va_arg(ap, void **);
len = va_arg(ap, size_t *);
Index: ober_get_string.3
===
RCS file: /cvs/src/lib/libutil/ober_get_string.3,v
retrieving revision 1.2
diff -u -p -r1.2 ober_get_string.3
--- ober_get_string.3   25 Oct 2019 04:00:10 -  1.2
+++ ober_get_string.3   8 Jan 2021 15:22:50 -
@@ -81,6 +81,7 @@ per byte.
 The following bytes are valid:
 .Bl -column -offset indent bytes ober_get_enumerated() "1: struct ber_element 
**"
 .It Sy byte Ta Sy function Ta Sy arguments
+.It $ Ta see below  Ta 0
 .It B Ta Fn ober_get_bitstring  Ta 2: Vt void ** , size_t *
 .It b Ta Fn ober_get_booleanTa 1: Vt int *
 .It d Ta Fn ober_get_integerTa 1: Vt int *
@@ -121,6 +122,9 @@ For
 .Sq t ,
 the class and type of the element are stored in the two corresponding
 variables, but if the element contains a value, that value is ignored.
+A
+.Sq $
+mandates the end of a sequence or set.
 .Pp
 For an opening parenthesis or brace, it is checked that the element
 is a sequence or a set, and parsing continues with its children.




snmpd(8): Remove traphandler process attempt 2

2021-01-05 Thread Martijn van Duren
With the traphandler code beaten into submission I was able to keep the
traphandler process removal diff more manageable. This diff does a
couple things.
- "listen on" now accepts any combination of read, write and notify.
  This combination removes the traphandler dependency on the generic
  listen on statement, which allows an admin to run snmpd in
  traphandler-only mode. This will break existing traphandler setups,
  but considering the benefit of not having the two functionalities
  mixed is worth it to me and is fully intentional.
  The names are choosen based on viewType names from RFC 3415 (VACM)
- The traphandler process is gone, resulting in a single dispatcher
  responsible for the initial parsing of the packets, which allows for
  better msg checking in the future. The current traphandler process
  does nothing more then what snmpe already does, but a lot crappier:
  the pledge was also too wide.
- We now check incoming trap packets against "trap community". The
  current code does no community verification.
- trap parsing errors are now shown in a similar fashion to the read
  and write requests.
- traphandler now support tcp!!!
- Minus 65 LoC

With this change regress requires the following diff:
Index: snmpd.sh
===
RCS file: /cvs/src/regress/usr.sbin/snmpd/snmpd.sh,v
retrieving revision 1.12
diff -u -p -r1.12 snmpd.sh
--- snmpd.sh8 Aug 2020 11:06:40 -   1.12
+++ snmpd.sh5 Jan 2021 20:46:19 -
@@ -65,6 +65,7 @@ cat > ${OBJDIR}/snmpd.conf < NUMBER
 %typehostcmn
 %typesrcaddr port
-%typeoptwrite yesno seclevel
+%typeoptwrite yesno seclevel listenopt listenopts
 %type  objtype cmd
 %type   oid hostoid trapoid
 %type  auth
@@ -281,54 +280,74 @@ listenproto   : UDP listen_udp
| TCP listen_tcp
| listen_udp
 
-listen_udp : STRING port   {
+listenopts : /* empty */ { $$ = 0; }
+   | listenopts listenopt { $$ |= $2; }
+   ;
+
+listenopt  : READ { $$ = ADDRESS_FLAG_READ; }
+   | WRITE { $$ = ADDRESS_FLAG_WRITE; }
+   | NOTIFY { $$ = ADDRESS_FLAG_NOTIFY; }
+   ;
+
+listen_udp : STRING port listenopts{
struct sockaddr_storage ss[16];
int nhosts, i;
+   char *port = $2;
+
+   if (port == NULL) {
+   if ($3 == ADDRESS_FLAG_NOTIFY)
+   port = SNMPTRAP_PORT;
+   else
+   port = SNMP_PORT;
+   }
 
-   nhosts = host($1, $2, SOCK_DGRAM, ss, nitems(ss));
+   nhosts = host($1, port, SOCK_DGRAM, ss, nitems(ss));
if (nhosts < 1) {
yyerror("invalid address: %s", $1);
free($1);
-   if ($2 != snmpd_port)
-   free($2);
+   free($2);
YYERROR;
}
if (nhosts > (int)nitems(ss))
log_warn("%s:%s resolves to more than %zu 
hosts",
-   $1, $2, nitems(ss));
+   $1, port, nitems(ss));
 
free($1);
-   if ($2 != snmpd_port)
-   free($2);
+   free($2);
for (i = 0; i < nhosts; i++) {
-   if (listen_add(&(ss[i]), SOCK_DGRAM) == -1) {
+   if (listen_add(&(ss[i]), SOCK_DGRAM, $3) == -1) 
{
yyerror("calloc");
YYERROR;
}
}
}
 
-listen_tcp : STRING port   {
+listen_tcp : STRING port listenopts{
struct sockaddr_storage ss[16];
int nhosts, i;
+   char *port = $2;
 
-   nhosts = host($1, $2, SOCK_STREAM, ss, nitems(ss));
+   if (port == NULL) {
+   if ($3 == ADDRESS_FLAG_NOTIFY)
+   port = SNMPTRAP_PORT;
+   else
+   port = SNMP_PORT;
+   }
+   nhosts = host($1, port, SOCK_STREAM, ss, nitems(ss));
if (nhosts < 1) {
yyerror("invalid address: %s", $1);
free($1);
-   if ($2 != snmpd_port)
- 

libagentx: Add notify (snmp trap) support

2021-01-04 Thread Martijn van Duren
__VA_ARGS__ }, \
 (sizeof((uint32_t []) { __VA_ARGS__ }) / sizeof(uint32_t))
 
@@ -147,3 +150,36 @@ void agentx_varbind_set_index_object(str
 struct agentx_index *, struct agentx_object *);
 void agentx_varbind_set_index_ipaddress(struct agentx_varbind *,
 struct agentx_index *, const struct in_addr *);
+
+struct agentx_notify *agentx_notify(struct agentx_context *, const uint32_t[],
+size_t);
+void agentx_notify_integer(struct agentx_notify *, const uint32_t[], size_t,
+int32_t);
+void agentx_notify_string(struct agentx_notify *, const uint32_t[], size_t,
+const char *);
+void agentx_notify_nstring(struct agentx_notify *, const uint32_t[], size_t,
+const char *, size_t);
+void agentx_notify_printf(struct agentx_notify *, const uint32_t[], size_t,
+const char *, ...) __attribute__((__format__ (printf, 4, 5)));
+void agentx_notify_null(struct agentx_notify *, const uint32_t[], size_t);
+void agentx_notify_oid(struct agentx_notify *, const uint32_t[], size_t,
+const uint32_t[], size_t);
+void agentx_notify_object(struct agentx_notify *, const uint32_t[], size_t,
+struct agentx_object *);
+void agentx_notify_index(struct agentx_notify *, const uint32_t[], size_t,
+struct agentx_index *);
+void agentx_notify_ipaddress(struct agentx_notify *, const uint32_t[], size_t,
+const struct in_addr *);
+void agentx_notify_counter32(struct agentx_notify *, const uint32_t[], size_t,
+uint32_t);
+void agentx_notify_gauge32(struct agentx_notify *, const uint32_t[], size_t,
+uint32_t);
+void agentx_notify_unsigned32(struct agentx_notify *, const uint32_t[], size_t,
+uint32_t);
+void agentx_notify_timeticks(struct agentx_notify *, const uint32_t[], size_t,
+uint32_t);
+void agentx_notify_opaque(struct agentx_notify *, const uint32_t[], size_t,
+const char *, size_t);
+void agentx_notify_counter64(struct agentx_notify *, const uint32_t[], size_t,
+uint64_t);
+void agentx_notify_send(struct agentx_notify *);
Index: agentx_internal.h
===
RCS file: /cvs/src/lib/libagentx/agentx_internal.h,v
retrieving revision 1.2
diff -u -p -r1.2 agentx_internal.h
--- agentx_internal.h   26 Oct 2020 16:02:16 -  1.2
+++ agentx_internal.h   4 Jan 2021 17:34:01 -
@@ -67,6 +67,7 @@ struct agentx_context {
enum agentx_dstate axc_dstate;
TAILQ_HEAD(, agentx_agentcaps) axc_agentcaps;
TAILQ_HEAD(, agentx_region) axc_regions;
+   TAILQ_HEAD(, agentx_notify) axc_notifications;
RB_HEAD(axc_objects, agentx_object) axc_objects;
TAILQ_ENTRY(agentx_context) axc_axs_contexts;
 };
Index: agentx_notify.3
===
RCS file: agentx_notify.3
diff -N agentx_notify.3
--- /dev/null   1 Jan 1970 00:00:00 -
+++ agentx_notify.3 4 Jan 2021 17:34:01 -
@@ -0,0 +1,177 @@
+.\" $OpenBSD: agentx.3,v 1.5 2020/12/03 22:47:21 jmc Exp $
+.\"
+.\" Copyright (c) 2020 Martijn van Duren 
+.\"
+.\" 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.
+.\"
+.Dd $Mdocdate: December 3 2020 $
+.Dt AGENTX_NOTIFY 3
+.Os
+.Sh NAME
+.Nm agentx_notify
+.Nm agentx_notify_integer
+.Nm agentx_notify_string
+.Nm agentx_notify_nstring
+.Nm agentx_notify_printf
+.Nm agentx_notify_null
+.Nm agentx_notify_oid
+.Nm agentx_notify_object
+.Nm agentx_notify_index
+.Nm agentx_notify_ipaddress
+.Nm agentx_notify_counter32
+.Nm agentx_notify_gauge32
+.Nm agentx_notify_unsigned32
+.Nm agentx_notify_timeticks
+.Nm agentx_notify_opaque
+.Nm agentx_notify_counter64
+.Nm agentx_notify_send
+.Sh SYNOPSIS
+.In agentx.h
+.Ft struct agentx_notify *
+.Fo agentx_notify
+.Fa "struct agentx_context *axc" "const uint32_t trapoid[]" "size_t oidlen"
+.Fc
+.Ft void
+.Fo agentx_notify_integer
+.Fa "struct agentx_notify *axn" "const uint32_t oid[]" "size_t oidlen"
+.Fa "int32_t value"
+.Fc
+.Ft void
+.Fo agentx_notify_string
+.Fa "struct agentx_notify *axn" "const uint32_t oid[]" "size_t oidlen"
+.Fa "const char *string"
+.Fc
+.Ft void
+.Fo agentx_notify_nstring
+.Fa "struct agentx_notify *ax

Re: snmp - remove BER_TYPE_BOOLEAN

2021-01-04 Thread Martijn van Duren
On Mon, 2021-01-04 at 08:15 +0100, Rob Schmersel wrote:
> On Sun, 03 Jan 2021 21:59:57 +0100
> Martijn van Duren  wrote:
> 
> > ping
> > 
> > On Mon, 2020-12-14 at 12:13 +0100, Martijn van Duren wrote:
> > > I can't find any reference in RFC2578 for a boolean type, nor have I
> > > seen it in the wild and the TruthValue diff I just committed give
> > > me a strong indication that this was added without any real reason.
> > > 
> > > OK to remove?
> > > 
> > > martijn@
> > > 
> > > Index: usr.bin/snmp/smi.c
> > > ===
> > > RCS file: /cvs/src/usr.bin/snmp/smi.c,v
> > > retrieving revision 1.13
> > > diff -u -p -r1.13 smi.c
> > > --- usr.bin/snmp/smi.c  14 Dec 2020 07:44:26 -  1.13
> > > +++ usr.bin/snmp/smi.c  14 Dec 2020 11:12:29 -
> > > @@ -95,9 +95,6 @@ smi_debug_elements(struct ber_element *r
> > > case BER_TYPE_EOC:
> > > fprintf(stderr, "end-of-content");
> > > break;
> > > -   case BER_TYPE_BOOLEAN:
> > > -   fprintf(stderr, "boolean");
> > > -   break;
> > > case BER_TYPE_INTEGER:
> > > fprintf(stderr, "integer");
> > > break;
> > > @@ -196,9 +193,6 @@ smi_debug_elements(struct ber_element *r
> > > goto invalid;
> > >  
> > > switch (root->be_encoding) {
> > > -   case BER_TYPE_BOOLEAN:
> > > -   fprintf(stderr, "%s", value);
> > > -   break;
> > > case BER_TYPE_INTEGER:
> > > case BER_TYPE_ENUMERATED:
> > > fprintf(stderr, "value %s", value);
> > > @@ -255,7 +249,6 @@ smi_print_element(struct ber_oid *oid, s
> > > struct textconv  tckey;
> > > size_t   len, i, slen;
> > > long long    v, ticks;
> > > -   int  d;
> > > int  is_hex = 0, ret;
> > > struct ber_oid   o;
> > > char strbuf[BUFSIZ];
> > > @@ -277,17 +270,6 @@ smi_print_element(struct ber_oid *oid, s
> > > }
> > >  
> > > switch (root->be_encoding) {
> > > -   case BER_TYPE_BOOLEAN:
> > > -   if (ober_get_boolean(root, ) == -1)
> > > -   goto fail;
> > > -   if (print_hint) {
> > > -   if (asprintf(, "INTEGER: %s(%d)",
> > > -   d ? "true" : "false", d) == -1)
> > > -   goto fail;
> > > -   } else
> > > -   if (asprintf(, "%s", d ? "true" :
> > > "false") == -1)
> > > -   goto fail;
> > > -   break;
> > > case BER_TYPE_INTEGER:
> > > case BER_TYPE_ENUMERATED:
> > > if (ober_get_integer(root, ) == -1)
> > > Index: usr.sbin/snmpd/smi.c
> > > ===
> > > RCS file: /cvs/src/usr.sbin/snmpd/smi.c,v
> > > retrieving revision 1.27
> > > diff -u -p -r1.27 smi.c
> > > --- usr.sbin/snmpd/smi.c24 Oct 2019 12:39:27 -  1.27
> > > +++ usr.sbin/snmpd/smi.c14 Dec 2020 11:12:29 -
> > > @@ -317,9 +317,6 @@ smi_debug_elements(struct ber_element *r
> > > case BER_TYPE_EOC:
> > > fprintf(stderr, "end-of-content");
> > > break;
> > > -   case BER_TYPE_BOOLEAN:
> > > -   fprintf(stderr, "boolean");
> > > -   break;
> > > case BER_TYPE_INTEGER:
> > > fprintf(stderr, "integer");
> > > break;
> > > @@ -417,9 +414,6 @@ smi_debug_elements(struct ber_element *r
> > > goto invalid;
> > >  
> > > switch (root->be_encoding) {
> > > -   case BER_TYPE_BOOLEAN:
> > > -   fprintf(stderr, "%s", value);
> > > -   break;
> > > case BE

Re: snmp - remove BER_TYPE_BOOLEAN

2021-01-03 Thread Martijn van Duren
ping

On Mon, 2020-12-14 at 12:13 +0100, Martijn van Duren wrote:
> I can't find any reference in RFC2578 for a boolean type, nor have I
> seen it in the wild and the TruthValue diff I just committed give me a
> strong indication that this was added without any real reason.
> 
> OK to remove?
> 
> martijn@
> 
> Index: usr.bin/snmp/smi.c
> ===
> RCS file: /cvs/src/usr.bin/snmp/smi.c,v
> retrieving revision 1.13
> diff -u -p -r1.13 smi.c
> --- usr.bin/snmp/smi.c  14 Dec 2020 07:44:26 -  1.13
> +++ usr.bin/snmp/smi.c  14 Dec 2020 11:12:29 -
> @@ -95,9 +95,6 @@ smi_debug_elements(struct ber_element *r
> case BER_TYPE_EOC:
> fprintf(stderr, "end-of-content");
> break;
> -   case BER_TYPE_BOOLEAN:
> -   fprintf(stderr, "boolean");
> -   break;
> case BER_TYPE_INTEGER:
> fprintf(stderr, "integer");
> break;
> @@ -196,9 +193,6 @@ smi_debug_elements(struct ber_element *r
> goto invalid;
>  
> switch (root->be_encoding) {
> -   case BER_TYPE_BOOLEAN:
> -   fprintf(stderr, "%s", value);
> -   break;
> case BER_TYPE_INTEGER:
> case BER_TYPE_ENUMERATED:
> fprintf(stderr, "value %s", value);
> @@ -255,7 +249,6 @@ smi_print_element(struct ber_oid *oid, s
> struct textconv  tckey;
> size_t   len, i, slen;
> long long    v, ticks;
> -   int  d;
> int  is_hex = 0, ret;
> struct ber_oid   o;
> char strbuf[BUFSIZ];
> @@ -277,17 +270,6 @@ smi_print_element(struct ber_oid *oid, s
> }
>  
> switch (root->be_encoding) {
> -   case BER_TYPE_BOOLEAN:
> -   if (ober_get_boolean(root, ) == -1)
> -   goto fail;
> -   if (print_hint) {
> -   if (asprintf(, "INTEGER: %s(%d)",
> -   d ? "true" : "false", d) == -1)
> -   goto fail;
> -   } else
> -   if (asprintf(, "%s", d ? "true" : "false") == -1)
> -   goto fail;
> -   break;
> case BER_TYPE_INTEGER:
> case BER_TYPE_ENUMERATED:
> if (ober_get_integer(root, ) == -1)
> Index: usr.sbin/snmpd/smi.c
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/smi.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 smi.c
> --- usr.sbin/snmpd/smi.c24 Oct 2019 12:39:27 -  1.27
> +++ usr.sbin/snmpd/smi.c14 Dec 2020 11:12:29 -
> @@ -317,9 +317,6 @@ smi_debug_elements(struct ber_element *r
> case BER_TYPE_EOC:
> fprintf(stderr, "end-of-content");
> break;
> -   case BER_TYPE_BOOLEAN:
> -   fprintf(stderr, "boolean");
> -   break;
> case BER_TYPE_INTEGER:
> fprintf(stderr, "integer");
> break;
> @@ -417,9 +414,6 @@ smi_debug_elements(struct ber_element *r
> goto invalid;
>  
> switch (root->be_encoding) {
> -   case BER_TYPE_BOOLEAN:
> -   fprintf(stderr, "%s", value);
> -   break;
> case BER_TYPE_INTEGER:
> case BER_TYPE_ENUMERATED:
> fprintf(stderr, "value %s", value);
> @@ -473,17 +467,10 @@ smi_print_element(struct ber_element *ro
> char*str = NULL, *buf, *p;
> size_t   len, i;
> long long    v;
> -   int  d;
> struct ber_oid   o;
> char strbuf[BUFSIZ];
>  
> switch (root->be_encoding) {
> -   case BER_TYPE_BOOLEAN:
> -   if (ober_get_boolean(root, ) == -1)
> -   goto fail;
> -   if (asprintf(, "%s(%d)", d ? "true" : "false", d) == -1)
> -   goto fail;
> -   break;
> case BER_TYPE_INTEGER:
> case BER_TYPE_ENUMERATED:
> if (ober_get_integer(root, ) == -1)
> 
> 




snmpd(8) make traphandler more secure

2021-01-03 Thread Martijn van Duren
Right now snmpd's traphandler_parse and traphandler_v1translate are just
weird to me and do very little ASN1 checking. Since I want to remove the
traphandler process anyway and the current code structue is in the way,
this diff is a logical first step towards that goal.

The new traphandler_v1translate should now be properly build around
RFC3584 section 3.1 and I've choosen to disable the proxy addition,
since we don't forward it to another host, but it does work for me and
can be enabled for this scenario if people feel strong about it.
Another major change people should be aware of is when running snmpd
with -N the sysUpTime and snmpTrapOID parameters will now be numerical
(where these were hardcode printed before).
A minor thing people should be aware of is that the new code is a lot
more strict on its ASN1 validation, so if you use it with crappy
SNMP entities that send broken packets, you're out of luck.

Also, traphandler_parse is now called only once, which should help in my
next step in removing the traphandler process altogether.

OK?

martijn@

Index: traphandler.c
===
RCS file: /cvs/src/usr.sbin/snmpd/traphandler.c,v
retrieving revision 1.18
diff -u -p -r1.18 traphandler.c
--- traphandler.c   6 Sep 2020 15:51:28 -   1.18
+++ traphandler.c   3 Jan 2021 14:20:17 -
@@ -28,6 +28,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -50,13 +51,12 @@ int  traphandler_bind(struct address *);
 voidtraphandler_recvmsg(int, short, void *);
 int traphandler_priv_recvmsg(struct privsep_proc *, struct imsg *);
 int traphandler_fork_handler(struct privsep_proc *, struct imsg *);
-int traphandler_parse(char *, size_t, struct ber_element **,
-   struct ber_element **, u_int *, struct ber_oid *);
-voidtraphandler_v1translate(struct ber_oid *, u_int, u_int);
-
+int traphandler_parse(struct ber_element *, char *, struct sockaddr *);
+struct ber_element *
+traphandler_v1translate(struct ber_element *, char *, int);
 int trapcmd_cmp(struct trapcmd *, struct trapcmd *);
 voidtrapcmd_exec(struct trapcmd *, struct sockaddr *,
-   struct ber_element *, char *, u_int);
+   struct ber_element *);
 
 char   *traphandler_hostname(struct sockaddr *, int);
 
@@ -102,7 +102,7 @@ traphandler_init(struct privsep *ps, str
/* listen for SNMP trap messages */
TAILQ_FOREACH(h, >sc_addresses, entry) {
event_set(>ev, h->fd, EV_READ|EV_PERSIST,
-   traphandler_recvmsg, ps);
+   traphandler_recvmsg, NULL);
event_add(>ev, NULL);
}
 }
@@ -180,104 +180,216 @@ snmpd_dispatch_traphandler(int fd, struc
 void
 traphandler_recvmsg(int fd, short events, void *arg)
 {
-   struct privsep  *ps = arg;
+   struct ber   ber = {0};
+   struct ber_element  *msg = NULL, *pdu;
char buf[8196];
-   struct iovec iov[2];
struct sockaddr_storage  ss;
socklen_tslen;
ssize_t  n;
-   struct ber_element  *req, *iter;
-   struct ber_oid   trapoid;
-   u_intuptime;
+   int  vers;
+   char*community;
 
slen = sizeof(ss);
if ((n = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *),
)) == -1)
return;
 
-   if (traphandler_parse(buf, n, , , , ) == -1)
-   goto done;
+   ober_set_application(, smi_application);
+   ober_set_readbuf(, buf, n);
 
-   iov[0].iov_base = 
-   iov[0].iov_len = ss.ss_len;
-   iov[1].iov_base = buf;
-   iov[1].iov_len = n;
+   if ((msg = ober_read_elements(, NULL)) == NULL)
+   goto parsefail;
 
-   /* Forward it to the parent process */
-   if (proc_composev(ps, PROC_PARENT, IMSG_ALERT, iov, 2) == -1)
-   goto done;
+   if (ober_scanf_elements(msg, "{dse", , , ) == -1)
+   goto parsefail;
 
- done:
-   if (req != NULL)
-   ober_free_elements(req);
-   return;
+   switch (vers) {
+   case SNMP_V1:
+   if (pdu->be_type != SNMP_C_TRAP)
+   goto parsefail;
+   break;
+   case SNMP_V2:
+   if (pdu->be_type != SNMP_C_TRAPV2)
+   goto parsefail;
+   break;
+   default:
+   goto parsefail;
+   }
+
+   (void)traphandler_parse(pdu, community, (struct sockaddr *));
+
+parsefail:
+   ober_free();
+   if (msg != NULL)
+   ober_free_elements(msg);
 }
 
 /*
  * Validate received message
  */
 int
-traphandler_parse(char *buf, size_t n, struct ber_element **req,
-struct ber_element **vbinds, u_int *uptime, struct ber_oid *trapoid)
+traphandler_parse(struct ber_element *pdu, char 

Re: [diff] src/usr.sbin/smtpd: change process names

2020-12-30 Thread Martijn van Duren
On Tue, 2020-12-29 at 08:57 +0100, Giovanni Bechis wrote:
> On 12/20/20 12:21 AM, gil...@poolp.org wrote:
> > December 19, 2020 11:26 PM, "Martijn van Duren" 
> >  wrote:
> > 
> > > Personally I'd rather wait to keep the names in sync, especially since
> > > it's an easy 2 line diff that can easily be incorperated in the bigger
> > > thing. But it's not something I'm going to loose sleep over if others
> > > thing it can go in right now.
> > > 
> > 
> > Fair enough :-)
> > 
> > Below is the diff that changes all references to pony into dispatcher.
> > 
> > I didn't rename pony.c to dispatcher.c as this would break the diff, but if 
> > this gets
> > committed I'll submit a diff for the rename + Makefile bit
> > 
> I like it and it reads OK for me.
>  Giovanni
> 
Here's the final diff that moves pony.c to dispatcher.c and (including
in smtpd.h).

OK?

martijn@

Index: bounce.c
===
RCS file: /cvs/src/usr.sbin/smtpd/bounce.c,v
retrieving revision 1.82
diff -u -p -r1.82 bounce.c
--- bounce.c24 Apr 2020 11:34:07 -  1.82
+++ bounce.c30 Dec 2020 08:25:55 -
@@ -290,7 +290,7 @@ bounce_drain()
}
 
log_debug("debug: bounce: requesting new enqueue socket...");
-   m_compose(p_pony, IMSG_QUEUE_SMTP_SESSION, 0, 0, -1, NULL, 0);
+   m_compose(p_dispatcher, IMSG_QUEUE_SMTP_SESSION, 0, 0, -1, 
NULL, 0);
 
running += 1;
}
Index: ca.c
===
RCS file: /cvs/src/usr.sbin/smtpd/ca.c,v
retrieving revision 1.36
diff -u -p -r1.36 ca.c
--- ca.c21 Sep 2019 07:46:53 -  1.36
+++ ca.c30 Dec 2020 08:25:55 -
@@ -110,10 +110,10 @@ ca(void)
 
config_peer(PROC_CONTROL);
config_peer(PROC_PARENT);
-   config_peer(PROC_PONY);
+   config_peer(PROC_DISPATCHER);
 
/* Ignore them until we get our config */
-   mproc_disable(p_pony);
+   mproc_disable(p_dispatcher);
 
if (pledge("stdio", NULL) == -1)
err(1, "pledge");
@@ -246,7 +246,7 @@ ca_imsg(struct mproc *p, struct imsg *im
ca_init();
 
/* Start fulfilling requests */
-   mproc_enable(p_pony);
+   mproc_enable(p_dispatcher);
return;
 
case IMSG_CTL_VERBOSE:
@@ -385,7 +385,7 @@ rsae_send_imsg(int flen, const unsigned 
if (n == 0)
break;
 
-   log_imsg(PROC_PONY, PROC_CA, );
+   log_imsg(PROC_DISPATCHER, PROC_CA, );
 
switch (imsg.hdr.type) {
case IMSG_CA_RSA_PRIVENC:
@@ -393,7 +393,7 @@ rsae_send_imsg(int flen, const unsigned 
break;
default:
/* Another imsg is queued up in the buffer */
-   pony_imsg(p_ca, );
+   dispatcher_imsg(p_ca, );
imsg_free();
continue;
}
@@ -569,14 +569,14 @@ ecdsae_send_enc_imsg(const unsigned char
if (n == 0)
break;
 
-   log_imsg(PROC_PONY, PROC_CA, );
+   log_imsg(PROC_DISPATCHER, PROC_CA, );
 
switch (imsg.hdr.type) {
case IMSG_CA_ECDSA_SIGN:
break;
default:
/* Another imsg is queued up in the buffer */
-   pony_imsg(p_ca, );
+   dispatcher_imsg(p_ca, );
imsg_free();
continue;
}
Index: config.c
===
RCS file: /cvs/src/usr.sbin/smtpd/config.c,v
retrieving revision 1.51
diff -u -p -r1.51 config.c
--- config.c18 Dec 2019 10:00:39 -  1.51
+++ config.c30 Dec 2020 08:25:55 -
@@ -325,8 +325,8 @@ config_peer(enum smtp_proc_type proc)
p = p_queue;
else if (proc == PROC_SCHEDULER)
p = p_scheduler;
-   else if (proc == PROC_PONY)
-   p = p_pony;
+   else if (proc == PROC_DISPATCHER)
+   p = p_dispatcher;
else if (proc == PROC_CA)
p = p_ca;
else
Index: control.c
===
RCS file: /cvs/src/usr.sbin/smtpd/control.c,v
retrieving revision 1.125
diff -u -p -r1.125 control.c
--- control.c   23 Sep 2020 19:11:50 -  1.125
+++

Re: smtpd: trim down on filter processes

2020-12-27 Thread Martijn van Duren
On Sun, 2020-12-27 at 11:18 -0700, Theo de Raadt wrote:
> fork_filter_process() does not feel like the right name for
> the function anymore.
> 
Why not? Right now we do fork and call system system in the child.
With my diff we move to fork -> exec

The fork part is most definitely still there. Or do you object to some
other part of the name?

> Take note the exit value of the process (as seen by wait elsewhere) will
> be subtly differe after this conversion from system() to execve().
> Upon failure, rather than being 127, it is now 1.

parent_sig_handler() for the SIGCHLD case does:
if (WEXITSTATUS(status) != 0) {
A little further down we also do:
mda_sysexit = WEXITSTATUS(status);
But mda_sysexit is only used for CHILD_MDA.
So I don't see a reason why this subtle difference matters here.
> 
> Martijn van Duren  wrote:
> 
> > Because filters use system(3) after forking we get 2 processes for every
> > filter: one for waiting for system(3) to return and one running the actual
> > filter.
> > 
> > Since the extra smtpd process does absolutely nothing we can just as easily
> > copy over what system(3) does internally for execve and call the shell
> > command directly.
> > 
> > OK?
> > 
> > martijn@
> > 
> > Index: smtpd.c
> > ===
> > RCS file: /cvs/src/usr.sbin/smtpd/smtpd.c,v
> > retrieving revision 1.335
> > diff -u -p -r1.335 smtpd.c
> > --- smtpd.c 23 Sep 2020 19:11:50 -  1.335
> > +++ smtpd.c 27 Dec 2020 17:39:02 -
> > @@ -1304,7 +1304,9 @@ fork_filter_process(const char *name, co
> > struct passwd   *pw;
> > struct group*gr;
> > char exec[_POSIX_ARG_MAX];
> > +   char*argp[] = { "sh", "-c", exec, NULL };
> > int  execr;
> > +   extern char **environ;
> >  
> > if (user == NULL)
> > user = SMTPD_USER;
> > @@ -1387,11 +1389,8 @@ fork_filter_process(const char *name, co
> >  */
> > if (read(STDERR_FILENO, , 1) != 0)
> > errx(1, "lka didn't properly close write end of error 
> > socket");
> > -   if (system(exec) == -1)
> > -   err(1, NULL);
> > -
> > -   /* there's no successful exit from a processor */
> > -   _exit(1);
> > +   execve(_PATH_BSHELL, argp, environ);
> > +   err(1, "execve");
> >  }
> >  
> >  static void
> > 
> > 




smtpd: trim down on filter processes

2020-12-27 Thread Martijn van Duren
Because filters use system(3) after forking we get 2 processes for every
filter: one for waiting for system(3) to return and one running the actual
filter.

Since the extra smtpd process does absolutely nothing we can just as easily
copy over what system(3) does internally for execve and call the shell
command directly.

OK?

martijn@

Index: smtpd.c
===
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.c,v
retrieving revision 1.335
diff -u -p -r1.335 smtpd.c
--- smtpd.c 23 Sep 2020 19:11:50 -  1.335
+++ smtpd.c 27 Dec 2020 17:39:02 -
@@ -1304,7 +1304,9 @@ fork_filter_process(const char *name, co
struct passwd   *pw;
struct group*gr;
char exec[_POSIX_ARG_MAX];
+   char*argp[] = { "sh", "-c", exec, NULL };
int  execr;
+   extern char **environ;
 
if (user == NULL)
user = SMTPD_USER;
@@ -1387,11 +1389,8 @@ fork_filter_process(const char *name, co
 */
if (read(STDERR_FILENO, , 1) != 0)
errx(1, "lka didn't properly close write end of error socket");
-   if (system(exec) == -1)
-   err(1, NULL);
-
-   /* there's no successful exit from a processor */
-   _exit(1);
+   execve(_PATH_BSHELL, argp, environ);
+   err(1, "execve");
 }
 
 static void




Re: [diff] src/usr.sbin/smtpd: change process names

2020-12-27 Thread Martijn van Duren
In that case fine by me.
Anyone else want to chime in?

On Sun, 2020-12-27 at 17:04 +, gil...@poolp.org wrote:
> it's slightly different:
> 
> ca is for "crypto agent" unsure if there's really an interest in renaming 
> internally,
> furthermore there's a separate crypto API for encrypted queue so not 
> distinguishing
> between crypto api and crypto agent might be confusing.
> 
> Gilles
> 
> 
> December 27, 2020 5:43 PM, "Martijn van Duren" 
>  wrote:
> 
> > This one reads OK to me, with one minor bikeshed:
> > You rename klondike to crypto, but the internals still refer to CA
> > everywhere. Wouldn't it be cleaner to leave klondike in step one and do
> > a s/CA/CRYPTO/ in a second step so everything is in concent?
> > Personally I prefer the name crypto over ca.
> > 
> > martijn@
> > 
> > On Sat, 2020-12-19 at 23:21 +, gil...@poolp.org wrote:
> > 
> > > December 19, 2020 11:26 PM, "Martijn van Duren" 
> > >  wrote:
> > > 
> > > Personally I'd rather wait to keep the names in sync, especially since
> > > it's an easy 2 line diff that can easily be incorperated in the bigger
> > > thing. But it's not something I'm going to loose sleep over if others
> > > thing it can go in right now.
> > > 
> > > Fair enough :-)
> > > 
> > > Below is the diff that changes all references to pony into dispatcher.
> > > 
> > > I didn't rename pony.c to dispatcher.c as this would break the diff, but 
> > > if this gets
> > > committed I'll submit a diff for the rename + Makefile bit
> > > 
> > > diff --git a/usr.sbin/smtpd/bounce.c b/usr.sbin/smtpd/bounce.c
> > > index e6fc55780a1..455da6ff8b1 100644
> > > --- a/usr.sbin/smtpd/bounce.c
> > > +++ b/usr.sbin/smtpd/bounce.c
> > > @@ -290,7 +290,7 @@ bounce_drain()
> > > }
> > > 
> > > log_debug("debug: bounce: requesting new enqueue socket...");
> > > -   m_compose(p_pony, IMSG_QUEUE_SMTP_SESSION, 0, 0, -1, 
> > > NULL, 0);
> > > +   m_compose(p_dispatcher, IMSG_QUEUE_SMTP_SESSION, 0, 0, 
> > > -1, NULL, 0);
> > > 
> > > running += 1;
> > > }
> > > diff --git a/usr.sbin/smtpd/ca.c b/usr.sbin/smtpd/ca.c
> > > index fdc177e28b3..0299ee6cecc 100644
> > > --- a/usr.sbin/smtpd/ca.c
> > > +++ b/usr.sbin/smtpd/ca.c
> > > @@ -110,10 +110,10 @@ ca(void)
> > > 
> > > config_peer(PROC_CONTROL);
> > > config_peer(PROC_PARENT);
> > > -   config_peer(PROC_PONY);
> > > +   config_peer(PROC_DISPATCHER);
> > > 
> > > /* Ignore them until we get our config */
> > > -   mproc_disable(p_pony);
> > > +   mproc_disable(p_dispatcher);
> > > 
> > > if (pledge("stdio", NULL) == -1)
> > > err(1, "pledge");
> > > @@ -246,7 +246,7 @@ ca_imsg(struct mproc *p, struct imsg *imsg)
> > > ca_init();
> > > 
> > > /* Start fulfilling requests */
> > > -   mproc_enable(p_pony);
> > > +   mproc_enable(p_dispatcher);
> > > return;
> > > 
> > > case IMSG_CTL_VERBOSE:
> > > @@ -385,7 +385,7 @@ rsae_send_imsg(int flen, const unsigned char *from, 
> > > unsigned char *to,
> > > if (n == 0)
> > > break;
> > > 
> > > -   log_imsg(PROC_PONY, PROC_CA, );
> > > +   log_imsg(PROC_DISPATCHER, PROC_CA, );
> > > 
> > > switch (imsg.hdr.type) {
> > > case IMSG_CA_RSA_PRIVENC:
> > > @@ -393,7 +393,7 @@ rsae_send_imsg(int flen, const unsigned char *from, 
> > > unsigned char *to,
> > > break;
> > > default:
> > > /* Another imsg is queued up in the buffer */
> > > -   pony_imsg(p_ca, );
> > > +   dispatcher_imsg(p_ca, );
> > > imsg_free();
> > > continue;
> > > }
> > > @@ -569,14 +569,14 @@ ecdsae_send_enc_imsg(const unsigned char *dgst, int 
> > > dgst_len,
> > > if (n == 0)
> > > break;
> > > 
> > > -   log_imsg(PROC_PONY, PROC_CA, );
> > > +   log_imsg(PROC_DISPATCHER, PROC_CA, );
> > > 
> > > switch (imsg.hdr.type) {
> > > case IMSG_CA_ECDSA_SIGN:
> > > break;
> > > default:
> > > /* Another imsg is queued up in the buffer */
> > > - 

Re: [diff] src/usr.sbin/smtpd: change process names

2020-12-27 Thread Martijn van Duren
This one reads OK to me, with one minor bikeshed:
You rename klondike to crypto, but the internals still refer to CA
everywhere. Wouldn't it be cleaner to leave klondike in step one and do
a s/CA/CRYPTO/ in a second step so everything is in concent?
Personally I prefer the name crypto over ca.

martijn@

On Sat, 2020-12-19 at 23:21 +, gil...@poolp.org wrote:
> December 19, 2020 11:26 PM, "Martijn van Duren" 
>  wrote:
> 
> > Personally I'd rather wait to keep the names in sync, especially since
> > it's an easy 2 line diff that can easily be incorperated in the bigger
> > thing. But it's not something I'm going to loose sleep over if others
> > thing it can go in right now.
> > 
> 
> Fair enough :-)
> 
> Below is the diff that changes all references to pony into dispatcher.
> 
> I didn't rename pony.c to dispatcher.c as this would break the diff, but if 
> this gets
> committed I'll submit a diff for the rename + Makefile bit
> 
> 
> 
> diff --git a/usr.sbin/smtpd/bounce.c b/usr.sbin/smtpd/bounce.c
> index e6fc55780a1..455da6ff8b1 100644
> --- a/usr.sbin/smtpd/bounce.c
> +++ b/usr.sbin/smtpd/bounce.c
> @@ -290,7 +290,7 @@ bounce_drain()
> }
>  
> log_debug("debug: bounce: requesting new enqueue socket...");
> -   m_compose(p_pony, IMSG_QUEUE_SMTP_SESSION, 0, 0, -1, NULL, 0);
> +   m_compose(p_dispatcher, IMSG_QUEUE_SMTP_SESSION, 0, 0, -1, 
> NULL, 0);
>  
> running += 1;
> }
> diff --git a/usr.sbin/smtpd/ca.c b/usr.sbin/smtpd/ca.c
> index fdc177e28b3..0299ee6cecc 100644
> --- a/usr.sbin/smtpd/ca.c
> +++ b/usr.sbin/smtpd/ca.c
> @@ -110,10 +110,10 @@ ca(void)
>  
> config_peer(PROC_CONTROL);
> config_peer(PROC_PARENT);
> -   config_peer(PROC_PONY);
> +   config_peer(PROC_DISPATCHER);
>  
> /* Ignore them until we get our config */
> -   mproc_disable(p_pony);
> +   mproc_disable(p_dispatcher);
>  
> if (pledge("stdio", NULL) == -1)
> err(1, "pledge");
> @@ -246,7 +246,7 @@ ca_imsg(struct mproc *p, struct imsg *imsg)
> ca_init();
>  
> /* Start fulfilling requests */
> -   mproc_enable(p_pony);
> +   mproc_enable(p_dispatcher);
> return;
>  
> case IMSG_CTL_VERBOSE:
> @@ -385,7 +385,7 @@ rsae_send_imsg(int flen, const unsigned char *from, 
> unsigned char *to,
> if (n == 0)
> break;
>  
> -   log_imsg(PROC_PONY, PROC_CA, );
> +   log_imsg(PROC_DISPATCHER, PROC_CA, );
>  
> switch (imsg.hdr.type) {
> case IMSG_CA_RSA_PRIVENC:
> @@ -393,7 +393,7 @@ rsae_send_imsg(int flen, const unsigned char *from, 
> unsigned char *to,
> break;
> default:
> /* Another imsg is queued up in the buffer */
> -   pony_imsg(p_ca, );
> +   dispatcher_imsg(p_ca, );
> imsg_free();
> continue;
> }
> @@ -569,14 +569,14 @@ ecdsae_send_enc_imsg(const unsigned char *dgst, int 
> dgst_len,
> if (n == 0)
> break;
>  
> -   log_imsg(PROC_PONY, PROC_CA, );
> +   log_imsg(PROC_DISPATCHER, PROC_CA, );
>  
> switch (imsg.hdr.type) {
> case IMSG_CA_ECDSA_SIGN:
> break;
> default:
> /* Another imsg is queued up in the buffer */
> -   pony_imsg(p_ca, );
> +   dispatcher_imsg(p_ca, );
> imsg_free();
> continue;
> }
> diff --git a/usr.sbin/smtpd/config.c b/usr.sbin/smtpd/config.c
> index 529420ac0f2..2882349ceba 100644
> --- a/usr.sbin/smtpd/config.c
> +++ b/usr.sbin/smtpd/config.c
> @@ -325,8 +325,8 @@ config_peer(enum smtp_proc_type proc)
> p = p_queue;
> else if (proc == PROC_SCHEDULER)
> p = p_scheduler;
> -   else if (proc == PROC_PONY)
> -   p = p_pony;
> +   else if (proc == PROC_DISPATCHER)
> +   p = p_dispatcher;
> else if (proc == PROC_CA)
> p = p_ca;
> else
> diff --git a/usr.sbi

Re: extern int optreset not needed

2020-12-27 Thread Martijn van Duren
OK martijn@

On Sat, 2020-12-26 at 23:24 +0100, Jan Stary wrote:
> ftpd doesn't need to declare extern int optreset
> as that is already done in the included unistd.h
> 
> Jan
> 
> Index: popen.c
> ===
> RCS file: /cvs/src/libexec/ftpd/popen.c,v
> retrieving revision 1.29
> diff -u -p -r1.29 popen.c
> --- popen.c 15 Jan 2020 22:06:59 -  1.29
> +++ popen.c 26 Dec 2020 22:05:49 -
> @@ -113,7 +113,6 @@ ftpd_ls(const char *path, pid_t *pidptr)
> (void)close(pdes[0]);
> closelog();
>  
> -   extern int optreset;
> extern int ls_main(int, char **);
>  
> /* reset getopt for ls_main */
> 




Re: [diff] src/usr.sbin/smtpd: plug a memory leak in regex lookups

2020-12-23 Thread Martijn van Duren
Committed, thanks.

On Wed, 2020-12-23 at 08:54 +0100, Gilles CHEHADE wrote:
> Hello,
> 
> The following diff plugs a memory leak in regex lookups.
> 
> Cheers,
> 
> 
> diff --git a/usr.sbin/smtpd/table.c b/usr.sbin/smtpd/table.c
> index 4691..d1578403 100644
> --- a/usr.sbin/smtpd/table.c
> +++ b/usr.sbin/smtpd/table.c
> @@ -470,6 +470,7 @@ table_regex_match(const char *string, const char *pattern)
>  {
> regex_t preg;
> int cflags = REG_EXTENDED|REG_NOSUB;
> +   int ret;
>  
> if (strncmp(pattern, "(?i)", 4) == 0) {
> cflags |= REG_ICASE;
> @@ -479,7 +480,11 @@ table_regex_match(const char *string, const char 
> *pattern)
> if (regcomp(, pattern, cflags) != 0)
> return (0);
>  
> -   if (regexec(, string, 0, NULL, 0) != 0)
> +   ret = regexec(, string, 0, NULL, 0);
> +
> +   regfree();
> +
> +   if (ret != 0)
> return (0);
>  
> return (1);
> 




smtp(1) add authentication

2020-12-20 Thread Martijn van Duren
Playing around with the filter API I want an easier way to send mail
with authentication instead of doing the transaction manually via
openssl or via bloated mailclients. Turns out we already have all the
plumbing in place and just need to hook it up.

OK?

martijn@

Index: smtpc.c
===
RCS file: /cvs/src/usr.sbin/smtpd/smtpc.c,v
retrieving revision 1.11
diff -u -p -r1.11 smtpc.c
--- smtpc.c 14 Sep 2020 18:32:11 -  1.11
+++ smtpc.c 20 Dec 2020 18:57:13 -
@@ -56,9 +56,8 @@ usage(void)
 {
extern char *__progname;
 
-   fprintf(stderr,
-   "usage: %s [-Chnv] [-F from] [-H helo] [-s server] [-S name] rcpt 
...\n",
-   __progname);
+   fprintf(stderr, "usage: %s [-Chnv] [-F from] [-H helo] [-a authfile] "
+   "[-s server] [-S name] rcpt ...\n", __progname);
exit(1);
 }
 
@@ -66,8 +65,12 @@ int
 main(int argc, char **argv)
 {
char hostname[256];
+   FILE *authfile;
int ch, i;
char *server = "localhost";
+   char *authstr = NULL;
+   size_t alloc = 0;
+   ssize_t len;
struct passwd *pw;
 
log_init(1, 0);
@@ -91,7 +94,7 @@ main(int argc, char **argv)
memset(, 0, sizeof(mail));
mail.from = pw->pw_name;
 
-   while ((ch = getopt(argc, argv, "CF:H:S:hns:v")) != -1) {
+   while ((ch = getopt(argc, argv, "CF:H:S:a:hns:v")) != -1) {
switch (ch) {
case 'C':
params.tls_verify = 0;
@@ -107,6 +110,23 @@ main(int argc, char **argv)
break;
case 'h':
usage();
+   break;
+   case 'a':
+   if ((authfile = fopen(optarg, "r")) == NULL)
+   fatal("%s: open", optarg);
+   if ((len = getline(, , authfile)) == -1)
+   fatal("%s: Failed to read username", optarg);
+   if (authstr[len - 1] == '\n')
+   authstr[len - 1] = '\0';
+   params.auth_user = authstr;
+   authstr = NULL;
+   len = 0;
+   if ((len = getline(, , authfile)) == -1)
+   fatal("%s: Failed to read password", optarg);
+   if (authstr[len - 1] == '\n')
+   authstr[len - 1] = '\0';
+   params.auth_pass = authstr;
+   fclose(authfile);
break;
case 'n':
noaction = 1;
Index: smtp.1
===
RCS file: /cvs/src/usr.sbin/smtpd/smtp.1,v
retrieving revision 1.7
diff -u -p -r1.7 smtp.1
--- smtp.1  4 Jul 2018 08:23:43 -   1.7
+++ smtp.1  20 Dec 2020 18:57:13 -
@@ -25,6 +25,7 @@
 .Op Fl Chnv
 .Op Fl F Ar from
 .Op Fl H Ar helo
+.Op Fl a Ar authfile
 .Op Fl s Ar server
 .Op Ar recipient ...
 .Sh DESCRIPTION
@@ -49,6 +50,13 @@ Set the return-path (MAIL FROM) for the 
 Default to the current username.
 .It Fl H Ar helo
 Define the hostname to advertise (HELO) when establishing the SMTP session.
+.It Fl a Ar authfile
+Perform a login before sending the message.
+The username and password are read from
+.Ar authfile
+and need to be on the first and second line respectively.
+This option requires a TLS or STARTTLS
+.Ar server .
 .It Fl h
 Display version and usage.
 .It Fl n




Re: [diff] src/usr.sbin/smtpd: change process names

2020-12-19 Thread Martijn van Duren
Personally I'd rather wait to keep the names in sync, especially since
it's an easy 2 line diff that can easily be incorperated in the bigger
thing. But it's not something I'm going to loose sleep over if others
thing it can go in right now.

On Sat, 2020-12-19 at 22:22 +, gil...@poolp.org wrote:
> I agree but I thought this should be done in a second time as it is quite
> invasive and not required for the change to be visible outside the daemon
> 
> 
> December 19, 2020 11:13 PM, "Martijn van Duren" 
>  wrote:
> 
> > I'm in favour of this change, since I like proper nomenclature.
> > But I think you should push this one to its logical conclusion and also
> > rename the enum and potential other pony/klondike references, because
> > with your diff the naming is inconsistent, which is even more confusing.
> > 
> > martijn@
> > 
> > On Sat, 2020-12-19 at 22:06 +, gil...@poolp.org wrote:
> > 
> > > Hello,
> > > 
> > > A very long time ago, smtpd had several more processes which then got 
> > > factored
> > > into a single one. We couldn't find a decent name back then but since a 
> > > hacker
> > > had requested a pony from me I temporarily named the process "pony 
> > > express" as
> > > it was in charge of delivering mail. Later, reyk improved the joke as he 
> > > named
> > > the privsep crypto process klondike.
> > > 
> > > A few years ago when the config was reworked, we used the term 
> > > "dispatcher" to
> > > identify if a mail was dispatched to the mda or mta layer.
> > > 
> > > Unless someone is very emotionally attached to the initial joke, I 
> > > suggest the
> > > pony express process be renamed to dispatcher and klondike to crypto. The 
> > > goal
> > > is not just to end the joke but also to avoid a process name with a 
> > > space, and
> > > also because it makes it less obvious what these processes do.
> > > 
> > > diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
> > > index 854c2ab0cb6..b364b22e472 100644
> > > --- a/usr.sbin/smtpd/smtpd.c
> > > +++ b/usr.sbin/smtpd/smtpd.c
> > > @@ -1913,9 +1913,9 @@ proc_title(enum smtp_proc_type proc)
> > > case PROC_SCHEDULER:
> > > return "scheduler";
> > > case PROC_PONY:
> > > -   return "pony express";
> > > +   return "dispatcher";
> > > case PROC_CA:
> > > -   return "klondike";
> > > +   return "crypto";
> > > case PROC_CLIENT:
> > > return "client";
> > > case PROC_PROCESSOR:




Re: [diff] src/usr.sbin/smtpd: change process names

2020-12-19 Thread Martijn van Duren
I'm in favour of this change, since I like proper nomenclature.
But I think you should push this one to its logical conclusion and also
rename the enum and potential other pony/klondike references, because
with your diff the naming is inconsistent, which is even more confusing.

martijn@

On Sat, 2020-12-19 at 22:06 +, gil...@poolp.org wrote:
> Hello,
> 
> A very long time ago, smtpd had several more processes which then got factored
> into a single one. We couldn't find a decent name back then but since a hacker
> had requested a pony from me I temporarily named the process "pony express" as
> it was in charge of delivering mail. Later, reyk improved the joke as he named
> the privsep crypto process klondike.
> 
> A few years ago when the config was reworked, we used the term "dispatcher" to
> identify if a mail was dispatched to the mda or mta layer.
> 
> Unless someone is very emotionally attached to the initial joke, I suggest the
> pony express process be renamed to dispatcher and klondike to crypto. The goal
> is not just to end the joke but also to avoid a process name with a space, and
> also because it makes it less obvious what these processes do.
> 
> 
> diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c
> index 854c2ab0cb6..b364b22e472 100644
> --- a/usr.sbin/smtpd/smtpd.c
> +++ b/usr.sbin/smtpd/smtpd.c
> @@ -1913,9 +1913,9 @@ proc_title(enum smtp_proc_type proc)
> case PROC_SCHEDULER:
> return "scheduler";
> case PROC_PONY:
> -   return "pony express";
> +   return "dispatcher";
> case PROC_CA:
> -   return "klondike";
> +   return "crypto";
> case PROC_CLIENT:
> return "client";
> case PROC_PROCESSOR:
> 




doas sprinkle some more CFLAGS

2020-12-18 Thread Martijn van Duren
So I ended up in doas again, this time with the CFLAGS I use for most of
my other projects. This popped up a few new not very exciting warnings.
Diff below compiles clean with both clang and gcc on amd64.

Worth doing?

martijn@

Index: Makefile
===
RCS file: /cvs/src/usr.bin/doas/Makefile,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile
--- Makefile3 Jul 2017 22:21:47 -   1.3
+++ Makefile18 Dec 2020 21:18:51 -
@@ -9,7 +9,11 @@ BINOWN= root
 BINMODE=4555
 
 CFLAGS+= -I${.CURDIR}
-COPTS+=-Wall
+CFLAGS+= -Wall
+CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
+CFLAGS+= -Wmissing-declarations
+CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
+CFLAGS+= -Wsign-compare
 YFLAGS=
 
 .include 
Index: doas.c
===
RCS file: /cvs/src/usr.bin/doas/doas.c,v
retrieving revision 1.84
diff -u -p -r1.84 doas.c
--- doas.c  9 Oct 2020 07:43:38 -   1.84
+++ doas.c  18 Dec 2020 21:18:51 -
@@ -94,7 +94,7 @@ parsegid(const char *s, gid_t *gid)
 
 static int
 match(uid_t uid, gid_t *groups, int ngroups, uid_t target, const char *cmd,
-const char **cmdargs, struct rule *r)
+const char * const*cmdargs, struct rule *r)
 {
int i;
 
@@ -134,7 +134,7 @@ match(uid_t uid, gid_t *groups, int ngro
 
 static int
 permit(uid_t uid, gid_t *groups, int ngroups, const struct rule **lastr,
-uid_t target, const char *cmd, const char **cmdargs)
+uid_t target, const char *cmd, const char * const*cmdargs)
 {
int i;
 
@@ -188,7 +188,7 @@ checkconfig(const char *confpath, int ar
exit(0);
 
if (permit(uid, groups, ngroups, , target, argv[0],
-   (const char **)argv + 1)) {
+   (const char * const*)argv + 1)) {
printf("permit%s\n", (rule->options & NOPASS) ? " nopass" : "");
exit(0);
} else {
@@ -244,7 +244,7 @@ good:
}
 }
 
-int
+static int
 unveilcommands(const char *ipath, const char *cmd)
 {
char *path = NULL, *p;
@@ -271,7 +271,7 @@ unveilcommands(const char *ipath, const 
 
if (cp) {
int r = snprintf(buf, sizeof buf, "%s/%s", cp, cmd);
-   if (r >= 0 && r < sizeof buf) {
+   if (r >= 0 && (size_t)r < sizeof buf) {
if (unveil(buf, "x") != -1)
unveils++;
}
@@ -394,7 +394,7 @@ main(int argc, char **argv)
 
cmd = argv[0];
if (!permit(uid, groups, ngroups, , target, cmd,
-   (const char **)argv + 1)) {
+   (const char * const*)argv + 1)) {
syslog(LOG_AUTHPRIV | LOG_NOTICE,
"command not permitted for %s: %s", mypw->pw_name, cmdline);
errc(1, EPERM, NULL);
Index: env.c
===
RCS file: /cvs/src/usr.bin/doas/env.c,v
retrieving revision 1.10
diff -u -p -r1.10 env.c
--- env.c   7 Jul 2019 19:21:28 -   1.10
+++ env.c   18 Dec 2020 21:18:51 -
@@ -32,8 +32,8 @@ const char *formerpath;
 
 struct envnode {
RB_ENTRY(envnode) node;
-   const char *key;
-   const char *value;
+   char *key;
+   char *value;
 };
 
 struct env {
Index: parse.y
===
RCS file: /cvs/src/usr.bin/doas/parse.y,v
retrieving revision 1.28
diff -u -p -r1.28 parse.y
--- parse.y 9 Oct 2020 07:43:38 -   1.28
+++ parse.y 18 Dec 2020 21:18:51 -
@@ -56,7 +56,7 @@ static void yyerror(const char *, ...);
 static int yylex(void);
 
 static size_t
-arraylen(const char **arr)
+arraylen(const char * const*arr)
 {
size_t cnt = 0;
 
@@ -222,7 +222,8 @@ int
 yylex(void)
 {
char buf[1024], *ebuf, *p, *str;
-   int i, c, quotes = 0, escape = 0, qpos = -1, nonkw = 0;
+   int c, quotes = 0, escape = 0, qpos = -1, nonkw = 0;
+   size_t i;
 
p = buf;
ebuf = buf + sizeof(buf);




Re: fortune: allow to use symlinks

2020-12-15 Thread Martijn van Duren
On Tue, 2020-12-15 at 15:10 +0300, Vadim Zhukov wrote:
> > I very rarely use fortune and I'm not familiar with the codebase, but
> > from some quick testing and code-scanning I found the following:
> > is_fortfile appends .dat to the input file and sees if it's accessible.
> > Adding a symlink to the corresponding .dat file make the thing work
> > perfectly well for me. Your diff seems to work, because you resolve
> > the path, which in turn gives back the correct location for the .dat,
> > not because symlinks are not suported.
> 
> Thank you very much for review. Indeed, adding second symlink fixes
> the initial issue, so the patch now seems useless...
> 
> > Personally I don't see good reason to add the additional logic which
> > can be solved with a second simple symlink, but if others think it's
> > worth it, comments inline.
> 
> ... but following your comments I've discovered that copy() function
> in fortune.c can return NULL, and that value isn't checked.
> 
> So I'm posting the whole diff for the sake of completeness, and what
> I really think worths committing is the last chunk, replacing "return
> NULL" with "err(1, NULL)" in copy(). Okay for it?

OK martijn@ for this last bit.
> 
> > martijn@
> > 
> > On Tue, 2020-12-15 at 01:09 +0300, Vadim Zhukov wrote:
> > > Hello, all.
> > > 
> > > This allows fortune(6) to open fortune files via symlinks.
> > > Maybe this is a stupid idea, I dunno, but it seems inconsistent
> > > that I can't put a symlink to my fortunes collection in
> > > /usr/share/games/fortune and then simply call "fortune foo"
> > > instead of "fortune /usr/local/share/games/fortune/ru/foo".
> > > 
> > > I decided to call readlink(2) explicitly rather than adding
> > > check of file type being open, since that resulted in less code.
> > > 
> > > Ah, and yes, I have a port of Russian fortune files pending,
> > > but that's for another list and another day.
> > > 
> > > So... okay/notokay anyone? :)
> 
> --
> WBR,
>   Vadim Zhukov
> 
> 
> Index: fortune.c
> ===
> RCS file: /cvs/src/games/fortune/fortune/fortune.c,v
> retrieving revision 1.60
> diff -u -p -r1.60 fortune.c
> --- fortune.c   10 Aug 2017 17:00:08 -  1.60
> +++ fortune.c   15 Dec 2020 11:46:00 -
> @@ -39,6 +39,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -388,8 +389,9 @@ add_file(int percent, char *file, char *
>  FILEDESC *parent)
>  {
> FILEDESC*fp;
> +   ssize_t  lnklen;
> int fd;
> -   char*path, *offensive;
> +   char*path, *offensive, lnkpath[PATH_MAX];
> boolwas_malloc;
> boolisdir;
>  
> @@ -420,8 +422,22 @@ add_file(int percent, char *file, char *
> }
>  
> DPRINTF(1, (stderr, "adding file \"%s\"\n", path));
> +
>  over:
> +   lnklen = readlink(path, lnkpath, sizeof(lnkpath));
> +   if (lnklen == -1) {
> +   if (errno != EINVAL)
> +   goto openfailed;
> +   } else {
> +   lnkpath[lnklen] = '\0';
> +   if (was_malloc)
> +   free(path);
> +   path = copy(lnkpath, NULL);
> +   was_malloc = 1;
> +   }
> +
> if ((fd = open(path, O_RDONLY)) < 0) {
> +openfailed:
> /*
>  * This is a sneak.  If the user said -a, and if the
>  * file we're given isn't a file, we check to see if
> @@ -718,7 +734,7 @@ copy(char *str, char *suf)
> char*new;
>  
> if (asprintf(, "%s%s", str, suf ? suf : "") == -1)
> -   return NULL;
> +   err(1, NULL);
> return new;
>  }
>  




Re: fortune: allow to use symlinks

2020-12-15 Thread Martijn van Duren
I very rarely use fortune and I'm not familiar with the codebase, but
from some quick testing and code-scanning I found the following:
is_fortfile appends .dat to the input file and sees if it's accessible.
Adding a symlink to the corresponding .dat file make the thing work
perfectly well for me. Your diff seems to work, because you resolve
the path, which in turn gives back the correct location for the .dat,
not because symlinks are not suported.

Personally I don't see good reason to add the additional logic which
can be solved with a second simple symlink, but if others think it's
worth it, comments inline.

martijn@

On Tue, 2020-12-15 at 01:09 +0300, Vadim Zhukov wrote:
> Hello, all.
> 
> This allows fortune(6) to open fortune files via symlinks.
> Maybe this is a stupid idea, I dunno, but it seems inconsistent
> that I can't put a symlink to my fortunes collection in
> /usr/share/games/fortune and then simply call "fortune foo"
> instead of "fortune /usr/local/share/games/fortune/ru/foo".
> 
> I decided to call readlink(2) explicitly rather than adding
> check of file type being open, since that resulted in less code.
> 
> Ah, and yes, I have a port of Russian fortune files pending,
> but that's for another list and another day.
> 
> So... okay/notokay anyone? :)
> 
> --
> WBR,
>   Vadim Zhukov
> 
> 
> Index: fortune.c
> ===
> RCS file: /cvs/src/games/fortune/fortune/fortune.c,v
> retrieving revision 1.60
> diff -u -p -r1.60 fortune.c
> --- fortune.c   10 Aug 2017 17:00:08 -  1.60
> +++ fortune.c   14 Dec 2020 22:05:33 -
> @@ -39,6 +39,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -388,8 +389,9 @@ add_file(int percent, char *file, char *
>  FILEDESC *parent)
>  {
> FILEDESC*fp;
> +   ssize_t  lnklen;
> int fd;
> -   char*path, *offensive;
> +   char*path, *offensive, lnkpath[PATH_MAX];
> boolwas_malloc;
> boolisdir;
>  
> @@ -420,8 +422,22 @@ add_file(int percent, char *file, char *
> }
>  
> DPRINTF(1, (stderr, "adding file \"%s\"\n", path));
> +
>  over:
> +   lnklen = readlink(path, lnkpath, PATH_MAX);
I'd prefer sizeof(lnkpath) instead of PATH_MAX, just to be a little more
robust.
> +   if (lnklen == -1) {
> +   if (errno != EINVAL)
> +   goto openfailed;
> +   } else {
> +   lnkpath[lnklen] = '\0';
> +   if (was_malloc)
> +   free(path);
> +   path = strdup(lnkpath);
This needs a NULL-check.
> +   was_malloc = 1;
> +   }
> +
> if ((fd = open(path, O_RDONLY)) < 0) {
> +openfailed:
> /*
>  * This is a sneak.  If the user said -a, and if the
>  * file we're given isn't a file, we check to see if
> 




snmp - remove BER_TYPE_BOOLEAN

2020-12-14 Thread Martijn van Duren
I can't find any reference in RFC2578 for a boolean type, nor have I
seen it in the wild and the TruthValue diff I just committed give me a
strong indication that this was added without any real reason.

OK to remove?

martijn@

Index: usr.bin/snmp/smi.c
===
RCS file: /cvs/src/usr.bin/snmp/smi.c,v
retrieving revision 1.13
diff -u -p -r1.13 smi.c
--- usr.bin/snmp/smi.c  14 Dec 2020 07:44:26 -  1.13
+++ usr.bin/snmp/smi.c  14 Dec 2020 11:12:29 -
@@ -95,9 +95,6 @@ smi_debug_elements(struct ber_element *r
case BER_TYPE_EOC:
fprintf(stderr, "end-of-content");
break;
-   case BER_TYPE_BOOLEAN:
-   fprintf(stderr, "boolean");
-   break;
case BER_TYPE_INTEGER:
fprintf(stderr, "integer");
break;
@@ -196,9 +193,6 @@ smi_debug_elements(struct ber_element *r
goto invalid;
 
switch (root->be_encoding) {
-   case BER_TYPE_BOOLEAN:
-   fprintf(stderr, "%s", value);
-   break;
case BER_TYPE_INTEGER:
case BER_TYPE_ENUMERATED:
fprintf(stderr, "value %s", value);
@@ -255,7 +249,6 @@ smi_print_element(struct ber_oid *oid, s
struct textconv  tckey;
size_t   len, i, slen;
long longv, ticks;
-   int  d;
int  is_hex = 0, ret;
struct ber_oid   o;
char strbuf[BUFSIZ];
@@ -277,17 +270,6 @@ smi_print_element(struct ber_oid *oid, s
}
 
switch (root->be_encoding) {
-   case BER_TYPE_BOOLEAN:
-   if (ober_get_boolean(root, ) == -1)
-   goto fail;
-   if (print_hint) {
-   if (asprintf(, "INTEGER: %s(%d)",
-   d ? "true" : "false", d) == -1)
-   goto fail;
-   } else
-   if (asprintf(, "%s", d ? "true" : "false") == -1)
-   goto fail;
-   break;
case BER_TYPE_INTEGER:
case BER_TYPE_ENUMERATED:
if (ober_get_integer(root, ) == -1)
Index: usr.sbin/snmpd/smi.c
===
RCS file: /cvs/src/usr.sbin/snmpd/smi.c,v
retrieving revision 1.27
diff -u -p -r1.27 smi.c
--- usr.sbin/snmpd/smi.c24 Oct 2019 12:39:27 -  1.27
+++ usr.sbin/snmpd/smi.c14 Dec 2020 11:12:29 -
@@ -317,9 +317,6 @@ smi_debug_elements(struct ber_element *r
case BER_TYPE_EOC:
fprintf(stderr, "end-of-content");
break;
-   case BER_TYPE_BOOLEAN:
-   fprintf(stderr, "boolean");
-   break;
case BER_TYPE_INTEGER:
fprintf(stderr, "integer");
break;
@@ -417,9 +414,6 @@ smi_debug_elements(struct ber_element *r
goto invalid;
 
switch (root->be_encoding) {
-   case BER_TYPE_BOOLEAN:
-   fprintf(stderr, "%s", value);
-   break;
case BER_TYPE_INTEGER:
case BER_TYPE_ENUMERATED:
fprintf(stderr, "value %s", value);
@@ -473,17 +467,10 @@ smi_print_element(struct ber_element *ro
char*str = NULL, *buf, *p;
size_t   len, i;
long longv;
-   int  d;
struct ber_oid   o;
char strbuf[BUFSIZ];
 
switch (root->be_encoding) {
-   case BER_TYPE_BOOLEAN:
-   if (ober_get_boolean(root, ) == -1)
-   goto fail;
-   if (asprintf(, "%s(%d)", d ? "true" : "false", d) == -1)
-   goto fail;
-   break;
case BER_TYPE_INTEGER:
case BER_TYPE_ENUMERATED:
if (ober_get_integer(root, ) == -1)




Re: snmpd drop traphandler process

2020-12-05 Thread Martijn van Duren
Found some minor issues.
Please disregard for now.

On Tue, 2020-12-01 at 17:12 +0100, Martijn van Duren wrote:
> Hello tech@,
> 
> Long story short: the traphandler process in snmpd annoys me a great
> deal and is in the way for overhauling the transport mapping section
> of snmpe, which is needed for implementing new agentx master support.
> 
> The current traphandler process is also a joke, since all it does is
> receive a message, does a minimal parsing validation and then pass
> then entire buffer to the parent process, which forks the actual
> handlers. This means that the current pledgeset is also way too wide
> for what traphandler does.
> 
> Since snmpe already does a similar packet parsing I see no reason to
> keep this initial verification in the traphandler process. The diff
> below drops the traphandler process and moves the receiving of the
> packets to snmpe, which then forwards the pdu (instead of the
> current whole packet) to the parent. I also extended the checking, so
> it should be a little more resilient to malformed packets.
> 
> While here I also didn't like the fact that listening on a trap-port
> always implies that snmp itself is also listening. This diff adds the
> trap keyword (for udp) on the listen on line, so that we can setup a
> traphandler-only setup. This gives the added bonus that we can now
> also choose the port we listen on for traps. Adding a listen trap
> statement requires a trap handle and vice versa.
> 
> It's not the pretties code, but it's a stopgap that allows me to move
> forward without creating even larger diffs and without (hopefully)
> breaking existing setups (apart from the keyword change).
> 
> OK?
> 
> martijn@
> 
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
> retrieving revision 1.62
> diff -u -p -r1.62 parse.y
> --- parse.y 30 Oct 2020 07:43:48 -  1.62
> +++ parse.y 1 Dec 2020 16:12:20 -
> @@ -94,11 +94,9 @@ char *symget(const char *);
>  struct snmpd   *conf = NULL;
>  static int  errors = 0;
>  static struct usmuser  *user = NULL;
> -static char*snmpd_port = SNMPD_PORT;
>  
>  int host(const char *, const char *, int,
>     struct sockaddr_storage *, int);
> -int listen_add(struct sockaddr_storage *, int);
>  
>  typedef struct {
> union {
> @@ -284,13 +282,16 @@ listenproto   : UDP listen_udp
>  listen_udp : STRING port   {
> struct sockaddr_storage ss[16];
> int nhosts, i;
> +   char *port = $2;
>  
> -   nhosts = host($1, $2, SOCK_DGRAM, ss, nitems(ss));
> +   if (port == NULL)
> +   port = SNMPD_PORT;
> +
> +   nhosts = host($1, port, SOCK_DGRAM, ss, nitems(ss));
> if (nhosts < 1) {
> yyerror("invalid address: %s", $1);
> free($1);
> -   if ($2 != snmpd_port)
> -   free($2);
> +   free($2);
> YYERROR;
> }
> if (nhosts > (int)nitems(ss))
> @@ -298,10 +299,38 @@ listen_udp: STRING port   {
>     $1, $2, nitems(ss));
>  
> free($1);
> -   if ($2 != snmpd_port)
> +   free($2);
> +   for (i = 0; i < nhosts; i++) {
> +   if (listen_add(&(ss[i]), SOCK_DGRAM, 0) == 
> -1) {
> +   yyerror("calloc");
> +   YYERROR;
> +   }
> +   }
> +   }
> +   | STRING port TRAP  {
> +   struct sockaddr_storage ss[16];
> +   int nhosts, i;
> +   char *port = $2;
> +
> +   if (port == NULL)
> +   port = SNMPD_TRAPPORT;
> +
> +   nhosts = host($1, port, SOCK_DGRAM, ss, nitems(ss));
> +   if (nhosts < 1) {
> +   yyerror("invalid address: %s", $1);
> +   free($1);
> free($2);
> +   YYERROR;
> 

snmpd drop traphandler process

2020-12-01 Thread Martijn van Duren
Hello tech@,

Long story short: the traphandler process in snmpd annoys me a great
deal and is in the way for overhauling the transport mapping section
of snmpe, which is needed for implementing new agentx master support.

The current traphandler process is also a joke, since all it does is
receive a message, does a minimal parsing validation and then pass
then entire buffer to the parent process, which forks the actual
handlers. This means that the current pledgeset is also way too wide
for what traphandler does.

Since snmpe already does a similar packet parsing I see no reason to
keep this initial verification in the traphandler process. The diff
below drops the traphandler process and moves the receiving of the
packets to snmpe, which then forwards the pdu (instead of the
current whole packet) to the parent. I also extended the checking, so
it should be a little more resilient to malformed packets.

While here I also didn't like the fact that listening on a trap-port
always implies that snmp itself is also listening. This diff adds the
trap keyword (for udp) on the listen on line, so that we can setup a
traphandler-only setup. This gives the added bonus that we can now
also choose the port we listen on for traps. Adding a listen trap
statement requires a trap handle and vice versa.

It's not the pretties code, but it's a stopgap that allows me to move
forward without creating even larger diffs and without (hopefully)
breaking existing setups (apart from the keyword change).

OK?

martijn@

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.62
diff -u -p -r1.62 parse.y
--- parse.y 30 Oct 2020 07:43:48 -  1.62
+++ parse.y 1 Dec 2020 16:12:20 -
@@ -94,11 +94,9 @@ char *symget(const char *);
 struct snmpd   *conf = NULL;
 static int  errors = 0;
 static struct usmuser  *user = NULL;
-static char*snmpd_port = SNMPD_PORT;
 
 int host(const char *, const char *, int,
struct sockaddr_storage *, int);
-int listen_add(struct sockaddr_storage *, int);
 
 typedef struct {
union {
@@ -284,13 +282,16 @@ listenproto   : UDP listen_udp
 listen_udp : STRING port   {
struct sockaddr_storage ss[16];
int nhosts, i;
+   char *port = $2;
 
-   nhosts = host($1, $2, SOCK_DGRAM, ss, nitems(ss));
+   if (port == NULL)
+   port = SNMPD_PORT;
+
+   nhosts = host($1, port, SOCK_DGRAM, ss, nitems(ss));
if (nhosts < 1) {
yyerror("invalid address: %s", $1);
free($1);
-   if ($2 != snmpd_port)
-   free($2);
+   free($2);
YYERROR;
}
if (nhosts > (int)nitems(ss))
@@ -298,10 +299,38 @@ listen_udp: STRING port   {
$1, $2, nitems(ss));
 
free($1);
-   if ($2 != snmpd_port)
+   free($2);
+   for (i = 0; i < nhosts; i++) {
+   if (listen_add(&(ss[i]), SOCK_DGRAM, 0) == -1) {
+   yyerror("calloc");
+   YYERROR;
+   }
+   }
+   }
+   | STRING port TRAP  {
+   struct sockaddr_storage ss[16];
+   int nhosts, i;
+   char *port = $2;
+
+   if (port == NULL)
+   port = SNMPD_TRAPPORT;
+
+   nhosts = host($1, port, SOCK_DGRAM, ss, nitems(ss));
+   if (nhosts < 1) {
+   yyerror("invalid address: %s", $1);
+   free($1);
free($2);
+   YYERROR;
+   }
+   if (nhosts > (int)nitems(ss))
+   log_warn("%s:%s resolves to more than %zu 
hosts",
+   $1, $2, nitems(ss));
+
+   free($1);
+   free($2);
for (i = 0; i < nhosts; i++) {
-   if (listen_add(&(ss[i]), SOCK_DGRAM) == -1) {
+   if (listen_add(&(ss[i]), SOCK_DGRAM,
+   ADDRESS_FLAG_TRAP) == -1) {
yyerror("calloc");
YYERROR;
   

Re: cat(1): simplify/flatten argument loops

2020-11-30 Thread Martijn van Duren
This one reads a lot better to me and even shaves of 2LoC. :-)

OK martijn@

On Mon, 2020-11-30 at 18:28 -0600, Scott Cheloha wrote:
> Hi,
> 
> The cook_args() and raw_args() functions in cat(1) are too clever.
> They handle multiple special cases in a single big loop with lots of
> branches.  It's been like this since at least 1989:
> 
> https://svnweb.freebsd.org/csrg/bin/cat/cat.c?view=markup=37179
> 
> The goal seems to be to avoid calling cook_buf()/raw_cat() from
> multiple places.  I think the result is convoluted.  If we isolated
> the special cases and called cook_buf()/raw_cat() from multiple places
> the result would be simpler and flatter.
> 
> You can break the cleanup in each function into four steps:
> 
> 1. Pull the no-args case out of the loop and handle it first.  Now we
>    don't need to check if (*argv == NULL) in the body of the loop.  One
>    fewer assignment to fp/fd, too.
> 
> 2. In the loop, isolate the (strcmp(*argv, "-") == 0) special case
>    from the normal filename case.  Now we don't need to check whether
>    we're working with stdin when we clean up at the end of a loop
>    iteration.  Setup and cleanup are adjacent, no additional branches
>    needed.
> 
> 3. Pass the file name as an argument to cook_buf() and raw_cat().
>    Now we don't need the global 'filename' variable.  Obviously
>    this means we don't need to assign it a value, either.
> 
> 4. Use a for-loop and move argv iteration into the loop header.
>    Now we increment argv in a single place in the loop.
> 
> Thoughts?
> 
> Index: cat.c
> ===
> RCS file: /cvs/src/bin/cat/cat.c,v
> retrieving revision 1.27
> diff -u -p -r1.27 cat.c
> --- cat.c   28 Jun 2019 13:34:58 -  1.27
> +++ cat.c   1 Dec 2020 00:24:20 -
> @@ -51,12 +51,11 @@ extern char *__progname;
>  
>  int bflag, eflag, nflag, sflag, tflag, vflag;
>  int rval;
> -char *filename;
>  
>  void cook_args(char *argv[]);
> -void cook_buf(FILE *);
> +void cook_buf(FILE *, const char *);
>  void raw_args(char *argv[]);
> -void raw_cat(int);
> +void raw_cat(int, const char *);
>  
>  int
>  main(int argc, char *argv[])
> @@ -110,30 +109,29 @@ cook_args(char **argv)
>  {
> FILE *fp;
>  
> -   fp = stdin;
> -   filename = "stdin";
> -   do {
> -   if (*argv) {
> -   if (!strcmp(*argv, "-"))
> -   fp = stdin;
> -   else if ((fp = fopen(*argv, "r")) == NULL) {
> -   warn("%s", *argv);
> -   rval = 1;
> -   ++argv;
> -   continue;
> -   }
> -   filename = *argv++;
> -   }
> -   cook_buf(fp);
> -   if (fp == stdin)
> +   if (*argv == NULL) {
> +   cook_buf(stdin, "stdin");
> +   return;
> +   }
> +
> +   for (; *argv != NULL; argv++) {
> +   if (!strcmp(*argv, "-")) {
> +   cook_buf(stdin, "stdin");
> clearerr(fp);
> -   else
> -   (void)fclose(fp);
> -   } while (*argv);
> +   continue;
> +   }
> +   if ((fp = fopen(*argv, "r")) == NULL) {
> +   warn("%s", *argv);
> +   rval = 1;
> +   continue;
> +   }
> +   cook_buf(fp, *argv);
> +   (void)fclose(fp);
> +   }
>  }
>  
>  void
> -cook_buf(FILE *fp)
> +cook_buf(FILE *fp, const char *filename)
>  {
> int ch, gobble, line, prev;
>  
> @@ -200,28 +198,28 @@ raw_args(char **argv)
>  {
> int fd;
>  
> -   fd = fileno(stdin);
> -   filename = "stdin";
> -   do {
> -   if (*argv) {
> -   if (!strcmp(*argv, "-"))
> -   fd = fileno(stdin);
> -   else if ((fd = open(*argv, O_RDONLY, 0)) == -1) {
> -   warn("%s", *argv);
> -   rval = 1;
> -   ++argv;
> -   continue;
> -   }
> -   filename = *argv++;
> +   if (*argv == NULL) {
> +   raw_cat(fileno(stdin), "stdin");
> +   return;
> +   }
> +
> +   for(; *argv != NULL; argv++) {
> +   if (!strcmp(*argv, "-")) {
> +   raw_cat(fileno(stdin), "stdin");
> +   continue;
> +   }
> +   if ((fd = open(*argv, O_RDONLY, 0)) == -1) {
> +   warn("%s", *argv);
> +   rval = 1;
> +   continue;
> }
> -   raw_cat(fd);
> -   if (fd != fileno(stdin))
> -   (void)close(fd);
> - 

snmp trap usage

2020-11-30 Thread Martijn van Duren
I missed an argc check which causes snmp trap to segfault if called with
too few arguments instead of showing usage.

OK?

martijn@

Index: snmpc.c
===
RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
retrieving revision 1.30
diff -u -p -r1.30 snmpc.c
--- snmpc.c 14 Sep 2020 15:12:27 -  1.30
+++ snmpc.c 30 Nov 2020 16:25:24 -
@@ -788,6 +788,9 @@ snmpc_trap(int argc, char *argv[])
if (version == SNMP_V1)
errx(1, "trap is not supported for snmp v1");
 
+   if (argc < 3)
+   usage();
+
if ((agent = snmpc_connect(argv[0], "162")) == NULL)
err(1, "%s", snmp_app->name);
 




Re: kvm_getfiles and KERN_FILE_BYFILE

2020-11-29 Thread Martijn van Duren
On Sun, 2020-11-29 at 16:15 -0800, Philip Guenther wrote:
> On Sun, Nov 29, 2020 at 12:14 PM Martijn van Duren 
>  wrote:
> > On Sat, 2020-11-28 at 16:23 -0800, Philip Guenther wrote:
> > > On Thu, Nov 26, 2020 at 1:08 PM Martijn van Duren 
> > >  wrote:
> > > > I'm currently playing around a bit with kvm_getfiles and found that I
> > > > couldn't use KERN_FILE_BYFILE with DTYPE_SOCKET.
> > > > According to kvm_getfiles(3):
> > > >      For KERN_FILE_BYFILE the recognized file types are defined in
> > > >      :
> > > > 
> > > >            DTYPE_VNODE           files and devices
> > > >            DTYPE_SOCKET          sockets, regardless of domain
> > > >            DTYPE_PIPE            pipes and FIFOs
> > > >            DTYPE_KQUEUE          kqueues
> > > > 
> > > > But these defines are under ifdef _KERNEL.
> > > > 
> > > > So is the manpage lying here, or should the defines be hoisted out
> > > > of the ifdef?
> > > > 
> > > 
> > > 
> > > Let's go ahead and hoist them: FreeBSD and NetBSD already have.  If 
> > > possible, the diff to do that should also simplify the #include bits in 
> > > these files:
> > >     usr.bin/netstat/inet.c
> > >     usr.bin/fstat/fstat.c
> > >     usr.bin/fstat/fuser.c
> > >     usr.bin/systat/netstat.c
> > > 
> > > 
> > > Philip Guenther
> > > 
> > 
> > The others have the #endif/#ifdef break rather low in the file.
> > Personally I reckon it's better reading if the common code is more
> > towards the top.
> > 
> > OK?
> > 
> 
> 
> ok guenther@
> 
> How do the userland clean up bits look?
> 
> 
> Philip Guenther
> 

Something like this?

Index: fstat/fstat.c
===
RCS file: /cvs/src/usr.bin/fstat/fstat.c,v
retrieving revision 1.101
diff -u -p -r1.101 fstat.c
--- fstat/fstat.c   22 Aug 2020 18:34:29 -  1.101
+++ fstat/fstat.c   30 Nov 2020 07:17:51 -
@@ -55,9 +55,7 @@
 #include 
 #include 
 #include 
-#define _KERNEL /* for DTYPE_* */
 #include 
-#undef _KERNEL
 
 #include 
 #include 
Index: fstat/fuser.c
===
RCS file: /cvs/src/usr.bin/fstat/fuser.c,v
retrieving revision 1.8
diff -u -p -r1.8 fuser.c
--- fstat/fuser.c   25 Jan 2019 00:19:26 -  1.8
+++ fstat/fuser.c   30 Nov 2020 07:17:51 -
@@ -45,9 +45,7 @@
 #include 
 #include 
 #include 
-#define _KERNEL /* for DTYPE_VNODE */
 #include 
-#undef _KERNEL
 
 #include 
 #include 
Index: systat/netstat.c
===
RCS file: /cvs/src/usr.bin/systat/netstat.c,v
retrieving revision 1.45
diff -u -p -r1.45 netstat.c
--- systat/netstat.c12 Mar 2015 01:03:00 -  1.45
+++ systat/netstat.c30 Nov 2020 07:17:51 -
@@ -38,9 +38,7 @@
 #include 
 #include 
 #include 
-#define _KERNEL
 #include 
-#undef _KERNEL
 
 #include 
 #include 
Index: netstat/inet.c
===
RCS file: /cvs/src/usr.bin/netstat/inet.c,v
retrieving revision 1.168
diff -u -p -r1.168 inet.c
--- netstat/inet.c  15 Jan 2020 14:02:37 -  1.168
+++ netstat/inet.c  30 Nov 2020 07:17:51 -
@@ -37,9 +37,7 @@
 #include 
 #include 
 #include 
-#define _KERNEL
 #include 
-#undef _KERNEL
 
 #include 
 #include 




Re: kvm_getfiles and KERN_FILE_BYFILE

2020-11-29 Thread Martijn van Duren
On Sat, 2020-11-28 at 16:23 -0800, Philip Guenther wrote:
> On Thu, Nov 26, 2020 at 1:08 PM Martijn van Duren 
>  wrote:
> > I'm currently playing around a bit with kvm_getfiles and found that I
> > couldn't use KERN_FILE_BYFILE with DTYPE_SOCKET.
> > According to kvm_getfiles(3):
> >      For KERN_FILE_BYFILE the recognized file types are defined in
> >      :
> > 
> >            DTYPE_VNODE           files and devices
> >            DTYPE_SOCKET          sockets, regardless of domain
> >            DTYPE_PIPE            pipes and FIFOs
> >            DTYPE_KQUEUE          kqueues
> > 
> > But these defines are under ifdef _KERNEL.
> > 
> > So is the manpage lying here, or should the defines be hoisted out
> > of the ifdef?
> > 
> 
> 
> Let's go ahead and hoist them: FreeBSD and NetBSD already have.  If possible, 
> the diff to do that should also simplify the #include bits in these files:
>     usr.bin/netstat/inet.c
>     usr.bin/fstat/fstat.c
>     usr.bin/fstat/fuser.c
>     usr.bin/systat/netstat.c
> 
> 
> Philip Guenther
> 

The others have the #endif/#ifdef break rather low in the file.
Personally I reckon it's better reading if the common code is more
towards the top.

OK?

martijn@

Index: file.h
===
RCS file: /cvs/src/sys/sys/file.h,v
retrieving revision 1.61
diff -u -p -r1.61 file.h
--- file.h  13 Mar 2020 10:07:01 -  1.61
+++ file.h  29 Nov 2020 20:12:30 -
@@ -38,7 +38,15 @@
 #else /* _KERNEL */
 #include 
 #include 
+#endif /* _KERNEL */
 
+#defineDTYPE_VNODE 1   /* file */
+#defineDTYPE_SOCKET2   /* communications endpoint */
+#defineDTYPE_PIPE  3   /* pipe */
+#defineDTYPE_KQUEUE4   /* event queue */
+#defineDTYPE_DMABUF5   /* DMA buffer (for DRM) */
+
+#ifdef _KERNEL
 struct proc;
 struct uio;
 struct knote;
@@ -80,11 +88,6 @@ struct file {
LIST_ENTRY(file) f_list;/* [F] list of active files */
struct mutex f_mtx;
u_int   f_flag; /* [a] see fcntl.h */
-#defineDTYPE_VNODE 1   /* file */
-#defineDTYPE_SOCKET2   /* communications endpoint */
-#defineDTYPE_PIPE  3   /* pipe */
-#defineDTYPE_KQUEUE4   /* event queue */
-#defineDTYPE_DMABUF5   /* DMA buffer (for DRM) */
u_int   f_iflags;   /* [a] internal flags */
int f_type; /* [I] descriptor type */
u_int   f_count;/* [a] reference count */




kvm_getfiles and KERN_FILE_BYFILE

2020-11-26 Thread Martijn van Duren
I'm currently playing around a bit with kvm_getfiles and found that I
couldn't use KERN_FILE_BYFILE with DTYPE_SOCKET.
According to kvm_getfiles(3):
 For KERN_FILE_BYFILE the recognized file types are defined in
 :

   DTYPE_VNODE   files and devices
   DTYPE_SOCKET  sockets, regardless of domain
   DTYPE_PIPEpipes and FIFOs
   DTYPE_KQUEUE  kqueues

But these defines are under ifdef _KERNEL.

So is the manpage lying here, or should the defines be hoisted out
of the ifdef?

martijn@



Minor tweak relayd agentx manpage

2020-10-30 Thread Martijn van Duren
I think metrics is a better word than statistics and it might help
people if they knew where to query for these metrics.

OK?
martijn@

Index: relayd.conf.5
===
RCS file: /cvs/src/usr.sbin/relayd/relayd.conf.5,v
retrieving revision 1.201
diff -u -p -r1.201 relayd.conf.5
--- relayd.conf.5   22 Oct 2020 08:00:24 -  1.201
+++ relayd.conf.5   30 Oct 2020 08:48:23 -
@@ -121,10 +121,12 @@ Here are the settings that can be set gl
 .It Ic agentx Oo Ic context Ar context Oc Oo Ic path Ar path Oc
 Export
 .Xr relayd 8
-statistics via an agentx compatible
+metrics via an agentx compatible
 .Pq snmp
 daemon by connecting to
 .Ar path .
+Metrics can be found under the relaydMIBObjects subtree
+.Pq enterprises.30155.3 .
 If
 .Ar path
 is omitted it will default to



snmpd(8) Remove old listen on syntax

2020-10-29 Thread Martijn van Duren
6.8 has been released. Time to remove the old syntax.

OK?

martijn@

? dispatcher_tm_udp.c
Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.61
diff -u -p -r1.61 parse.y
--- parse.y 10 Sep 2020 17:54:47 -  1.61
+++ parse.y 29 Oct 2020 15:14:24 -
@@ -130,7 +130,7 @@ typedef struct {
 %token   NUMBER
 %typehostcmn
 %typesrcaddr port
-%typeoptwrite yesno seclevel proto
+%typeoptwrite yesno seclevel
 %type  objtype cmd
 %type   oid hostoid trapoid
 %type  auth
@@ -279,7 +279,7 @@ main: LISTEN ON listenproto
 
 listenproto: UDP listen_udp
| TCP listen_tcp
-   | listen_empty
+   | listen_udp
 
 listen_udp : STRING port   {
struct sockaddr_storage ss[16];
@@ -335,34 +335,6 @@ listen_tcp : STRING port   {
}
}
 
-/* Remove after deprecation period and replace with listen_udp */
-listen_empty   : STRING port proto {
-   struct sockaddr_storage ss[16];
-   int nhosts, i;
-
-   nhosts = host($1, $2, $3, ss, nitems(ss));
-   if (nhosts < 1) {
-   yyerror("invalid address: %s", $1);
-   free($1);
-   if ($2 != snmpd_port)
-   free($2);
-   YYERROR;
-   }
-   if (nhosts > (int)nitems(ss))
-   log_warn("%s:%s resolves to more than %zu 
hosts",
-   $1, $2, nitems(ss));
-
-   free($1);
-   if ($2 != snmpd_port)
-   free($2);
-   for (i = 0; i < nhosts; i++) {
-   if (listen_add(&(ss[i]), $3) == -1) {
-   yyerror("calloc");
-   YYERROR;
-   }
-   }
-   }
-
 port   : /* empty */   {
$$ = snmpd_port;
}
@@ -385,21 +357,6 @@ port   : /* empty */   {
YYERROR;
}
$$ = number;
-   }
-   ;
-
-proto  : /* empty */   {
-   $$ = SOCK_DGRAM;
-   }
-   | UDP   {
-   log_warnx("udp as last keyword on listen on line is "
-   "deprecated");
-   $$ = SOCK_DGRAM;
-   }
-   | TCP   {
-   log_warnx("tcp as last keyword on listen on line is "
-   "deprecated");
-   $$ = SOCK_STREAM;
}
;
 



relayd(8) remove snmp keyword

2020-10-29 Thread Martijn van Duren
6.8 is out in the wild. I guess this is as good a time as any to remove
the old snmp keyword.

OK?

martijn@

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/relayd/parse.y,v
retrieving revision 1.248
diff -u -p -r1.248 parse.y
--- parse.y 26 Oct 2020 16:52:06 -  1.248
+++ parse.y 29 Oct 2020 14:49:54 -
@@ -175,15 +175,15 @@ typedef struct {
 %token LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT PATH
 %token PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE
 %token REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND
-%token SESSION SNMP SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
-%token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT TRAP URL WITH TTL RTABLE
+%token SESSION SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP
+%token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE
 %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE
 %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS
 %token WEBSOCKETS
 %token   STRING
 %token   NUMBER
-%typecontext hostname interface table value optstring path
-%typehttp_type loglevel quick trap
+%typecontext hostname interface table value path
+%typehttp_type loglevel quick
 %typedstmode flag forwardmode retry
 %typeopttls opttlsclient
 %typeredirect_proto relay_proto match
@@ -457,23 +457,6 @@ main   : INTERVAL NUMBER   {
AGENTX_MASTER_PATH,
sizeof(conf->sc_conf.agentx_path));
}
-   | SNMP trap optstring   {
-   log_warnx("The snmp keyword is deprecated, please use 
agentx");
-   conf->sc_conf.flags |= F_AGENTX;
-   if ($3) {
-   if (strlcpy(conf->sc_conf.agentx_path,
-   $3, sizeof(conf->sc_conf.agentx_path)) >=
-   sizeof(conf->sc_conf.agentx_path)) {
-   yyerror("agentx path truncated");
-   free($3);
-   YYERROR;
-   }
-   free($3);
-   } else
-   (void)strlcpy(conf->sc_conf.agentx_path,
-   "/var/run/agentx.sock",
-   sizeof(conf->sc_conf.agentx_path));
-   }
| SOCKET STRING {
conf->sc_ps->ps_csock.cs_name = $2;
}
@@ -485,9 +468,6 @@ path: /* nothing */ { $$ = NULL; }
 context: /* nothing */ { $$ = NULL; }
| CONTEXT STRING{ $$ = $2; }
 
-trap   : /* nothing */ { $$ = 0; }
-   | TRAP  { $$ = 1; }
-
 loglevel   : STATE CHANGES { $$ = RELAYD_OPT_LOGUPDATE; }
| HOST CHECKS   { $$ = RELAYD_OPT_LOGHOSTCHECK; }
| CONNECTION{ $$ = (RELAYD_OPT_LOGCON |
@@ -2371,10 +2351,6 @@ optnl: '\n' optnl
 
 nl : '\n' optnl
;
-
-optstring  : STRING{ $$ = $1; }
-   | /* nothing */ { $$ = NULL; }
-   ;
 %%
 
 struct keywords {
@@ -2499,7 +2475,6 @@ lookup(char *s)
{ "send",   SEND },
{ "session",SESSION },
{ "set",SET },
-   { "snmp",   SNMP },
{ "socket", SOCKET },
{ "source-hash",SRCHASH },
{ "splice", SPLICE },
@@ -2516,7 +2491,6 @@ lookup(char *s)
{ "tls",TLS },
{ "to", TO },
{ "transparent",TRANSPARENT },
-   { "trap",   TRAP },
{ "ttl",TTL },
{ "url",URL },
{ "value",  VALUE },



Re: libagentx add agentx_varbind_unsigned32

2020-10-27 Thread Martijn van Duren
On Tue, 2020-10-27 at 19:09 +0100, Martijn van Duren wrote:
> To prevent any future confusion around unsigned ints I'd like to add
> agentx_varbind_unsigned32 as an alias to agentx_varbind_gauge32.
> 
> According to RFC 2578 section 2:
> -- an unsigned 32-bit quantity
> -- indistinguishable from Gauge32
> 
> OK?
> Still OK to ride yesterdays bump?
> 
> martijn@
> 
And of course the manpage bits:

Index: agentx.3
===
RCS file: /cvs/src/lib/libagentx/agentx.3,v
retrieving revision 1.3
diff -u -p -r1.3 agentx.3
--- agentx.327 Oct 2020 17:33:05 -  1.3
+++ agentx.327 Oct 2020 18:15:39 -
@@ -62,6 +62,7 @@
 .Nm agentx_varbind_ipaddress ,
 .Nm agentx_varbind_counter32 ,
 .Nm agentx_varbind_gauge32 ,
+.Nm agentx_varbind_unsigned32 ,
 .Nm agentx_varbind_timeticks ,
 .Nm agentx_varbind_opaque ,
 .Nm agentx_varbind_counter64 ,
@@ -222,6 +223,8 @@
 .Ft void
 .Fn agentx_varbind_gauge32 "struct agentx_varbind *sav" "uint32_t value"
 .Ft void
+.Fn agentx_varbind_unsigned32 "struct agentx_varbind *sav" "uint32_t value"
+.Ft void
 .Fo agentx_varbind_timeticks
 .Fa "struct agentx_varbind *sav"  "uint32_t value"
 .Fc
@@ -517,6 +520,8 @@ Set the return value to ipaddress.
 Set the return value to an uint32_t of type counter32.
 .It Fn agentx_varbind_gauge32
 Set the return value to an uint32_t of type gauge32.
+.It Fn agentx_varbind_unsigned32
+A wrapper around agentx_varbind_gauge32.
 .It Fn agentx_varbind_timeticks
 Set the return value to an uint32_t of type timeticks.
 .It Fn agentx_varbind_opaque



libagentx add agentx_varbind_unsigned32

2020-10-27 Thread Martijn van Duren
To prevent any future confusion around unsigned ints I'd like to add
agentx_varbind_unsigned32 as an alias to agentx_varbind_gauge32.

According to RFC 2578 section 2:
-- an unsigned 32-bit quantity
-- indistinguishable from Gauge32

OK?
Still OK to ride yesterdays bump?

martijn@

Index: Symbols.list
===
RCS file: /cvs/src/lib/libagentx/Symbols.list,v
retrieving revision 1.2
diff -u -p -r1.2 Symbols.list
--- Symbols.list26 Oct 2020 15:45:56 -  1.2
+++ Symbols.list27 Oct 2020 18:08:51 -
@@ -42,6 +42,7 @@ agentx_varbind_index
 agentx_varbind_ipaddress
 agentx_varbind_counter32
 agentx_varbind_gauge32
+agentx_varbind_unsigned32
 agentx_varbind_timeticks
 agentx_varbind_opaque
 agentx_varbind_counter64
Index: agentx.c
===
RCS file: /cvs/src/lib/libagentx/agentx.c,v
retrieving revision 1.7
diff -u -p -r1.7 agentx.c
--- agentx.c27 Oct 2020 17:19:44 -  1.7
+++ agentx.c27 Oct 2020 18:08:51 -
@@ -3152,6 +3152,12 @@ agentx_varbind_gauge32(struct agentx_var
 }
 
 void
+agentx_varbind_unsigned32(struct agentx_varbind *axv, uint32_t value)
+{
+   agentx_varbind_gauge32(axv, value);
+}
+
+void
 agentx_varbind_timeticks(struct agentx_varbind *axv, uint32_t value)
 {
axv->axv_vb.avb_type = AX_DATA_TYPE_TIMETICKS;
Index: agentx.h
===
RCS file: /cvs/src/lib/libagentx/agentx.h,v
retrieving revision 1.4
diff -u -p -r1.4 agentx.h
--- agentx.h27 Oct 2020 17:19:44 -  1.4
+++ agentx.h27 Oct 2020 18:08:51 -
@@ -116,6 +116,7 @@ void agentx_varbind_ipaddress(struct age
 const struct in_addr *);
 void agentx_varbind_counter32(struct agentx_varbind *, uint32_t);
 void agentx_varbind_gauge32(struct agentx_varbind *, uint32_t);
+void agentx_varbind_unsigned32(struct agentx_varbind *, uint32_t);
 void agentx_varbind_timeticks(struct agentx_varbind *, uint32_t);
 void agentx_varbind_opaque(struct agentx_varbind *, const char *, size_t);
 void agentx_varbind_counter64(struct agentx_varbind *, uint64_t);



libagentx use variable for malloc argument

2020-10-26 Thread Martijn van Duren
OK?

martijn@

Index: ax.c
===
RCS file: /cvs/src/lib/libagentx/ax.c,v
retrieving revision 1.2
diff -u -p -r1.2 ax.c
--- ax.c26 Oct 2020 16:02:16 -  1.2
+++ ax.c26 Oct 2020 18:07:30 -
@@ -69,9 +69,9 @@ ax_new(int fd)
if ((ax = calloc(1, sizeof(*ax))) == NULL)
return NULL;
ax->ax_fd = fd;
-   if ((ax->ax_rbuf = malloc(512)) == NULL)
-   goto fail;
ax->ax_rbsize = 512;
+   if ((ax->ax_rbuf = malloc(ax->ax_rbsize)) == NULL)
+   goto fail;
ax->ax_byteorder = AX_BYTE_ORDER_NATIVE;
 
return ax;



Let relayd use libagentx

2020-10-26 Thread Martijn van Duren
Mostly mechanical diff coping with the API-change for libagentx
just committed and link it to libagentx instead of using its own
copy.

This also allows for the removal of {sub,}agentx.[ch]
subagentx_internal.h and subagentx_log.c, not included in the diff.

OK?

martijn@

Index: Makefile
===
RCS file: /cvs/src/usr.sbin/relayd/Makefile,v
retrieving revision 1.34
diff -u -p -r1.34 Makefile
--- Makefile14 Sep 2020 11:30:25 -  1.34
+++ Makefile26 Oct 2020 16:19:09 -
@@ -2,15 +2,14 @@
 
 PROG=  relayd
 SRCS=  parse.y
-SRCS+= agentx.c agentx_control.c ca.c carp.c check_icmp.c \
-   check_script.c check_tcp.c check_tls.c config.c control.c \
-   hce.c log.c name2id.c pfe.c pfe_filter.c pfe_route.c proc.c \
-   relay.c relay_http.c relay_udp.c relayd.c \
-   shuffle.c ssl.c subagentx.c subagentx_log.c util.c
+SRCS+= agentx_control.c ca.c carp.c check_icmp.c check_script.c \
+   check_tcp.c check_tls.c config.c control.c hce.c log.c \
+   name2id.c pfe.c pfe_filter.c pfe_route.c proc.c relay.c \
+   relay_http.c relay_udp.c relayd.c shuffle.c ssl.c util.c
 MAN=   relayd.8 relayd.conf.5
 
-LDADD= -levent -ltls -lssl -lcrypto -lutil
-DPADD= ${LIBEVENT} ${LIBSSL} ${LIBCRYPTO} ${LIBUTIL}
+LDADD= -lagentx -levent -ltls -lssl -lcrypto -lutil
+DPADD= ${LIBAGENTX} ${LIBEVENT} ${LIBSSL} ${LIBCRYPTO} ${LIBUTIL}
 CFLAGS+=   -Wall -I${.CURDIR}
 CFLAGS+=   -Wstrict-prototypes -Wmissing-prototypes
 CFLAGS+=   -Wmissing-declarations
Index: agentx_control.c
===
RCS file: /cvs/src/usr.sbin/relayd/agentx_control.c,v
retrieving revision 1.2
diff -u -p -r1.2 agentx_control.c
--- agentx_control.c25 Oct 2020 10:17:49 -  1.2
+++ agentx_control.c26 Oct 2020 16:19:09 -
@@ -37,7 +37,7 @@
 #include 
 
 #include "relayd.h"
-#include "subagentx.h"
+#include 
 
 #define RELAYD_MIB "1.3.6.1.4.1.30155.3"
 #define SNMP_ELEMENT(x...) do {\
@@ -52,7 +52,7 @@ static struct snmp_oidhosttrapoid = {
 };
 */
 
-#define RELAYDINFO SUBAGENTX_ENTERPRISES, 30155, 3, 2
+#define RELAYDINFO AGENTX_ENTERPRISES, 30155, 3, 2
 #define RELAYDREDIRECTSRELAYDINFO, 1
 #define RELAYDREDIRECTENTRYRELAYDREDIRECTS, 1
 #define RELAYDREDIRECTINDEXRELAYDREDIRECTENTRY, 1
@@ -124,69 +124,69 @@ static struct snmp_oidhosttrapoid = {
 #define RELAYDTABLENAMERELAYDTABLEENTRY, 2
 #define RELAYDTABLESTATUS  RELAYDTABLEENTRY, 3
 
-void agentx_needsock(struct subagentx *, void *, int);
+void agentx_needsock(struct agentx *, void *, int);
 
 struct relayd *env;
 
-struct subagentx *sa = NULL;
-struct subagentx_index *relaydRedirectIdx, *relaydRelayIdx;
-struct subagentx_index *relaydRouterIdx, *relaydNetRouteIdx;
-struct subagentx_index *relaydHostIdx, *relaydSessionRelayIdx;
-struct subagentx_index *relaydSessionIdx, *relaydTableIdx;
-
-struct subagentx_object *relaydRedirectIndex, *relaydRedirectStatus;
-struct subagentx_object *relaydRedirectName, *relaydRedirectCnt;
-struct subagentx_object *relaydRedirectAvg, *relaydRedirectLast;
-struct subagentx_object *relaydRedirectAvgHour, *relaydRedirectLastHour;
-struct subagentx_object *relaydRedirectAvgDay, *relaydRedirectLastDay;
-
-struct subagentx_object *relaydRelayIndex, *relaydRelayStatus;
-struct subagentx_object *relaydRelayName, *relaydRelayCnt;
-struct subagentx_object *relaydRelayAvg, *relaydRelayLast;
-struct subagentx_object *relaydRelayAvgHour, *relaydRelayLastHour;
-struct subagentx_object *relaydRelayAvgDay, *relaydRelayLastDay;
-
-struct subagentx_object *relaydRouterIndex, *relaydRouterTableIndex;
-struct subagentx_object *relaydRouterStatus, *relaydRouterName;
-struct subagentx_object *relaydRouterLabel, *relaydRouterRtable;
-
-struct subagentx_object *relaydNetRouteIndex, *relaydNetRouteAddr;
-struct subagentx_object *relaydNetRouteAddrType, *relaydNetRoutePrefixLen;
-struct subagentx_object *relaydNetRouteRouterIndex;
-
-struct subagentx_object *relaydHostIndex, *relaydHostParentIndex;
-struct subagentx_object *relaydHostTableIndex, *relaydHostName;
-struct subagentx_object *relaydHostAddress, *relaydHostAddressType;
-struct subagentx_object *relaydHostStatus, *relaydHostCheckCnt;
-struct subagentx_object *relaydHostUpCnt, *relaydHostErrno;
-
-struct subagentx_object *relaydSessionIndex, *relaydSessionRelayIndex;
-struct subagentx_object *relaydSessionInAddr, *relaydSessionInAddrType;
-struct subagentx_object *relaydSessionOutAddr, *relaydSessionOutAddrType;
-struct subagentx_object *relaydSessionPortIn, *relaydSessionPortOut;
-struct subagentx_object *relaydSessionAge, *relaydSessionIdle;
-struct subagentx_object *relaydSessionStatus, *relaydSessionPid;
+struct agentx *sa 

Re: ping(8) put hop_limit warning in verbose mode

2020-10-20 Thread Martijn van Duren
On Tue, 2020-10-20 at 15:59 +0200, Florian Obser wrote:
> On Tue, Oct 20, 2020 at 03:46:19PM +0200, Martijn van Duren wrote:
> > On Tue, 2020-10-20 at 15:19 +0200, Florian Obser wrote:
> > > On Tue, Oct 20, 2020 at 09:20:32AM +0200, Martijn van Duren wrote:
> > > > I have an icinga-instance running on openbsd.amsterdam. Here I found
> > > > that sometimes check_ping from the monitoring-plugins package fails,
> > > > because ping(8) sends "failed to get receiving hop limit", but still
> > > > receives all the ping replies. These packets/annomalies are clearly
> > > > not meant for us.
> > > 
> > > But it is. This is comming from the local machine,
> > > see L949ff of netinet6/ip6_input.c.
> > 
> > What I meant to say is meant for ping(8). All the icmp echo replies
> > still arrive and are accounted for.
> > 
> 
> I don't understand.
> 
> I patched the kernel to make sbcreatecontrol() fail 50% of the time:
> 
> $ ping6 -qc10 fe80::5667:51ff:fede:e7ce%vio0
> PING fe80::5667:51ff:fede:e7ce%vio0 (fe80::5667:51ff:fede:e7ce%vio0): 56 data 
> bytes
> ping6: failed to get receiving hop limit
> ping6: failed to get receiving hop limit
> ping6: failed to get receiving hop limit
> ping6: failed to get receiving hop limit
> 
> --- fe80::5667:51ff:fede:e7ce%vio0 ping statistics ---
> 10 packets transmitted, 6 packets received, 40.0% packet loss
> round-trip min/avg/max/std-dev = 0.980/1.196/1.955/0.342 ms
> 
> I assure you, I do not have 40% packet loss towards my gateway.
> The packets are not accounted for.
> 
When running:
/usr/local/libexec/nagios/check_ping -vv -6 -H  -c 500,75% -w 250,50%
in a tight loop at some point I get the following output:

CMD: /sbin/ping6 -n -c 5 
Output: PING  (): 56 data bytes
Output: 64 bytes from : icmp_seq=0 hlim=57 time=1.724 ms
Output: 64 bytes from : icmp_seq=1 hlim=57 time=1.612 ms
Output: 64 bytes from : icmp_seq=2 hlim=57 time=1.785 ms
Output: 64 bytes from : icmp_seq=3 hlim=57 time=1.762 ms
Output: 64 bytes from : icmp_seq=4 hlim=57 time=1.708 ms
Output:
Output: ---  ping statistics ---
Output: 5 packets transmitted, 5 packets received, 0.0% packet loss
Output: round-trip min/avg/max/std-dev = 1.612/1.718/1.785/0.060 ms
Got stderr: ping6: failed to get receiving hop limit
PING WARNING - System call sent warnings to stderr Packet loss = 0%, RTA = 1.72 
ms|rta=1.718000ms;3000.00;5000.00;0.00 pl=0%;80;100;0
3000.00:80% 5000.00:100%

So I have 5 echo requests, 5 echo replies and one unrelated packet not
related to my ping command. Yet this notice to stderr forces check_ping
into a warning state.



Re: ping(8) put hop_limit warning in verbose mode

2020-10-20 Thread Martijn van Duren
On Tue, 2020-10-20 at 15:19 +0200, Florian Obser wrote:
> On Tue, Oct 20, 2020 at 09:20:32AM +0200, Martijn van Duren wrote:
> > I have an icinga-instance running on openbsd.amsterdam. Here I found
> > that sometimes check_ping from the monitoring-plugins package fails,
> > because ping(8) sends "failed to get receiving hop limit", but still
> > receives all the ping replies. These packets/annomalies are clearly
> > not meant for us.
> 
> But it is. This is comming from the local machine,
> see L949ff of netinet6/ip6_input.c.

What I meant to say is meant for ping(8). All the icmp echo replies
still arrive and are accounted for.

> sbcreatecontrol() fails because it tries to allocate space with
> M_DONTWAIT. Looks like you drove your system out of resources.

I see nothing in dmesg or the logs. Is there another to verify this?
And assuming it is indeed run out of resources, is there a way to
fix this, because the (virtual) hardware doesn't looks swamped.
> 
> While the local system receives all replies and passes them on to
> ping6(8) they are not counted as received. So ping6(8) will report
> packet loss while there is none.

In this case it's the other way around: warnings are being generated,
but all icmp echo replies are received intact by ping(8). But I
understand your point. The question remains then how I can debug this
further.

> I think it's a mistake to hide the warning because it will lead people
> on a wild goose chase.
> Also since ping6(8) will report packet loss I'm not conviced this will
> solve your problem.
> 
> > Since this check is done before the ICMP6_ECHO_REPLY check and our
> > manpage states:
> > -v  Verbose output.  ICMP packets other than ECHO_REPLY that are
> > received are listed.
> > I think the following diff is warranted and solves my false warning
> > states.
> > 
> > OK?
> > 
> > martijn@
> > 
> > Index: ping.c
> > ===
> > RCS file: /cvs/src/sbin/ping/ping.c,v
> > retrieving revision 1.240
> > diff -u -p -r1.240 ping.c
> > --- ping.c  11 Feb 2020 18:41:39 -  1.240
> > +++ ping.c  20 Oct 2020 07:19:49 -
> > @@ -1180,7 +1180,8 @@ pr_pack(u_char *buf, int cc, struct msgh
> > icp6 = (struct icmp6_hdr *)buf;
> >  
> > if ((hoplim = get_hoplim(mhdr)) == -1) {
> > -   warnx("failed to get receiving hop limit");
> > +   if (options & F_VERBOSE)
> > +   warnx("failed to get receiving hop limit");
> > return;
> > }
> >  
> > 



ping(8) put hop_limit warning in verbose mode

2020-10-20 Thread Martijn van Duren
I have an icinga-instance running on openbsd.amsterdam. Here I found
that sometimes check_ping from the monitoring-plugins package fails,
because ping(8) sends "failed to get receiving hop limit", but still
receives all the ping replies. These packets/annomalies are clearly
not meant for us.

Since this check is done before the ICMP6_ECHO_REPLY check and our
manpage states:
-v  Verbose output.  ICMP packets other than ECHO_REPLY that are
received are listed.
I think the following diff is warranted and solves my false warning
states.

OK?

martijn@

Index: ping.c
===
RCS file: /cvs/src/sbin/ping/ping.c,v
retrieving revision 1.240
diff -u -p -r1.240 ping.c
--- ping.c  11 Feb 2020 18:41:39 -  1.240
+++ ping.c  20 Oct 2020 07:19:49 -
@@ -1180,7 +1180,8 @@ pr_pack(u_char *buf, int cc, struct msgh
icp6 = (struct icmp6_hdr *)buf;
 
if ((hoplim = get_hoplim(mhdr)) == -1) {
-   warnx("failed to get receiving hop limit");
+   if (options & F_VERBOSE)
+   warnx("failed to get receiving hop limit");
return;
}
 



Re: Non-const basename: usr.bin/sed

2020-10-10 Thread Martijn van Duren
On Sat, 2020-10-10 at 17:21 +0200, Christian Weisgerber wrote:
> Changing basename(3) and dirname(3) to the POSIX-mandated non-const
> parameters produces this warnings when compiling sed(1):
> 
> /usr/src/usr.bin/sed/main.c:401:16: warning: passing 'const char *' to 
> parameter
>  of type 'char *' discards qualifiers 
> [-Wincompatible-pointer-types-discards-qua
> lifiers]
> 
> Here's a fix to accommodate a basename(3) that takes a non-const
> parameter and may in fact modify the string buffer.  Based on FreeBSD
> like the surrounding in-place editing code.
> 
> OK?
> 
Wouldn't the following diff be a little simpler?
No need to check the return value of strlcpy, since we do a lstat
before, which can return a ENAMETOOLONG.

martijn@

Index: main.c
===
RCS file: /cvs/src/usr.bin/sed/main.c,v
retrieving revision 1.40
diff -u -p -r1.40 main.c
--- main.c  8 Dec 2018 23:11:24 -   1.40
+++ main.c  10 Oct 2020 17:51:53 -
@@ -343,6 +343,7 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
 {
struct stat sb;
size_t len;
+   char dirbuf[PATH_MAX];
char *p;
int c, fd;
static int firstfile;
@@ -397,8 +398,9 @@ mf_fgets(SPACE *sp, enum e_spflag spflag
if (len > sizeof(oldfname))
error(FATAL, "%s: name too long", 
fname);
}
-   len = snprintf(tmpfname, sizeof(tmpfname), 
"%s/sedXX",
-   dirname(fname));
+   strlcpy(dirbuf, fname, sizeof(dirbuf));
+   len = snprintf(tmpfname, sizeof(tmpfname),
+   "%s/sedXX", dirname(dirbuf));
if (len >= sizeof(tmpfname))
error(FATAL, "%s: name too long", fname);
if ((fd = mkstemp(tmpfname)) == -1)



pthread_spin_unlock and ownership behaviour

2020-10-03 Thread Martijn van Duren
Back in 2012 kurt@ added an abort call for the undefined behaviour cases
on pthread_mutex_unlock. This helped me a great deal in examining the
cause of some weird behaviour in icinga (or in the case of openbsd, just
plain crash).

For shits and giggles I deceided to look into pthread_spin_unlock and
saw that we return EPERM here, while POSIX states that this behaviour
is unconditionally undefined.[0] Is there a reason why we shouldn't
abort here as well?

I don't have a particular usecase for this, but the mutex case helped me
and it only seems like the right thing to do from a semetrical point of
view. The only cases of pthread_spin_unlock in base I found were in
libunbound (which with my testing with unwind didn't caused any issues)
and gnu/llvm/compiler-rt/lib/tsan, which I don't know where to test.
I have no idea which ports use it.

martijn@

[0] 
https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_spin_unlock.html

Index: librthread/rthread_spin_lock.c
===
RCS file: /cvs/src/lib/librthread/rthread_spin_lock.c,v
retrieving revision 1.5
diff -u -p -r1.5 rthread_spin_lock.c
--- librthread/rthread_spin_lock.c  6 Apr 2020 00:01:08 -   1.5
+++ librthread/rthread_spin_lock.c  3 Oct 2020 09:42:21 -
@@ -102,12 +102,12 @@ pthread_spin_unlock(pthread_spinlock_t *
pthread_spinlock_t l;
 
if (lock == NULL || *lock == NULL)
-   return (EINVAL);
+   abort();
 
l = *lock;
 
if (l->owner != self)
-   return (EPERM);
+   abort();
 
l->owner = NULL;
_spinunlock(>lock);
Index: libpthread/man/pthread_spin_unlock.3
===
RCS file: /cvs/src/lib/libpthread/man/pthread_spin_unlock.3,v
retrieving revision 1.3
diff -u -p -r1.3 pthread_spin_unlock.3
--- libpthread/man/pthread_spin_unlock.36 Apr 2020 00:01:08 -   
1.3
+++ libpthread/man/pthread_spin_unlock.33 Oct 2020 09:42:21 -
@@ -38,17 +38,14 @@ functions.
 .Sh RETURN VALUES
 If successful,
 .Fn pthread_spin_unlock
-returns zero; otherwise an error number is returned to indicate the error.
+returns zero.
 .Sh ERRORS
 .Fn pthread_spin_unlock
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
+will call
+.Xr abort 3
+if the value specified by
 .Fa lock
-is invalid.
-.It Bq Er EPERM
-The lock is not owned by the calling thread.
+is invalid or if the lock is not owned by the calling thread.
 .El
 .Sh SEE ALSO
 .Xr pthread_spin_init 3 ,



snmp(1) Add support for printing human readable enums

2020-09-20 Thread Martijn van Duren
SNMP contains quite a few enumerations, which are annoying to read, even
if you have the MIB at hand. This diff adds support for integer
enumerations. I've only implemented TruthValue for now, but others
should be easy to add. I went for a normal linear search since most
enums don't even hit 10 elements, comparison is int-based and thus the
added complexity of something like RB_* seems like enormous overkill.

I've removed BER_TYPE_BOOLEAN, since it's not part of the SNMP-spec and
thus dead code. I added it originally because snmpd's smi.c contained
it.

I should probably rewrite smi_print_element at some point, but I'm not
confident enough in its intricacies to make that jump just yet. One
thing at a time.

OK?

martijn@

Index: mib.h
===
RCS file: /cvs/src/usr.bin/snmp/mib.h,v
retrieving revision 1.8
diff -u -p -r1.8 mib.h
--- mib.h   12 Sep 2020 18:11:43 -  1.8
+++ mib.h   20 Sep 2020 15:23:48 -
@@ -1034,8 +1034,8 @@
{ MIBDECL(ifHCOutBroadcastPkts) },  \
{ MIBDECL(ifLinkUpDownTrapEnable) },\
{ MIBDECL(ifHighSpeed) },   \
-   { MIBDECL(ifPromiscuousMode) }, \
-   { MIBDECL(ifConnectorPresent) },\
+   { MIBDECL(ifPromiscuousMode), "TruthValue" },   \
+   { MIBDECL(ifConnectorPresent), "TruthValue" },  \
{ MIBDECL(ifAlias) },   \
{ MIBDECL(ifCounterDiscontinuityTime) },\
{ MIBDECL(ifStackTable) },  \
@@ -1460,10 +1460,15 @@
{ MIBEND }  \
 }
 
-#define TEXTCONV_TREE {\
-   { "SnmpAdminString", "255t", BER_TYPE_OCTETSTRING }, \
-   { "DisplayString", "255a", BER_TYPE_OCTETSTRING }, \
-   { NULL, NULL }  \
+#define TEXTCONV_TREE {
\
+   { "SnmpAdminString", BER_TYPE_OCTETSTRING, "255t" },\
+   { "DisplayString", BER_TYPE_OCTETSTRING, "255a" },  \
+   { "TruthValue", BER_TYPE_INTEGER, NULL, (struct textconv_enum[]){\
+   { 1, "true" },  \
+   { 2, "false" }, \
+   {}  \
+   }}, \
+   {  }\
 }
 
 voidmib_init(void);
Index: smi.c
===
RCS file: /cvs/src/usr.bin/snmp/smi.c,v
retrieving revision 1.12
diff -u -p -r1.12 smi.c
--- smi.c   8 Aug 2020 13:02:54 -   1.12
+++ smi.c   20 Sep 2020 15:23:48 -
@@ -39,6 +39,7 @@
 #define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
 
 char *smi_displayhint_os(struct textconv *, int, const char *, size_t, int);
+char *smi_displayhint_int(struct textconv*, int, long long);
 
 int smi_oid_cmp(struct oid *, struct oid *);
 int smi_key_cmp(struct oid *, struct oid *);
@@ -254,7 +255,6 @@ smi_print_element(struct ber_oid *oid, s
struct textconv  tckey;
size_t   len, i, slen;
long longv, ticks;
-   int  d;
int  is_hex = 0, ret;
struct ber_oid   o;
char strbuf[BUFSIZ];
@@ -276,17 +276,6 @@ smi_print_element(struct ber_oid *oid, s
}
 
switch (root->be_encoding) {
-   case BER_TYPE_BOOLEAN:
-   if (ober_get_boolean(root, ) == -1)
-   goto fail;
-   if (print_hint) {
-   if (asprintf(, "INTEGER: %s(%d)",
-   d ? "true" : "false", d) == -1)
-   goto fail;
-   } else
-   if (asprintf(, "%s", d ? "true" : "false") == -1)
-   goto fail;
-   break;
case BER_TYPE_INTEGER:
case BER_TYPE_ENUMERATED:
if (ober_get_integer(root, ) == -1)
@@ -345,6 +334,10 @@ smi_print_element(struct ber_oid *oid, s
break;
}
hint = "INTEGER: ";
+   if (object != NULL && object->o_textconv != NULL &&
+   object->o_textconv->tc_syntax == root->be_encoding)
+   return smi_displayhint_int(object->o_textconv,
+   print_hint, v);
if (root->be_class == BER_CLASS_APPLICATION) {
if (root->be_type == SNMP_T_COUNTER32)
hint = "Counter32: ";
@@ -628,6 +621,31 @@ smi_foreach(struct oid *oid)
if (oid == NULL)
return RB_MIN(oidtree, _oidtree);
return RB_NEXT(oidtree, _oidtree, oid);
+}
+
+char *

Re: Fwd: opensmtpd can't handle long lines in aliases table

2020-09-18 Thread Martijn van Duren
That's what you get if you're doing a quick diff on the job.
Missed a free case which is in Edgar's original diff.

Noticed by tb@

On Fri, 2020-09-18 at 14:46 +0200, Martijn van Duren wrote:
> Could you try the diff below?
> It should do exactly the same thing with less code.
> 
> martijn@
> 
> On Fri, 2020-09-18 at 08:30 -0400, Aisha Tammy wrote:
> > Hi,
> > 
> >   Edgar (cc'ed) has kindly provided patches to fix a buffer error in 
> > mailaddr.c
> > for opensmtpd.
> > 
> > I've minimally tested it and am forwarding the patches.
> > 
> > Would like to be able to get them into 6.8 release as this is quite 
> > problematic 
> > with lots of aliases.
> > 
> > Thanks,
> > Aisha
> > 
> > 
> >  Forwarded Message 
> > Subject: Re: opensmtpd can't handle long lines in aliases table
> > Date: Thu, 6 Aug 2020 19:47:33 -0500
> > From: Edgar Pettijohn 
> > To: AIsha Tammy 
> > 
> > Here are a few simple patches as discussed. These were written to apply
> > against current. However, they are pretty simple and may well apply to
> > others. With that in mind if you are using any filters they may not
> > work. My production system is still a couple version behind and the
> > current smtpd wouldn't work with some of my custom filters. So I had to
> > use a fairly basic temporary config for testing. I'm also including my
> > test  table.
> > 
> > Steps involved: (untested off memory mostly, use doas as necessary)
> > 
> > cd /usr
> > cvs -d $CVSROOT checkout src
> > 
> > cp *.patch /usr/src/usr.sbin/smtpd
> > cd /usr/src/usr.sbin/smtpd
> > 
> > for file in `ls *.patch`
> > do
> > patch < $file
> > done
> > 
> > make
> > rcctl stop smtpd
> > 
> > #use the just built version at /usr/src/usr.sbin/smtpd/smtpd/smtpd
> > smtpd/smtpd -d -T expand
> > 
> > send a test email
> > 
> > if all goes well run it for an appropriat amount of time and make sure
> > there are not issues. If your satisfied send the patches to bugs@.
> > 
> > Enjoy,
> > 
> > Edgar
> > 
Index: mailaddr.c
===
RCS file: /cvs/src/usr.sbin/smtpd/mailaddr.c,v
retrieving revision 1.3
diff -u -p -r1.3 mailaddr.c
--- mailaddr.c  31 May 2018 21:06:12 -  1.3
+++ mailaddr.c  18 Sep 2020 12:55:41 -
@@ -80,12 +80,10 @@ int
 mailaddr_line(struct maddrmap *maddrmap, const char *s)
 {
struct maddrnodemn;
-   charbuffer[LINE_MAX];
-   char   *p, *subrcpt;
+   char   *p, *subrcpt, *buffer;
int ret;
 
-   memset(buffer, 0, sizeof buffer);
-   if (strlcpy(buffer, s, sizeof buffer) >= sizeof buffer)
+   if ((buffer = strdup(s)) == NULL)
return 0;
 
p = buffer;
@@ -93,11 +91,15 @@ mailaddr_line(struct maddrmap *maddrmap,
subrcpt = strip(subrcpt);
if (subrcpt[0] == '\0')
continue;
-   if (!text_to_mailaddr(, subrcpt))
+   if (!text_to_mailaddr(, subrcpt)) {
+   free(buffer);
return 0;
+   }
log_debug("subrcpt: [%s]", subrcpt);
maddrmap_insert(maddrmap, );
}
+
+   free(buffer);
 
if (ret >= 0)
return 1;



Re: Fwd: opensmtpd can't handle long lines in aliases table

2020-09-18 Thread Martijn van Duren
Could you try the diff below?
It should do exactly the same thing with less code.

martijn@

On Fri, 2020-09-18 at 08:30 -0400, Aisha Tammy wrote:
> Hi,
> 
>   Edgar (cc'ed) has kindly provided patches to fix a buffer error in 
> mailaddr.c
> for opensmtpd.
> 
> I've minimally tested it and am forwarding the patches.
> 
> Would like to be able to get them into 6.8 release as this is quite 
> problematic 
> with lots of aliases.
> 
> Thanks,
> Aisha
> 
> 
>  Forwarded Message 
> Subject: Re: opensmtpd can't handle long lines in aliases table
> Date: Thu, 6 Aug 2020 19:47:33 -0500
> From: Edgar Pettijohn 
> To: AIsha Tammy 
> 
> Here are a few simple patches as discussed. These were written to apply
> against current. However, they are pretty simple and may well apply to
> others. With that in mind if you are using any filters they may not
> work. My production system is still a couple version behind and the
> current smtpd wouldn't work with some of my custom filters. So I had to
> use a fairly basic temporary config for testing. I'm also including my
> test  table.
> 
> Steps involved: (untested off memory mostly, use doas as necessary)
> 
> cd /usr
> cvs -d $CVSROOT checkout src
> 
> cp *.patch /usr/src/usr.sbin/smtpd
> cd /usr/src/usr.sbin/smtpd
> 
> for file in `ls *.patch`
> do
> patch < $file
> done
> 
> make
> rcctl stop smtpd
> 
> #use the just built version at /usr/src/usr.sbin/smtpd/smtpd/smtpd
> smtpd/smtpd -d -T expand
> 
> send a test email
> 
> if all goes well run it for an appropriat amount of time and make sure
> there are not issues. If your satisfied send the patches to bugs@.
> 
> Enjoy,
> 
> Edgar
> 
> 

Index: mailaddr.c
===
RCS file: /cvs/src/usr.sbin/smtpd/mailaddr.c,v
retrieving revision 1.3
diff -u -p -r1.3 mailaddr.c
--- mailaddr.c  31 May 2018 21:06:12 -  1.3
+++ mailaddr.c  18 Sep 2020 12:45:46 -
@@ -80,12 +80,10 @@ int
 mailaddr_line(struct maddrmap *maddrmap, const char *s)
 {
struct maddrnodemn;
-   charbuffer[LINE_MAX];
-   char   *p, *subrcpt;
+   char   *p, *subrcpt, *buffer;
int ret;
 
-   memset(buffer, 0, sizeof buffer);
-   if (strlcpy(buffer, s, sizeof buffer) >= sizeof buffer)
+   if ((buffer = strdup(s)) == NULL)
return 0;
 
p = buffer;
@@ -98,6 +96,8 @@ mailaddr_line(struct maddrmap *maddrmap,
log_debug("subrcpt: [%s]", subrcpt);
maddrmap_insert(maddrmap, );
}
+
+   free(buffer);
 
if (ret >= 0)
return 1;



syslogd close higher fds on pipe exec

2020-09-16 Thread Martijn van Duren
I don't think we should keep these fds around on exec.

OK?

Index: privsep.c
===
RCS file: /cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.71
diff -u -p -r1.71 privsep.c
--- privsep.c   5 Jul 2019 13:23:27 -   1.71
+++ privsep.c   16 Sep 2020 09:59:36 -
@@ -519,6 +519,7 @@ open_pipe(char *cmd)
 
if (dup2(fd[0], STDIN_FILENO) == -1)
err(1, "dup2 failed");
+   closefrom(STDERR_FILENO + 1);
if (execv("/bin/sh", argp) == -1)
err(1, "execv %s", cmd);
/* NOTREACHED */



agentx in services

2020-09-15 Thread Martijn van Duren
I currently don't see any reason for adding agentx over tcp support to
our daemons, but according to RFC2741 section 8.1.1 it should go over
"wel-known port 705".

Worth adding or just drop it?

martijn@

Index: services
===
RCS file: /cvs/src/etc/services,v
retrieving revision 1.97
diff -u -p -r1.97 services
--- services26 Jun 2020 19:51:14 -  1.97
+++ services15 Sep 2020 09:43:00 -
@@ -175,6 +175,7 @@ ldaps   636/tcp # LDAP 
over SSL
 ldaps  636/udp
 ldp646/tcp
 ldp646/udp
+agentx 705/tcp
 silc   706/tcp # Secure Live Internet 
Conferencing
 silc   706/udp
 kerberos-adm   749/tcp # Kerberos 5 kadmin



Re: agentx and clang static analyzer

2020-09-15 Thread Martijn van Duren
> > Index: subagentx.c
> > ===
> > RCS file: /cvs/src/usr.sbin/relayd/subagentx.c,v
> > retrieving revision 1.1
> > diff -u -p -r1.1 subagentx.c
> > --- subagentx.c 14 Sep 2020 11:30:25 -  1.1
> > +++ subagentx.c 15 Sep 2020 09:05:58 -
> > @@ -2929,7 +2929,7 @@ getnext:
> > index->sav_idatacomplete = 1;
> > break;
> > case AGENTX_DATA_TYPE_IPADDRESS:
> > -   ipaddress = calloc(1, sizeof(ipaddress));
> > +   ipaddress = calloc(1, sizeof(*ipaddress));
> > if (ipaddress == NULL) {
> > subagentx_log_sag_warn(sag,
> > "Failed to bind ipaddress index");
> 
> Not ok for this, it's probably correct, but there are other instances of this
> in this code and so you need to engage brain, not static analyzer, go fix or
> don't fix them all in a separate commit. 
> 
Could only find one more:

Index: subagentx.c
===
RCS file: /cvs/src/usr.sbin/relayd/subagentx.c,v
retrieving revision 1.1
diff -u -p -r1.1 subagentx.c
--- subagentx.c 14 Sep 2020 11:30:25 -  1.1
+++ subagentx.c 15 Sep 2020 09:27:46 -
@@ -2929,7 +2929,7 @@ getnext:
index->sav_idatacomplete = 1;
break;
case AGENTX_DATA_TYPE_IPADDRESS:
-   ipaddress = calloc(1, sizeof(ipaddress));
+   ipaddress = calloc(1, sizeof(*ipaddress));
if (ipaddress == NULL) {
subagentx_log_sag_warn(sag,
"Failed to bind ipaddress index");
@@ -2951,7 +2951,7 @@ getnext:
}
if (j <= sav->sav_vb.avb_oid.aoi_idlen)
index->sav_idatacomplete = 1;
-   data->avb_ostring.aos_slen = sizeof(ipaddress);
+   data->avb_ostring.aos_slen = sizeof(*ipaddress);
data->avb_ostring.aos_string =
(unsigned char *)ipaddress;
break;



agentx and clang static analyzer

2020-09-15 Thread Martijn van Duren
There are 3 things that actually look like valid complaints when running
clang's static analyzer.

1) A dead store in agentx_recv.
2) sizeof(ipaddress) intead of sizeof(*ipaddress). Since this is ipv4,
   this is only a problem if sizeof(pointer) is smaller then 4 bytes,
   which can't happen afaik.
3) dst does indeed need to be dereffed, but since dstlen and buflen are
   initialized to 0 and srclen is practically always larger then 0
   we're fine. I'm keeping the *dst here as an additional safeguard.

The rest seem like false positives to me.

OK?

martijn@

Index: agentx.c
===
RCS file: /cvs/src/usr.sbin/relayd/agentx.c,v
retrieving revision 1.16
diff -u -p -r1.16 agentx.c
--- agentx.c14 Sep 2020 11:30:25 -  1.16
+++ agentx.c15 Sep 2020 09:05:57 -
@@ -135,7 +135,6 @@ agentx_recv(struct agentx *ax)
header.aph_packetid = agentx_pdutoh32(, u8);
u8 += 4;
header.aph_plength = agentx_pdutoh32(, u8);
-   u8 += 4;
 
if (header.aph_version != 1) {
errno = EPROTO;
Index: subagentx.c
===
RCS file: /cvs/src/usr.sbin/relayd/subagentx.c,v
retrieving revision 1.1
diff -u -p -r1.1 subagentx.c
--- subagentx.c 14 Sep 2020 11:30:25 -  1.1
+++ subagentx.c 15 Sep 2020 09:05:58 -
@@ -2929,7 +2929,7 @@ getnext:
index->sav_idatacomplete = 1;
break;
case AGENTX_DATA_TYPE_IPADDRESS:
-   ipaddress = calloc(1, sizeof(ipaddress));
+   ipaddress = calloc(1, sizeof(*ipaddress));
if (ipaddress == NULL) {
subagentx_log_sag_warn(sag,
"Failed to bind ipaddress index");
@@ -3833,7 +3833,7 @@ subagentx_strcat(char **dst, const char 
}
 
srclen = strlen(src);
-   if (dst == NULL || dstlen + srclen > buflen) {
+   if (*dst == NULL || dstlen + srclen > buflen) {
nbuflen = (((dstlen + srclen) / 512) + 1) * 512;
tmp = recallocarray(*dst, buflen, nbuflen, sizeof(*tmp));
if (tmp == NULL)



snmp request specific OIDs from mibtree

2020-09-14 Thread Martijn van Duren
Sometimes I want to know the OID from a name and vice versa.
I'm done doing these by hand. Diff below does this for me:

$ ./obj/snmp mibtree -On snmpTrapOID.0
.1.3.6.1.6.3.1.1.4.1.0

OK?

martijn@

Index: snmp.1
===
RCS file: /cvs/src/usr.bin/snmp/snmp.1,v
retrieving revision 1.14
diff -u -p -r1.14 snmp.1
--- snmp.1  8 Aug 2020 07:11:47 -   1.14
+++ snmp.1  14 Sep 2020 14:50:09 -
@@ -49,6 +49,7 @@
 .Nm
 .Cm mibtree
 .Op Fl O Ar fns
+.Op Ar oid ...
 .Sh DESCRIPTION
 The
 .Nm
@@ -165,8 +166,12 @@ An SNMP based version of the
 .Xr df 1
 command.
 If no size suffix is shown the sizes are in kilobytes.
-.It Nm Cm mibtree Op Fl O Ar fnS
+.It Nm Cm mibtree Oo Fl O Ar fnS Oc Op Ar oid ...
 Dump the tree of compiled-in MIB objects.
+If
+.Ar oid
+is specified it wil print the objects in the requested output format if
+available, or print a warning if the object can't be found.
 .El
 .Pp
 The
Index: snmpc.c
===
RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
retrieving revision 1.29
diff -u -p -r1.29 snmpc.c
--- snmpc.c 12 Sep 2020 18:11:43 -  1.29
+++ snmpc.c 14 Sep 2020 14:50:10 -
@@ -80,7 +80,7 @@ struct snmp_app snmp_apps[] = {
{ "set", 1, NULL, "agent oid type value [oid type value] ...", 
snmpc_set },
{ "trap", 1, NULL, "agent uptime oid [oid type value] ...", snmpc_trap 
},
{ "df", 1, "C:", "[-Ch] [-Cr] agent", snmpc_df },
-   { "mibtree", 0, "O:", "[-O fnS]", snmpc_mibtree }
+   { "mibtree", 0, "O:", "[-O fnS] [oid] ...", snmpc_mibtree }
 };
 struct snmp_app *snmp_app = NULL;
 
@@ -1060,11 +1060,25 @@ int
 snmpc_mibtree(int argc, char *argv[])
 {
struct oid *oid;
+   struct ber_oid soid;
char buf[BUFSIZ];
+   int i;
 
-   for (oid = NULL; (oid = smi_foreach(oid)) != NULL;) {
-   smi_oid2string(>o_id, buf, sizeof(buf), oid_lookup);
-   printf("%s\n", buf);
+   if (argc == 0) {
+   for (oid = NULL; (oid = smi_foreach(oid)) != NULL;) {
+   smi_oid2string(>o_id, buf, sizeof(buf),
+   oid_lookup);
+   printf("%s\n", buf);
+   }
+   } else {
+   for (i = 0; i < argc; i++) {
+   if (smi_string2oid(argv[i], ) == -1) {
+   warnx("%s: Unknown object identifier", argv[i]);
+   continue;
+   }
+   smi_oid2string(, buf, sizeof(buf), oid_lookup);
+   printf("%s\n", buf);
+   }
}
return 0;
 }



Re: smtpd.conf add admd keyword

2020-09-12 Thread Martijn van Duren
Any takers?

On Sun, 2020-09-06 at 17:06 +0200, Martijn van Duren wrote:
> EHLO,
> 
> RFC8601 defines the authentication-results header which can be used to
> show the verification-results of DKIM, SPF, DMARC, and others.
> 
> I can think of quite a few filters that could be build around this
> header:
> - the prior mentioned
> - detecting the header before accepting it into ones ADMD
> - using it to calculate some sort of spam-score by some other filter
> 
> These are the 3 main categories that spring to mind, with especially
> the first one having the option to be split in quite a few different
> filters on itself.
> 
> Since setting the authservid on every of these filters (once they
> arrive) will be cumbersome and error-prone I would like to propose to
> distribute this value from a single point in the smtpd.conf.
> 
> I already have a filter-admdscrub basically ready and I'm working on a
> filter-dkimverify every now and then (no where near done yet) which can
> use this feature.
> 
> OK?
> 
> martijn@
> 
> Index: lka_filter.c
> ===
> RCS file: /cvs/src/usr.sbin/smtpd/lka_filter.c,v
> retrieving revision 1.62
> diff -u -p -r1.62 lka_filter.c
> --- lka_filter.c  24 Apr 2020 11:34:07 -  1.62
> +++ lka_filter.c  6 Sep 2020 15:05:21 -
> @@ -210,6 +210,8 @@ lka_proc_config(struct processor_instanc
>   io_printf(pi->io, "config|subsystem|smtp-in\n");
>   if (pi->subsystems & FILTER_SUBSYSTEM_SMTP_OUT)
>   io_printf(pi->io, "config|subsystem|smtp-out\n");
> + io_printf(pi->io, "config|admd|%s\n",
> + env->sc_admd != NULL ? env->sc_admd : env->sc_hostname);
>   io_printf(pi->io, "config|ready\n");
>  }
>  
> Index: parse.y
> ===
> RCS file: /cvs/src/usr.sbin/smtpd/parse.y,v
> retrieving revision 1.278
> diff -u -p -r1.278 parse.y
> --- parse.y   1 Jun 2020 05:21:30 -   1.278
> +++ parse.y   6 Sep 2020 15:05:21 -
> @@ -173,7 +173,7 @@ typedef struct {
>  
>  %}
>  
> -%token   ACTION ALIAS ANY ARROW AUTH AUTH_OPTIONAL
> +%token   ACTION ADMD ALIAS ANY ARROW AUTH AUTH_OPTIONAL
>  %token   BACKUP BOUNCE BYPASS
>  %token   CA CERT CHAIN CHROOT CIPHERS COMMIT COMPRESSION CONNECT
>  %token   DATA DATA_LINE DHE DISCONNECT DOMAIN
> @@ -209,6 +209,7 @@ grammar   : /* empty */
>   | grammar include '\n'
>   | grammar varset '\n'
>   | grammar bounce '\n'
> + | grammar admd '\n'
>   | grammar ca '\n'
>   | grammar mda '\n'
>   | grammar mta '\n'
> @@ -310,6 +311,21 @@ BOUNCE WARN_INTERVAL {
>  ;
>  
>  
> +admd:
> +ADMD STRING {
> + size_t i;
> +
> + for (i = 0; $2[i] != '\0'; i++) {
> + if (!isprint($2[i])) {
> + yyerror("not a valid admd");
> + free($2);
> + YYERROR;
> + }
> + }
> + conf->sc_admd = $2;
> +};
> +
> +
>  ca:
>  CA STRING {
>   char buf[HOST_NAME_MAX+1];
> @@ -2603,6 +2619,7 @@ lookup(char *s)
>   /* this has to be sorted always */
>   static const struct keywords keywords[] = {
>   { "action", ACTION },
> + { "admd",   ADMD },
>   { "alias",  ALIAS },
>   { "any",ANY },
>   { "auth",   AUTH },
> Index: smtpd.conf.5
> ===
> RCS file: /cvs/src/usr.sbin/smtpd/smtpd.conf.5,v
> retrieving revision 1.251
> diff -u -p -r1.251 smtpd.conf.5
> --- smtpd.conf.5  27 Aug 2020 08:58:30 -  1.251
> +++ smtpd.conf.5  6 Sep 2020 15:05:21 -
> @@ -313,6 +313,11 @@ which is useful on machines with multipl
>  If the list contains more than one address, all of them are used
>  in such a way that traffic is routed as efficiently as possible.
>  .El
> +.It Ic admd Ar authservid
> +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 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
> Index: smtpd.h
> 

Re: snmpd refactor listen on grammar

2020-09-08 Thread Martijn van Duren
On Tue, 2020-09-08 at 19:33 +0200, Denis Fondras wrote:
> On Sun, Sep 06, 2020 at 10:11:02PM +0200, Martijn van Duren wrote:
> > Moving towards individual transport mappings, it's becoming more 
> > convenient to have the protocol directly after the listen on statement.
> > This gives me more flexibility in using mapping-specific APIs, also
> > when other transport mappings might become available in the future it
> > allows for easier mapping-specific features.
> > 
> > While here I decided to also add port support for snmpe, which at this
> > point is rather trivial. Traphandler is not my point of focus at this
> > time.
> > 
> > having udp|tcp at the last position is still supported, but generates a
> > pretty deprecated warning. Probably to be removed after release.
> > 
> > OK?
> > 
> 
> OK denis@
> 
> Can you check that port > 0 ? Because it prints "snmpd.conf:7: invalid
> address: ::1" which is not correct (though using 0 or -1 for port is a weird
> idea).
> 
> > martijn@
> > 
Sure

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.60
diff -u -p -r1.60 parse.y
--- parse.y 6 Sep 2020 15:51:28 -   1.60
+++ parse.y 9 Sep 2020 05:45:10 -
@@ -40,9 +40,11 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -92,6 +94,7 @@ char  *symget(const char *);
 struct snmpd   *conf = NULL;
 static int  errors = 0;
 static struct usmuser  *user = NULL;
+static char*snmpd_port = SNMPD_PORT;
 
 int host(const char *, const char *, int,
struct sockaddr_storage *, int);
@@ -122,11 +125,11 @@ 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 HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER
+%token HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER PORT
 %token   STRING
 %token   NUMBER
 %typehostcmn
-%typesrcaddr
+%typesrcaddr port
 %typeoptwrite yesno seclevel proto
 %type  objtype cmd
 %type   oid hostoid trapoid
@@ -193,28 +196,7 @@ yesno  :  STRING   {
}
;
 
-main   : LISTEN ON STRING proto{
-   struct sockaddr_storage ss[16];
-   int nhosts, i;
-
-   nhosts = host($3, SNMPD_PORT, $4, ss, nitems(ss));
-   if (nhosts < 1) {
-   yyerror("invalid address: %s", $3);
-   free($3);
-   YYERROR;
-   }
-   if (nhosts > (int)nitems(ss))
-   log_warn("%s resolves to more than %zu hosts",
-   $3, nitems(ss));
-   free($3);
-
-   for (i = 0; i < nhosts; i++) {
-   if (listen_add(&(ss[i]), $4) == -1) {
-   yyerror("calloc");
-   YYERROR;
-   }
-   }
-   }
+main   : LISTEN ON listenproto
| READONLY COMMUNITY STRING {
if (strlcpy(conf->sc_rdcommunity, $3,
sizeof(conf->sc_rdcommunity)) >=
@@ -295,6 +277,132 @@ main  : LISTEN ON STRING proto{
}
;
 
+listenproto: UDP listen_udp
+   | TCP listen_tcp
+   | listen_empty
+
+listen_udp : STRING port   {
+   struct sockaddr_storage ss[16];
+   int nhosts, i;
+
+   nhosts = host($1, $2, SOCK_DGRAM, ss, nitems(ss));
+   if (nhosts < 1) {
+   yyerror("invalid address: %s", $1);
+   free($1);
+   if ($2 != snmpd_port)
+   free($2);
+   YYERROR;
+   }
+   if (nhosts > (int)nitems(ss))
+   log_warn("%s:%s resolves to more than %zu 
hosts",
+   $1, $2, nitems(ss));
+
+   free($1);
+   if ($2 != snmpd_port)
+   free($2);
+ 

snmpd refactor listen on grammar

2020-09-06 Thread Martijn van Duren
Moving towards individual transport mappings, it's becoming more 
convenient to have the protocol directly after the listen on statement.
This gives me more flexibility in using mapping-specific APIs, also
when other transport mappings might become available in the future it
allows for easier mapping-specific features.

While here I decided to also add port support for snmpe, which at this
point is rather trivial. Traphandler is not my point of focus at this
time.

having udp|tcp at the last position is still supported, but generates a
pretty deprecated warning. Probably to be removed after release.

OK?

martijn@

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.60
diff -u -p -r1.60 parse.y
--- parse.y 6 Sep 2020 15:51:28 -   1.60
+++ parse.y 6 Sep 2020 20:08:08 -
@@ -40,6 +40,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -92,6 +93,7 @@ char  *symget(const char *);
 struct snmpd   *conf = NULL;
 static int  errors = 0;
 static struct usmuser  *user = NULL;
+static char*snmpd_port = SNMPD_PORT;
 
 int host(const char *, const char *, int,
struct sockaddr_storage *, int);
@@ -122,11 +124,11 @@ 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 HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER
+%token HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER PORT
 %token   STRING
 %token   NUMBER
 %typehostcmn
-%typesrcaddr
+%typesrcaddr port
 %typeoptwrite yesno seclevel proto
 %type  objtype cmd
 %type   oid hostoid trapoid
@@ -193,28 +195,7 @@ yesno  :  STRING   {
}
;
 
-main   : LISTEN ON STRING proto{
-   struct sockaddr_storage ss[16];
-   int nhosts, i;
-
-   nhosts = host($3, SNMPD_PORT, $4, ss, nitems(ss));
-   if (nhosts < 1) {
-   yyerror("invalid address: %s", $3);
-   free($3);
-   YYERROR;
-   }
-   if (nhosts > (int)nitems(ss))
-   log_warn("%s resolves to more than %zu hosts",
-   $3, nitems(ss));
-   free($3);
-
-   for (i = 0; i < nhosts; i++) {
-   if (listen_add(&(ss[i]), $4) == -1) {
-   yyerror("calloc");
-   YYERROR;
-   }
-   }
-   }
+main   : LISTEN ON listenproto
| READONLY COMMUNITY STRING {
if (strlcpy(conf->sc_rdcommunity, $3,
sizeof(conf->sc_rdcommunity)) >=
@@ -295,6 +276,128 @@ main  : LISTEN ON STRING proto{
}
;
 
+listenproto: UDP listen_udp
+   | TCP listen_tcp
+   | listen_empty
+
+listen_udp : STRING port   {
+   struct sockaddr_storage ss[16];
+   int nhosts, i;
+
+   nhosts = host($1, $2, SOCK_DGRAM, ss, nitems(ss));
+   if (nhosts < 1) {
+   yyerror("invalid address: %s", $1);
+   free($1);
+   if ($2 != snmpd_port)
+   free($2);
+   YYERROR;
+   }
+   if (nhosts > (int)nitems(ss))
+   log_warn("%s:%s resolves to more than %zu 
hosts",
+   $1, $2, nitems(ss));
+
+   free($1);
+   if ($2 != snmpd_port)
+   free($2);
+   for (i = 0; i < nhosts; i++) {
+   if (listen_add(&(ss[i]), SOCK_DGRAM) == -1) {
+   yyerror("calloc");
+   YYERROR;
+   }
+   }
+   }
+
+listen_tcp : STRING port   {
+   struct sockaddr_storage ss[16];
+   int nhosts, i;
+
+   nhosts = host($1, $2, SOCK_STREAM, ss, nitems(ss));
+   if (nhosts < 1) {
+   yyerror("invalid address: %s", $1);
+   free($1);
+ 

snmpd remove snmpe_dispatch_parent

2020-09-06 Thread Martijn van Duren
going for another easy picking: snmpe_dispatch_parent is just an empty
stub. proc.c assigns proc_dispatch_null to p_cb if it's null, which 
effectively does the same thing.

OK?

martijn@

Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.66
diff -u -p -r1.66 snmpe.c
--- snmpe.c 6 Sep 2020 15:51:28 -   1.66
+++ snmpe.c 6 Sep 2020 16:37:10 -
@@ -46,7 +46,6 @@ void   snmpe_tryparse(int, struct snmp_me
 int snmpe_parsevarbinds(struct snmp_message *);
 voidsnmpe_response(struct snmp_message *);
 voidsnmpe_sig_handler(int sig, short, void *);
-int snmpe_dispatch_parent(int, struct privsep_proc *, struct imsg *);
 int snmpe_bind(struct address *);
 voidsnmpe_recvmsg(int fd, short, void *);
 voidsnmpe_readcb(int fd, short, void *);
@@ -60,7 +59,7 @@ struct imsgev *iev_parent;
 static const struct timevalsnmpe_tcp_timeout = { 10, 0 }; /* 10s */
 
 static struct privsep_proc procs[] = {
-   { "parent", PROC_PARENT,snmpe_dispatch_parent }
+   { "parent", PROC_PARENT }
 };
 
 void
@@ -133,17 +132,6 @@ snmpe_shutdown(void)
close(h->fd);
}
kr_shutdown();
-}
-
-int
-snmpe_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
-{
-   switch (imsg->hdr.type) {
-   default:
-   break;
-   }
-
-   return (-1);
 }
 
 int



smtpd.conf add admd keyword

2020-09-06 Thread Martijn van Duren
EHLO,

RFC8601 defines the authentication-results header which can be used to
show the verification-results of DKIM, SPF, DMARC, and others.

I can think of quite a few filters that could be build around this
header:
- the prior mentioned
- detecting the header before accepting it into ones ADMD
- using it to calculate some sort of spam-score by some other filter

These are the 3 main categories that spring to mind, with especially
the first one having the option to be split in quite a few different
filters on itself.

Since setting the authservid on every of these filters (once they
arrive) will be cumbersome and error-prone I would like to propose to
distribute this value from a single point in the smtpd.conf.

I already have a filter-admdscrub basically ready and I'm working on a
filter-dkimverify every now and then (no where near done yet) which can
use this feature.

OK?

martijn@

Index: lka_filter.c
===
RCS file: /cvs/src/usr.sbin/smtpd/lka_filter.c,v
retrieving revision 1.62
diff -u -p -r1.62 lka_filter.c
--- lka_filter.c24 Apr 2020 11:34:07 -  1.62
+++ lka_filter.c6 Sep 2020 15:05:21 -
@@ -210,6 +210,8 @@ lka_proc_config(struct processor_instanc
io_printf(pi->io, "config|subsystem|smtp-in\n");
if (pi->subsystems & FILTER_SUBSYSTEM_SMTP_OUT)
io_printf(pi->io, "config|subsystem|smtp-out\n");
+   io_printf(pi->io, "config|admd|%s\n",
+   env->sc_admd != NULL ? env->sc_admd : env->sc_hostname);
io_printf(pi->io, "config|ready\n");
 }
 
Index: parse.y
===
RCS file: /cvs/src/usr.sbin/smtpd/parse.y,v
retrieving revision 1.278
diff -u -p -r1.278 parse.y
--- parse.y 1 Jun 2020 05:21:30 -   1.278
+++ parse.y 6 Sep 2020 15:05:21 -
@@ -173,7 +173,7 @@ typedef struct {
 
 %}
 
-%token ACTION ALIAS ANY ARROW AUTH AUTH_OPTIONAL
+%token ACTION ADMD ALIAS ANY ARROW AUTH AUTH_OPTIONAL
 %token BACKUP BOUNCE BYPASS
 %token CA CERT CHAIN CHROOT CIPHERS COMMIT COMPRESSION CONNECT
 %token DATA DATA_LINE DHE DISCONNECT DOMAIN
@@ -209,6 +209,7 @@ grammar : /* empty */
| grammar include '\n'
| grammar varset '\n'
| grammar bounce '\n'
+   | grammar admd '\n'
| grammar ca '\n'
| grammar mda '\n'
| grammar mta '\n'
@@ -310,6 +311,21 @@ BOUNCE WARN_INTERVAL {
 ;
 
 
+admd:
+ADMD STRING {
+   size_t i;
+
+   for (i = 0; $2[i] != '\0'; i++) {
+   if (!isprint($2[i])) {
+   yyerror("not a valid admd");
+   free($2);
+   YYERROR;
+   }
+   }
+   conf->sc_admd = $2;
+};
+
+
 ca:
 CA STRING {
char buf[HOST_NAME_MAX+1];
@@ -2603,6 +2619,7 @@ lookup(char *s)
/* this has to be sorted always */
static const struct keywords keywords[] = {
{ "action", ACTION },
+   { "admd",   ADMD },
{ "alias",  ALIAS },
{ "any",ANY },
{ "auth",   AUTH },
Index: smtpd.conf.5
===
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.conf.5,v
retrieving revision 1.251
diff -u -p -r1.251 smtpd.conf.5
--- smtpd.conf.527 Aug 2020 08:58:30 -  1.251
+++ smtpd.conf.56 Sep 2020 15:05:21 -
@@ -313,6 +313,11 @@ which is useful on machines with multipl
 If the list contains more than one address, all of them are used
 in such a way that traffic is routed as efficiently as possible.
 .El
+.It Ic admd Ar authservid
+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 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
Index: smtpd.h
===
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.h,v
retrieving revision 1.656
diff -u -p -r1.656 smtpd.h
--- smtpd.h 8 Apr 2020 07:30:44 -   1.656
+++ smtpd.h 6 Sep 2020 15:05:21 -
@@ -624,6 +624,8 @@ struct smtpd {
char   *sc_srs_key;
char   *sc_srs_key_backup;
int sc_srs_ttl;
+
+   char   *sc_admd;
 };
 
 #defineTRACE_DEBUG 0x0001



Document errno for ober_read_elements

2020-09-03 Thread Martijn van Duren
So here's my attempt at documenting errno for ober_read_elements.

martijn@

Index: ober_read_elements.3
===
RCS file: /cvs/src/lib/libutil/ober_read_elements.3,v
retrieving revision 1.1
diff -u -p -r1.1 ober_read_elements.3
--- ober_read_elements.324 Oct 2019 12:39:26 -  1.1
+++ ober_read_elements.33 Sep 2020 18:48:56 -
@@ -142,9 +142,10 @@ frees any dynamically allocated storage 
 .Fn ober_read_elements
 returns a pointer to a fully populated list of one or more
 .Vt ber_element
-structures or
-.Dv NULL
-on a type mismatch or read error.
+structures.
+Otherwise \-1 is returned and the global variable
+.Va errno
+is set to indicate the error.
 .Pp
 .Fn ober_get_writebuf
 returns the number of bytes contained within the buffer
@@ -155,7 +156,30 @@ or \-1 on failure.
 returns the number of bytes written.
 Otherwise \-1 is returned and the global variable
 .Va errno
-is set to indicate the error.
+is set to
+.Er ENOMEM
+to indicate the error.
+.Sh ERRORS
+.Fn ober_read_elements
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOMEM
+No memory was available to create the full
+.Vt ber_element
+structure list.
+.It Bq Er ENOBUFS
+.Fn ober_read_elements
+was called before calling
+.Fn ober_set_readbuf .
+.It Bq Er ECANCELED
+.Fa buf
+does not contain enough data to complete the unpacking.
+.It Bq Er EINVAL
+.Fa buf
+does not contain a valid BER data structure.
+.It Bq Er ERANGE
+One of the values in the structure is larger then the library can unpack.
+.El
 .Sh SEE ALSO
 .Xr read 2 ,
 .Xr recv 2 ,



Re: Add more errnos to ober_read_elements

2020-09-03 Thread Martijn van Duren
Apparently I missed one...

On Thu, 2020-09-03 at 18:00 +0200, Martijn van Duren wrote:
> Just reminded myself of this one.
> The manpage says nothing about ober_read_elements setting errno upon
> failure, yet it does in most cases. Furthermore, applications like
> snmpd use errno in ober_read_elements to determine if a read is
> incomplete (checking for ECANCELED), without initializing errno to
> 0.
> 
> The danger here is that since some stale errno might linger and a
> return from ober_read_elements with NULL could test against an old
> errno.
> 
> Diff below tries to remedy this.
> 
> OK?
> 
> martijn@

Index: ber.c
===
RCS file: /cvs/src/lib/libutil/ber.c,v
retrieving revision 1.16
diff -u -p -r1.16 ber.c
--- ber.c   3 Sep 2020 17:01:15 -   1.16
+++ ber.c   3 Sep 2020 18:47:38 -
@@ -1258,8 +1258,10 @@ ober_read_element(struct ber *ber, struc
}
case BER_TYPE_INTEGER:
case BER_TYPE_ENUMERATED:
-   if (len > (ssize_t)sizeof(long long))
+   if (len > (ssize_t)sizeof(long long)) {
+   errno = ERANGE;
return -1;
+   }
for (i = 0; i < len; i++) {
if (ober_getc(ber, ) != 1)
return -1;



Add more errnos to ober_read_elements

2020-09-03 Thread Martijn van Duren
Just reminded myself of this one.
The manpage says nothing about ober_read_elements setting errno upon
failure, yet it does in most cases. Furthermore, applications like
snmpd use errno in ober_read_elements to determine if a read is
incomplete (checking for ECANCELED), without initializing errno to
0.

The danger here is that since some stale errno might linger and a
return from ober_read_elements with NULL could test against an old
errno.

Diff below tries to remedy this.

OK?

martijn@

Index: ber.c
===
RCS file: /cvs/src/lib/libutil/ber.c,v
retrieving revision 1.15
diff -u -p -r1.15 ber.c
--- ber.c   24 Oct 2019 12:39:26 -  1.15
+++ ber.c   3 Sep 2020 15:58:23 -
@@ -1266,8 +1266,10 @@ ober_read_element(struct ber *ber, struc
 
/* smallest number of contents octets only */
if ((i == 1 && last == 0 && (c & 0x80) == 0) ||
-   (i == 1 && last == 0xff && (c & 0x80) != 0))
+   (i == 1 && last == 0xff && (c & 0x80) != 0)) {
+   errno = EINVAL;
return -1;
+   }
 
val <<= 8;
val |= c;
@@ -1299,8 +1301,10 @@ ober_read_element(struct ber *ber, struc
((u_char *)elm->be_val)[len] = '\0';
break;
case BER_TYPE_NULL: /* no payload */
-   if (len != 0)
+   if (len != 0) {
+   errno = EINVAL;
return -1;
+   }
break;
case BER_TYPE_SEQUENCE:
case BER_TYPE_SET:
@@ -1346,8 +1350,10 @@ ober_read(struct ber *ber, void *buf, si
 {
size_t  sz;
 
-   if (ber->br_rbuf == NULL)
+   if (ber->br_rbuf == NULL) {
+   errno = ENOBUFS;
return -1;
+   }
 
sz = ber->br_rend - ber->br_rptr;
if (len > sz) {



Re: snmp df, use smi_print_element

2020-09-03 Thread Martijn van Duren
On Thu, 2020-09-03 at 09:49 +0200, Martijn van Duren wrote:
> At the moment it's not wise to run "snmp df" against untrusted
> instances, since it outputs the hrStorageDescr without checking the
> bytes being printed.
> 
> Make use of the new DISPLAY-HINT functionality of smi.c to make sure
> the string is actually DisplayHint compliant.
> 
> While here add the extra continuity-check in the second loop.
> 
> OK?
> 
> martijn@
> 
There was still a minor alignment issue in the previous diff, since
printf looks at the bytes printed and not the width of the characters,
which gives a wrong result if there's a replacement character in use.

Diff below fixes this.

All other fields should be printable ascii only and thus safe to use
in this way.

Index: mib.h
===
RCS file: /cvs/src/usr.bin/snmp/mib.h,v
retrieving revision 1.7
diff -u -p -r1.7 mib.h
--- mib.h   8 Aug 2020 14:01:31 -   1.7
+++ mib.h   3 Sep 2020 08:54:12 -
@@ -961,7 +961,7 @@
{ MIBDECL(hrStorageEntry) },\
{ MIBDECL(hrStorageIndex) },\
{ MIBDECL(hrStorageType) }, \
-   { MIBDECL(hrStorageDescr) },\
+   { MIBDECL(hrStorageDescr), "DisplayString" },   \
{ MIBDECL(hrStorageAllocationUnits) },  \
{ MIBDECL(hrStorageSize) }, \
{ MIBDECL(hrStorageUsed) }, \
Index: snmpc.c
===
RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
retrieving revision 1.28
diff -u -p -r1.28 snmpc.c
--- snmpc.c 3 Aug 2020 14:45:54 -   1.28
+++ snmpc.c 3 Sep 2020 08:54:12 -
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "smi.h"
 #include "snmp.h"
@@ -58,6 +59,7 @@ int snmpc_print(struct ber_element *);
 __dead void snmpc_printerror(enum snmp_error, struct ber_element *, int,
 const char *);
 char *snmpc_hex2bin(char *, size_t *);
+ssize_t snmpc_mbswidth(char *);
 struct ber_element *snmpc_varbindparse(int, char *[]);
 void usage(void);
 
@@ -820,8 +822,8 @@ snmpc_df(int argc, char *argv[])
 {
struct snmpc_df {
uint32_t index;
-   /* DisplayString is 255a DISPLAY-HINT */
-   char descr[256];
+   char *descr;
+   int descrwidth;
/* Theoretical maximum for 2 32 bit values multiplied */
char size[21];
char used[21];
@@ -833,7 +835,8 @@ snmpc_df(int argc, char *argv[])
struct ber_oid sizeoid = {{ 1, 3, 6, 1, 2, 1, 25, 2, 3, 1, 5 }, 11};
struct ber_oid usedoid = {{ 1, 3, 6, 1, 2, 1, 25, 2, 3, 1, 6 }, 11};
struct ber_oid oid, *reqoid;
-   struct ber_element *pdu, *varbind;
+   char oids[SNMP_MAX_OID_STRLEN];
+   struct ber_element *pdu, *varbind, *elm;
struct snmp_agent *agent;
int errorstatus, errorindex;
int class;
@@ -890,8 +893,9 @@ snmpc_df(int argc, char *argv[])
return 1;
}
for (; varbind != NULL; varbind = varbind->be_next) {
-   (void) ober_scanf_elements(varbind, "{oS", );
-   if (ober_oid_cmp(, ) != 2)
+   if (ober_scanf_elements(varbind, "{os", ,
+   ) == -1 ||
+   ober_oid_cmp(, ) != 2)
break;
rows++;
} 
@@ -899,19 +903,29 @@ snmpc_df(int argc, char *argv[])
err(1, "malloc");
(void) ober_scanf_elements(pdu, "{SSS{e", );
for (; i < rows; varbind = varbind->be_next, i++) {
-   if (ober_scanf_elements(varbind, "{os", ,
-   ) == -1) {
+   if (ober_scanf_elements(varbind, "{oe", ,
+   ) == -1) {
i--;
rows--;
continue;
}
+   if (ober_oid_cmp(, ) != 2)
+   break;
df[i].index = oid.bo_id[oid.bo_n - 1];
-   len = strlcpy(df[i].descr, string,
-   sizeof(df[i].descr));
-   if (len > (int) sizeof(df[i].descr))
-   len = (int) sizeof(df[i].descr) - 1;
-   if (len > descrlen)
-   descrlen = len;
+   if ((df[i].descr = smi_print_element(, elm, 0,
+   smi_os_ascii, 0, utf8)) == NULL) {
+   smi_oid2string(, oids, sizeof(oids)

snmp df, use smi_print_element

2020-09-03 Thread Martijn van Duren
At the moment it's not wise to run "snmp df" against untrusted
instances, since it outputs the hrStorageDescr without checking the
bytes being printed.

Make use of the new DISPLAY-HINT functionality of smi.c to make sure
the string is actually DisplayHint compliant.

While here add the extra continuity-check in the second loop.

OK?

martijn@

Index: mib.h
===
RCS file: /cvs/src/usr.bin/snmp/mib.h,v
retrieving revision 1.7
diff -u -p -r1.7 mib.h
--- mib.h   8 Aug 2020 14:01:31 -   1.7
+++ mib.h   3 Sep 2020 07:42:12 -
@@ -961,7 +961,7 @@
{ MIBDECL(hrStorageEntry) },\
{ MIBDECL(hrStorageIndex) },\
{ MIBDECL(hrStorageType) }, \
-   { MIBDECL(hrStorageDescr) },\
+   { MIBDECL(hrStorageDescr), "DisplayString" },   \
{ MIBDECL(hrStorageAllocationUnits) },  \
{ MIBDECL(hrStorageSize) }, \
{ MIBDECL(hrStorageUsed) }, \
Index: snmpc.c
===
RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
retrieving revision 1.28
diff -u -p -r1.28 snmpc.c
--- snmpc.c 3 Aug 2020 14:45:54 -   1.28
+++ snmpc.c 3 Sep 2020 07:42:12 -
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "smi.h"
 #include "snmp.h"
@@ -58,6 +59,7 @@ int snmpc_print(struct ber_element *);
 __dead void snmpc_printerror(enum snmp_error, struct ber_element *, int,
 const char *);
 char *snmpc_hex2bin(char *, size_t *);
+ssize_t snmpc_mbswidth(char *);
 struct ber_element *snmpc_varbindparse(int, char *[]);
 void usage(void);
 
@@ -820,8 +822,7 @@ snmpc_df(int argc, char *argv[])
 {
struct snmpc_df {
uint32_t index;
-   /* DisplayString is 255a DISPLAY-HINT */
-   char descr[256];
+   char *descr;
/* Theoretical maximum for 2 32 bit values multiplied */
char size[21];
char used[21];
@@ -833,7 +834,8 @@ snmpc_df(int argc, char *argv[])
struct ber_oid sizeoid = {{ 1, 3, 6, 1, 2, 1, 25, 2, 3, 1, 5 }, 11};
struct ber_oid usedoid = {{ 1, 3, 6, 1, 2, 1, 25, 2, 3, 1, 6 }, 11};
struct ber_oid oid, *reqoid;
-   struct ber_element *pdu, *varbind;
+   char oids[SNMP_MAX_OID_STRLEN];
+   struct ber_element *pdu, *varbind, *elm;
struct snmp_agent *agent;
int errorstatus, errorindex;
int class;
@@ -890,8 +892,9 @@ snmpc_df(int argc, char *argv[])
return 1;
}
for (; varbind != NULL; varbind = varbind->be_next) {
-   (void) ober_scanf_elements(varbind, "{oS", );
-   if (ober_oid_cmp(, ) != 2)
+   if (ober_scanf_elements(varbind, "{os", ,
+   ) == -1 ||
+   ober_oid_cmp(, ) != 2)
break;
rows++;
} 
@@ -899,17 +902,26 @@ snmpc_df(int argc, char *argv[])
err(1, "malloc");
(void) ober_scanf_elements(pdu, "{SSS{e", );
for (; i < rows; varbind = varbind->be_next, i++) {
-   if (ober_scanf_elements(varbind, "{os", ,
-   ) == -1) {
+   if (ober_scanf_elements(varbind, "{oe", ,
+   ) == -1) {
i--;
rows--;
continue;
}
+   if (ober_oid_cmp(, ) != 2)
+   break;
df[i].index = oid.bo_id[oid.bo_n - 1];
-   len = strlcpy(df[i].descr, string,
-   sizeof(df[i].descr));
-   if (len > (int) sizeof(df[i].descr))
-   len = (int) sizeof(df[i].descr) - 1;
+   if ((df[i].descr = smi_print_element(, elm, 0,
+   smi_os_ascii, 0, utf8)) == NULL) {
+   smi_oid2string(, oids, sizeof(oids),
+   oid_lookup);
+   warn("df: can't print oid %s", oids);
+   i--;
+   rows--;
+   continue;
+   }
+   if ((len = (int) snmpc_mbswidth(df[i].descr)) == -1)
+   err(1, "df: invalid hrStorageDescr");
if (len > descrlen)
descrlen = len;
} 
@@ -1325,6 +1337,24 @@ fail:
errno = EINVAL;
free(decstr);
return NULL;
+}
+
+ssize_t
+snmpc_mbswidth(char *str)
+{
+   wchar_t 

snmpd(8) start cleaning up socket code.

2020-08-25 Thread Martijn van Duren
I would like to move snmpd(8) to a more modular dispatch/transport map
system, but that's going to be quite the undertaking. To make things a
little better to grok I'd like to split of the trap receiver components
out of struct address as a first step. While doing this I can also
greatly simplify the code for resolving hosts.
According parse.y's cvs log:
revision 1.15
date: 2008/07/18 12:35:27;  author: reyk;  state: Exp;  lines: +22 -14;
merge host_v6 with relayd's version to use getaddrinfo instead of
inet_pton.  host_v4, host_v6, and host_dns could be merged into one
function using getaddrinfo but i keep it in multiple functions to keep
it in sync with the other daemons using this common code.

Since I intent to completely overhaul this part of the code I see no
reason to keep this in sync.

No functional change intended, except that trap receiver's
source-address might now also be a resolvable hostname.

OK?

martijn@

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.59
diff -u -p -r1.59 parse.y
--- parse.y 23 Aug 2020 07:39:57 -  1.59
+++ parse.y 25 Aug 2020 19:52:01 -
@@ -91,16 +91,11 @@ char*symget(const char *);
 
 struct snmpd   *conf = NULL;
 static int  errors = 0;
-static struct addresslist  *hlist;
 static struct usmuser  *user = NULL;
 
-struct address *host_v4(const char *);
-struct address *host_v6(const char *);
-int host_dns(const char *, struct addresslist *,
-   int, in_port_t, struct ber_oid *, char *,
-   struct address *, int);
-int host(const char *, struct addresslist *,
-   int, in_port_t, struct ber_oid *, char *, char *, int);
+int host(const char *, const char *, int,
+   struct sockaddr_storage *, int);
+int listen_add(struct sockaddr_storage *, int);
 
 typedef struct {
union {
@@ -120,6 +115,8 @@ typedef struct {
int lineno;
 } YYSTYPE;
 
+#define NELEM(a) (sizeof(a) / sizeof((a)[0]))
+
 %}
 
 %token INCLUDE
@@ -199,13 +196,26 @@ yesno :  STRING   {
;
 
 main   : LISTEN ON STRING proto{
-   if (host($3, >sc_addresses, 16, SNMPD_PORT, NULL,
-   NULL, NULL, $4) <= 0) {
-   yyerror("invalid ip address: %s", $3);
+   struct sockaddr_storage ss[16];
+   int nhosts, i;
+
+   nhosts = host($3, SNMPD_PORT, $4, ss, NELEM(ss));
+   if (nhosts < 1) {
+   yyerror("invalid address: %s", $3);
free($3);
YYERROR;
}
+   if (nhosts > (int)NELEM(ss))
+   log_warn("%s resolves to more than %zu hosts",
+   $3, NELEM(ss));
free($3);
+
+   for (i = 0; i < nhosts; i++) {
+   if (listen_add(&(ss[i]), $4) == -1) {
+   yyerror("calloc");
+   YYERROR;
+   }
+   }
}
| READONLY COMMUNITY STRING {
if (strlcpy(conf->sc_rdcommunity, $3,
@@ -240,11 +250,7 @@ main   : LISTEN ON STRING proto{
}
free($3);
}
-   | TRAP RECEIVER {
-   hlist = >sc_trapreceivers;
-   } host  {
-   hlist = NULL;
-   }
+   | TRAP RECEIVER host
| TRAP HANDLE hostcmn trapoid cmd {
struct trapcmd *cmd = $5.data;
 
@@ -420,13 +426,40 @@ srcaddr   : /* empty */   
{ $$ = NULL; }
;
 
 hostdef: STRING hostoid hostcmn srcaddr{
-   if (host($1, hlist, 1,
-   SNMPD_TRAPPORT, $2, $3, $4, IPPROTO_UDP) <= 0) {
+   struct sockaddr_storage ss;
+   struct trap_address *tr;
+
+   if ((tr = calloc(1, sizeof(*tr))) == NULL) {
+   yyerror("calloc");
+   YYERROR;
+   }
+
+   if (host($1, SNMPD_TRAPPORT, SOCK_DGRAM, , 1) <= 0) {
yyerror("invalid host: %s", $1);
free($1);
+   free($2);
+   free($3);
+   free($4);
+  

Re: smtpd filters: accept bypass in commit stage

2020-08-25 Thread Martijn van Duren
Does this filter actually work for you? Not by my testing, nor my
understanding of filters. Filter-dkimsign works during the
filter-dataline phase, so you'd have to circumvent that one, which is
not supported.

Personally I'd sign the domain anyway, since it gives the receiver
some additional information where a message might have been altered if
it happens somewhere down a MTA-chain, but if you really don't want to
sign the message you could try setting the phase to data, since that's
where filter-dkimsign's magic happens. I haven't tested this though,
so it might be just the data-command and not the actual data.
If that doesn't work your best bet at this point is two different
listen statement for the two domains.

martijn@

On Tue, 2020-08-25 at 04:30 +, Lucas wrote:
> Hello tech@,
> 
> I keep getting a syntax error with the following seemingly correct
> line:
> 
>   filter "dkimsign-override" phase commit \
>   match mail-from  bypass
> 
> The problem (`/etc/mail/smtpd.conf:20: syntax error`) arises from
> smtpd.conf's grammar only allowing `filter_action_builtin_nojunk` for
> `commit` phase. It turns out that the current definition of
> `filter_action_builtin_nojunk` means no junk and no bypass. Address
> that moving bypass action to nojunk.
> 
> My usecase for it is to avoid DKIM-signing emails that are externally
> relayed with `opensmtpd-filters-dkimsign`: if I also own
> lucas@domain.invalid, I don't want smtpd to sign lucas@domain.invalid's
> emails, just lu...@sexy.is'. This seems possible with `filter-chain`,
> and technically could be decided in `mail-from` phase, but sadly
> `bypass` doesn't short-circuit. Second best option is to `bypass`
> during `commit` phase, which is when `filter-dkimsign` does its magic.
> 
> Comments?
> 
> -Lucas
> 
> 
> Index: parse.y
> ===
> RCS file: /home/cvs/src/usr.sbin/smtpd/parse.y,v
> retrieving revision 1.278
> diff -u -p -r1.278 parse.y
> --- parse.y   1 Jun 2020 05:21:30 -   1.278
> +++ parse.y   25 Aug 2020 04:05:27 -
> @@ -1527,9 +1527,6 @@ filter_action_builtin_nojunk
>  | JUNK {
>   filter_config->junk = 1;
>  }
> -| BYPASS {
> - filter_config->bypass = 1;
> -}
>  ;
>  
>  filter_action_builtin_nojunk:
> @@ -1544,6 +1541,9 @@ REJECT STRING {
>  }
>  | REPORT STRING {
>   filter_config->report = $2;
> +}
> +| BYPASS {
> + filter_config->bypass = 1;
>  }
>  ;
>  
> 



snmpd(8) Remove struct listen_sock

2020-08-09 Thread Martijn van Duren
I still want to move udp/tcp handling out of snmpe, so that there's 
better layering, but my previous diff never got any response and might  
do with some more polishing.

For now, lets remove listen_sock from snmpd, since there's a 1:1
correlation with struct address. This saves a couple of callocs during
startup and 18 LoC.

OK?

martijn@

Index: parse.y
===
RCS file: /cvs/src/usr.sbin/snmpd/parse.y,v
retrieving revision 1.58
diff -u -p -r1.58 parse.y
--- parse.y 30 Jun 2020 17:11:49 -  1.58
+++ parse.y 9 Aug 2020 14:08:18 -
@@ -997,7 +997,6 @@ parse_config(const char *filename, u_int
conf->sc_flags = flags;
conf->sc_confpath = filename;
TAILQ_INIT(>sc_addresses);
-   TAILQ_INIT(>sc_sockets);
strlcpy(conf->sc_rdcommunity, "public", SNMPD_MAXCOMMUNITYLEN);
strlcpy(conf->sc_rwcommunity, "private", SNMPD_MAXCOMMUNITYLEN);
strlcpy(conf->sc_trcommunity, "public", SNMPD_MAXCOMMUNITYLEN);
Index: snmpd.h
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
retrieving revision 1.88
diff -u -p -r1.88 snmpd.h
--- snmpd.h 8 Aug 2020 13:39:57 -   1.88
+++ snmpd.h 9 Aug 2020 14:08:18 -
@@ -482,6 +482,9 @@ struct address {
struct sockaddr_storage  ss;
in_port_tport;
int  ipproto;
+   int  fd;
+   struct event ev;
+   struct event evt;
 
TAILQ_ENTRY(address) entry;
 
@@ -492,15 +495,6 @@ struct address {
 };
 TAILQ_HEAD(addresslist, address);
 
-struct listen_sock {
-   int s_fd;
-   int s_ipproto;
-   struct events_ev;
-   struct events_evt;
-   TAILQ_ENTRY(listen_sock)entry;
-};
-TAILQ_HEAD(socklist, listen_sock);
-
 enum usmauth {
AUTH_NONE = 0,
AUTH_MD5,   /* HMAC-MD5-96, RFC3414 */
@@ -545,7 +539,6 @@ struct snmpd {
 
const char  *sc_confpath;
struct addresslist   sc_addresses;
-   struct socklist  sc_sockets;
struct timeval   sc_starttime;
u_int32_tsc_engine_boots;
 
Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.63
diff -u -p -r1.63 snmpe.c
--- snmpe.c 8 Aug 2020 13:39:57 -   1.63
+++ snmpe.c 9 Aug 2020 14:08:18 -
@@ -68,7 +68,6 @@ snmpe(struct privsep *ps, struct privsep
 {
struct snmpd*env = ps->ps_env;
struct address  *h;
-   struct listen_sock  *so;
 #ifdef DEBUG
char buf[BUFSIZ];
struct oid  *oid;
@@ -82,14 +81,9 @@ snmpe(struct privsep *ps, struct privsep
 #endif
 
/* bind SNMP UDP/TCP sockets */
-   TAILQ_FOREACH(h, >sc_addresses, entry) {
-   if ((so = calloc(1, sizeof(*so))) == NULL)
-   fatal("snmpe: %s", __func__);
-   if ((so->s_fd = snmpe_bind(h)) == -1)
+   TAILQ_FOREACH(h, >sc_addresses, entry)
+   if ((h->fd = snmpe_bind(h)) == -1)
fatal("snmpe: failed to bind SNMP socket");
-   so->s_ipproto = h->ipproto;
-   TAILQ_INSERT_TAIL(>sc_sockets, so, entry);
-   }
 
proc_run(ps, p, procs, nitems(procs), snmpe_init, NULL);
 }
@@ -99,7 +93,7 @@ void
 snmpe_init(struct privsep *ps, struct privsep_proc *p, void *arg)
 {
struct snmpd*env = ps->ps_env;
-   struct listen_sock  *so;
+   struct address  *h;
 
kr_init();
trap_init();
@@ -107,17 +101,17 @@ snmpe_init(struct privsep *ps, struct pr
usm_generate_keys();
 
/* listen for incoming SNMP UDP/TCP messages */
-   TAILQ_FOREACH(so, >sc_sockets, entry) {
-   if (so->s_ipproto == IPPROTO_TCP) {
-   if (listen(so->s_fd, 5) < 0)
+   TAILQ_FOREACH(h, >sc_addresses, entry) {
+   if (h->ipproto == IPPROTO_TCP) {
+   if (listen(h->fd, 5) < 0)
fatalx("snmpe: failed to listen on socket");
-   event_set(>s_ev, so->s_fd, EV_READ, snmpe_acceptcb, 
so);
-   evtimer_set(>s_evt, snmpe_acceptcb, so);
+   event_set(>ev, h->fd, EV_READ, snmpe_acceptcb, h);
+   evtimer_set(>evt, snmpe_acceptcb, h);
} else {
-   event_set(>s_ev, so->s_fd, EV_READ|EV_PERSIST,
+   event_set(>ev, h->fd, EV_READ|EV_PERSIST,
snmpe_recvmsg, env);
}
-   event_add(>s_ev, NULL);
+   event_add(>ev, NULL);
}
 
/* no filesystem 

Re: ksh [emacs.c] -- simplify isu8cont()

2020-07-26 Thread Martijn van Duren
On Sun, 2020-07-26 at 04:15 +0100, ropers wrote:
> On 25/07/2020, Martijn van Duren  wrote:
> > This function is used throughout the OpenBSD tree and I think it's
> > fine as it is. This way it's clearer to me that it's about byte
> > 7 and 8
> 
> You mean bits 7 and 8 when counting from 1 from the right?

obvious type-O is obvious.
> 
> > and not have to do the math in my head to check if we
> > might have botched it.
> > 
> > Also compilers should be smart enough to optimize this out at
> > compile-time anyway.
> > 
> > martijn@
> 
> So the (0x80 | 0x40) was supposed to be *for* legibility?
> 
> IMHO it hurts legibility, but admittedly, it depends on who you are
> and what you have memorised:
> Finding (0x80 | 0x40) easier than 0xC0 assumes that people have nibble
> translation between binary and hexadecimal memorised all the way up to
> 8 but *NOT* up to C.  And that they find dealing with two values and
> an extra binary OR still less hassle than remembering that C is 1100.
> Of course if that's your decision, that's your decision, but speaking
> as a novice C programmer, I think 'C' is easier. ;D [0]

I'm lazy, so I only remember the power exponents (1-4) and everthing
in between is just derivative. And since I and a handful of others
maintain this code I think we should do what we think is most readable
to us. If say schwarze@ were to change his mind and come up with this
patch I'd give it more serious thought on how hard it would be for me
to make the switch, but we're not going to change it because some
outsider might find it easier to read.
Don't get me wrong, I appreciate the patch and I do encourage you to
find new things to work on, but this one is just a matter of opinion
and in this case the people who actually maintain this code have a
different opinion and they tend to win, maybe your next patch will
convince us (I actually hope so).
> 
> But while you're reading this, would you at least consider committing
> the explanatory comment?  Not everybody is already familiar with how
> UTF-8 works, and I think this comment above the function is still some
> extra hand-holding beginners might find useful:
> /* is octet a UTF-8 continuation byte? */

Opinions differ, but I find comments like these just take up useless
screen space, because it basically reiterates what it states in the
function name.
> 
> Also, while you're here, can anyone tell me what the zot in x_zots() /
> x_zotc() actually stands for?  I thought it was "zero out the
> {string|character}" when I looked at x_zots(), but then I doubted
> myself once I saw that that's not strictly what x_zotc() actually
> does.  Does anyone know?

I have no idea, but it's been there since it's import in 1996 and
with only a quick search I can't find the original repository, so
no clue there.
> 
> Ian
> 
> 
> footnote:
> [0] Which latter thought, incidentally, is also why someone invented BCHS. ;)
> 
> 
> 
> 
> > On Sat, 2020-07-25 at 17:40 +0100, ropers wrote:
> > > Index: emacs.c
> > > ===
> > > RCS file: /cvs/src/bin/ksh/emacs.c,v
> > > retrieving revision 1.87
> > > diff -u -r1.87 emacs.c
> > > --- emacs.c   8 May 2020 14:30:42 -   1.87
> > > +++ emacs.c   25 Jul 2020 16:31:22 -
> > > @@ -269,10 +269,11 @@
> > >   { 0, 0, 0 },
> > >  };
> > > 
> > > +/* is octet a UTF-8 continuation byte? */
> > >  int
> > >  isu8cont(unsigned char c)
> > >  {
> > > - return (c & (0x80 | 0x40)) == 0x80;
> > > + return (c & 0xC0) == 0x80;
> > >  }
> > > 
> > >  int
> > > 



Re: ksh [emacs.c] -- simplify isu8cont()

2020-07-25 Thread Martijn van Duren
This function is used throughout the OpenBSD tree and I think it's
fine as it is. This way it's clearer to me that it's about byte
7 and 8 and not have to do the math in my head to check if we
might have botched it.

Also compilers should be smart enough to optimize this out at
compile-time anyway.

martijn@

On Sat, 2020-07-25 at 17:40 +0100, ropers wrote:
> Index: emacs.c
> ===
> RCS file: /cvs/src/bin/ksh/emacs.c,v
> retrieving revision 1.87
> diff -u -r1.87 emacs.c
> --- emacs.c   8 May 2020 14:30:42 -   1.87
> +++ emacs.c   25 Jul 2020 16:31:22 -
> @@ -269,10 +269,11 @@
>   { 0, 0, 0 },
>  };
> 
> +/* is octet a UTF-8 continuation byte? */
>  int
>  isu8cont(unsigned char c)
>  {
> - return (c & (0x80 | 0x40)) == 0x80;
> + return (c & 0xC0) == 0x80;
>  }
> 
>  int
> 



Re: Potential grep bug?

2020-07-22 Thread Martijn van Duren
Any takers?

On Wed, 2020-06-24 at 13:27 +0200, Martijn van Duren wrote:
> Moving to tech@
> 
> On Tue, 2020-06-23 at 22:17 -0900, Philip Guenther wrote:
> > Nope.  This is a grep of a single file, so procfile() must be overflowing
> > and this only 'fixes' it by relying on signed overflow, which is undefined
> > behavior, being handled in a particular way by the compiler.  So, luck
> > (which fails when the compiler decides to hate you).  There are more places
> > that need to change for the reported problem to be handled safely.
> > 
> > Philip Guenther
> 
> I'm not sure I understand exactly what you mean, but the overflow can
> still propagate through to the return value. Since everything propagated
> up from procfile is only eventually used to determine the exit value we
> can start treating it as a boolean.
> 
> I gave a quick glance at freebsd and they also treat it as a boolean,
> but more explicitly. They however don't appear have overflow detection.
> 
> Is this better?
> 
> martijn@
> > 
> > On Tue, Jun 23, 2020 at 9:58 PM Martijn van Duren <
> > open...@list.imperialat.at> wrote:
> > 
> > > This seems to fix the issue for me.
> > > 
> > > OK?
> > > 
> > > martijn@
> > > 
> > > On Tue, 2020-06-23 at 19:29 -0700, Jordan Geoghegan wrote:
> > > > Hello,
> > > > 
> > > > I was working on a couple POSIX regular expressions to search for and
> > > > validate IPv4 and IPv6 addresses with optional CIDR blocks, and
> > > > encountered some strange behaviour from the base system grep.
> > > > 
> > > > I wanted to validate my regex against a list of every valid IPv4
> > > > address, so I generated a list with a zsh 1 liner:
> > > > 
> > > >   for i in {0..255}; do; echo $i.{0..255}.{0..255}.{0..255} ; done |
> > > > tr '[:space:]' '\n' > IPv4.txt
> > > > 
> > > > My intentions were to test the regex by running it with 'grep -c' to
> > > > confirm there was indeed 2^32 addresses matched, and I also wanted to
> > > > benchmark and compare performance between BSD grep, GNU grep and
> > > > ripgrep. The command I used:
> > > > 
> > > > grep -Eoc
> > > > 
> > > "((25[0-5]|(2[0-4]|1{0,1}[[:digit:]]){0,1}[[:digit:]])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[[:digit:]]){0,1}[[:digit:]])(/[1-9]|/[1-2][[:digit:]]|/3[0-2])?"
> > > > My findings were surprising. Both GNU grep and ripgrep were able get
> > > > through the file in roughly 10 and 20 minutes respectively, whereas the
> > > > base system grep took over 20 hours! What interested me the most was
> > > > that the base system grep when run with '-c' returned '0' for match
> > > > count. It seems that 'grep -c' will have its counter overflow if there
> > > > are more than 2^32-1 matches (4294967295) and then the counter will
> > > > start counting from zero again for further matches.
> > > > 
> > > >  ryzen$ time zcat IPv4.txt.gz | grep -Eoc
> > > "((25[0-5]|(2[0-4]|1{0,1}...
> > > >  0
> > > >  1222m09.32s real  1224m28.02s user 1m16.17s system
> > > > 
> > > >  ryzen$ time zcat allip.txt.gz | ggrep -Eoc
> > > "((25[0-5]|(2[0-4]|1{0,1}...
> > > >  4294967296
> > > >  10m00.38s real11m40.57s user 0m30.55s system
> > > > 
> > > >  ryzen$ time rg -zoc "((25[0-5]|(2[0-4]|1{0,1}...
> > > >  4294967296
> > > >  21m06.36s real27m06.04s user 0m50.08s system
> > > > 
> > > > # See the counter overflow/reset:
> > > >  jot 4294967350 | grep -c "^[[:digit:]]"
> > > >  54
> > > > 
> > > > All testing was done on a Ryzen desktop machine running 6.7 stable.
> > > > 
> > > > The grep counting bug can be reproduced with this command:
> > > > jot 4294967296 | nice grep -c "^[[:digit:]]"
> > > > 
> > > > Regards,
> > > > 
> > > > Jordan
> > > > 
> Index: grep.c
> ===
> RCS file: /cvs/src/usr.bin/grep/grep.c,v
> retrieving revision 1.64
> diff -u -p -r1.64 grep.c
> --- grep.c3 Dec 2019 09:14:37 -   1.64
> +++ grep.c24 Jun 2020 11:26:25 -
> @@ -517,7 +517,7 @@ main(int argc, char *argv[])
>   c = grep_tree(argv);
>   else
&g

join(1) remove redundant memory copy

2020-07-22 Thread Martijn van Duren
When r1.28 converted join(1) to getline(3) it left the old intermediate
line variable. This means using an additional memcpy and reallocing.
I reckon this is wasted cycles and screen filling.

Major difference is that our getline allocates to the next power of 2,
while the current code overcommits a maximum of ~100 bytes. I reckon
this is a fair trade-off.

regress still passes.

OK?

martijn@

Index: join.c
===
RCS file: /cvs/src/usr.bin/join/join.c,v
retrieving revision 1.32
diff -u -p -r1.32 join.c
--- join.c  14 Nov 2018 15:16:09 -  1.32
+++ join.c  22 Jul 2020 18:19:34 -
@@ -271,9 +271,8 @@ slurp(INPUT *F)
 {
LINE *lp, *lastlp, tmp;
ssize_t len;
-   size_t linesize;
u_long cnt;
-   char *bp, *fieldp, *line;
+   char *bp, *fieldp;
 
/*
 * Read all of the lines from an input file that have the same
@@ -281,8 +280,6 @@ slurp(INPUT *F)
 */
 
F->setcnt = 0;
-   line = NULL;
-   linesize = 0;
for (lastlp = NULL; ; ++F->setcnt) {
/*
 * If we're out of space to hold line structures, allocate
@@ -320,22 +317,12 @@ slurp(INPUT *F)
F->pushbool = 0;
continue;
}
-   if ((len = getline(, , F->fp)) == -1)
+   if ((len = getline(&(lp->line), &(lp->linealloc), F->fp)) == -1)
break;
 
/* Remove trailing newline, if it exists, and copy line. */
-   if (line[len - 1] == '\n')
+   if (lp->line[len - 1] == '\n')
len--;
-   if (lp->linealloc <= len + 1) {
-   char *p;
-   u_long newsize = lp->linealloc +
-   MAXIMUM(100, len + 1 - lp->linealloc);
-   if ((p = realloc(lp->line, newsize)) == NULL)
-   err(1, NULL);
-   lp->line = p;
-   lp->linealloc = newsize;
-   }
-   memcpy(lp->line, line, len);
lp->line[len] = '\0';
 
/* Split the line into fields, allocate space as necessary. */
@@ -363,7 +350,6 @@ slurp(INPUT *F)
break;
}
}
-   free(line);
 }
 
 char *



snmpd(8) clean up snmpe_parsevarbinds

2020-07-19 Thread Martijn van Duren
I'm not quite sure yet where I want to move with snmpe_parsevarbinds, 
but the current implementation just gives me a headache every time I 
read it. There's still of plenty of issues in here, like not fully
complient gathering of statistics, relying on synchronous handling of
varbinds (required for proper AgentX support) and not taking RFC3584
into acount. But my goal for now is a small step to making things
more readable and see where we can go from there.

Regress still passes and except for some minor changes in the handling
of snmp_intotal{req,set}vars no functional changes intended.

For people who wonder what happened to the 1 return value: this value
was only used when agentx was called, which is currently no more.

OK?

martijn@

Index: snmpd.h
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
retrieving revision 1.87
diff -u -p -r1.87 snmpd.h
--- snmpd.h 30 Jun 2020 17:11:49 -  1.87
+++ snmpd.h 19 Jul 2020 12:08:04 -
@@ -394,19 +394,10 @@ struct snmp_message {
struct ber_element  *sm_req;
struct ber_element  *sm_resp;
 
-   int  sm_i;
-   struct ber_element  *sm_a;
-   struct ber_element  *sm_b;
-   struct ber_element  *sm_c;
-   struct ber_element  *sm_next;
-   struct ber_element  *sm_last;
-   struct ber_element  *sm_end;
-
u_int8_t sm_data[READ_BUF_SIZE];
size_t   sm_datalen;
 
u_intsm_version;
-   u_intsm_state;
 
/* V1, V2c */
char sm_community[SNMPD_MAXCOMMUNITYLEN];
Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.62
diff -u -p -r1.62 snmpe.c
--- snmpe.c 2 May 2020 14:22:31 -   1.62
+++ snmpe.c 19 Jul 2020 12:08:04 -
@@ -400,124 +400,112 @@ int
 snmpe_parsevarbinds(struct snmp_message *msg)
 {
struct snmp_stats   *stats = _env->sc_stats;
+   struct ber_element  *varbind, *value, *rvarbind = NULL;
+   struct ber_element  *pvarbind = NULL, *end;
char buf[BUFSIZ];
struct ber_oid   o;
-   int  ret = 0;
+   int  i;
 
msg->sm_errstr = "invalid varbind element";
 
-   if (msg->sm_i == 0) {
-   msg->sm_i = 1;
-   msg->sm_a = msg->sm_varbind;
-   msg->sm_last = NULL;
-   }
-
-for (; msg->sm_a != NULL && msg->sm_i < SNMPD_MAXVARBIND;
-   msg->sm_a = msg->sm_next, msg->sm_i++) {
-   msg->sm_next = msg->sm_a->be_next;
-
-   if (msg->sm_a->be_class != BER_CLASS_UNIVERSAL ||
-   msg->sm_a->be_type != BER_TYPE_SEQUENCE)
-   continue;
-   if ((msg->sm_b = msg->sm_a->be_sub) == NULL)
-   continue;
-
-   for (msg->sm_state = 0; msg->sm_state < 2 && msg->sm_b != NULL;
-   msg->sm_b = msg->sm_b->be_next) {
-   switch (msg->sm_state++) {
-   case 0:
-   if (ober_get_oid(msg->sm_b, ) != 0)
-   goto varfail;
-   if (o.bo_n < BER_MIN_OID_LEN ||
-   o.bo_n > BER_MAX_OID_LEN)
-   goto varfail;
-   if (msg->sm_context == SNMP_C_SETREQ)
-   stats->snmp_intotalsetvars++;
-   else
-   stats->snmp_intotalreqvars++;
-   log_debug("%s: %s: oid %s",
-   __func__, msg->sm_host,
-   smi_oid2string(, buf, sizeof(buf), 0));
-   break;
-   case 1:
-   msg->sm_c = NULL;
-   msg->sm_end = NULL;
-
-   switch (msg->sm_context) {
-
-   case SNMP_C_GETNEXTREQ:
-   msg->sm_c = ober_add_sequence(NULL);
-   ret = mps_getnextreq(msg, msg->sm_c,
-   );
-   if (ret == 0 || ret == 1)
-   break;
-   ober_free_elements(msg->sm_c);
-   msg->sm_error = SNMP_ERROR_NOSUCHNAME;
-   goto varfail;
-
-   case SNMP_C_GETREQ:
-   msg->sm_c = ober_add_sequence(NULL);
-   

Re: LC_MESSAGES in xargs(1)

2020-07-16 Thread Martijn van Duren
I gave a quick look at replacing prompt with readpassphrase(3), but that
would be more trouble than it's worth. (adjusting pledge, semantics
change in where the "?..." would be printed).

Minor nits inline, but either way OK martijn@

On Thu, 2020-07-16 at 21:49 +0200, Ingo Schwarze wrote:
> Hi Jan,
> 
> Jan Stary wrote on Thu, Jul 16, 2020 at 09:45:44AM +0200:
> 
> > Does xargs need to set LC_MESSAGES?
> 
> As it stands, your patch doesn't make much sense.  It is true that
> it doesn't change behaviour, but it leaves more cruft behund than
> it tidies up.
> 
> That said, i agree that we will never implement LC_MESSAGES.
> 
> That allows a nice cleanup, simplifying the code and getting rid
> of several headers and several calls to complicated functions.
> 
> Remarks:
>  * .Tn was deprecated years ago.
>  * On OpenBSD, as the manual page says, nl_langinfo(3) is really
>only useful for CODESET.
>  * There is no need to put a marker "return value ignored on
>purpose" where ignoring the return value almost never indicates
>a bug, like for fprintf, fflush, fclose.

If you're going to change this, please also remove them from run()

>  * Usually, we prefer getline(3) over fgetln(3), but none of the
>arguments making it better really applies here, so we can as
>well leave it.  The only downside is that ttyfp needs to remain
>open until the stdio input buffer has been inspected, so we need
>another automatic variable, "doit", but it's still simpler than
>the malloc(3) dance that getline(3) would require.

Another option would be fgets, but probably still more hassle then
it's worth.

> OK?
>   Ingo
> 
> 
> Index: xargs.1
> ===
> RCS file: /cvs/src/usr.bin/xargs/xargs.1,v
> retrieving revision 1.28
> diff -u -p -r1.28 xargs.1
> --- xargs.1   4 Jun 2014 06:48:33 -   1.28
> +++ xargs.1   16 Jul 2020 19:29:52 -
> @@ -213,11 +213,11 @@ at once.
>  .It Fl p
>  Echo each command to be executed and ask the user whether it should be
>  executed.
> -An affirmative response,
> +If the answer starts with
>  .Ql y
> -in the POSIX locale,
> -causes the command to be executed, any other response causes it to be
> -skipped.
> +or
> +.Ql Y ,
> +the command is executed; otherwise it is skipped.
>  No commands are executed if the process is not attached to a terminal.
>  .It Fl R Ar replacements
>  Specify the maximum number of arguments that
> @@ -330,8 +330,7 @@ The flags
>  are extensions to
>  .St -p1003.1-2008 .
>  .Pp
> -The meanings of the 123, 124, and 125 exit values were taken from
> -.Tn GNU
> +The meanings of the 123, 124, and 125 exit values were taken from GNU
>  .Nm xargs .
>  .Sh HISTORY
>  The
> Index: xargs.c
> ===
> RCS file: /cvs/src/usr.bin/xargs/xargs.c,v
> retrieving revision 1.34
> diff -u -p -r1.34 xargs.c
> --- xargs.c   12 Jun 2018 15:24:31 -  1.34
> +++ xargs.c   16 Jul 2020 19:29:52 -
> @@ -41,10 +41,7 @@
>  #include 
>  #include 
>  #include 
> -#include 
> -#include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> @@ -86,8 +83,6 @@ main(int argc, char *argv[])
>   eofstr = "";
>   Jflag = nflag = 0;
>  
> - (void)setlocale(LC_MESSAGES, "");
> -
>   /*
>* POSIX.2 limits the exec line length to ARG_MAX - 2K.  Running that
>* caused some E2BIG errors, so it was changed to ARG_MAX - 4K.  Given
> @@ -607,26 +602,19 @@ waitchildren(const char *name, int waita
>  static int
>  prompt(void)
>  {
> - regex_t cre;
>   size_t rsize;
> - int match;
>   char *response;
>   FILE *ttyfp;
> + int doit = 0;
>  
>   if ((ttyfp = fopen(_PATH_TTY, "r")) == NULL)
>   return (2); /* Indicate that the TTY failed to open. */
> - (void)fprintf(stderr, "?...");
> - (void)fflush(stderr);
> - if ((response = fgetln(ttyfp, )) == NULL ||
> - regcomp(, nl_langinfo(YESEXPR), REG_BASIC) != 0) {
> - (void)fclose(ttyfp);
> - return (0);
> - }
> - response[rsize - 1] = '\0';
> - match = regexec(, response, 0, NULL, 0);
> - (void)fclose(ttyfp);
> - regfree();
> - return (match == 0);
> + fprintf(stderr, "?...");
> + fflush(stderr);

According to setvbuf(3):
The standard error stream stderr is initially unbuffered.
And since setvbuf is not called in xargs this seems superfluous to me.
If this is correct, there's a second fflush that can also be removed.

> + response = fgetln(ttyfp, );
> + doit = response != NULL && (*response == 'y' || *response == 'Y');
> + fclose(ttyfp);
> + return (doit);
>  }
>  
>  static void
> 



Re: [patch] snmpd hrStorageSize negative values

2020-07-01 Thread Martijn van Duren
On Wed, 2020-07-01 at 10:59 -0400, Johan Huldtgren wrote:
> hello,
> 
> On 2017-11-27 10:31, Gerhard Roth wrote:
> > On Sat, 25 Nov 2017 11:42:07 -0700 Joel Knight  
> > wrote:
> > > On Thu, Mar 9, 2017 at 10:02 PM, Joel Knight  
> > > wrote:
> > > > Hi.
> > > > 
> > > > snmpd(8) uses unsigned ints internally to represent the size and used
> > > > space of a file system. The HOST-RESOURCES-MIB defines the valid
> > > > values for those OIDs as 0..2147483647. With sufficiently large file
> > > > systems, this can cause negative numbers to be returned for the size
> > > > and used space OIDs.
> > > > 
> > > > .1.3.6.1.2.1.25.2.3.1.5.36=-1573167768  
> > > 
> > > Hi. Just wanted to bump this again and see if anyone that cares about
> > > snmp could take a look? Looking for oks and someone who wouldn't mind
> > > committing it.
> > > 
> > > 
> > > > At sthen's suggestion, do what net-snmp does and fiddle with the
> > > > values to prevent wrapping. Yes this mucks with the actual values of
> > > > size, used space, and block size, but it allows snmpd to convey the
> > > > proper size and used space of the file system which is what most
> > > > everybody is really interested in.
> > > > 
> > > > In case gmail hoses this diff, it's also here:
> > > > https://www.packetmischief.ca/files/patches/snmpd.hrstorage2.diff  
> > 
> > Hi Joel,
> > 
> > I think this won't work unless you also change the type of 'size' and
> > 'used' to u_int64_t.
> 
> I ran into an issue where my snmpd underreported my filesystem size.
> 
> $ df -h /ftp
> Filesystem SizeUsed   Avail Capacity  Mounted on
> /dev/sd0a 50.5T   13.7T   34.3T29%/ftp
> 
> However snmp reports something different.
> 
> $ snmp walk -v 2c -c public localhost hrStorage
> 
> hrStorageDescr.40 = STRING: /ftp
> hrStorageAllocationUnits.40 = INTEGER: 8192 Bytes
> hrStorageSize.40 = INTEGER: 2487209520
> 
> sthen@ pointed me to this thread but suggested 'int_t' as opposed to
> 'u_int_64_t', making that change and applying it fixes the issue for
> me.
> 
> hrStorageDescr.40 = STRING: /ftp
> hrStorageAllocationUnits.40 = INTEGER: 32768
> hrStorageUsed.40 = INTEGER: 459624840
> 
> Updated patch attached.
> 
> thanks,
> 
> .jh

Some minor tweaks:
- Use u_int64_t instead of size_t
- Put the calculation outside the switch, so memory can profit as well.

OK?

martijn@

Index: mib.c
===
RCS file: /cvs/src/usr.sbin/snmpd/mib.c,v
retrieving revision 1.99
diff -u -p -r1.99 mib.c
--- mib.c   15 May 2020 00:56:03 -  1.99
+++ mib.c   1 Jul 2020 15:39:37 -
@@ -563,7 +563,7 @@ mib_hrstorage(struct oid *oid, struct be
u_int32_tidx;
struct statfs   *mntbuf, *mnt;
int  mntsize, maxsize;
-   u_int32_tunits, size, used, fail = 0;
+   u_int64_tunits, size, used, fail = 0;
const char  *descr = NULL;
int  mib[] = { CTL_HW, 0 };
u_int64_tphysmem, realmem;
@@ -645,6 +645,12 @@ mib_hrstorage(struct oid *oid, struct be
used = mnt->f_blocks - mnt->f_bfree;
sop = [3];
break;
+   }
+
+   while (size > INT32_MAX) {
+   units *= 2;
+   size /= 2;
+   used /= 2;
}
 
/* Tables need to prepend the OID on their own */



Re: Potential grep bug?

2020-06-24 Thread Martijn van Duren
Moving to tech@

On Tue, 2020-06-23 at 22:17 -0900, Philip Guenther wrote:
> Nope.  This is a grep of a single file, so procfile() must be overflowing
> and this only 'fixes' it by relying on signed overflow, which is undefined
> behavior, being handled in a particular way by the compiler.  So, luck
> (which fails when the compiler decides to hate you).  There are more places
> that need to change for the reported problem to be handled safely.
> 
> Philip Guenther

I'm not sure I understand exactly what you mean, but the overflow can
still propagate through to the return value. Since everything propagated
up from procfile is only eventually used to determine the exit value we
can start treating it as a boolean.

I gave a quick glance at freebsd and they also treat it as a boolean,
but more explicitly. They however don't appear have overflow detection.

Is this better?

martijn@
> 
> 
> On Tue, Jun 23, 2020 at 9:58 PM Martijn van Duren <
> open...@list.imperialat.at> wrote:
> 
> > This seems to fix the issue for me.
> > 
> > OK?
> > 
> > martijn@
> > 
> > On Tue, 2020-06-23 at 19:29 -0700, Jordan Geoghegan wrote:
> > > Hello,
> > > 
> > > I was working on a couple POSIX regular expressions to search for and
> > > validate IPv4 and IPv6 addresses with optional CIDR blocks, and
> > > encountered some strange behaviour from the base system grep.
> > > 
> > > I wanted to validate my regex against a list of every valid IPv4
> > > address, so I generated a list with a zsh 1 liner:
> > > 
> > >   for i in {0..255}; do; echo $i.{0..255}.{0..255}.{0..255} ; done |
> > > tr '[:space:]' '\n' > IPv4.txt
> > > 
> > > My intentions were to test the regex by running it with 'grep -c' to
> > > confirm there was indeed 2^32 addresses matched, and I also wanted to
> > > benchmark and compare performance between BSD grep, GNU grep and
> > > ripgrep. The command I used:
> > > 
> > > grep -Eoc
> > > 
> > "((25[0-5]|(2[0-4]|1{0,1}[[:digit:]]){0,1}[[:digit:]])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[[:digit:]]){0,1}[[:digit:]])(/[1-9]|/[1-2][[:digit:]]|/3[0-2])?"
> > > My findings were surprising. Both GNU grep and ripgrep were able get
> > > through the file in roughly 10 and 20 minutes respectively, whereas the
> > > base system grep took over 20 hours! What interested me the most was
> > > that the base system grep when run with '-c' returned '0' for match
> > > count. It seems that 'grep -c' will have its counter overflow if there
> > > are more than 2^32-1 matches (4294967295) and then the counter will
> > > start counting from zero again for further matches.
> > > 
> > >  ryzen$ time zcat IPv4.txt.gz | grep -Eoc
> > "((25[0-5]|(2[0-4]|1{0,1}...
> > >  0
> > >  1222m09.32s real  1224m28.02s user 1m16.17s system
> > > 
> > >  ryzen$ time zcat allip.txt.gz | ggrep -Eoc
> > "((25[0-5]|(2[0-4]|1{0,1}...
> > >  4294967296
> > >  10m00.38s real11m40.57s user 0m30.55s system
> > > 
> > >  ryzen$ time rg -zoc "((25[0-5]|(2[0-4]|1{0,1}...
> > >  4294967296
> > >  21m06.36s real27m06.04s user 0m50.08s system
> > > 
> > > # See the counter overflow/reset:
> > >  jot 4294967350 | grep -c "^[[:digit:]]"
> > >  54
> > > 
> > > All testing was done on a Ryzen desktop machine running 6.7 stable.
> > > 
> > > The grep counting bug can be reproduced with this command:
> > > jot 4294967296 | nice grep -c "^[[:digit:]]"
> > > 
> > > Regards,
> > > 
> > > Jordan
> > > 
Index: grep.c
===
RCS file: /cvs/src/usr.bin/grep/grep.c,v
retrieving revision 1.64
diff -u -p -r1.64 grep.c
--- grep.c  3 Dec 2019 09:14:37 -   1.64
+++ grep.c  24 Jun 2020 11:26:25 -
@@ -517,7 +517,7 @@ main(int argc, char *argv[])
c = grep_tree(argv);
else
for (c = 0; argc--; ++argv)
-   c += procfile(*argv);
+   c |= procfile(*argv);
 
exit(c ? (file_err ? (qflag ? 0 : 2) : 0) : (file_err ? 2 : 1));
 }
Index: util.c
===
RCS file: /cvs/src/usr.bin/grep/util.c,v
retrieving revision 1.62
diff -u -p -r1.62 util.c
--- util.c  3 Dec 2019 09:14:37 -   1.62
+++ util.c  24 Jun 2020 11:26:25 -
@@ -91,7 +91,7 @@ grep_tree(char **argv)
 

Re: snmp(1) initial UTF-8 support

2020-06-13 Thread Martijn van Duren
And of course I still had a potential buffer overflow in there...

On Sat, 2020-06-13 at 09:16 +0200, Martijn van Duren wrote:
> Minor change: I forgot to forward the display_hint flag to
> smi_displayhint_os. Now -OQ and -Oq work as well.
> 
> On Thu, 2020-06-11 at 21:17 +0200, Martijn van Duren wrote:
> > Hello Ingo,
> > 
> > Thanks for looking into this.
> > 
> > On Sun, 2020-05-31 at 16:32 +0200, Ingo Schwarze wrote:
> > > Hi Martijn,
> > > 
> > > Martijn van Duren wrote on Tue, May 19, 2020 at 10:25:37PM +0200:
> > > 
> > > > So according to RFC2579 an octetstring can contain UTF-8 characters if  
> > > > so described in the DISPLAY-HINT. One of the main consumers of this is
> > > > SnmpAdminString, which is used quite a lot.
> > > > 
> > > > Now that we trimmed a little fat from snmp's oid, I wanted to fill it
> > > > up again and implemented the bare minimum DISPLAY-HINT parsing that is
> > > > required for SnmpAdminString. Other parts of the syntax can be atter
> > > > at a later state if desirable.
> > > > 
> > > > Now I decided to implement this a little different from net-snmp,
> > > > because they throw incomplete sequences directly to the terminal,
> > > > which I recon is not a sane approach.
> > > 
> > > No, definitely not.  Never throw invalid or incomplete UTF-8 at the
> > > terminal unless the user unambiguously requests just that (like
> > > with `printf "a\x80z\n"` or `cat /usr/bin/cc` or something like that).
> > > 
> > > > I choose to take the approach taken by the likes of wall(1) and replace
> > > > invalid and incomplete sequences with a '?'.
> > > 
> > > If the specification says that the user is only allowed to put valid
> > > UTF-8 into octetstrings (and not arbitrary bytes), replacing invalid
> > > bytes at output time is both acceptable and feels like the only
> > > sensible option, unless something like vis(3) is considered more
> > > appropriate.
> > 
> > RFC2579 section 3.1 bullet (3): or `t' for UTF-8
> > So it should be valid UTF-8.
> > > However, the reason why wall(1) uses '?' as the replacement character
> > > is because wall(1) must not assume that the output device can handle
> > > UTF-8 and has to work safely if all the output device can handle is
> > > ASCII.  So, wall(1) has to live with the inconvenience that when you
> > > see a question mark, you don't know whether it really is a question
> > > mark or whether it originally used to be garbage input.
> > 
> > Fair enough.
> > > If i understand correctly, here we are talking about output that is
> > > UTF-8 anyway.  So instead of (ab)using the question mark, you might
> > > consider using the U+FFFD REPLACEMENT CHARACTER.  The intended
> > > purpose of that one is to stand in for invalid and inconplete
> > > byte sequences, and also for characters that cannot be displayed.
> > 
> > I like that one, used in diff below.
> > > > This because DISPLAY-HINT already states that too long sequences
> > > > strings should be cut short at the final multibyte character fitting
> > > > inside the specified length, meaning that output can already get
> > > > mangled.
> > > > 
> > > > This also brings me to the question how we should handle DISPLAY-HINT
> > > > in the case of -Oa and -Ox. Net-snmp prioritizes DISPLAY-HINT over
> > > > these, but it has the option to disable this by disabling MIB-loading
> > > > via -m''; This implementation doesn't give us the that option (yet?).
> > > > The current diff follows net-snmp, but there is something to say to
> > > > prioritize -Ox over DISPLAY-HINT, so an admin can use it to debug
> > > > snmp-output without it being mangled. Any feedback here is welcome.
> > > > 
> > > > Once it's clear if this is the right approach I'll do a thorough search
> > > > through mib.h on which objects actually can use this new definition.
> > > 
> > > I can't really comment on what snmp(1) should do, or which settings
> > > should override which other settings.
> > 
> > I'll leave it as is for now. If people actually need to original mangled
> > data we can always revisit. It's not something major that people heavily
> > rely on.
> > > Do i understand correctly that you want to make -Oa print invalid
> > > UTF-8 to the terminal?
> > 
> > No, to be in line w

Re: snmp(1) initial UTF-8 support

2020-06-13 Thread Martijn van Duren
Minor change: I forgot to forward the display_hint flag to
smi_displayhint_os. Now -OQ and -Oq work as well.

On Thu, 2020-06-11 at 21:17 +0200, Martijn van Duren wrote:
> Hello Ingo,
> 
> Thanks for looking into this.
> 
> On Sun, 2020-05-31 at 16:32 +0200, Ingo Schwarze wrote:
> > Hi Martijn,
> > 
> > Martijn van Duren wrote on Tue, May 19, 2020 at 10:25:37PM +0200:
> > 
> > > So according to RFC2579 an octetstring can contain UTF-8 characters if  
> > > so described in the DISPLAY-HINT. One of the main consumers of this is
> > > SnmpAdminString, which is used quite a lot.
> > > 
> > > Now that we trimmed a little fat from snmp's oid, I wanted to fill it
> > > up again and implemented the bare minimum DISPLAY-HINT parsing that is
> > > required for SnmpAdminString. Other parts of the syntax can be atter
> > > at a later state if desirable.
> > > 
> > > Now I decided to implement this a little different from net-snmp,
> > > because they throw incomplete sequences directly to the terminal,
> > > which I recon is not a sane approach.
> > 
> > No, definitely not.  Never throw invalid or incomplete UTF-8 at the
> > terminal unless the user unambiguously requests just that (like
> > with `printf "a\x80z\n"` or `cat /usr/bin/cc` or something like that).
> > 
> > > I choose to take the approach taken by the likes of wall(1) and replace
> > > invalid and incomplete sequences with a '?'.
> > 
> > If the specification says that the user is only allowed to put valid
> > UTF-8 into octetstrings (and not arbitrary bytes), replacing invalid
> > bytes at output time is both acceptable and feels like the only
> > sensible option, unless something like vis(3) is considered more
> > appropriate.
> 
> RFC2579 section 3.1 bullet (3): or `t' for UTF-8
> So it should be valid UTF-8.
> > However, the reason why wall(1) uses '?' as the replacement character
> > is because wall(1) must not assume that the output device can handle
> > UTF-8 and has to work safely if all the output device can handle is
> > ASCII.  So, wall(1) has to live with the inconvenience that when you
> > see a question mark, you don't know whether it really is a question
> > mark or whether it originally used to be garbage input.
> 
> Fair enough.
> > If i understand correctly, here we are talking about output that is
> > UTF-8 anyway.  So instead of (ab)using the question mark, you might
> > consider using the U+FFFD REPLACEMENT CHARACTER.  The intended
> > purpose of that one is to stand in for invalid and inconplete
> > byte sequences, and also for characters that cannot be displayed.
> 
> I like that one, used in diff below.
> > > This because DISPLAY-HINT already states that too long sequences
> > > strings should be cut short at the final multibyte character fitting
> > > inside the specified length, meaning that output can already get
> > > mangled.
> > > 
> > > This also brings me to the question how we should handle DISPLAY-HINT
> > > in the case of -Oa and -Ox. Net-snmp prioritizes DISPLAY-HINT over
> > > these, but it has the option to disable this by disabling MIB-loading
> > > via -m''; This implementation doesn't give us the that option (yet?).
> > > The current diff follows net-snmp, but there is something to say to
> > > prioritize -Ox over DISPLAY-HINT, so an admin can use it to debug
> > > snmp-output without it being mangled. Any feedback here is welcome.
> > > 
> > > Once it's clear if this is the right approach I'll do a thorough search
> > > through mib.h on which objects actually can use this new definition.
> > 
> > I can't really comment on what snmp(1) should do, or which settings
> > should override which other settings.
> 
> I'll leave it as is for now. If people actually need to original mangled
> data we can always revisit. It's not something major that people heavily
> rely on.
> > Do i understand correctly that you want to make -Oa print invalid
> > UTF-8 to the terminal?
> 
> No, to be in line with net-snmp, what snmp(1) does is the following:
> - Without a -O flag it sees if all bytes are printable and if so print
>   the string, if not prints the full string in hex.
> - With -Oa it prints all printable bytes and replaces unprintable
>   characters with '.'.
> - With -Ox it prints all bytes in hex.
> 
> > If so, that would sound reasonable to me,
> > for the following reason.  Printing non-printable ASCII to the
> > terminal is often dangerous, it can screw up or reconfigure the
> 

Re: snmp(1) initial UTF-8 support

2020-06-11 Thread Martijn van Duren
Hello Ingo,

Thanks for looking into this.

On Sun, 2020-05-31 at 16:32 +0200, Ingo Schwarze wrote:
> Hi Martijn,
> 
> Martijn van Duren wrote on Tue, May 19, 2020 at 10:25:37PM +0200:
> 
> > So according to RFC2579 an octetstring can contain UTF-8 characters if  
> > so described in the DISPLAY-HINT. One of the main consumers of this is
> > SnmpAdminString, which is used quite a lot.
> > 
> > Now that we trimmed a little fat from snmp's oid, I wanted to fill it
> > up again and implemented the bare minimum DISPLAY-HINT parsing that is
> > required for SnmpAdminString. Other parts of the syntax can be atter
> > at a later state if desirable.
> > 
> > Now I decided to implement this a little different from net-snmp,
> > because they throw incomplete sequences directly to the terminal,
> > which I recon is not a sane approach.
> 
> No, definitely not.  Never throw invalid or incomplete UTF-8 at the
> terminal unless the user unambiguously requests just that (like
> with `printf "a\x80z\n"` or `cat /usr/bin/cc` or something like that).
> 
> > I choose to take the approach taken by the likes of wall(1) and replace
> > invalid and incomplete sequences with a '?'.
> 
> If the specification says that the user is only allowed to put valid
> UTF-8 into octetstrings (and not arbitrary bytes), replacing invalid
> bytes at output time is both acceptable and feels like the only
> sensible option, unless something like vis(3) is considered more
> appropriate.

RFC2579 section 3.1 bullet (3): or `t' for UTF-8
So it should be valid UTF-8.
> 
> However, the reason why wall(1) uses '?' as the replacement character
> is because wall(1) must not assume that the output device can handle
> UTF-8 and has to work safely if all the output device can handle is
> ASCII.  So, wall(1) has to live with the inconvenience that when you
> see a question mark, you don't know whether it really is a question
> mark or whether it originally used to be garbage input.

Fair enough.
> 
> If i understand correctly, here we are talking about output that is
> UTF-8 anyway.  So instead of (ab)using the question mark, you might
> consider using the U+FFFD REPLACEMENT CHARACTER.  The intended
> purpose of that one is to stand in for invalid and inconplete
> byte sequences, and also for characters that cannot be displayed.

I like that one, used in diff below.
> 
> > This because DISPLAY-HINT already states that too long sequences
> > strings should be cut short at the final multibyte character fitting
> > inside the specified length, meaning that output can already get
> > mangled.
> > 
> > This also brings me to the question how we should handle DISPLAY-HINT
> > in the case of -Oa and -Ox. Net-snmp prioritizes DISPLAY-HINT over
> > these, but it has the option to disable this by disabling MIB-loading
> > via -m''; This implementation doesn't give us the that option (yet?).
> > The current diff follows net-snmp, but there is something to say to
> > prioritize -Ox over DISPLAY-HINT, so an admin can use it to debug
> > snmp-output without it being mangled. Any feedback here is welcome.
> > 
> > Once it's clear if this is the right approach I'll do a thorough search
> > through mib.h on which objects actually can use this new definition.
> 
> I can't really comment on what snmp(1) should do, or which settings
> should override which other settings.

I'll leave it as is for now. If people actually need to original mangled
data we can always revisit. It's not something major that people heavily
rely on.
> 
> Do i understand correctly that you want to make -Oa print invalid
> UTF-8 to the terminal?

No, to be in line with net-snmp, what snmp(1) does is the following:
- Without a -O flag it sees if all bytes are printable and if so print
  the string, if not prints the full string in hex.
- With -Oa it prints all printable bytes and replaces unprintable
  characters with '.'.
- With -Ox it prints all bytes in hex.

> If so, that would sound reasonable to me,
> for the following reason.  Printing non-printable ASCII to the
> terminal is often dangerous, it can screw up or reconfigure the
> terminal, so -Oa is already an option that must be used with care,
> just like `cat /usr/bin/cc`.  While printing invalid UTF-8 is not
> a good idea in general, it is less dangerous than printing non-printable
> ASCII, so just passing the bytes through for -Oa doesn't make
> anything more dangerous than it already is.
> 
> Maybe -Oa should have a warning in the manual page about the dangers
> of using it on untrusted data?  Not sure.

So no, it's not dangerous.
> 
> Oh, by the way, when -Oa is not specified and there is UTF-8
> content, 

Re: Some redundant code lines in sys

2020-06-05 Thread Martijn van Duren
On Fri, 2020-06-05 at 14:20 +0100, Stuart Henderson wrote:
> On 2020/06/05 13:50, Denis Fondras wrote:
> > On Fri, Jun 05, 2020 at 12:56:21PM +0200, Prof. Dr. Steffen Wendzel wrote:
> > > Dear all:
> > > 
> > > just in case this appears useful to you: I found some redundant code
> > > lines in the following files.
> > > 
> > > sys/net/pipex.h:
> > >struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
> > >struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
> > > 
> > > usr.sbin/relayd/agentx.c
> > >snmp_agentx_oid(pdu, oid) == -1 ||
> > >snmp_agentx_oid(pdu, oid) == -1 ||
> > > 
> > > usr.sbin/snmpd/agentx.c:
> > >  snmp_agentx_oid(pdu, oid) == -1 ||
> > >  snmp_agentx_oid(pdu, oid) == -1 ||
> 
> My first thought for these two was "were they just accidentally
> duplicated, or was something else meant to be there instead". Looking at
> the commit and code (the function is identical in snmpd and relayd) I am
> going more on the side of accidental dup (plus removing it doesn't
> change behaviour of code that been running for a while) so OK with me.

It's definitely a duplicate. This is when an unregister-pdu is created,
which only contains a single OID. Ranges can be specified, that's done
via the range_index/range_bound combo, or as the RFC names them:
range_subid/upper_bound.

Since the unregister pdu is a client generated pdu it's by definition
not being called in snmpd(8). A quick grep in relayd shows that it's
also never called there.
> 
> > > usr.sbin/bgpd/rde.h:
> > >   void path_init(u_int32_t);
> > >   void path_init(u_int32_t);
> > > 
> > > lib/libcurses/nc_tparm.h:
> > > #define TPARM_1(a,b) TPARM_2(a,b,0)
> > > #define TPARM_1(a,b) TPARM_2(a,b,0)
> > > 
> > 
> > Nice catch, thank you.
> > 
> > 
> > Index: lib/libcurses/nc_tparm.h
> > ===
> > RCS file: /cvs/src/lib/libcurses/nc_tparm.h,v
> > retrieving revision 1.1
> > diff -u -p -r1.1 nc_tparm.h
> > --- lib/libcurses/nc_tparm.h12 Jan 2010 23:21:59 -  1.1
> > +++ lib/libcurses/nc_tparm.h5 Jun 2020 11:45:41 -
> > @@ -62,6 +62,5 @@
> >  #define TPARM_3(a,b,c,d) TPARM_4(a,b,c,d,0)
> >  #define TPARM_2(a,b,c) TPARM_3(a,b,c,0)
> >  #define TPARM_1(a,b) TPARM_2(a,b,0)
> > -#define TPARM_1(a,b) TPARM_2(a,b,0)
> >  #define TPARM_0(a) TPARM_1(a,0)
> >  #endif
> > Index: sys/net/pipex.h
> > ===
> > RCS file: /cvs/src/sys/net/pipex.h,v
> > retrieving revision 1.22
> > diff -u -p -r1.22 pipex.h
> > --- sys/net/pipex.h 26 May 2020 07:06:37 -  1.22
> > +++ sys/net/pipex.h 5 Jun 2020 11:45:44 -
> > @@ -206,7 +206,6 @@ int   pipex_notify_close
> >  
> >  struct mbuf   *pipex_output (struct mbuf *, int, int, struct 
> > pipex_iface_context *);
> >  struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
> > -struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
> >  struct mbuf   *pipex_pppoe_input (struct mbuf *, struct 
> > pipex_session *);
> >  struct pipex_session  *pipex_pptp_lookup_session (struct mbuf *);
> >  struct mbuf   *pipex_pptp_input (struct mbuf *, struct 
> > pipex_session *);
> > Index: usr.sbin/bgpd/rde.h
> > ===
> > RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
> > retrieving revision 1.233
> > diff -u -p -r1.233 rde.h
> > --- usr.sbin/bgpd/rde.h 24 Jan 2020 05:44:05 -  1.233
> > +++ usr.sbin/bgpd/rde.h 5 Jun 2020 11:45:45 -
> > @@ -557,7 +557,6 @@ re_rib(struct rib_entry *re)
> >  }
> >  
> >  voidpath_init(u_int32_t);
> > -voidpath_init(u_int32_t);
> >  voidpath_shutdown(void);
> >  voidpath_hash_stats(struct rde_hashstats *);
> >  int path_compare(struct rde_aspath *, struct rde_aspath *);
> > Index: usr.sbin/relayd/agentx.c
> > ===
> > RCS file: /cvs/src/usr.sbin/relayd/agentx.c,v
> > retrieving revision 1.14
> > diff -u -p -r1.14 agentx.c
> > --- usr.sbin/relayd/agentx.c28 May 2017 10:39:15 -  1.14
> > +++ usr.sbin/relayd/agentx.c5 Jun 2020 11:45:45 -
> > @@ -654,7 +654,6 @@ snmp_agentx_unregister_pdu(struct snmp_o
> >  
> > if (snmp_agentx_raw(pdu, , sizeof(uhdr)) == -1 ||
> > snmp_agentx_oid(pdu, oid) == -1 ||
> > -   snmp_agentx_oid(pdu, oid) == -1 ||
> > (range_index && snmp_agentx_int(pdu, _bound) == -1)) {
> > snmp_agentx_pdu_free(pdu);
> > return (NULL);
> > Index: usr.sbin/snmpd/agentx.c
> > ===
> > RCS file: /cvs/src/usr.sbin/snmpd/agentx.c,v
> > retrieving revision 1.13
> > diff -u -p -r1.13 agentx.c
> > --- usr.sbin/snmpd/agentx.c 17 Jun 2018 18:19:59 - 

Re: Some redundant code lines in sys

2020-06-05 Thread Martijn van Duren
OK martijn@

On Fri, 2020-06-05 at 13:50 +0200, Denis Fondras wrote:
> On Fri, Jun 05, 2020 at 12:56:21PM +0200, Prof. Dr. Steffen Wendzel wrote:
> > Dear all:
> > 
> > just in case this appears useful to you: I found some redundant code
> > lines in the following files.
> > 
> > sys/net/pipex.h:
> >struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
> >struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
> > 
> > usr.sbin/relayd/agentx.c
> >snmp_agentx_oid(pdu, oid) == -1 ||
> >snmp_agentx_oid(pdu, oid) == -1 ||
> > 
> > usr.sbin/snmpd/agentx.c:
> >  snmp_agentx_oid(pdu, oid) == -1 ||
> >  snmp_agentx_oid(pdu, oid) == -1 ||
> > 
> > usr.sbin/bgpd/rde.h:
> >   void path_init(u_int32_t);
> >   void path_init(u_int32_t);
> > 
> > lib/libcurses/nc_tparm.h:
> > #define TPARM_1(a,b) TPARM_2(a,b,0)
> > #define TPARM_1(a,b) TPARM_2(a,b,0)
> > 
> 
> Nice catch, thank you.
> 
> 
> Index: lib/libcurses/nc_tparm.h
> ===
> RCS file: /cvs/src/lib/libcurses/nc_tparm.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 nc_tparm.h
> --- lib/libcurses/nc_tparm.h  12 Jan 2010 23:21:59 -  1.1
> +++ lib/libcurses/nc_tparm.h  5 Jun 2020 11:45:41 -
> @@ -62,6 +62,5 @@
>  #define TPARM_3(a,b,c,d) TPARM_4(a,b,c,d,0)
>  #define TPARM_2(a,b,c) TPARM_3(a,b,c,0)
>  #define TPARM_1(a,b) TPARM_2(a,b,0)
> -#define TPARM_1(a,b) TPARM_2(a,b,0)
>  #define TPARM_0(a) TPARM_1(a,0)
>  #endif
> Index: sys/net/pipex.h
> ===
> RCS file: /cvs/src/sys/net/pipex.h,v
> retrieving revision 1.22
> diff -u -p -r1.22 pipex.h
> --- sys/net/pipex.h   26 May 2020 07:06:37 -  1.22
> +++ sys/net/pipex.h   5 Jun 2020 11:45:44 -
> @@ -206,7 +206,6 @@ int   pipex_notify_close
>  
>  struct mbuf   *pipex_output (struct mbuf *, int, int, struct 
> pipex_iface_context *);
>  struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
> -struct pipex_session  *pipex_pppoe_lookup_session (struct mbuf *);
>  struct mbuf   *pipex_pppoe_input (struct mbuf *, struct 
> pipex_session *);
>  struct pipex_session  *pipex_pptp_lookup_session (struct mbuf *);
>  struct mbuf   *pipex_pptp_input (struct mbuf *, struct pipex_session 
> *);
> Index: usr.sbin/bgpd/rde.h
> ===
> RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
> retrieving revision 1.233
> diff -u -p -r1.233 rde.h
> --- usr.sbin/bgpd/rde.h   24 Jan 2020 05:44:05 -  1.233
> +++ usr.sbin/bgpd/rde.h   5 Jun 2020 11:45:45 -
> @@ -557,7 +557,6 @@ re_rib(struct rib_entry *re)
>  }
>  
>  void  path_init(u_int32_t);
> -void  path_init(u_int32_t);
>  void  path_shutdown(void);
>  void  path_hash_stats(struct rde_hashstats *);
>  int   path_compare(struct rde_aspath *, struct rde_aspath *);
> Index: usr.sbin/relayd/agentx.c
> ===
> RCS file: /cvs/src/usr.sbin/relayd/agentx.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 agentx.c
> --- usr.sbin/relayd/agentx.c  28 May 2017 10:39:15 -  1.14
> +++ usr.sbin/relayd/agentx.c  5 Jun 2020 11:45:45 -
> @@ -654,7 +654,6 @@ snmp_agentx_unregister_pdu(struct snmp_o
>  
>   if (snmp_agentx_raw(pdu, , sizeof(uhdr)) == -1 ||
>   snmp_agentx_oid(pdu, oid) == -1 ||
> - snmp_agentx_oid(pdu, oid) == -1 ||
>   (range_index && snmp_agentx_int(pdu, _bound) == -1)) {
>   snmp_agentx_pdu_free(pdu);
>   return (NULL);
> Index: usr.sbin/snmpd/agentx.c
> ===
> RCS file: /cvs/src/usr.sbin/snmpd/agentx.c,v
> retrieving revision 1.13
> diff -u -p -r1.13 agentx.c
> --- usr.sbin/snmpd/agentx.c   17 Jun 2018 18:19:59 -  1.13
> +++ usr.sbin/snmpd/agentx.c   5 Jun 2020 11:45:45 -
> @@ -658,7 +658,6 @@ snmp_agentx_unregister_pdu(struct snmp_o
>  
>   if (snmp_agentx_raw(pdu, , sizeof(uhdr)) == -1 ||
>   snmp_agentx_oid(pdu, oid) == -1 ||
> - snmp_agentx_oid(pdu, oid) == -1 ||
>   (range_index && snmp_agentx_int(pdu, _bound) == -1)) {
>   snmp_agentx_pdu_free(pdu);
>   return (NULL);
> 



"extent" in dmesg

2020-06-02 Thread Martijn van Duren
After updating today I noticed a couple of new extent messages in my  
dmesg, which I apparently missed last upgrade. Luckily the dmesg buffer
is large enough to find the first mention.

The machine runs just fine, but I just wanted to post it here, because
it does stand out and I don't know how useful the information is.

full dmesg with and without below

martijn@

OpenBSD 6.7 (GENERIC.MP) #182: Thu May  7 11:11:58 MDT 2020
dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 16908218368 (16124MB)
avail mem = 16383160320 (15624MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 3.0 @ 0xaf04c000 (63 entries)
bios0: vendor LENOVO version "N22ET53W (1.30 )" date 02/19/2019
bios0: LENOVO 20L7S27G00
acpi0 at bios0: ACPI 5.0
acpi0: sleep states S0 S3 S4 S5
acpi0: tables DSDT FACP SSDT UEFI SSDT SSDT HPET APIC MCFG ECDT SSDT SSDT BOOT 
BATB SLIC SSDT SSDT SSDT LPIT WSMT SSDT SSDT SSDT DBGP DBG2 MSDM DMAR ASF! FPDT 
BGRT UEFI
acpi0: wakeup devices GLAN(S4) XHC_(S3) XDCI(S4) HDAS(S4) RP01(S4) PXSX(S4) 
RP02(S4) PXSX(S4) PXSX(S4) RP04(S4) PXSX(S4) RP05(S4) PXSX(S4) RP06(S4) 
PXSX(S4) RP07(S4) [...]
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpihpet0 at acpi0: 2399 Hz
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, 1789.11 MHz, 06-8e-0a
cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-
CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,TSC_ADJUST,SGX,BMI1,
AVX2,SMEP,BMI2,ERMS,INVPCID,MPX,RDSEED,ADX,SMAP,CLFLUSHOPT,PT,MD_CLEAR,TSXFA,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,XSAVEC,XGETBV1,XSAVES,MELTDOWN
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 10 var ranges, 88 fixed ranges
cpu0: apic clock running at 24MHz
cpu0: mwait min=64, max=64, C-substates=0.2.1.2.4.1.1.1, IBE
cpu1 at mainbus0: apid 2 (application processor)
cpu1: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, 1789.26 MHz, 06-8e-0a
cpu1: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-
CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,TSC_ADJUST,SGX,BMI1,
AVX2,SMEP,BMI2,ERMS,INVPCID,MPX,RDSEED,ADX,SMAP,CLFLUSHOPT,PT,MD_CLEAR,TSXFA,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,XSAVEC,XGETBV1,XSAVES,MELTDOWN
cpu1: 256KB 64b/line 8-way L2 cache
cpu1: smt 0, core 1, package 0
cpu2 at mainbus0: apid 4 (application processor)
cpu2: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, 1789.27 MHz, 06-8e-0a
cpu2: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-
CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,TSC_ADJUST,SGX,BMI1,
AVX2,SMEP,BMI2,ERMS,INVPCID,MPX,RDSEED,ADX,SMAP,CLFLUSHOPT,PT,MD_CLEAR,TSXFA,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,XSAVEC,XGETBV1,XSAVES,MELTDOWN
cpu2: 256KB 64b/line 8-way L2 cache
cpu2: smt 0, core 2, package 0
cpu3 at mainbus0: apid 6 (application processor)
cpu3: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, 1790.42 MHz, 06-8e-0a
cpu3: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE,SSE3,PCLMUL,DTES64,MWAIT,DS-
CPL,VMX,EST,TM2,SSSE3,SDBG,FMA3,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,PERF,ITSC,FSGSBASE,TSC_ADJUST,SGX,BMI1,
AVX2,SMEP,BMI2,ERMS,INVPCID,MPX,RDSEED,ADX,SMAP,CLFLUSHOPT,PT,MD_CLEAR,TSXFA,IBRS,IBPB,STIBP,L1DF,SSBD,SENSOR,ARAT,XSAVEOPT,XSAVEC,XGETBV1,XSAVES,MELTDOWN
cpu3: 256KB 64b/line 8-way L2 cache
cpu3: smt 0, core 3, package 0
ioapic0 at mainbus0: apid 2 pa 0xfec0, version 20, 120 pins
acpimcfg0 at acpi0
acpimcfg0: addr 0xf800, bus 0-63
acpiec0 at acpi0
acpiprt0 at acpi0: bus 0 (PCI0)
acpiprt1 at acpi0: bus 1 (RP01)
acpiprt2 at acpi0: bus -1 (RP02)
acpiprt3 at acpi0: bus -1 (RP03)
acpiprt4 at acpi0: bus -1 (RP04)
acpiprt5 at acpi0: bus 4 (RP05)
acpiprt6 at acpi0: bus -1 (RP06)
acpiprt7 at acpi0: bus 61 (RP07)
acpiprt8 at acpi0: bus -1 (RP08)
acpiprt9 at acpi0: bus 62 (RP09)
acpiprt10 at acpi0: bus -1 (RP10)
acpiprt11 at acpi0: bus -1 (RP11)
acpiprt12 at acpi0: bus -1 (RP12)
acpiprt13 at acpi0: bus -1 (RP13)
acpiprt14 at acpi0: bus -1 (RP14)
acpiprt15 at acpi0: bus -1 (RP15)
acpiprt16 at acpi0: bus -1 (RP16)
acpiprt17 at acpi0: bus -1 (RP17)
acpiprt18 at 

snmp(1) initial UTF-8 support

2020-05-19 Thread Martijn van Duren
So according to RFC2579 an octetstring can contain UTF-8 characters if  
so described in the DISPLAY-HINT. One of the main consumers of this is
SnmpAdminString, which is used quite a lot.

Now that we trimmed a little fat from snmp's oid, I wanted to fill it
up again and implemented the bare minimum DISPLAY-HINT parsing that is
required for SnmpAdminString. Other parts of the syntax can be atter
at a later state if desirable.

Now I decided to implement this a little different from net-snmp,
because they throw incomplete sequences directly to the terminal, which
I recon is not a sane approach. I choose to take the approach taken by
the likes of wall(1) and replace invalid and incomplete sequences with
a '?'. This because DISPLAY-HINT already states that too long sequences
strings should be cut short at the final multibyte character fitting
inside the specified length, meaning that output can already get
mangled.

This also brings me to the question how we should handle DISPLAY-HINT
in the case of -Oa and -Ox. Net-snmp prioritizes DISPLAY-HINT over
these, but it has the option to disable this by disabling MIB-loading
via -m''; This implementation doesn't give us the that option (yet?).
The current diff follows net-snmp, but there is something to say to
prioritize -Ox over DISPLAY-HINT, so an admin can use it to debug
snmp-output without it being mangled. Any feedback here is welcome.

Once it's clear if this is the right approach I'll do a thorough search
through mib.h on which objects actually can use this new definition.

Example choosen because his copyright was in front of me:
$ snmp walk 127.0.0.1 sysContact  
sysContact.0 = Hex-STRING: 52 65 79 6B 20 46 6C C3 B6 74 65 72
$ ./obj/snmp walk 127.0.0.1 sysContact
sysContact.0 = Reyk Flöter
$ LC_ALL=C
$ ./obj/snmp walk 127.0.0.1 sysContact
sysContact.0 = Reyk Fl?ter

Thoughts?

martijn@

Index: mib.c
===
RCS file: /cvs/src/usr.bin/snmp/mib.c,v
retrieving revision 1.2
diff -u -p -r1.2 mib.c
--- mib.c   19 May 2020 13:41:01 -  1.2
+++ mib.c   19 May 2020 20:21:42 -
@@ -27,9 +27,11 @@
 #include "smi.h"
 
 static struct oid mib_tree[] = MIB_TREE;
+static struct textconv textconv_tree[] = TEXTCONV_TREE;
 
 void
 mib_init(void)
 {
smi_mibtree(mib_tree);
+   smi_textconvtree(textconv_tree);
 }
Index: mib.h
===
RCS file: /cvs/src/usr.bin/snmp/mib.h,v
retrieving revision 1.1
diff -u -p -r1.1 mib.h
--- mib.h   9 Aug 2019 06:17:59 -   1.1
+++ mib.h   19 May 2020 20:21:42 -
@@ -751,7 +751,7 @@
{ MIBDECL(sysDescr) },  \
{ MIBDECL(sysOID) },\
{ MIBDECL(sysUpTime) }, \
-   { MIBDECL(sysContact) },\
+   { MIBDECL(sysContact), "SnmpAdminString" }, \
{ MIBDECL(sysName) },   \
{ MIBDECL(sysLocation) },   \
{ MIBDECL(sysServices) },   \
@@ -1345,6 +1345,11 @@
{ MIBDECL(ipfRouteEntRouteMetric5) },   \
{ MIBDECL(ipfRouteEntStatus) }, \
{ MIBEND }  \
+}
+
+#define TEXTCONV_TREE {\
+   { "SnmpAdminString", "255t", BER_TYPE_OCTETSTRING }, \
+   { NULL, NULL }  \
 }
 
 voidmib_init(void);
Index: smi.c
===
RCS file: /cvs/src/usr.bin/snmp/smi.c,v
retrieving revision 1.8
diff -u -p -r1.8 smi.c
--- smi.c   19 May 2020 13:41:01 -  1.8
+++ smi.c   19 May 2020 20:21:42 -
@@ -24,10 +24,13 @@
 #include 
 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 #include "ber.h"
 #include "mib.h"
@@ -36,8 +39,12 @@
 
 #define MINIMUM(a, b)  (((a) < (b)) ? (a) : (b))
 
+int isu8cont(unsigned char);
+char *smi_displayhint_os(struct textconv *, const char *, size_t);
+
 int smi_oid_cmp(struct oid *, struct oid *);
 int smi_key_cmp(struct oid *, struct oid *);
+int smi_textconv_cmp(struct textconv *, struct textconv *);
 struct oid * smi_findkey(char *);
 
 RB_HEAD(oidtree, oid);
@@ -48,6 +55,10 @@ RB_HEAD(keytree, oid);
 RB_PROTOTYPE(keytree, oid, o_keyword, smi_key_cmp)
 struct keytree smi_keytree;
 
+RB_HEAD(textconvtree, textconv);
+RB_PROTOTYPE(textconvtree, textconv, tc_entry, smi_textconv_cmp);
+struct textconvtree smi_tctree;
+
 int
 smi_init(void)
 {
@@ -181,7 +192,7 @@ smi_debug_elements(struct ber_element *r
fprintf(stderr, "(%u) encoding %u ",
root->be_type, root->be_encoding);
 
-   if ((value = smi_print_element(root, 1, smi_os_default,
+   if ((value = smi_print_element(NULL, root, 1, smi_os_default,
smi_oidl_numeric)) == NULL)
goto 

Re: snmp(1) cleanup snmpd legacy

2020-05-18 Thread Martijn van Duren
Anyone feeling like trimming a little fat?

On Fri, 2020-05-08 at 11:41 +0200, Martijn van Duren wrote:
> Diff below removes fields from struct oid used by snmpd but not useful
> for snmp(1). Minus 503LoC and -200kb on installed binary.
> No functional change intended.
> 
> OK?
> 
> martijn@
> 
> Index: mib.c
> ===
> RCS file: /cvs/src/usr.bin/snmp/mib.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 mib.c
> --- mib.c 9 Aug 2019 06:17:59 -   1.1
> +++ mib.c 8 May 2020 09:40:59 -
> @@ -27,466 +27,9 @@
>  #include "smi.h"
>  
>  static struct oid mib_tree[] = MIB_TREE;
> -static struct oid base_mib[] = {
> - { MIB(mib_2),   OID_MIB },
> - { MIB(sysDescr),OID_RD },
> - { MIB(sysOID),  OID_RD },
> - { MIB(sysUpTime),   OID_RD },
> - { MIB(sysContact),  OID_RW },
> - { MIB(sysName), OID_RW },
> - { MIB(sysLocation), OID_RW },
> - { MIB(sysServices), OID_RS },
> - { MIB(sysORLastChange), OID_RD },
> - { MIB(sysORIndex),  OID_TRD },
> - { MIB(sysORID), OID_TRD },
> - { MIB(sysORDescr),  OID_TRD },
> - { MIB(sysORUpTime), OID_TRD },
> - { MIB(snmp),OID_MIB },
> - { MIB(snmpInPkts),  OID_RD },
> - { MIB(snmpOutPkts), OID_RD },
> - { MIB(snmpInBadVersions),   OID_RD },
> - { MIB(snmpInBadCommunityNames), OID_RD },
> - { MIB(snmpInBadCommunityUses),  OID_RD },
> - { MIB(snmpInASNParseErrs),  OID_RD },
> - { MIB(snmpInTooBigs),   OID_RD },
> - { MIB(snmpInNoSuchNames),   OID_RD },
> - { MIB(snmpInBadValues), OID_RD },
> - { MIB(snmpInReadOnlys), OID_RD },
> - { MIB(snmpInGenErrs),   OID_RD },
> - { MIB(snmpInTotalReqVars),  OID_RD },
> - { MIB(snmpInTotalSetVars),  OID_RD },
> - { MIB(snmpInGetRequests),   OID_RD },
> - { MIB(snmpInGetNexts),  OID_RD },
> - { MIB(snmpInSetRequests),   OID_RD },
> - { MIB(snmpInGetResponses),  OID_RD },
> - { MIB(snmpInTraps), OID_RD },
> - { MIB(snmpOutTooBigs),  OID_RD },
> - { MIB(snmpOutNoSuchNames),  OID_RD },
> - { MIB(snmpOutBadValues),OID_RD },
> - { MIB(snmpOutGenErrs),  OID_RD },
> - { MIB(snmpOutGetRequests),  OID_RD },
> - { MIB(snmpOutGetNexts), OID_RD },
> - { MIB(snmpOutSetRequests),  OID_RD },
> - { MIB(snmpOutGetResponses), OID_RD },
> - { MIB(snmpOutTraps),OID_RD },
> - { MIB(snmpEnableAuthenTraps),   OID_RW },
> - { MIB(snmpSilentDrops), OID_RD },
> - { MIB(snmpProxyDrops),  OID_RD },
> - { MIBEND }
> -};
> -
> -static struct oid usm_mib[] = {
> - { MIB(snmpEngine),  OID_MIB },
> - { MIB(snmpEngineID),OID_RD },
> - { MIB(snmpEngineBoots), OID_RD },
> - { MIB(snmpEngineTime),  OID_RD },
> - { MIB(snmpEngineMaxMsgSize),OID_RD },
> - { MIB(usmStats),OID_MIB },
> - { MIB(usmStatsUnsupportedSecLevels),OID_RD },
> - { MIB(usmStatsNotInTimeWindow), OID_RD },
> - { MIB(usmStatsUnknownUserNames),OID_RD },
> - { MIB(usmStatsUnknownEngineId), OID_RD },
> - { MIB(usmStatsWrongDigests),OID_RD },
> - { MIB(usmStatsDecryptionErrors),OID_RD },
> - { MIBEND }
> -};
> -
> -static struct oid hr_mib[] = {
> - { MIB(host),OID_MIB },
> - { MIB(hrSystemUptime),  OID_RD },
> - { MIB(hrSystemDate),OID_RD },
> - { MIB(hrSystemProcesses),   OID_RD },
> - { MIB(hrSystemMaxProcesses),OID_RD },
> - { MIB(hrMemorySize),OID_RD },
> - { MIB(hrStorageIndex),  OID_TRD },
> - { MIB(hrStorageType),   OID_TRD },
> - { MIB(hrStorageDescr),  OID_TRD },
> - { MIB(hrStorageAllocationUnits),OID_TRD },
> - { MIB(hrStorageSize),   OID_TRD },
> - { MIB(hrStorageUsed),   OID_TRD },
> - { MIB(hrStorageAllocationFailures), OID_TRD },
> - { MIB(hrDeviceIndex),   OID_TRD },
> - { MIB(hrDeviceType),OID_TRD },
> - { MIB(hrDeviceDescr),   OID_TRD },
> - 

snmp(1): Silence gcc warnings

2020-05-10 Thread Martijn van Duren
Clang is smart enough to know that the usage of the variables is
guarded, gcc apparently is not.

No functional change, just silence some compiler warnings.

OK?

martijn@

Index: snmpc.c
===
RCS file: /cvs/src/usr.bin/snmp/snmpc.c,v
retrieving revision 1.23
diff -u -p -r1.23 snmpc.c
--- snmpc.c 8 May 2020 12:21:07 -   1.23
+++ snmpc.c 10 May 2020 16:39:55 -
@@ -111,10 +111,10 @@ main(int argc, char *argv[])
const EVP_CIPHER *cipher = NULL;
struct snmp_sec *sec;
char *user = NULL;
-   enum usm_key_level authkeylevel;
+   enum usm_key_level authkeylevel = USM_KEY_UNSET;
char *authkey = NULL;
size_t authkeylen = 0;
-   enum usm_key_level privkeylevel;
+   enum usm_key_level privkeylevel = USM_KEY_UNSET;
char *privkey = NULL;
size_t privkeylen = 0;
int seclevel = SNMP_MSGFLAG_REPORT;
@@ -122,7 +122,7 @@ main(int argc, char *argv[])
char *ctxengineid = NULL, *secengineid = NULL;
size_t ctxengineidlen, secengineidlen;
int zflag = 0;
-   long long boots, time;
+   long long boots = 0, time = 0;
char optstr[BUFSIZ];
const char *errstr;
char *strtolp;



snmp(1) cleanup snmpd legacy

2020-05-08 Thread Martijn van Duren
Diff below removes fields from struct oid used by snmpd but not useful
for snmp(1). Minus 503LoC and -200kb on installed binary.
No functional change intended.

OK?

martijn@

Index: mib.c
===
RCS file: /cvs/src/usr.bin/snmp/mib.c,v
retrieving revision 1.1
diff -u -p -r1.1 mib.c
--- mib.c   9 Aug 2019 06:17:59 -   1.1
+++ mib.c   8 May 2020 09:40:59 -
@@ -27,466 +27,9 @@
 #include "smi.h"
 
 static struct oid mib_tree[] = MIB_TREE;
-static struct oid base_mib[] = {
-   { MIB(mib_2),   OID_MIB },
-   { MIB(sysDescr),OID_RD },
-   { MIB(sysOID),  OID_RD },
-   { MIB(sysUpTime),   OID_RD },
-   { MIB(sysContact),  OID_RW },
-   { MIB(sysName), OID_RW },
-   { MIB(sysLocation), OID_RW },
-   { MIB(sysServices), OID_RS },
-   { MIB(sysORLastChange), OID_RD },
-   { MIB(sysORIndex),  OID_TRD },
-   { MIB(sysORID), OID_TRD },
-   { MIB(sysORDescr),  OID_TRD },
-   { MIB(sysORUpTime), OID_TRD },
-   { MIB(snmp),OID_MIB },
-   { MIB(snmpInPkts),  OID_RD },
-   { MIB(snmpOutPkts), OID_RD },
-   { MIB(snmpInBadVersions),   OID_RD },
-   { MIB(snmpInBadCommunityNames), OID_RD },
-   { MIB(snmpInBadCommunityUses),  OID_RD },
-   { MIB(snmpInASNParseErrs),  OID_RD },
-   { MIB(snmpInTooBigs),   OID_RD },
-   { MIB(snmpInNoSuchNames),   OID_RD },
-   { MIB(snmpInBadValues), OID_RD },
-   { MIB(snmpInReadOnlys), OID_RD },
-   { MIB(snmpInGenErrs),   OID_RD },
-   { MIB(snmpInTotalReqVars),  OID_RD },
-   { MIB(snmpInTotalSetVars),  OID_RD },
-   { MIB(snmpInGetRequests),   OID_RD },
-   { MIB(snmpInGetNexts),  OID_RD },
-   { MIB(snmpInSetRequests),   OID_RD },
-   { MIB(snmpInGetResponses),  OID_RD },
-   { MIB(snmpInTraps), OID_RD },
-   { MIB(snmpOutTooBigs),  OID_RD },
-   { MIB(snmpOutNoSuchNames),  OID_RD },
-   { MIB(snmpOutBadValues),OID_RD },
-   { MIB(snmpOutGenErrs),  OID_RD },
-   { MIB(snmpOutGetRequests),  OID_RD },
-   { MIB(snmpOutGetNexts), OID_RD },
-   { MIB(snmpOutSetRequests),  OID_RD },
-   { MIB(snmpOutGetResponses), OID_RD },
-   { MIB(snmpOutTraps),OID_RD },
-   { MIB(snmpEnableAuthenTraps),   OID_RW },
-   { MIB(snmpSilentDrops), OID_RD },
-   { MIB(snmpProxyDrops),  OID_RD },
-   { MIBEND }
-};
-
-static struct oid usm_mib[] = {
-   { MIB(snmpEngine),  OID_MIB },
-   { MIB(snmpEngineID),OID_RD },
-   { MIB(snmpEngineBoots), OID_RD },
-   { MIB(snmpEngineTime),  OID_RD },
-   { MIB(snmpEngineMaxMsgSize),OID_RD },
-   { MIB(usmStats),OID_MIB },
-   { MIB(usmStatsUnsupportedSecLevels),OID_RD },
-   { MIB(usmStatsNotInTimeWindow), OID_RD },
-   { MIB(usmStatsUnknownUserNames),OID_RD },
-   { MIB(usmStatsUnknownEngineId), OID_RD },
-   { MIB(usmStatsWrongDigests),OID_RD },
-   { MIB(usmStatsDecryptionErrors),OID_RD },
-   { MIBEND }
-};
-
-static struct oid hr_mib[] = {
-   { MIB(host),OID_MIB },
-   { MIB(hrSystemUptime),  OID_RD },
-   { MIB(hrSystemDate),OID_RD },
-   { MIB(hrSystemProcesses),   OID_RD },
-   { MIB(hrSystemMaxProcesses),OID_RD },
-   { MIB(hrMemorySize),OID_RD },
-   { MIB(hrStorageIndex),  OID_TRD },
-   { MIB(hrStorageType),   OID_TRD },
-   { MIB(hrStorageDescr),  OID_TRD },
-   { MIB(hrStorageAllocationUnits),OID_TRD },
-   { MIB(hrStorageSize),   OID_TRD },
-   { MIB(hrStorageUsed),   OID_TRD },
-   { MIB(hrStorageAllocationFailures), OID_TRD },
-   { MIB(hrDeviceIndex),   OID_TRD },
-   { MIB(hrDeviceType),OID_TRD },
-   { MIB(hrDeviceDescr),   OID_TRD },
-   { MIB(hrDeviceID),  OID_TRD },
-   { MIB(hrDeviceStatus),  OID_TRD },
-   { MIB(hrDeviceErrors),  OID_TRD },
-   { MIB(hrProcessorFrwID),OID_TRD },
-   { MIB(hrProcessorLoad), OID_TRD },
-   { MIB(hrSWRunIndex),OID_TRD },
-   { MIB(hrSWRunName), OID_TRD },
-   { MIB(hrSWRunID),   OID_TRD },
-   { 

Re: Disable snmpd 'private' community

2020-05-01 Thread Martijn van Duren
Moving to tech@

On 5/1/20 5:17 PM, Steven Surdock wrote:
> I see that snmpd.conf supports "read-write disabled", but this doesn't seem 
> to _completely_ disable the private community.  If I set "read-write 
> disabled" I can still poll values using the 'private' community.  Is this a 
> bug or a feature? 
> 
> -Steve S.
> 

I'd say this is a bug, disabled should be disabled.
Diff below fixes this. With this we can most likely also remove the test
on snmpe.c:467, but I don't feel confident enough to do that just yet.

Another important question is if we should enable read-write by default,
but let's save that discussion for a different time/thread.

OK?

martijn@

Index: snmpe.c
===
RCS file: /cvs/src/usr.sbin/snmpd/snmpe.c,v
retrieving revision 1.61
diff -u -p -r1.61 snmpe.c
--- snmpe.c 14 Feb 2020 15:08:46 -  1.61
+++ snmpe.c 1 May 2020 15:38:40 -
@@ -309,7 +309,8 @@ snmpe_parse(struct snmp_message *msg)
stats->snmp_ingetnexts++;
if (msg->sm_version != SNMP_V3 &&
strcmp(env->sc_rdcommunity, msg->sm_community) != 0 &&
-   strcmp(env->sc_rwcommunity, msg->sm_community) != 0) {
+   (env->sc_readonly ||
+   strcmp(env->sc_rwcommunity, msg->sm_community) != 0)) {
stats->snmp_inbadcommunitynames++;
msg->sm_errstr = "wrong read community";
goto fail;
@@ -320,7 +321,8 @@ snmpe_parse(struct snmp_message *msg)
case SNMP_C_SETREQ:
stats->snmp_insetrequests++;
if (msg->sm_version != SNMP_V3 &&
-   strcmp(env->sc_rwcommunity, msg->sm_community) != 0) {
+   (env->sc_readonly ||
+   strcmp(env->sc_rwcommunity, msg->sm_community) != 0)) {
if (strcmp(env->sc_rdcommunity, msg->sm_community) != 0)
stats->snmp_inbadcommunitynames++;
else



Re: a POSIXy diff for what(1)

2020-04-18 Thread Martijn van Duren
Looks fine to me. And I don't expect the tool to be widely used on
OpenBSD. Anyone objects/OK?

Small sidenote: Could you attach your diffs inline in the future? It's
the standard way of doing things here. I've added it here, so people
who don't want to open the file can see it.

martijn@

On 4/18/20 10:06 AM, Andras Farkas wrote:
> I don't use what often, but I do use it sometimes.  Today I noticed
> the format of what's output on OpenBSD was different than that of what
> on FreeBSD.
> Looking in what.1:
> https://man.openbsd.org/what
> I noticed OpenBSD's what is documented as abiding by POSIX:
> https://pubs.opengroup.org/onlinepubs/9699919799/utilities/what.html
> Thus, the following output:
> 
> tewi$ what /usr/bin/lorder
> /usr/bin/lorder
> $OpenBSD: lorder.sh,v 1.15 2015/07/03 11:43:55 jca Exp $
> lorder.sh   8.1 (Berkeley) 6/6/93
> 
> is missing a single colon after the name/path/argument.
> After applying the attached diff, the output is:
> 
> tewi$ ./what /usr/bin/lorder
> /usr/bin/lorder:
> $OpenBSD: lorder.sh,v 1.15 2015/07/03 11:43:55 jca Exp $
> lorder.sh   8.1 (Berkeley) 6/6/93
> 
> Hope this helps!  Of course, if there's a reason the : is omitted,
> that's fine too.
> 
Index: what.c
===
RCS file: /cvs/src/usr.bin/what/what.c,v
retrieving revision 1.15
diff -u -p -r1.15 what.c
--- what.c  9 Oct 2015 01:37:09 -   1.15
+++ what.c  18 Apr 2020 07:55:29 -
@@ -85,7 +85,7 @@ main(int argc, char *argv[])
perror(*argv);
exit(matches ? 0 : 1);
}
-   printf("%s\n", *argv);
+   printf("%s:\n", *argv);
search(match);
} while(*++argv);
exit(matches ? 0 : 1);



Re: smtpd: fix report event format

2020-04-08 Thread Martijn van Duren
On 4/8/20 6:15 PM, Joerg Jung wrote:
> 
>> On 8. Apr 2020, at 17:19, Eric Faurot  wrote:
>>
>> Some users had issues with report events for MAIL FROM and RCPT TO
>> when "|" appear in the mail address (yes, it seems to happen), because
>> that's also the field separator.  To make parsing the report lines a
>> bit more straightforward, it's better to put the address as the last
>> field.
> 
> While this obviously would fix things, I wonder if there is a better choice 
> for 
> the separator available, to avoid similar issues in future.
> Something that does not show up in hostnames, mail from, rcpt to, or 
> anything else SMTP (filter) protocol related.
> Maybe better use ‘$' or even a control character like RS/US record/unit 
> separator (ASCII no 29/30)?

Ultimately I'm fine either way, as long as I get the time to update
libopensmtpd between when it's decided and the actual commit.

But if we're going to change the separator we need to think this through,
because I don't want to open a new can of worms while cleaning up the
previous. For example '$' doesn't seem like a reasonable candidate. If
we look at RFC5321 section 4.1.2. we see that local-part is defined as
Dot-string / Quoted-string and Dot-string is defined as Atom *("."  Atom)
and finally Atom is defined as 1*atext.
Unfortunately atext isn't defined in this document, but the closest I
found (number-wise) was in RFC5322, which states:
   atext   =   ALPHA / DIGIT /; Printable US-ASCII
   "!" / "#" /;  characters not including
   "$" / "%" /;  specials.  Used for atoms.
   "&" / "'" /
   "*" / "+" /
   "-" / "/" /
   "=" / "?" /
   "^" / "_" /
   "`" / "{" /
   "|" / "}" /
   "~"
So practically any non-control ascii character.

Furthermore, I fixed the data-section some time ago, so I'm fairly
confident that that is safe in its current form, but if we want to pick
something that prevents us from things blowing up in our face in the
future we should also consider the part of the transaction that accepts
the widest range of input. According to RFC5321 section 4.1.1.4:
   The mail data may contain any of the 128 ASCII character
   codes, although experience has indicated that use of control
   characters other than SP, HT, CR, and LF may cause problems and
   SHOULD be avoided when possible.
So even though people should not send control-characters, they may be
send anyway, which brings us back into the risky category. This means
that control-characters are also out the window, which would leave us
with a field-separator in the 128-255 range.

I could update libopensmtpd quite easily to use a byte in that range,
but considering the protocol was intended to also be used with standard
unix tools as well I reckon that a lot of people wouldn't know how to
cope with that without some very firm handholding and the same probably
goes for control characters.

So to be clear: I'm not saying we shouldn't change the separator, but
if we want to go down that route there are quite a few edge cases that
need to be covered. So until someone works out the perfect candidate
it might be better to stick with the devil we know.
> 
>> Note that this is a protocol change, so external filters will have
>> to be updated.
>>
>> Eric.
>>
>> Index: lka_filter.c
>> ===
>> RCS file: /cvs/src/usr.sbin/smtpd/lka_filter.c,v
>> retrieving revision 1.60
>> diff -u -p -r1.60 lka_filter.c
>> --- lka_filter.c 8 Jan 2020 01:41:11 -   1.60
>> +++ lka_filter.c 4 Apr 2020 08:39:19 -
>> @@ -35,7 +35,7 @@
>> #include "smtpd.h"
>> #include "log.h"
>>
>> -#define PROTOCOL_VERSION"0.5"
>> +#define PROTOCOL_VERSION"0.6"
>>
>> struct filter;
>> struct filter_session;
>> @@ -1526,7 +1526,7 @@ lka_report_smtp_tx_mail(const char *dire
>>  break;
>>  }
>>  report_smtp_broadcast(reqid, direction, tv, "tx-mail", "%08x|%s|%s\n",
>> -msgid, address, result);
>> +msgid, result, address);
>> }
>>
>> void
>> @@ -1546,7 +1546,7 @@ lka_report_smtp_tx_rcpt(const char *dire
>>  break;
>>  }
>>  report_smtp_broadcast(reqid, direction, tv, "tx-rcpt", "%08x|%s|%s\n",
>> -msgid, address, result);
>> +msgid, result, address);
>> }
>>
>> void
>>
>



Include /var/www/tmp into base install

2020-04-07 Thread Martijn van Duren
This came up during u2k20 while discussing tempfiles for gotweb inside a
chroot. At the moment we don't include it by default and ports have to
create it themselves. Since I assume we want web applications to run
inside a /var/www chroot as much as possible and even some libc
functions depend on /tmp being available I'd argue we should include it
by default.

I also choose to make the directory 1777, similar to a normal /tmp,
since both multiple slowcgi or php-fpm pools can run simultaneously
under different users.

The cleanup functions don't reflect the current /tmp cleanup style, but
we can move the existing find statements to -delete in a separate patch.

I already had some positive feedback during u2k20 on the concept.
OK?

martijn@

Index: etc//daily
===
RCS file: /cvs/src/etc/daily,v
retrieving revision 1.93
diff -u -p -r1.93 daily
--- etc//daily  9 Sep 2019 20:02:26 -   1.93
+++ etc//daily  7 Apr 2020 14:37:15 -
@@ -55,6 +55,11 @@ if [ -d /tmp -a ! -L /tmp ]; then
! -path ./.ICE-unix ! -name . \
-execdir rmdir -- {} \; >/dev/null 2>&1; }
 fi
+if [ -d /var/www/tmp -a ! -L /var/www/tmp ]; then
+   cd /var/www/tmp && {
+   find -x . -type f -atime +7 -delete 2>/dev/null
+   find -x . -type d -empty -delete 2>/dev/null
+fi
 
 # Additional junk directory cleanup would go like this:
 #if [ -d /scratch -a ! -L /scratch ]; then
Index: etc//rc
===
RCS file: /cvs/src/etc/rc,v
retrieving revision 1.543
diff -u -p -r1.543 rc
--- etc//rc 24 Jan 2020 06:17:37 -  1.543
+++ etc//rc 7 Apr 2020 14:37:15 -
@@ -532,7 +532,7 @@ if [[ -f /etc/ptmp ]]; then
'password file may be incorrect -- /etc/ptmp exists'
 fi
 
-echo clearing /tmp
+echo clearing temporary directories
 
 # Prune quickly with one rm, then use find to clean up /tmp/[lqv]*
 # (not needed with mfs /tmp, but doesn't hurt there...).
@@ -540,6 +540,7 @@ echo clearing /tmp
 (cd /tmp &&
 find . -maxdepth 1 ! -name . ! -name lost+found ! -name quota.user \
! -name quota.group ! -name vi.recover -execdir rm -rf -- {} \;)
+(cd /var/www/tmp && find . -x -delete)
 
 # Create Unix sockets directories for X if needed and make sure they have
 # correct permissions.
Index: etc//mtree/4.4BSD.dist
===
RCS file: /cvs/src/etc/mtree/4.4BSD.dist,v
retrieving revision 1.314
diff -u -p -r1.314 4.4BSD.dist
--- etc//mtree/4.4BSD.dist  29 Nov 2019 03:28:20 -  1.314
+++ etc//mtree/4.4BSD.dist  7 Apr 2020 14:37:15 -
@@ -749,6 +749,7 @@ var
 ..
 runtype=dir uname=root gname=daemon mode=755
 ..
+tmptype=dir uname=root gname=wheel mode=01777
 ..
 
 # ./var/audit



worm(6): Remove stdin garbage after end

2020-04-01 Thread Martijn van Duren
When playing worm(6) and you crash there's a sleep of 2 seconds that
still allows input to be put into the terminal buffer that doesn't get  
read until the application stops.
A similar case is possible in a more limited timespan if you win the
game.

The diff below flushes the input buffer just before exiting curses and
the application, leaving me with no clutter in my $SHELL.
I choose to also add '\n' as an escape character, since it's not part
of the game and allows me to exit after a crash faster (which always
annoys me) and allows me to add a new command straight away.

The crash() case might be a bit elaborate, but it's the closest to the
behaviour we have right now, minus the garbage.

Thoughts? OK?

martijn

Index: worm.c
===
RCS file: /cvs/src/games/worm/worm.c,v
retrieving revision 1.39
diff -u -p -r1.39 worm.c
--- worm.c  24 Aug 2018 11:14:49 -  1.39
+++ worm.c  1 Apr 2020 08:27:03 -
@@ -40,6 +40,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define HEAD '@'
@@ -239,7 +240,12 @@ rnd(int range)
 void
 newpos(struct body *bp)
 {
+   int ch;
+
if (visible_len == (LINES-3) * (COLS-3) - 1) {
+   timeout(0);
+   while ((ch = getch()) != '\n' && ch != ERR)
+   continue;
endwin();
printf("\nYou won!\nYour final score was %d\n\n", score);
exit(0);
@@ -387,7 +393,17 @@ newlink(void)
 void
 crash(void)
 {
-   sleep(2);
+   int ch, delay;
+   struct timespec tstart, tnow, texp;
+
+   timeout(2000);
+   (void) clock_gettime(CLOCK_MONOTONIC, );
+   while ((ch = getch()) != ERR && ch != '\n') {
+   (void) clock_gettime(CLOCK_MONOTONIC, );
+   timespecsub(, , );
+   delay = 2000 - (texp.tv_sec * 1000) - (texp.tv_nsec / 100);
+   timeout(delay >= 0 ? delay : 0);
+   }
clear();
endwin();
printf("Well, you ran into something and the game is over.\n");



snmpd(8) (temporary) removal of sysortable

2020-03-24 Thread Martijn van Duren
We currently abuse sysORTable to display information in a way that it
shouldn't. According to SNMPv2-MIB:
"The (conceptual) table listing the capabilities of
the local SNMP application acting as a command
responder with respect to various MIB modules.
SNMP entities having dynamically-configurable support
of MIB modules will have a dynamically-varying number
of conceptual rows."

I must admit that from a first glance our usage seems correct, but I
found the following text in RFC2741 (AGENTX):
An Object Identifier containing the value of an invocation
of the AGENT-CAPABILITIES macro, which the master agent
exports as a value of sysORID for the indicated context.
(Recall that the value of an invocation of an AGENT-
CAPABILITIES macro is an object identifier that describes a
precise level of support with respect to implemented MIB
modules.  A more complete discussion of the AGENT-
CAPABILITIES macro and related sysORID values can be found
in section 6 of STD 58, RFC 2580 [7].)

And if we look at section 6.6 of RFC 2580:
6.6.  Mapping of the AGENT-CAPABILITIES value

   The value of an invocation of the AGENT-CAPABILITIES macro is an
   OBJECT IDENTIFIER, which names the value of sysORID [3] for which
   this capabilities statement is valid.

This means that that the OIDs used in the sysORTable need to reference
an AGENT-CAPABILITIES macro, which need to be defined separately and we
currently don't have those.

Apart from the above we also falsely return sysORIndex, which has
MAX-ACCESS not-accessible.

I propose we remove the sysORTable code until we either:
1) Have a proper AGENT-CAPABILITIES file for snmpd(8)
2) Have proper support for agentx-AddAgentCaps-PDU

This removes falsities from our code and allows us to reimplement it in
a more scalable way for agentx support in the future.

OK?

martijn@

ps. I know that net-snmp does something similar, but that doesn't mean I
would like to copy their spec-violations.

Index: mib.c
===
--- mib.c   (revision 1)
+++ mib.c   (working copy)
@@ -65,7 +65,6 @@
 
 int mib_getsys(struct oid *, struct ber_oid *, struct ber_element **);
 int mib_getsnmp(struct oid *, struct ber_oid *, struct ber_element **);
-int mib_sysor(struct oid *, struct ber_oid *, struct ber_element **);
 int mib_setsnmp(struct oid *, struct ber_oid *, struct ber_element **);
 
 static struct oid mib_tree[] = MIB_TREE;
@@ -75,7 +74,6 @@
 
 /* base MIB tree */
 static struct oid base_mib[] = {
-   { MIB(mib_2),   OID_MIB },
{ MIB(sysDescr),OID_RD, mib_getsys },
{ MIB(sysOID),  OID_RD, mib_getsys },
{ MIB(sysUpTime),   OID_RD, mib_getsys },
@@ -84,11 +82,6 @@
{ MIB(sysLocation), OID_RW, mib_getsys, mps_setstr },
{ MIB(sysServices), OID_RS, mib_getsys },
{ MIB(sysORLastChange), OID_RD, mps_getts },
-   { MIB(sysORIndex),  OID_TRD, mib_sysor },
-   { MIB(sysORID), OID_TRD, mib_sysor },
-   { MIB(sysORDescr),  OID_TRD, mib_sysor },
-   { MIB(sysORUpTime), OID_TRD, mib_sysor },
-   { MIB(snmp),OID_MIB },
{ MIB(snmpInPkts),  OID_RD, mib_getsnmp },
{ MIB(snmpOutPkts), OID_RD, mib_getsnmp },
{ MIB(snmpInBadVersions),   OID_RD, mib_getsnmp },
@@ -190,68 +183,6 @@
 }
 
 int
-mib_sysor(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
-{
-   struct ber_element  *ber = *elm;
-   u_int32_tidx = 1, nmib = 0;
-   struct oid  *next, *miboid;
-   char buf[SNMPD_MAXSTRLEN];
-
-   /* Count MIB root OIDs in the tree */
-   for (next = NULL;
-   (next = smi_foreach(next, OID_MIB)) != NULL; nmib++);
-
-   /* Get and verify the current row index */
-   idx = o->bo_id[OIDIDX_sysOREntry];
-   if (idx > nmib)
-   return (1);
-
-   /* Find the MIB root element for this Id */
-   for (next = miboid = NULL, nmib = 1;
-   (next = smi_foreach(next, OID_MIB)) != NULL; nmib++) {
-   if (nmib == idx)
-   miboid = next;
-   }
-   if (miboid == NULL)
-   return (-1);
-
-   /* Tables need to prepend the OID on their own */
-   ber = ober_add_oid(ber, o);
-
-   switch (o->bo_id[OIDIDX_sysOR]) {
-   case 1:
-   ber = ober_add_integer(ber, idx);
-   break;
-   case 2:
-   ber = ober_add_oid(ber, >o_id);
-   break;
-   case 3:
-   /*
-* This should be a description of the MIB.
-* But we use the 

snmpd(8): Remove restricted socket

2020-03-23 Thread Martijn van Duren
snmpd's normal socket is pretty much deprecated and the restricted
variant is even more useless. In other words lets pick it apart one
step at a time. This diff removes the restricted keyword and related
code.

While here I also removed the unimplemented IMSG_CTL_RELOAD logic.

For those wondering why I removed the CTL_CONN_LOCKED flag: It's only
checked in control_dispatch_imsg, so there's no point in setting it on
agentx sockets.

OK?

martijn@

Index: control.c
===
--- control.c   (revision 1)
+++ control.c   (working copy)
@@ -80,7 +80,7 @@
return (-1);
}
 
-   if (cs->cs_restricted || cs->cs_agentx) {
+   if (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 {
@@ -174,7 +174,6 @@
log_warn("%s: agentx", __func__);
return;
}
-   c->flags |= CTL_CONN_LOCKED;
c->iev.handler = control_dispatch_agentx;
TAILQ_INIT(>oids);
} else
@@ -249,21 +248,6 @@
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",
-   );
-   return;
-   }
-   }
-
control_imsg_forward();
 
switch (imsg.hdr.type) {
@@ -282,14 +266,6 @@
c->flags |= CTL_CONN_NOTIFY;
break;
 
-   case IMSG_SNMP_LOCK:
-   if (IMSG_DATA_SIZE())
-   return control_close(c, "invalid size", );
-
-   /* enable restricted control mode */
-   c->flags |= CTL_CONN_LOCKED;
-   break;
-
case IMSG_SNMP_AGENTX:
if (IMSG_DATA_SIZE())
return control_close(c, "invalid size", );
@@ -313,7 +289,6 @@
}
/* disable IMSG notifications */
c->flags &= ~CTL_CONN_NOTIFY;
-   c->flags |= CTL_CONN_LOCKED;
c->iev.handler = control_dispatch_agentx;
break;
 
@@ -330,11 +305,7 @@
proc_forward_imsg(>sc_ps, , i, -1);
}
break;
-   case IMSG_CTL_RELOAD:
-   if (IMSG_DATA_SIZE())
-   return control_close(c, "invalid size", );
-   proc_forward_imsg(>sc_ps, , PROC_PARENT, -1);
-   break;
+
default:
control_close(c, "invalid type", );
return;
Index: parse.y
===
--- parse.y (revision 1)
+++ parse.y (working copy)
@@ -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;
@@ -133,7 +128,7 @@
 %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 SOCKET AGENTX HANDLE DEFAULT SRCADDR TCP UDP PFADDRFILTER
 %token   STRING
 %token   NUMBER
 %typehostcmn
@@ -305,10 +300,7 @@
YYERROR;
}
rcsock->cs_name = $2;
-   if ($3 == SOCK_TYPE_RESTRICTED)
-   rcsock->cs_restricted = 1;
-   else if ($3 == SOCK_TYPE_AGENTX)
-   rcsock->cs_agentx = 1;
+   rcsock->cs_agentx = 1;
TAILQ_INSERT_TAIL(>sc_ps.ps_rcsocks,
rcsock, cs_entry);
} else {
@@ -541,8 +533,7 @@
}
;
 
-socktype   : RESTRICTED{ $$ = 

  1   2   3   4   >