Re: acme-client(1): dns-01
Daniel Moch wrote: > I like being able to specify a user to run the script as. In my case > it's sufficient to run the script as 'nobody'. Regarding this second sentence: never use nobody for another purpose. It has other purposes, and if people follow this pattern of using nobody then potentially even more things will "share" the uid, creating risks. Create a new user, if you must.
Re: acme-client(1): dns-01
Quoth Florian Obser : > Comments, tests? Works as advertized. Tested against Vultr DNS. When generating a star cert, the config parser requires the starred name(s) be quoted. The error in this situation is a bit vague, just a reference to a syntax error on the line IIRC. Not sure if that can be addressed, but I thought I'd mention it, especially since the config in /etc/examples doesn't quote these. I like being able to specify a user to run the script as. In my case it's sufficient to run the script as 'nobody'. These scripts end up being called hooks in other, similar utilities. Maybe you could replace "exec" with "hook," or "hook exec" if you want to keep it semi-grammatical. Thanks! -- Daniel Moch https://djmo.ch
IPsec IPv6 PMTU
Hi, This diff makes path MTU discovery work for IPv6 IPsec ESP over IPv4 tunnel. Basically it ports code from v4 to v6. It also makes v4 and v6 code look simmilar. If you want, I can split this for easier review. ok? bluhm Index: netinet/icmp6.h === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/icmp6.h,v retrieving revision 1.50 diff -u -p -r1.50 icmp6.h --- netinet/icmp6.h 28 Oct 2020 17:27:35 - 1.50 +++ netinet/icmp6.h 22 Dec 2020 17:05:39 - @@ -599,6 +599,7 @@ void icmp6_prepare(struct mbuf *); voidicmp6_redirect_input(struct mbuf *, int); voidicmp6_redirect_output(struct mbuf *, struct rtentry *); int icmp6_sysctl(int *, u_int, void *, size_t *, void *, size_t); +struct rtentry *icmp6_mtudisc_clone(struct sockaddr_in6 *, u_int, int); struct ip6ctlparam; void icmp6_mtudisc_update(struct ip6ctlparam *, int); Index: netinet/ip_input.c === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.352 diff -u -p -r1.352 ip_input.c --- netinet/ip_input.c 16 Nov 2020 06:44:38 - 1.352 +++ netinet/ip_input.c 22 Dec 2020 17:05:39 - @@ -1418,8 +1418,8 @@ ip_forward(struct mbuf *m, struct ifnet goto freecopy; } + memset(, 0, sizeof(ro)); sin = satosin(_dst); - memset(sin, 0, sizeof(*sin)); sin->sin_family = AF_INET; sin->sin_len = sizeof(*sin); sin->sin_addr = ip->ip_dst; @@ -1429,6 +1429,7 @@ ip_forward(struct mbuf *m, struct ifnet rt = rtalloc_mpath(sintosa(sin), >ip_src.s_addr, m->m_pkthdr.ph_rtableid); if (rt == NULL) { + ipstat_inc(ips_noroute); icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0); return; } Index: netinet/ip_ipsp.h === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_ipsp.h,v retrieving revision 1.196 diff -u -p -r1.196 ip_ipsp.h --- netinet/ip_ipsp.h 5 Nov 2020 19:28:28 - 1.196 +++ netinet/ip_ipsp.h 22 Dec 2020 17:05:39 - @@ -610,6 +610,7 @@ voidesp4_ctlinput(int, struct sockaddr #ifdef INET6 intesp6_input(struct mbuf **, int *, int, int); +void esp6_ctlinput(int, struct sockaddr *, u_int, void *); #endif /* INET6 */ /* XF_IPCOMP */ Index: netinet/ip_output.c === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_output.c,v retrieving revision 1.358 diff -u -p -r1.358 ip_output.c --- netinet/ip_output.c 20 Dec 2020 21:15:47 - 1.358 +++ netinet/ip_output.c 22 Dec 2020 17:05:39 - @@ -612,7 +612,7 @@ ip_output_ipsec_send(struct tdb *tdb, st ntohl(tdb->tdb_spi), tdb->tdb_mtu, rt, rt_mtucloned)); if (rt != NULL) { rt->rt_mtu = tdb->tdb_mtu; - if (ro && ro->ro_rt != NULL) { + if (ro != NULL && ro->ro_rt != NULL) { rtfree(ro->ro_rt); ro->ro_rt = rtalloc(>ro_dst, RT_RESOLVE, m->m_pkthdr.ph_rtableid); Index: netinet/ipsec_input.c === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ipsec_input.c,v retrieving revision 1.173 diff -u -p -r1.173 ipsec_input.c --- netinet/ipsec_input.c 1 Sep 2020 01:53:34 - 1.173 +++ netinet/ipsec_input.c 24 Dec 2020 19:22:09 - @@ -66,6 +66,7 @@ #ifdef INET6 #include #include +#include #include #include #endif /* INET6 */ @@ -83,6 +84,7 @@ #include "bpfilter.h" void ipsec_common_ctlinput(u_int, int, struct sockaddr *, void *, int); +void ipsec6_common_ctlinput(u_int, int, struct sockaddr *, void *, int); #ifdef ENCDEBUG #define DPRINTF(x) if (encdebug) printf x @@ -946,18 +948,43 @@ ipcomp4_input(struct mbuf **mp, int *off } void +ipsec_set_mtu(struct tdb *tdbp, u_int32_t mtu, uint64_t timeout, +const char *msg) +{ + ssize_t adjust; + + if (timeout == 0) + timeout = ip_mtudisc_timeout; + /* Walk the chain backwards to the first tdb */ + NET_ASSERT_LOCKED(); + for (; tdbp; tdbp = tdbp->tdb_inext) { + if (tdbp->tdb_flags & TDBF_INVALID || + (adjust = ipsec_hdrsz(tdbp)) == -1) + return; + + mtu -= adjust; + + /* Store adjusted MTU in tdb */ + tdbp->tdb_mtu = mtu; + tdbp->tdb_mtutimeout = gettime() + timeout; + DPRINTF(("%s: %s: spi %08x mtu %d adjust %ld timeout %llu\n", + __func__, msg, ntohl(tdbp->tdb_spi),
acme-client(1): dns-01
'tis the season to be jolly... I think it's time to kick the tires on this one. I don't like the "exec" keyword, we should find something better. Also, should the user be optional? Oh, and it's not enforcing that exec is present in the config. sthen pointed me in the direction of dehydrated https://github.com/dehydrated-io/dehydrated/blob/master/docs/dns-verification.md and uacme https://github.com/ndilieto/uacme as examples for acme clients that implement hooks for (dns) challenges I implemented the uacme api since I find that less ugly. It should be trivial to transmogrify it with a shell one-liner to support dehydrated. Comments, tests? diff --git acme-client.conf.5 acme-client.conf.5 index 3c5fd1c2362..e580a365c51 100644 --- acme-client.conf.5 +++ acme-client.conf.5 @@ -170,11 +170,55 @@ in one file, and is required by most browsers. This is optional if .Ar domain certificate is specified. -.It Ic sign with Ar authority +.It Ic sign with Ar authority Op Ic challenge Ar type The certificate authority (as declared above in the .Sx AUTHORITIES section) to use. If this setting is absent, the first authority specified is used. +.Ar type +can be +.Cm http +or +.Cm dns . +It defaults to +.Cm http . +.It Ic exec Ar script Ic as Ar user +Run +.Ar script +as user +.Ar user +for each +.Cm dns +challenge. +This is required when using the +.Cm dns +challenge type. +The script is called with five arguments: +.Bl -tag -width Ds +.It Ar method +.Cm begin , +.Cm done , +or +.Cm failed . +.Cm begin +indicates that a DNS record should be created and +.Cm done +or +.Cm failed +indicate that a DNS record should be removed. +.It Ar type +.Cm dns-01 . +.It Ar ident +The domain. +.It Ar token +Unused, for compatibility with existing hook scripts. +.It Ar auth +The challenge response. +.El +.Pp +The script needs to create a DNS record of the form +.Dl _acme-challenge.ident 30 IN TXT auth +and exit once it has propagated to all name servers. .It Ic challengedir Ar path The directory in which the challenge file will be stored. If it is not specified, a default of diff --git chngproc.c chngproc.c index 476daed3416..deef61fccc6 100644 --- chngproc.c +++ chngproc.c @@ -15,10 +15,13 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include + #include #include #include #include +#include #include #include #include @@ -26,8 +29,38 @@ #include "extern.h" -int -chngproc(int netsock, const char *root) +static int +do_exec(const char *exec, const char *method, const char *type, +const char *ident, const char *token, const char *auth) +{ + pid_tpid; + int status; + + switch (pid = fork()) { + case -1: + warn("fork"); + return -1; + case 0: /* child */ + /* XXX close netproc fd */ + if (pledge("stdio rpath exec", NULL) == -1) { + warn("pledge"); + return -1; + } + execl(exec, exec, method, type, ident, token, auth, NULL); + warn("execl %s", exec); + _exit(1); + } + if (waitpid(pid, , 0) == -1) { + warn("waitpid"); + return -1; + } + if (WEXITSTATUS(status) == 0) + return 0; + return -1; +} + +static int +chngproc_http(int netsock, const char *root) { char *tok = NULL, *th = NULL, *fmt = NULL, **fs = NULL; size_ti, fsz = 0; @@ -153,3 +186,114 @@ out: free(tok); return rc; } + +static int +chngproc_dns(int netsock, const char* exec, const char *exec_as) +{ + struct passwd *pw; + size_t i, identsz = 0; + long lval; + int rc = 0, cc; + enum chngop op; + char*ident = NULL, *tok = NULL, *auth = NULL; + char**idents = NULL; + void*pp; + + if ((pw = getpwnam(exec_as)) == NULL) { + warn("getpwnam"); + goto out; + } + if (setgroups(1, >pw_gid) || + setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || + setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) { + warnx("can't drop privileges"); + goto out; + } + + if (unveil(exec, "x") == -1) { + warn("unveil"); + goto out; + } + + if (pledge("stdio rpath proc exec", NULL) == -1) { + warn("pledge"); + goto out; + } + + for (;;) { + op = CHNG__MAX; + if ((lval = readop(netsock, COMM_CHNG_OP)) == 0) + op = CHNG_STOP; + else if (lval == CHNG_SYN) + op = lval; + + if (op == CHNG__MAX) { + warnx("unknown operation from netproc"); + goto out; + } else if
ftp(1): handle HTTP 308
Hello tech@, Given that ftp already deals with HTTP 307, I think we can teach it to deal with HTTP 308 too. HTTP 308 is to HTTP 301 what HTTP 307 is to HTTP 302: Permanently Moved, but doesn't allow to change the HTTP verb. Definition of HTTP 308 can be found in RFC 7538. oolong$ ftp -Mo /dev/null http://h.lgv5.net/c/308 Trying 78.47.117.79... Requesting http://h.lgv5.net/c/308 ftp: Error retrieving http://h.lgv5.net/c/308: 308 Permanent Redirect oolong$ ./ftp -Mo /dev/null http://h.lgv5.net/c/308 Trying 78.47.117.79... Requesting http://h.lgv5.net/c/308 Redirected to http://h.lgv5.net/c/200 Trying 78.47.117.79... Requesting http://h.lgv5.net/c/200 480 bytes received in 0.00 seconds (4.66 MB/s) Cheers! -Lucas Index: fetch.c === RCS file: /home/cvs/src/usr.bin/ftp/fetch.c,v retrieving revision 1.198 diff -u -p -r1.198 fetch.c --- fetch.c 18 Oct 2020 20:35:18 - 1.198 +++ fetch.c 24 Dec 2020 14:03:03 - @@ -843,6 +843,7 @@ noslash: case 302: /* Found */ case 303: /* See Other */ case 307: /* Temporary Redirect */ + case 308: /* Permanent Redirect */ isredirect++; if (redirect_loop++ > 10) { warnx("Too many redirections requested");
sdhc@acpi improvements
Some ACPI platforms targetting linux that have quirky SDHC controllers use ACPI _DSD properties to override the capability register of the controller. An example is the SDHC controller on the Raspberry Pi4. Diff below implements this. ok? Index: dev/acpi/sdhc_acpi.c === RCS file: /cvs/src/sys/dev/acpi/sdhc_acpi.c,v retrieving revision 1.15 diff -u -p -r1.15 sdhc_acpi.c --- dev/acpi/sdhc_acpi.c8 May 2020 11:18:01 - 1.15 +++ dev/acpi/sdhc_acpi.c24 Dec 2020 11:19:35 - @@ -84,6 +84,7 @@ sdhc_acpi_attach(struct device *parent, struct sdhc_acpi_softc *sc = (struct sdhc_acpi_softc *)self; struct acpi_attach_args *aaa = aux; struct aml_value res; + uint32_t cap, capmask; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_node = aaa->aaa_node; @@ -140,10 +141,18 @@ sdhc_acpi_attach(struct device *parent, sdhc_acpi_power_on(sc, sc->sc_node); sdhc_acpi_explore(sc); + cap = acpi_getpropint(sc->sc_node, "sdhci-caps", 0); + capmask = acpi_getpropint(sc->sc_node, "sdhci-caps-mask", 0); + if (capmask != 0) { + cap = bus_space_read_4(sc->sc_memt, sc->sc_memh, + SDHC_CAPABILITIES); + cap &= ~capmask; + } + sc->sc.sc_host = >sc_host; sc->sc.sc_dmat = aaa->aaa_dmat; sdhc_host_found(>sc, sc->sc_memt, sc->sc_memh, - aaa->aaa_size[0], 1, 0); + aaa->aaa_size[0], 1, cap); } int
Re: acme-client(1): fulfil all challenges, then tell the the CA
On Wed, Dec 23, 2020 at 09:58:41PM +, Stuart Henderson wrote: > On 2020/12/23 18:09, Florian Obser wrote: > > First fulfil all challenges then tell the CA that it should check. > > > > With a CSR with multiple SANs acme-client would write one challenge, > > tell the CA, write the next challenge and so on. > > > > For http-01 this doesn't matter but I think this will be nicer for dns-01 > > because there are propagation delays to consider. > > > > Please be extra careful checking this. If I mess this up people might > > run into renewal issues months from now. And when that happens people > > tend to comment... (Which I also pull this out of the big diff I'm > > currently working on for dns-01.) > > > > OK? > > I tested by forcibly renewing some multi-name certificates. I saw that > letsencrypt didn't bother re-challenging because they already had a > recent auth so I moved them to buypass, all looks good. (FWIW I did Yes, it's a bit annoying that you can't force a revalidation. Say you fiddle around with your webserver config and want to test if acme-client still works. Chances are that you won't notice if there is a problem because let's encrypt just hands you a renewed cert. Another way to force a revalidation is deleting the account key... > some ecdsa as well as rsa, not that it matters for this test). Thanks, one thing I'm worried about is some challenges being valid and others are pending. (I.e. is the "if() continue" correct, pretty sure it is since I just pull it down...) But I have no idea how to test that. > > Reads good and works for me, OK. > > > > diff --git netproc.c netproc.c > > index 38732a4dd01..7c502643acc 100644 > > --- netproc.c > > +++ netproc.c > > @@ -840,7 +840,12 @@ netproc(int kfd, int afd, int Cfd, int cfd, int dfd, > > int rfd, > > if (readop(Cfd, COMM_CHNG_ACK) != CHNG_ACK) > > goto out; > > > > - /* Write to the CA that it's ready. */ > > + } > > + /* Write to the CA that it's ready. */ > > + for (i = 0; i < order.authsz; i++) { > > + if (chngs[i].status == CHNG_VALID || > > + chngs[i].status == CHNG_INVALID) > > + continue; > > if (!dochngresp(, [i])) > > goto out; > > } > > > > > > -- > > I'm not entirely sure you are real. > > > -- I'm not entirely sure you are real.