openbsd-ports/comms/amtterm/patches/patch-redir_c

197 lines
4.7 KiB
Plaintext

Add SSL/auth code
https://github.com/Openwsman/wsmancli/issues/10#issuecomment-751253133
Index: redir.c
--- redir.c.orig
+++ redir.c
@@ -29,9 +29,12 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <sys/time.h>
#include "tcp.h"
+#include "ssl.h"
#include "redir.h"
+#include "auth.h"
static const char *state_name[] = {
[ REDIR_NONE ] = "NONE",
@@ -100,7 +103,7 @@ static ssize_t redir_write(struct redir *r, const char
if (r->trace)
hexdump("out", buf, count);
- rc = write(r->sock, buf, count);
+ rc = sslwrite(r->ctx, buf, count);
if (-1 == rc)
snprintf(r->err, sizeof(r->err), "write(socket): %s", strerror(errno));
return rc;
@@ -142,8 +145,11 @@ const char *redir_state_desc(enum redir_state state)
int redir_connect(struct redir *r)
{
static unsigned char *defport = "16994";
+ static unsigned char *sslport = "16995";
struct addrinfo ai;
+ if (r->cacert)
+ defport = sslport;
memset(&ai, 0, sizeof(ai));
ai.ai_socktype = SOCK_STREAM;
ai.ai_family = PF_UNSPEC;
@@ -151,6 +157,11 @@ int redir_connect(struct redir *r)
redir_state(r, REDIR_CONNECT);
r->sock = tcp_connect(&ai, NULL, NULL, r->host,
strlen(r->port) ? r->port : defport);
+ r->ctx = sslinit(r->sock, r->cacert);
+ if(r->ctx == NULL) {
+ close(r->sock);
+ r->sock = -1;
+ }
if (-1 == r->sock) {
redir_state(r, REDIR_ERROR);
/* FIXME: better error message */
@@ -179,11 +190,13 @@ int redir_stop(struct redir *r)
redir_state(r, REDIR_CLOSED);
redir_write(r, request, sizeof(request));
+ sslexit(r->ctx);
+ r->ctx = NULL;
close(r->sock);
return 0;
}
-int redir_auth(struct redir *r)
+static int redir_auth_old(struct redir *r)
{
int ulen = strlen(r->user);
int plen = strlen(r->pass);
@@ -205,6 +218,79 @@ int redir_auth(struct redir *r)
return rc;
}
+static int io(void *parm, unsigned char *data, int len, int mode)
+{
+ int rc;
+ struct redir *r;
+ struct timeval tv;
+ fd_set set;
+
+ switch(mode)
+ {
+ case READ:
+ r = (struct redir *)parm;
+ while (len) {
+ FD_ZERO(&set);
+ FD_SET(r->sock,&set);
+ if (!sslready(r->ctx)) {
+ tv.tv_sec = HEARTBEAT_INTERVAL * 4 / 1000;
+ tv.tv_usec = 0;
+ switch (select(r->sock+1,&set,NULL,NULL,&tv)) {
+ case -1:
+ perror("select");
+ return -1;
+ case 0:
+ fprintf(stderr,"select: timeout\n");
+ return -1;
+ }
+ }
+ rc = sslread(r->ctx, data, len);
+ switch (rc) {
+ case -1:
+ fprintf(stderr, "read(socket): %s", strerror(errno));
+ return -1;
+ case 0:
+ fprintf(stderr, "EOF from socket");
+ return -1;
+ default:
+ if (r->trace)
+ hexdump("in ", data, rc);
+ data += rc;
+ len -= rc;
+ }
+ }
+ return 0;
+
+ case WRITE:
+ r = (struct redir *)parm;
+ if (redir_write(r, data, len) != len)
+ return -1;
+ return 0;
+
+ case RANDOM:
+ gettimeofday(&tv, NULL);
+ if (sizeof(tv) <= len)
+ memcpy(data, &tv, sizeof(tv));
+ else
+ memcpy(data, &tv, len);
+ return 0;
+ }
+
+ return -1;
+}
+
+int redir_auth(struct redir *r)
+{
+ int rc;
+
+ if (r->legacy)
+ return redir_auth_old(r);
+
+ redir_state(r, REDIR_AUTH);
+ rc = authenticate(0, r->user, r->pass, io, r);
+ return rc;
+}
+
int redir_sol_start(struct redir *r)
{
unsigned char request[START_SOL_REDIRECTION_LENGTH] = {
@@ -280,7 +366,7 @@ int redir_sol_recv(struct redir *r)
ready yet, but should be here Real Soon Now. */
flags = fcntl(r->sock,F_GETFL);
fcntl(r->sock,F_SETFL, flags & (~O_NONBLOCK));
- count = read(r->sock, msg, count);
+ count = sslread(r->ctx, msg, count);
fcntl(r->sock,F_SETFL, flags);
switch (count) {
@@ -309,12 +395,13 @@ int redir_data(struct redir *r)
{
int rc, bshift;
+repeat:
if (r->trace) {
fprintf(stderr, "in --\n");
if (r->blen)
fprintf(stderr, "in : already have %d\n", r->blen);
}
- rc = read(r->sock, r->buf + r->blen, sizeof(r->buf) - r->blen);
+ rc = sslread(r->ctx, r->buf + r->blen, sizeof(r->buf) - r->blen);
switch (rc) {
case -1:
snprintf(r->err, sizeof(r->err), "read(socket): %s", strerror(errno));
@@ -456,18 +543,24 @@ int redir_data(struct redir *r)
memmove(r->buf, r->buf + bshift, r->blen - bshift);
r->blen -= bshift;
}
+ if (r->ctx && sslready(r->ctx))
+ goto repeat;
return 0;
again:
/* need more data, jump back into poll/select loop */
if (r->trace)
fprintf(stderr, "in : need more data\n");
+ if (sslready(r->ctx))
+ goto repeat;
return 0;
err:
if (r->trace)
fprintf(stderr, "in : ERROR (%s)\n", r->err);
redir_state(r, REDIR_ERROR);
+ sslexit(r->ctx);
+ r->ctx = NULL;
close(r->sock);
return -1;
}