ref: fa130c953552f0d4844349f2b9d48b48620ac183
parent: 74dfb591e159b5d4600e34dc736a611b2f4a11ba
author: Igor Böhm <igor@9lab.org>
date: Thu Oct 6 18:41:13 EDT 2022
acmed: remove obsolete ip/acmed.c Remove stale ip/acmed.c left over after move from ip/ to auth/ in d8a1437cf4d604b66faad24f274b447d85039d63.
--- a/sys/src/cmd/ip/acmed.c
+++ /dev/null
@@ -1,905 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <json.h>
-#include <mp.h>
-#include <libsec.h>
-#include <auth.h>
-#include <authsrv.h>
-
-typedef struct Hdr Hdr;
-
-#pragma varargck type "E" char*
-
-struct Hdr {
- char *name;
- char *val;
- int nval;
-};
-
-#define Keyspec "proto=rsa service=acme role=sign hash=sha256 acct=%s"
-#define Useragent "useragent aclient-plan9"
-#define Contenttype "contenttype application/jose+json"
-#define between(x,min,max) (((min-1-x) & (x-max-1))>>8)
-int debug;
-int (*challengefn)(char*, char*, char*, int*);
-char *keyspec;
-char *provider = "https://acme-v02.api.letsencrypt.org/directory"; /* default endpoint */
-char *challengecmd;
-char *challengeout;
-char *keyid;
-char *epnewnonce;
-char *epnewacct;
-char *epneworder;
-char *eprevokecert;
-char *epkeychange;
-char *jwsthumb;
-JSON *jwskey;
-
-#define dprint(...) if(debug)fprint(2, __VA_ARGS__);
-
-char*
-evsmprint(char *fmt, va_list ap)
-{
- char *r;
-
- if((r = vsmprint(fmt, ap)) == nil)
- abort();
- return r;
-}
-
-char*
-esmprint(char *fmt, ...)
-{
- va_list ap;
- char *r;
-
- va_start(ap, fmt);
- r = evsmprint(fmt, ap);
- va_end(ap);
- return r;
-}
-
-int
-encurl64chr(int o)
-{
- int c;
-
- c = between(o, 0, 25) & ('A'+o);
- c |= between(o, 26, 51) & ('a'+(o-26));
- c |= between(o, 52, 61) & ('0'+(o-52));
- c |= between(o, 62, 62) & ('-');
- c |= between(o, 63, 63) & ('_');
- return c;
-}
-char*
-encurl64(void *in, int n)
-{
- int lim;
- char *out, *p;
-
- lim = 4*n/3 + 5;
- if((out = malloc(lim)) == nil)
- abort();
- enc64x(out, lim, in, n, encurl64chr);
- if((p = strchr(out, '=')) != nil)
- *p = 0;
- return out;
-}
-
-char*
-signRS256(char *hdr, char *prot)
-{
- uchar hash[SHA2_256dlen];
- DigestState *s;
- AuthRpc *rpc;
- int afd;
- char *r;
-
- if((afd = open("/mnt/factotum/rpc", ORDWR|OCEXEC)) < 0)
- return nil;
- if((rpc = auth_allocrpc(afd)) == nil){
- close(afd);
- return nil;
- }
- if(auth_rpc(rpc, "start", keyspec, strlen(keyspec)) != ARok){
- auth_freerpc(rpc);
- close(afd);
- return nil;
- }
-
- s = sha2_256((uchar*)hdr, strlen(hdr), nil, nil);
- s = sha2_256((uchar*)".", strlen("."), nil, s);
- sha2_256((uchar*)prot, strlen(prot), hash, s);
-
- if(auth_rpc(rpc, "write", hash, sizeof(hash)) != ARok)
- sysfatal("sign: write hash: %r");
- if(auth_rpc(rpc, "read", nil, 0) != ARok)
- sysfatal("sign: read sig: %r");
- r = encurl64(rpc->arg, rpc->narg);
- auth_freerpc(rpc);
- close(afd);
- return r;
-}
-
-/*
- * Reads all available data from an fd.
- * guarantees returned value is terminated.
- */
-static void*
-slurp(int fd, int *n)
-{
- char *b;
- int r, sz;
-
- *n = 0;
- sz = 32;
- if((b = malloc(sz)) == nil)
- abort();
- while(1){
- if(*n + 1 == sz){
- sz *= 2;
- if((b = realloc(b, sz)) == nil)
- abort();
- }
- r = read(fd, b + *n, sz - *n - 1);
- if(r == 0)
- break;
- if(r == -1){
- free(b);
- return nil;
- }
- *n += r;
- }
- b[*n] = 0;
- return b;
-}
-
-static int
-webopen(char *url, char *dir, int ndir)
-{
- char buf[16];
- int n, cfd, conn;
-
- if((cfd = open("/mnt/web/clone", ORDWR|OCEXEC)) == -1)
- return -1;
- if((n = read(cfd, buf, sizeof(buf)-1)) == -1)
- goto Error;
- buf[n] = 0;
- conn = atoi(buf);
-
- if(fprint(cfd, "url %s", url) == -1)
- goto Error;
- snprint(dir, ndir, "/mnt/web/%d", conn);
- return cfd;
-Error:
- close(cfd);
- return -1;
-}
-
-static char*
-get(char *url, int *n)
-{
- char *r, dir[64], path[80];
- int cfd, dfd;
-
- r = nil;
- dfd = -1;
- if((cfd = webopen(url, dir, sizeof(dir))) == -1)
- goto Error;
- snprint(path, sizeof(path), "%s/%s", dir, "body");
- if((dfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- r = slurp(dfd, n);
-Error:
- if(dfd != -1) close(dfd);
- if(cfd != -1) close(cfd);
- return r;
-}
-
-static char*
-post(char *url, char *buf, int nbuf, int *nret, Hdr *h)
-{
- char *r, dir[64], path[80];
- int cfd, dfd, hfd, ok;
-
- r = nil;
- ok = 0;
- dfd = -1;
- hfd = -1;
- if((cfd = webopen(url, dir, sizeof(dir))) == -1)
- goto Error;
- if(write(cfd, Contenttype, strlen(Contenttype)) == -1)
- goto Error;
- snprint(path, sizeof(path), "%s/%s", dir, "postbody");
- if((dfd = open(path, OWRITE|OCEXEC)) == -1)
- goto Error;
- if(write(dfd, buf, nbuf) != nbuf)
- goto Error;
- close(dfd);
- snprint(path, sizeof(path), "%s/%s", dir, "body");
- if((dfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- if(h != nil){
- snprint(path, sizeof(path), "%s/%s", dir, h->name);
- if((hfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- if((h->val = slurp(hfd, &h->nval)) == nil)
- goto Error;
- }
- if((r = slurp(dfd, nret)) == nil)
- goto Error;
- ok = 1;
-Error:
- if(hfd != -1) close(hfd);
- if(dfd != -1) close(dfd);
- if(cfd != -1) close(cfd);
- if(!ok && h != nil){
- free(h->val);
- h->val = nil;
- h->nval = 0;
- }
- return r;
-}
-
-static int
-endpoints(void)
-{
- JSON *j;
- JSONEl *e;
- char *s;
- int n;
-
- if((s = get(provider, &n)) == nil)
- sysfatal("get %s: %r", provider);
- if((j = jsonparse(s)) == nil)
- sysfatal("parse endpoints: %r");
- if(j->t != JSONObject)
- sysfatal("expected object");
- for(e = j->first; e != nil; e = e->next){
- if(e->val->t != JSONString)
- continue;
- if(strcmp(e->name, "keyChange") == 0)
- epkeychange = strdup(e->val->s);
- else if(strcmp(e->name, "newAccount") == 0)
- epnewacct = strdup(e->val->s);
- else if(strcmp(e->name, "newNonce") == 0)
- epnewnonce = strdup(e->val->s);
- else if(strcmp(e->name, "newOrder") == 0)
- epneworder = strdup(e->val->s);
- else if(strcmp(e->name, "revokeCert") == 0)
- eprevokecert = strdup(e->val->s);
- }
- jsonfree(j);
- free(s);
- if(epnewnonce==nil|| epnewacct==nil || epneworder==nil
- || eprevokecert==nil || epkeychange==nil){
- sysfatal("missing directory entries");
- return -1;
- }
- return 0;
-}
-
-static char*
-getnonce(void)
-{
- char *r, dir[64], path[80];
- int n, cfd, dfd, hfd;
-
- r = nil;
- dfd = -1;
- hfd = -1;
- if((cfd = webopen(epnewnonce, dir, sizeof(dir))) == -1)
- goto Error;
- fprint(cfd, "request HEAD");
-
- snprint(path, sizeof(path), "%s/%s", dir, "body");
- if((dfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- snprint(path, sizeof(path), "%s/%s", dir, "replaynonce");
- if((hfd = open(path, OREAD|OCEXEC)) == -1)
- goto Error;
- r = slurp(hfd, &n);
-Error:
- if(hfd != -1)
- close(hfd);
- if(dfd != -1)
- close(dfd);
- close(cfd);
- return r;
-}
-
-char*
-jwsenc(char *hdr, char *msg, int *nbuf)
-{
- char *h, *m, *s, *r;
-
- h = encurl64(hdr, strlen(hdr));
- m = encurl64(msg, strlen(msg));
- s = signRS256(h, m);
- if(s == nil)
- return nil;
-
- r = esmprint(
- "{\n"
- "\"protected\": \"%s\",\n"
- "\"payload\": \"%s\",\n"
- "\"signature\": \"%s\"\n"
- "}\n",
- h, m, s);
- *nbuf = strlen(r);
- free(h);
- free(m);
- free(s);
-
- return r;
-}
-
-char*
-jwsheader(char *url)
-{
- char *nonce;
-
- if((nonce = getnonce()) == nil)
- sysfatal("get nonce: %r");
- return esmprint(
- "{"
- "\"alg\": \"RS256\","
- "\"nonce\": \"%E\","
- "\"kid\": \"%E\","
- "\"url\": \"%E\""
- "}",
- nonce, keyid, url);
-}
-
-char*
-jwsrequest(char *url, int *nresp, Hdr *h, char *fmt, ...)
-{
- char *hdr, *msg, *req, *resp;
- int nreq;
- va_list ap;
-
- va_start(ap, fmt);
- hdr = jwsheader(url);
- msg = evsmprint(fmt, ap);
- req = jwsenc(hdr, msg, &nreq);
- dprint("req=\"%s\"\n", req);
- resp = post(url, req, nreq, nresp, h);
- free(hdr);
- free(req);
- free(msg);
- va_end(ap);
- dprint("resp=%s\n", resp);
- return resp;
-}
-
-static void
-mkaccount(char *addr)
-{
- char *nonce, *hdr, *msg, *req, *resp;
- int nreq, nresp;
- Hdr loc = { "location" };
-
- if((nonce = getnonce()) == nil)
- sysfatal("get nonce: %r");
- hdr = esmprint(
- "{"
- "\"alg\": \"RS256\","
- "\"jwk\": %J,"
- "\"nonce\": \"%E\","
- "\"url\": \"%E\""
- "}",
- jwskey, nonce, epnewacct);
- msg = esmprint(
- "{"
- "\"termsOfServiceAgreed\": true,"
- "\"contact\": [\"mailto:%E\"]"
- "}",
- addr);
- free(nonce);
- if((req = jwsenc(hdr, msg, &nreq)) == nil)
- sysfatal("failed to sign: %r");
- dprint("req=\"%s\"\n", req);
-
- if((resp = post(epnewacct, req, nreq, &nresp, &loc)) == nil)
- sysfatal("failed req: %r");
- dprint("resp=%s, loc=%s\n", resp, loc.val);
- keyid = loc.val;
-}
-
-static JSON*
-submitorder(char **dom, int ndom, Hdr *hdr)
-{
- char *req, *resp, *sep, rbuf[8192];
- int nresp, i;
- JSON *r;
-
- sep = "";
- req = seprint(rbuf, rbuf+sizeof(rbuf),
- "{"
- " \"identifiers\": [");
- for(i = 0; i < ndom; i++){
- req = seprint(req, rbuf+sizeof(rbuf),
- "%s{"
- " \"type\": \"dns\","
- " \"value\": \"%E\""
- "}",
- sep, dom[i]);
- sep = ",";
- }
- req = seprint(req, rbuf+sizeof(rbuf),
- " ],"
- " \"wildcard\": false"
- "}");
- if(req - rbuf < 2)
- sysfatal("truncated order");
- resp = jwsrequest(epneworder, &nresp, hdr, "%s", rbuf);
- if(resp == nil)
- sysfatal("submit order: %r");
- if((r = jsonparse(resp)) == nil)
- sysfatal("parse order: %r");
- free(resp);
- return r;
-}
-
-static void
-hashauthbuf(char *buf, int nbuf)
-{
- uchar hash[SHA2_256dlen];
- char *enc;
-
- sha2_256((uchar*)buf, strlen(buf), hash, nil);
- if((enc = encurl64(hash, sizeof(hash))) == nil)
- sysfatal("hashbuf: %r");
- if(snprint(buf, nbuf, "%s", enc) != strlen(enc))
- sysfatal("hashbuf: buffer too small, truncated");
- free(enc);
-}
-
-static int
-runchallenge(char *ty, char *dom, char *tok, int *matched)
-{
- char auth[1024];
- Waitmsg *w;
- int pid;
-
- snprint(auth, sizeof(auth), "%s.%s", tok, jwsthumb);
- if(strcmp(ty, "dns-01") == 0)
- hashauthbuf(auth, sizeof(auth));
-
- pid = fork();
- switch(pid){
- case -1:
- return -1;
- case 0:
- dup(1, 2);
- execl(challengecmd, challengecmd, ty, dom, tok, auth, nil);
- sysfatal("%s: %r", challengecmd);
- }
-
- while((w = wait()) != nil){
- if(w->pid != pid){
- free(w);
- continue;
- }
- if(w->msg[0] == '\0'){
- free(w);
- *matched = 1;
- return 0;
- }
- werrstr("%s", w->msg);
- free(w);
- return -1;
- }
- return -1;
-}
-
-static int
-httpchallenge(char *ty, char *, char *tok, int *matched)
-{
- char path[1024];
- int fd, r;
-
- if(strcmp(ty, "http-01") != 0)
- return -1;
- *matched = 1;
-
- snprint(path, sizeof(path), "%s/%s", challengeout, tok);
- if((fd = create(path, OWRITE|OCEXEC, 0666)) == -1)
- return -1;
- r = fprint(fd, "%s.%s\n", tok, jwsthumb);
- close(fd);
- return r;
-}
-
-static int
-dnschallenge(char *ty, char *dom, char *tok, int *matched)
-{
- char auth[1024];
- int fd;
-
- if(strcmp(ty, "dns-01") != 0)
- return -1;
- *matched = 1;
-
- snprint(auth, sizeof(auth), "%s.%s", tok, jwsthumb);
- hashauthbuf(auth, sizeof(auth));
-
- if((fd = create(challengeout, OWRITE|OCEXEC, 0666)) == -1){
- werrstr("could not create challenge: %r");
- return -1;
- }
- if(fprint(fd,"dom=_acme-challenge.%s soa=\n\ttxt=\"%s\"\n", dom, auth) == -1){
- werrstr("could not write challenge: %r");
- close(fd);
- return -1;
- }
- close(fd);
-
- if((fd = open("/net/dns", OWRITE|OCEXEC)) == -1){
- werrstr("could not open dns ctl: %r");
- return -1;
- }
- if(fprint(fd, "refresh") == -1){
- werrstr("could not write dns refresh: %r");
- close(fd);
- return -1;
- }
- close(fd);
-
- return 0;
-}
-
-static int
-challenge(JSON *j, char *authurl, JSON *id, char *dom[], int ndom, int *matched)
-{
- JSON *dn, *ty, *url, *tok, *poll, *state;
- char *resp;
- int i, nresp;
-
- if((dn = jsonbyname(id, "value")) == nil)
- return -1;
- if(dn->t != JSONString)
- return -1;
-
- /* make sure the identifier matches the csr */
- for(i = 0; i < ndom; i++){
- if(cistrcmp(dom[i], dn->s) == 0)
- break;
- }
- if(i >= ndom){
- werrstr("unknown challenge identifier '%s'", dn->s);
- return -1;
- }
-
- if((ty = jsonbyname(j, "type")) == nil)
- return -1;
- if((url = jsonbyname(j, "url")) == nil)
- return -1;
- if((tok = jsonbyname(j, "token")) == nil)
- return -1;
-
- if(ty->t != JSONString || url->t != JSONString || tok->t != JSONString)
- return -1;
-
- dprint("trying challenge %s\n", ty->s);
- if(challengefn(ty->s, dn->s, tok->s, matched) == -1){
- dprint("challengefn failed: %r\n");
- return -1;
- }
-
- if((resp = jwsrequest(url->s, &nresp, nil, "{}")) == nil)
- sysfatal("challenge: post %s: %r", url->s);
- free(resp);
-
- for(i = 0; i < 60; i++){
- sleep(1000);
- if((resp = jwsrequest(authurl, &nresp, nil, "")) == nil)
- sysfatal("challenge: post %s: %r", url->s);
- if((poll = jsonparse(resp)) == nil){
- free(resp);
- return -1;
- }
- if((state = jsonbyname(poll, "status")) != nil && state->t == JSONString){
- if(strcmp(state->s, "valid") == 0){
- jsonfree(poll);
- return 0;
- }
- else if(strcmp(state->s, "pending") != 0){
- fprint(2, "error: %J", poll);
- werrstr("status '%s'", state->s);
- jsonfree(poll);
- return -1;
- }
- }
- jsonfree(poll);
- }
- werrstr("timeout");
- return -1;
-}
-
-static int
-dochallenges(char *dom[], int ndom, JSON *order)
-{
- JSON *chals, *j, *cl, *id;
- JSONEl *ae, *ce;
- int nresp, matched;
- char *resp;
-
- if((j = jsonbyname(order, "authorizations")) == nil){
- werrstr("parse response: missing authorizations");
- return -1;
- }
- if(j->t != JSONArray){
- werrstr("parse response: authorizations must be array");
- return -1;
- }
- for(ae = j->first; ae != nil; ae = ae->next){
- if(ae->val->t != JSONString){
- werrstr("challenge: auth must be url");
- return -1;
- }
- if((resp = jwsrequest(ae->val->s, &nresp, nil, "")) == nil){
- werrstr("challenge: request %s: %r", ae->val->s);
- return -1;
- }
- if((chals = jsonparse(resp)) == nil){
- werrstr("invalid challenge: %r");
- return -1;
- }
- if((id = jsonbyname(chals, "identifier")) == nil){
- werrstr("missing identifier");
- jsonfree(chals);
- return -1;
- }
- if((cl = jsonbyname(chals, "challenges")) == nil){
- werrstr("missing challenge");
- jsonfree(chals);
- return -1;
- }
- matched = 0;
- for(ce = cl->first; ce != nil; ce = ce->next){
- if(challenge(ce->val, ae->val->s, id, dom, ndom, &matched) == 0)
- break;
- if(matched)
- werrstr("could not complete challenge: %r");
- }
- if(!matched)
- sysfatal("no matching auth type");
- jsonfree(chals);
- free(resp);
- }
- return 0;
-}
-
-static int
-submitcsr(JSON *order, char *b64csr)
-{
- char *resp;
- int nresp;
- JSON *j;
-
- if((j = jsonbyname(order, "finalize")) == nil)
- sysfatal("parse response: missing authorizations");
- if(j->t != JSONString)
- werrstr("parse response: finalizer must be string");
- if((resp = jwsrequest(j->s, &nresp, nil, "{\"csr\":\"%E\"}", b64csr)) == nil)
- sysfatal("submit csr: %r");
- free(resp);
- return 0;
-}
-
-static int
-fetchcert(char *url)
-{
- JSON *cert, *poll, *state;
- int i, r, nresp;
- char *resp;
-
- poll = nil;
- for(i = 0; i < 60; i++){
- sleep(1000);
- if((resp = jwsrequest(url, &nresp, nil, "")) == nil)
- return -1;
- if((poll = jsonparse(resp)) == nil){
- free(resp);
- return -1;
- }
- free(resp);
- if((state = jsonbyname(poll, "status")) != nil && state->t == JSONString){
- if(strcmp(state->s, "valid") == 0)
- break;
- else if(strcmp(state->s, "pending") != 0 && strcmp(state->s, "processing") != 0){
- fprint(2, "error: %J", poll);
- werrstr("invalid request: %s", state->s);
- jsonfree(poll);
- return -1;
-
- }
- }
- jsonfree(poll);
- }
- if(poll == nil){
- werrstr("timed out");
- return -1;
- }
- if((cert = jsonbyname(poll, "certificate")) == nil || cert->t != JSONString){
- werrstr("missing cert url in response");
- jsonfree(poll);
- return -1;
- }
- if((resp = jwsrequest(cert->s, &nresp, nil, "")) == nil){
- jsonfree(poll);
- return -1;
- }
- jsonfree(poll);
- r = write(1, resp, nresp);
- free(resp);
- if(r != nresp)
- return -1;
- return 0;
-}
-
-static void
-getcert(char *csrpath)
-{
- char *csr, *dom[64], name[2048];
- uchar *der;
- int nder, ndom, fd;
- RSApub *rsa;
- Hdr loc = { "location" };
- JSON *o;
-
- if((fd = open(csrpath, OREAD|OCEXEC)) == -1)
- sysfatal("open %s: %r", csrpath);
- if((der = slurp(fd, &nder)) == nil)
- sysfatal("read %s: %r", csrpath);
- if((rsa = X509reqtoRSApub(der, nder, name, sizeof(name))) == nil)
- sysfatal("decode csr: %r");
- if((csr = encurl64(der, nder)) == nil)
- sysfatal("encode %s: %r", csrpath);
- if((ndom = getfields(name, dom, nelem(dom), 1, ", ")) == nelem(dom))
- sysfatal("too man domains");
- rsapubfree(rsa);
- close(fd);
- free(der);
-
- if((o = submitorder(dom, ndom, &loc)) == nil)
- sysfatal("order: %r");
- if(dochallenges(dom, ndom, o) == -1)
- sysfatal("challenge: %r");
- if(submitcsr(o, csr) == -1)
- sysfatal("signing cert: %r");
- if(fetchcert(loc.val) == -1)
- sysfatal("saving cert: %r");
- free(csr);
-}
-
-static int
-Econv(Fmt *f)
-{
- char *s;
- Rune r;
- int w;
-
- w = 0;
- s = va_arg(f->args, char*);
- while(*s){
- s += chartorune(&r, s);
- if(r == '\\' || r == '\"')
- w += fmtrune(f, '\\');
- w += fmtrune(f, r);
- }
- return w;
-}
-
-static int
-loadkey(char *path)
-{
- uchar h[SHA2_256dlen];
- char key[8192];
- JSON *j, *e, *kty, *n;
- DigestState *ds;
- int fd, nr;
-
- if((fd = open(path, OREAD|OCEXEC)) == -1)
- return -1;
- nr = readn(fd, key, sizeof(key));
- close(fd);
- if(nr == -1)
- return -1;
- key[nr] = 0;
-
- if((j = jsonparse(key)) == nil)
- return -1;
- if((e = jsonbyname(j, "e")) == nil || e->t != JSONString)
- return -1;
- if((kty = jsonbyname(j, "kty")) == nil || kty->t != JSONString)
- return -1;
- if((n = jsonbyname(j, "n")) == nil || n->t != JSONString)
- return -1;
-
- ds = sha2_256((uchar*)"{\"e\":\"", 6, nil, nil);
- ds = sha2_256((uchar*)e->s, strlen(e->s), nil, ds);
- ds = sha2_256((uchar*)"\",\"kty\":\"", 9, nil, ds);
- ds = sha2_256((uchar*)kty->s, strlen(kty->s), nil, ds);
- ds = sha2_256((uchar*)"\",\"n\":\"", 7, nil, ds);
- ds = sha2_256((uchar*)n->s, strlen(n->s), nil, ds);
- sha2_256((uchar*)"\"}", 2, h, ds);
- jwskey = j;
- jwsthumb = encurl64(h, sizeof(h));
- return 0;
-}
-
-static void
-usage(void)
-{
- fprint(2, "usage: %s [-a acctkey] [-e cmd | -o chalout -t type] [-p provider] acct csr\n", argv0);
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- char *acctkey, *ct, *co;
-
- JSONfmtinstall();
- fmtinstall('E', Econv);
-
- ct = nil;
- co = nil;
- acctkey = nil;
- ARGBEGIN{
- case 'd':
- debug++;
- break;
- case 'a':
- acctkey = EARGF(usage());
- break;
- case 'e':
- challengecmd = EARGF(usage());
- break;
- case 'o':
- co = EARGF(usage());
- break;
- case 't':
- ct = EARGF(usage());
- break;
- case 'p':
- provider = EARGF(usage());
- break;
- default:
- usage();
- break;
- }ARGEND;
-
- if(challengecmd != nil){
- if(ct != nil || co != nil)
- usage();
- challengeout = "/dev/null";
- challengefn = runchallenge;
- }else if(ct == nil || strcmp(ct, "http") == 0){
- challengeout = (co != nil) ? co : "/usr/web/.well-known/acme-challenge";
- challengefn = httpchallenge;
- }else if(strcmp(ct, "dns") == 0){
- challengeout = (co != nil) ? co : "/lib/ndb/dnschallenge";
- challengefn = dnschallenge;
- }else {
- sysfatal("unknown challenge type '%s'", ct);
- }
-
- if(argc != 2)
- usage();
-
- if(acctkey == nil)
- acctkey = esmprint("/sys/lib/tls/acmed/%s.pub", argv[0]);
- if((keyspec = smprint(Keyspec, argv[0])) == nil)
- sysfatal("smprint: %r");
- if(loadkey(acctkey) == -1)
- sysfatal("load key: %r");
-
- if(endpoints() == -1)
- sysfatal("endpoints: %r");
- mkaccount(argv[0]);
- getcert(argv[1]);
- exits(nil);
-}