commit 58b141cfaab7898107a6c4bc674ddfacf46ce267 from: Omar Polo date: Wed Dec 21 09:11:03 2022 UTC kamiftp: backout 8f7253b29f275cfc3fd6111a54ce1cdd6622d1ee don't use funopen(3) as it's not portable, found the hard way by cage. libbsd provides a funopen(3) on top of GNU libc' fopencookie, but I'd like to avoid dependencies on functions that are hard to port to other platforms. commit - dfd2478304e3802321f96d969b68c7f08bd70d8c commit + 58b141cfaab7898107a6c4bc674ddfacf46ce267 blob - 733177d3c2233b99bef23a212c437ddaab83ba02 blob + 4d41a34c5e4e357eb7c5d451e6f5d845656da0d8 --- kamiftp/ftp.c +++ kamiftp/ftp.c @@ -58,7 +58,9 @@ const char *crtpath; const char *keypath; /* state */ -FILE *fp; +struct tls_config *tlsconf; +struct tls *ctx; +int sock; struct evbuffer *buf; struct evbuffer *dirbuf; uint32_t msize; @@ -131,51 +133,6 @@ spawn(const char *argv0, ...) } } -static int -stdio_tls_write(void *arg, const char *buf, int len) -{ - struct tls *ctx = arg; - ssize_t ret; - - do { - ret = tls_write(ctx, buf, len); - } while (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT); - - if (ret == -1) - warn("tls_write: %s", tls_error(ctx)); - - return ret; -} - -static int -stdio_tls_read(void *arg, char *buf, int len) -{ - struct tls *ctx = arg; - ssize_t ret; - - do { - ret = tls_read(ctx, buf, len); - } while (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT); - - if (ret == -1) - warn("tls_read: %s", tls_error(ctx)); - - return ret; -} - -static int -stdio_tls_close(void *arg) -{ - struct tls *ctx = arg; - int ret; - - do { - ret = tls_close(ctx); - } while (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT); - - return ret; -} - static void tty_resized(int signo) { @@ -205,16 +162,30 @@ nextfid(void) static void do_send(void) { - size_t r; + const void *buf; + size_t nbytes; + ssize_t r; if (xdump) hexdump("outgoing message", EVBUFFER_DATA(evb), EVBUFFER_LENGTH(evb)); while (EVBUFFER_LENGTH(evb) != 0) { - r = fwrite(EVBUFFER_DATA(evb), 1, EVBUFFER_LENGTH(evb), fp); - if (r == 0) - fatalx("unexpected EOF"); + buf = EVBUFFER_DATA(evb); + nbytes = EVBUFFER_LENGTH(evb); + + if (ctx == NULL) { + r = write(sock, buf, nbytes); + if (r == 0 || r == -1) + errx(1, "EOF"); + } else { + r = tls_write(ctx, buf, nbytes); + if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) + continue; + if (r == -1) + errx(1, "tls: %s", tls_error(ctx)); + } + evbuffer_drain(evb, r); } } @@ -222,24 +193,33 @@ do_send(void) static void mustread(void *d, size_t len) { - size_t r; + ssize_t r; - r = fread(d, 1, len, fp); - if (r != len) - errx(1, "unexpected EOF"); + while (len != 0) { + if (ctx == NULL) { + r = read(sock, d, len); + if (r == 0 || r == -1) + errx(1, "EOF"); + } else { + r = tls_read(ctx, d, len); + if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) + continue; + if (r == -1) + errx(1, "tls: %s", tls_error(ctx)); + } + + d += r; + len -= r; + } } static void recv_msg(void) { - size_t r; uint32_t len, l; char tmp[BUFSIZ]; - r = fread(&len, 1, sizeof(len), fp); - if (r != sizeof(len)) - errx(1, "unexpected EOF"); - + mustread(&len, sizeof(len)); len = le32toh(len); if (len < HEADERSIZE) errx(1, "read message of invalid length %d", len); @@ -248,12 +228,9 @@ recv_msg(void) while (len != 0) { l = MIN(len, sizeof(tmp)); - - r = fread(tmp, 1, l, fp); - if (r != l) - errx(1, "unexpected EOF"); - len -= r; - evbuffer_add(buf, tmp, r); + mustread(tmp, l); + len -= l; + evbuffer_add(buf, tmp, l); } if (xdump) @@ -852,11 +829,47 @@ woc_file(int fd, const char *prompt, const char *path) return 0; } -static int -dial(const char *host, const char *port) +static void +do_tls_connect(const char *host, const char *port) +{ + int handshake; + + if ((tlsconf = tls_config_new()) == NULL) + fatalx("tls_config_new"); + tls_config_insecure_noverifycert(tlsconf); + tls_config_insecure_noverifyname(tlsconf); + + if (keypath == NULL) + keypath = crtpath; + + if (tls_config_set_keypair_file(tlsconf, crtpath, keypath) == -1) + fatalx("can't load certs (%s, %s)", crtpath, keypath); + + if ((ctx = tls_client()) == NULL) + fatal("tls_client"); + if (tls_configure(ctx, tlsconf) == -1) + fatalx("tls_configure: %s", tls_error(ctx)); + + if (tls_connect(ctx, host, port) == -1) + fatalx("can't connect to %s:%s: %s", host, port, + tls_error(ctx)); + + for (handshake = 0; !handshake;) { + switch (tls_handshake(ctx)) { + case -1: + fatalx("tls_handshake: %s", tls_error(ctx)); + case 0: + handshake = 1; + break; + } + } +} + +static void +do_ctxt_connect(const char *host, const char *port) { struct addrinfo hints, *res, *res0; - int sock, error, saved_errno; + int error, saved_errno; const char *cause = NULL; memset(&hints, 0, sizeof(hints)); @@ -886,10 +899,10 @@ dial(const char *host, const char *port) break; } - freeaddrinfo(res0); + if (sock == -1) err(1, "%s", cause); - return sock; + freeaddrinfo(res0); } static void @@ -900,48 +913,11 @@ do_connect(const char *host, const char *port, const c char *errstr; fprintf(stderr, "connecting to %s:%s...", host, port); - - if (tls) { - struct tls_config *conf; - struct tls *ctx; - int r; - - if ((conf = tls_config_new()) == NULL) - fatalx("failed to create TLS config"); - tls_config_insecure_noverifycert(conf); - tls_config_insecure_noverifyname(conf); - - if (keypath == NULL) - keypath = crtpath; - - if (tls_config_set_keypair_file(conf, crtpath, keypath) == -1) - fatalx("failed to load certs: (%s, %s)", crtpath, - keypath); - - if ((ctx = tls_client()) == NULL) - fatalx("failed to create TLS client"); - if (tls_configure(ctx, conf) == -1) - fatalx("failed to configure TLS client"); - tls_config_free(conf); - if (tls_connect(ctx, host, port) == -1) - fatalx("failed to connect to %s:%s: %s", host, port, - tls_error(ctx)); - - do { - r = tls_handshake(ctx); - } while (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT); - fp = funopen(ctx, stdio_tls_read, stdio_tls_write, NULL, - stdio_tls_close); - if (fp == NULL) - fatal("funopen"); - } else { - int fd; - - fd = dial(host, port); - if ((fp = fdopen(fd, "r+")) == NULL) - fatal("fdopen"); - } + if (tls) + do_tls_connect(host, port); + else + do_ctxt_connect(host, port); fprintf(stderr, " done!\n"); @@ -1148,7 +1124,6 @@ void cmd_bye(int argc, const char **argv) { log_warnx("bye\n"); - fclose(fp); exit(0); } @@ -1731,7 +1706,6 @@ cd_or_fetch(const char *path, const char *outfile) if (fetch_fid(nfid, fd, outfile) == -1) err(1, "write %s", outfile); close(fd); - fclose(fp); exit(0); } @@ -1865,5 +1839,4 @@ main(int argc, char **argv) } printf("\n"); - fclose(fp); }