lex(1): warning with -Wmisleading-indentation in generated scanner

2021-05-04 Thread Nick Gasson
Hi,

When I build my program with the lex(1) in OpenBSD I get the following
warning:

src/lexer.c:2415:3: warning: misleading indentation; statement is not part of 
the previous 'if'
  [-Wmisleading-indentation]
return yy_is_jam ? 0 : yy_current_state;
^
src/lexer.c:2412:2: note: previous statement is here
if ( ! yy_is_jam )
^

It comes from this section of code in the generated scanner:

if ( ! yy_is_jam )
*(yy_state_ptr)++ = yy_current_state;

return yy_is_jam ? 0 : yy_current_state;

This also happens when building lex(1) with WARNINGS=yes and possibly
other programs in base.  The diff below adds a blank line to the M4
skeleton file and changes the indentation to

if ( ! yy_is_jam )
*(yy_state_ptr)++ = yy_current_state;

return yy_is_jam ? 0 : yy_current_state;

I noticed upstream flex fixed the same problem by removing the leading
whitespace before the return which produces identical output, but I
prefer the diff below as it preserves the correct indentation in the
skeleton file.

https://github.com/westes/flex/blob/master/src/flex.skl#L1761


Index: usr.bin/lex/flex.skl
===
RCS file: /cvs/src/usr.bin/lex/flex.skl,v
retrieving revision 1.17
diff -u -p -u -p -r1.17 flex.skl
--- usr.bin/lex/flex.skl6 Aug 2020 17:23:29 -   1.17
+++ usr.bin/lex/flex.skl5 May 2021 02:32:47 -
@@ -1807,6 +1807,7 @@ m4_ifdef( [[M4_YY_USES_REJECT]],
 %% [17.0] code to find the next state, and perhaps do backing up, goes here

M4_YY_NOOP_GUTS_VAR();
+
return yy_is_jam ? 0 : yy_current_state;
 }



smtpd: document "pki" option for relay delivery in smtpd.conf(5)

2020-09-13 Thread Nick Gasson
Hi,

I struggled a bit to configure smtpd to relay to a remote server that
requires SSL client certificates. The solution is to just add a "pki
host.example.org" option, but "pki" is not listed as a valid option for
the relay delivery method, even though the parser accepts it.

Index: smtpd.conf.5
===
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.conf.5,v
retrieving revision 1.251
diff -u -p -u -p -r1.251 smtpd.conf.5
--- smtpd.conf.527 Aug 2020 08:58:30 -  1.251
+++ smtpd.conf.513 Sep 2020 12:37:03 -
@@ -280,6 +280,14 @@ and
 .Dq smtps
 protocols for authentication.
 Server certificates for those protocols are verified by default.
+.It Cm pki Ar pkiname
+For secure connections,
+use the certificate associated with
+.Ar pkiname
+(declared in a
+.Ic pki
+directive)
+to prove the client's identity to the remote mail server.
 .It Cm srs
 When relaying a mail resulting from a forward,
 use the Sender Rewriting Scheme to rewrite sender address.

--
Thanks,
Nick



ftp(1): add SOCKS proxy support

2020-11-26 Thread Nick Gasson
Hi,

I often need to go through a SOCKS proxy to access certain sites. The
diff below adds SOCKS5 support to ftp(1) for HTTP transfers, similar to
curl(1). Enabled when http_proxy is set to a socks5:// URL.

Also fixes two existing memory leaks: proxyurl (set to NULL on line 646
before freeing) and sslpath (never freed).

Tested with ssh -D and a few other SOCKS5 proxies. Also verified the
existing HTTP proxy feature still works with squid(8).


