197 lines
4.7 KiB
Plaintext
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;
|
|
}
|