Index: usr.bin/ftp/fetch.c
===
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.198
diff -u -p -u -r1.198 fetch.c
--- usr.bin/ftp/fetch.c 18 Oct 2020 20:35:18 -  1.198
+++ usr.bin/ftp/fetch.c 26 Nov 2020 13:51:10 -
@@ -88,10 +88,14 @@ static int  proxy_connect(int, char *, ch
 static int stdio_tls_write_wrapper(void *, const char *, int);
 static int stdio_tls_read_wrapper(void *, char *, int);
 #endif /* !NOSSL */
+static int read_fully(int, void *, size_t);
+static int write_fully(int, const void *, size_t);
+static int socks5_connect(int, const char *, const char *);
 
 #defineFTP_URL "ftp://";/* ftp URL prefix */
 #defineHTTP_URL"http://";   /* http URL prefix */
 #defineHTTPS_URL   "https://";  /* https URL prefix */
+#defineSOCKS5_URL  "socks5://" /* socks5 URL prefix */
 #defineFILE_URL"file:" /* file URL prefix */
 #define FTP_PROXY  "ftp_proxy" /* env var with ftp proxy location */
 #define HTTP_PROXY "http_proxy"/* env var with http proxy location */
@@ -345,6 +349,7 @@ url_get(const char *origline, const char
int save_errno;
const size_t buflen = 128 * 1024;
int chunked = 0;
+   enum proxy_scheme proxy = PROXY_NONE;
 
direction = "received";
 
@@ -455,11 +460,16 @@ noslash:
proxyurl = strdup(proxyenv);
if (proxyurl == NULL)
errx(1, "Can't allocate memory for proxy URL.");
-   if (strncasecmp(proxyurl, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
+   if (strncasecmp(proxyurl, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) 
{
host = proxyurl + sizeof(HTTP_URL) - 1;
-   else if (strncasecmp(proxyurl, FTP_URL, sizeof(FTP_URL) - 1) == 
0)
+   proxy = PROXY_HTTP;
+   } else if (strncasecmp(proxyurl, FTP_URL, sizeof(FTP_URL) - 1) 
== 0) {
host = proxyurl + sizeof(FTP_URL) - 1;
-   else {
+   proxy = PROXY_HTTP;  /* Treat ftp:// as a HTTP proxy */
+   } else if (strncasecmp(proxyurl, SOCKS5_URL, sizeof(SOCKS5_URL) 
- 1) == 0) {
+   host = proxyurl + sizeof(SOCKS5_URL) - 1;
+   proxy = PROXY_SOCKS5;
+   } else {
warnx("Malformed proxy URL: %s", proxyenv);
goto cleanup_url_get;
}
@@ -467,11 +477,14 @@ noslash:
warnx("Malformed proxy URL: %s", proxyenv);
goto cleanup_url_get;
}
+   }
+
+   if (proxy == PROXY_HTTP) {
if (*--path == '\0')
*path = '/';/* add / back to real path */
path = strchr(host, '/');   /* remove trailing / on host */
if (!EMPTYSTRING(path))
-   *path++ = '\0'; /* i guess this ++ is useless */
+   *path = '\0';
 
path = strchr(host, '@');   /* look for credentials in 
proxy */
if (!EMPTYSTRING(path)) {
@@ -623,9 +636,21 @@ noslash:
port = NULL;
 
 #ifndef NOSSL
-   if (proxyenv && sslhost)
+   if (proxy == PROXY_HTTP && sslhost)
proxy_connect(fd, sslhost, proxy_credentials);
 #endif /* !NOSSL */
+
+   if (proxy == PROXY_SOCKS5) {
+   portnum = strrchr(proxyhost, ':');
+   if (portnum != NULL)
+   *portnum++ = '\0';
+   else
+   portnum = ishttpsurl ? httpsport : httpport;
+
+   if (socks5_connect(fd, proxyhost, portnum) != 0)
+   goto cleanup_url_get;
+   }
+
break;
}
freeaddrinfo(res0);
@@ -641,9 +666,10 @@ noslash:
 #ifndef NOSSL
if (ishttpsurl) {
ssize_t ret;
-   if (proxyenv && sslpath) {
+   if (proxy == PROXY_HTTP && sslpath) {
+   /* HTTP proxy CONNECT handled above. */
ishttpsurl = 0;
-   proxyurl = NULL;
+   proxy = PROXY_NONE;
path = sslpath;
}
if (sslhost == 

Re: ftp(1): add SOCKS proxy support

2021-01-02 Thread Nick Gasson
Hi Steffen,

On 11/27/20 05:59 AM, Steffen Nurpmeso wrote:
> Nick Gasson wrote in
>  <87im9srza8@bertha.nickg.me.uk>:
>  |Hi,
>  |
>  |I often need to go through a SOCKS proxy to access certain sites. The
>  |diff below adds SOCKS5 support to ftp(1) for HTTP transfers, similar to
>  |curl(1). Enabled when http_proxy is set to a socks5:// URL.
>  |
>  |Also fixes two existing memory leaks: proxyurl (set to NULL on line 646
>  |before freeing) and sslpath (never freed).
>  |
>  |Tested with ssh -D and a few other SOCKS5 proxies. Also verified the
>  |existing HTTP proxy feature still works with squid(8).
>
> By the way, the $SOCKS5_PROXY environment variable becomes used
> for automatic selection of SOCKS5.  (Some things on FreeBSD,
> lynx(1), and, hm, the MUA i maintain, s-nail; maybe more.)
>

(Sorry for the late reply.)

Yes I see FreeBSD fetch added SOCKS5_PROXY recently. I've updated the
diff below to support that too. Anyone interested?

--
Thanks,
Nick


Index: usr.bin/ftp/fetch.c
===
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.199
diff -u -p -u -r1.199 fetch.c
--- usr.bin/ftp/fetch.c 1 Jan 2021 17:39:54 -   1.199
+++ usr.bin/ftp/fetch.c 2 Jan 2021 12:02:39 -
@@ -88,13 +88,18 @@ static int  proxy_connect(int, char *, ch
 static int stdio_tls_write_wrapper(void *, const char *, int);
 static int stdio_tls_read_wrapper(void *, char *, int);
 #endif /* !NOSSL */
+static int read_fully(int, void *, size_t);
+static int write_fully(int, const void *, size_t);
+static int socks5_connect(int, const char *, const char *);
 
 #defineFTP_URL "ftp://";/* ftp URL prefix */
 #defineHTTP_URL"http://";   /* http URL prefix */
 #defineHTTPS_URL   "https://";  /* https URL prefix */
+#defineSOCKS5_URL  "socks5://" /* socks5 URL prefix */
 #defineFILE_URL"file:" /* file URL prefix */
 #define FTP_PROXY  "ftp_proxy" /* env var with ftp proxy location */
 #define HTTP_PROXY "http_proxy"/* env var with http proxy location */
+#define SOCKS5_PROXY   "SOCKS5_PROXY"  /* env var with socks5 proxy location */
 
 #define EMPTYSTRING(x) ((x) == NULL || (*(x) == '\0'))
 
@@ -345,6 +350,7 @@ url_get(const char *origline, const char
int save_errno;
const size_t buflen = 128 * 1024;
int chunked = 0;
+   enum proxy_scheme proxy = PROXY_NONE;
 
direction = "received";
 
@@ -455,11 +461,16 @@ noslash:
proxyurl = strdup(proxyenv);
if (proxyurl == NULL)
errx(1, "Can't allocate memory for proxy URL.");
-   if (strncasecmp(proxyurl, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
+   if (strncasecmp(proxyurl, HTTP_URL, sizeof(HTTP_URL) - 1) == 0) 
{
host = proxyurl + sizeof(HTTP_URL) - 1;
-   else if (strncasecmp(proxyurl, FTP_URL, sizeof(FTP_URL) - 1) == 
0)
+   proxy = PROXY_HTTP;
+   } else if (strncasecmp(proxyurl, FTP_URL, sizeof(FTP_URL) - 1) 
== 0) {
host = proxyurl + sizeof(FTP_URL) - 1;
-   else {
+   proxy = PROXY_HTTP;  /* Treat ftp:// as a HTTP proxy */
+   } else if (strncasecmp(proxyurl, SOCKS5_URL, sizeof(SOCKS5_URL) 
- 1) == 0) {
+   host = proxyurl + sizeof(SOCKS5_URL) - 1;
+   proxy = PROXY_SOCKS5;
+   } else {
warnx("Malformed proxy URL: %s", proxyenv);
goto cleanup_url_get;
}
@@ -467,11 +478,14 @@ noslash:
warnx("Malformed proxy URL: %s", proxyenv);
goto cleanup_url_get;
}
+   }
+
+   if (proxy == PROXY_HTTP) {
if (*--path == '\0')
*path = '/';/* add / back to real path */
path = strchr(host, '/');   /* remove trailing / on host */
if (!EMPTYSTRING(path))
-   *path++ = '\0'; /* i guess this ++ is useless */
+   *path = '\0';
 
path = strchr(host, '@');   /* look for credentials in 
proxy */
if (!EMPTYSTRING(path)) {
@@ -623,9 +637,25 @@ noslash:
port = NULL;
 
 #ifndef NOSSL
-   if (proxyenv && sslhost)
+   if (proxy == PROXY_HTTP && sslhost)
proxy_connect(fd, sslhost, proxy_credentials);
 #endif /* !NOSSL */
+
+   if (proxy ==

systat(1): improve parsing of delay value

2021-01-25 Thread Nick Gasson
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.


Index: usr.bin/systat/main.c
===
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.72
diff -u -p -u -p -r1.72 main.c
--- usr.bin/systat/main.c   12 Jan 2020 20:51:08 -  1.72
+++ usr.bin/systat/main.c   25 Jan 2021 08:07:34 -
@@ -415,6 +415,22 @@ gethz(void)
 }
 
 int
+parse_delay(const char *str, double *delay)
+{
+   char *endptr = NULL;
+   double value;
+
+   value = strtod(str, &endptr);
+   if (*endptr == '\0') {
+   if (value <= 0)
+   value = 5;
+   *delay = value;
+   return 0;
+   } else
+   return 1;
+}
+
+int
 main(int argc, char *argv[])
 {
char errbuf[_POSIX2_LINE_MAX];
@@ -475,9 +491,8 @@ main(int argc, char *argv[])
nflag = 1;
break;
case 's':
-   delay = atof(optarg);
-   if (delay <= 0)
-   delay = 5;
+   if (parse_delay(optarg, &delay))
+   errx(1, "-s %s: invalid delay value", optarg);
break;
case 'w':
rawwidth = strtonum(optarg, 1, MAX_LINE_BUF-1, &errstr);
@@ -497,16 +512,14 @@ main(int argc, char *argv[])
argv += optind;
 
if (argc == 1) {
-   double del = atof(argv[0]);
-   if (del == 0)
+   if (parse_delay(argv[0], &delay))
viewstr = argv[0];
-   else
-   delay = del;
} else if (argc == 2) {
viewstr = argv[0];
-   delay = atof(argv[1]);
-   if (delay <= 0)
-   delay = 5;
+   if (parse_delay(argv[1], &delay))
+   errx(1, "invalid delay value: %s", argv[1]);
+   } else {
+   usage();
}
 
udelay = (useconds_t)(delay * 100.0);