Re: Request for a Lockdown option

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

 



Steffen Nurpmeso wrote in
 <20240704180538.iV4uex29@steffen%sdaoden.eu>:
 |Simon Josefsson wrote in
 | <87jzi1fg24.fsf@xxxxxxxxxxx>:
 ||Jochen Bern <Jochen.Bern@xxxxxxxxx> writes:
 ||> (And since you mention "port knocking", I'd like to repeat how fond I
 ||> am of upgrading that original concept to a single-packet
 ||> crypto-armored implementation like fwknop.)
 ||
 ||I am reluctantly considering to use some kind of port knocking mechanism
 ||on some machines, however I really don't want to carry around shared
 ||symmetric keys or setup yet another public/private key infrastructure
 ||for that purpose.  I already have a working infrastructure for SSH
 ||authentication.
 ||
 ||Does anyone know of any implementation that allows me to configure a
 ||PGP/SSH/FIDO/TPM/whatever public key on the server side, and it then
 ||only listens to signed port knocks from the corresponding private keys?
 ...
 |No, but for many years i do have a super simple port-knock server
 |to do the I/O plus sh(1)ell based client which can do .. whatever.
 ...
 |With the possibilities that ssh-keygen -Y sign|verify have added,
 |one could easily adapt the server and client to send "user-name
 |MSG", so that the server could look into authorized_keys of
 |user-name and verify MSG, whatever that is.

Hey!  That vision of yours, in conjunction with that -Y
possibility of ssh-keygen thrilled me so much i wrote a draft.
It uses TLS over TCP to secure the packet.  (Not UDP based, hm.)
It is not yet fully worked out, but that draft i like, i will
change to use that approach next week for sure -- no more becoming
root locally in order to port knock, only need loaded ssh-agent!

	echo >&2 'SYNOPSIS: '$0' create-server-cert email-address filename'

self-signed port-knock server cert creation.
clients need to have the cert for TLS verification.

	echo >&2 'SYNOPSIS: '$0' create-ssh-key email-address filename'

create a ssh key for port knock purposes.
Users then knock via

	echo >&2 'SYNOPSIS: '$0' knock path-to-ssh-pubkey path-to-port-knock-bin host port server-cert'

a little bit complicated yet.
The C binary needs to be compiled via

  gcc -W -Wall -pedantic -o /tmp/zt port-knock-bin.c  -lssl -lcrypto

and then run via

  cd /tmp/
  ./zt -v server ./.Z.key ./.Z.pub 10000 /tmp/port-knock.sh /tmp/.ZX.ALLO

The client then does

  ./port-knock.sh knock .ZX.pub /tmp/zt localhost 10000 /tmp/.Z.pub

Of course it is a play thing, but for you all it is sunday and
maybe you like it.  'Will review and polish it on Monday.
TLS client certificates and things like capsicum or pledge/unveil
or missing for, also after Monday.

--steffen
|
|Der Kragenbaer,                The moon bear,
|der holt sich munter           he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)
#!/bin/sh -
#@ port-knock.sh: port knock user interface (for port-knock-bin.c server).
#@ The binary requires the *SSL library, the script openssl and ssh-keygen with -Y support.
syno() {
	echo >&2 'TODO not yet SYNOPSIS: '$0' create-client-cert email-address filename'
	echo >&2 'SYNOPSIS: '$0' create-server-cert email-address filename'
	echo >&2 'SYNOPSIS: '$0' create-ssh-key email-address filename'
	echo >&2 'SYNOPSIS: '$0' knock path-to-ssh-pubkey path-to-port-knock-bin host port server-cert'

	echo >&2 '[SYNOPSIS: '$0' . sig-pool-file ip-address [sig-to-verify (else block)]'
	exit 64 # EX_USAGE
}
#


# FIXME
# Termination via SIGTERM; Usually started with a driver like start-stop-daemon, note --no-close and --output (to be
# used with -v, otherwise freopen("/dev/null", "w", stderr) is used):
# 
# 	ssd=start-stop-daemon
# 	port_knock__init() {
# 		name=port_knock
# 		pid=/run/${name}.pid
# 		prog=/root/port-knock-server
# 	}
# 	port_knock_start() {
# 		port_knock__init
# 		# --no-close --output /tmp/.port_knock.log
# 		eval ${ssd} --start --background --make-pidfile --pidfile ${pid} --exec ${prog} -- ${PORT_KNOCK_ARGS}
# 	}
# 	port_knock_stop() { daemon__genstop port_knock; }
# 	port_knock_status() { port_knock__init; daemons__stat_and_dog n; }
# 	port_knock_watchdog() { port_knock__init; daemons__stat_and_dog y; }
# 

#
# 2020 - 2024 Steffen Nurpmeso <steffen@xxxxxxxxxx>
# Public Domain

blacklist() {
	logger -t /root/bin/port-knock-client.sh "black listing $1"
	/root/bin/net-qos.sh add alien_super "$1"
	/root/bin/net-qos.sh del port_knock "$1"
}

whitelist() {
	logger -t /root/bin/port-knock-client.sh "white listing $1 for 30 seconds"
	/root/bin/net-qos.sh del alien_super "$1"
	/root/bin/net-qos.sh del sshorvpn "$1"
	/root/bin/net-qos.sh del port_knock "$1"
	/root/bin/net-qos.sh eval fw_rules_ins 1 i^a^-src "$1"
#	 /root/bin/net-qos.sh start-daemon sshd
	(
		sleep 30
		/root/bin/net-qos.sh eval eval fw_rules_del i^a^-src "$1"
	) </dev/null >/dev/null 2>&1 &
}

case "$1" in
create-client-cert)
	[ $# -ne 3 ] && syno
	echo >&2 'TODO note client certificates are not yet supported'
	exec openssl req -new -newkey $OPENSSL_KEY_ARGS -x509 -nodes -days 3333 \
		-subj "/emailAddress=$2" \
		-addext extendedKeyUsage=clientAuth -addext nsCertType=client \
		-out "$3.pub" -keyout "$3.key"
	;;
create-server-cert)
	[ $# -ne 3 ] && syno
	exec openssl req -new -newkey $OPENSSL_KEY_ARGS -x509 -nodes -days 3333 \
		-subj "/emailAddress=$2" \
		-addext extendedKeyUsage=serverAuth -addext nsCertType=server \
		-out "$3.pub" -keyout "$3.key"
	;;
create-ssh-key)
	[ $# -ne 3 ] && syno
	exec ssh-keygen -t ed25519 -C port-knock/"$2" -N ''  -f "$3"
	;;
knock)
	[ $# -ne 6 ] && syno
	data=$(</dev/null ssh-keygen -Y sign -n port-knock -f "$2" |
		sed -Ee '/^-+BEGIN SSH/d;/^-+END SSH/d;s/$/ /' | tr -d '\012 ')
	"$3" -v client $6 $5 $4 "$data"
	;;
.)
	# PWD=/tmp/!
	ok=
	if [ $# -eq 4 ]; then
		# FIXME TMP FILE
		{
			echo '-----BEGIN SSH SIGNATURE-----'
			echo "$4"
			echo '-----END SSH SIGNATURE-----'
		} > /tmp/.TMP
		if ssh-keygen -Y find-principals -f "$2" -s /tmp/.TMP >/dev/null 2>&1; then
			ok=y;
		fi
	fi
	if [ -n "$ok" ]; then
		echo whitelist "$3" >> /tmp/.ZZZZ
	else
		echo blacklist "$3" >> /tmp/.ZZZZ
	fi
	;;
*)
	echo >&2 'Invalid command: '$1
	syno
	;;
esac

exit 0
# s-sht-mode
/*@ port-knock-bin.c: C backend for port-knock.sh; please see there.
 *@ TODO - client certificates (DB file?  Or, empty file, name "is fingerprint")
 *@ TODO - capsicum / pledge/unveil (fork from server a forker process that forks+execv the command)
 *
 * Copyright (c) 2020 - 2024 Steffen Nurpmeso <steffen@xxxxxxxxxx>.
 * SPDX-License-Identifier: ISC
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#define _GNU_SOURCE

#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include <openssl/err.h>
#include <openssl/opensslv.h>
#include <openssl/ssl.h>

#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* For SO_{SND,RCV}TIMEO and SO_LINGER */
#define a_TIMEOUT_SECS 42

/* Bytes we should reserve for the largest possible SSH signature (ED25519=295, RSA=1560) + 1 */
#define a_SSH_SIG_LEN 2048

/* */
#define a_BIN_SH "/bin/sh"

/*  >8 -- 8< */

#if defined OPENSSL_VERSION_NUMBER && !defined LIBRESSL_VERSION_NUMBER &&\
	OPENSSL_VERSION_NUMBER + 0 >= 0x30000000L
# define a_SSL_CTX_load_verify_file(CTXP,FILE) SSL_CTX_load_verify_file(CTXP, FILE)
#else
# define a_SSL_CTX_load_verify_file(CTXP,FILE) SSL_CTX_load_verify_locations(CTXP, FILE, NULL)
#endif

enum{
	a_EX_OK,
	a_EX_ERR,
	a_EX_USAGE = 64,
	a_EX_NOHOST = 68,
	a_EX_UNAVAILABLE = 69,
	a_EX_OSERR = 71,
	a_EX_IOERR = 74
};

static int a_verbose;
static int volatile a_sig_seen;

static int a_server(SSL_CTX *ctxp, int port, char const *cmd_path, char const *sigpool);
static int a_client(SSL_CTX *ctxp, char const *host, char const *port, char const *data);

/* Logs and closes sofd on error */
static SSL *a_sock_init(SSL_CTX *ctxp, int sofd);

static void a_sig_hdl(int sig);

int
main(int argc, char **argv){
	char const *prog, *host, *port;
	int es, srv, portno;
	SSL_CTX *ctxp;

	ctxp = NULL;
	es = 1;
	prog = (argc == 0) ? "port-knock" : argv[0];
	port = host = NULL; /* xxx UNINIT(..,NULL); */

	if(argc < 6)
		goto jesyn;

	fclose(stdin);
	fclose(stdout);
	if(!strcmp(argv[1], "-v")){
		a_verbose = 1;
		--argc, ++argv;
	}else
		freopen("/dev/null", "w", stderr);

	if(!strcmp(argv[1], "server")){
		srv = 1;
		if(argc != 7)
			goto jesyn;
	}else if(!strcmp(argv[1], "client")){
		srv = 0;
		if(argc < 6 || argc > 7)
			goto jesyn;
	}else
		goto jesyn;
	++es;

	ctxp = SSL_CTX_new(srv ? TLS_server_method() : TLS_client_method());
	if(ctxp == NULL){
		fprintf(stderr, "Cannot create TLS context: %s\n", ERR_error_string(ERR_get_error(), NULL));
		goto jleave;
	}
	SSL_CTX_set_mode(ctxp, SSL_MODE_AUTO_RETRY);
	++es;

	if(srv){
		if(SSL_CTX_use_PrivateKey_file(ctxp, argv[2], SSL_FILETYPE_PEM) != 1){
			fprintf(stderr, "Cannot use serv-privkey-file: %s: %s\n",
				argv[2], ERR_error_string(ERR_get_error(), NULL));
			goto jesyn;
		}
		++es;
	}

	if(srv || argc > 6){
		if(SSL_CTX_use_certificate_chain_file(ctxp, argv[2 + srv]) != 1){
			fprintf(stderr, "Cannot use (serv-pubkey|cli-cert)-file: %s: %s\n",
				argv[2 + srv], ERR_error_string(ERR_get_error(), NULL));
			goto jesyn;
		}
		if(!srv)
			fprintf(stderr, "TODO Client certificates are not yet supported (ignored)\n");
		--argc, ++argv;
		++es;
	}

	if(!srv){
		SSL_CTX_set_verify(ctxp, SSL_VERIFY_PEER, NULL);
		if(a_SSL_CTX_load_verify_file(ctxp, argv[2]) != 1){
			fprintf(stderr, "Client cannot load CA serv-pubkey-file: %s: %s\n",
				argv[2], ERR_error_string(ERR_get_error(), NULL));
			goto jesyn;
		}
		++es;
	}

	portno = atoi(port = argv[3]);
	if(portno <= 0 || portno > 65535){
		fprintf(stderr, "Bad port (must be >0 and <65536): %s -> %d\n", argv[3], portno);
		goto jesyn;
	}
	++es;

	if(!srv){
		host = argv[4];
		if(*host == '\0'){
			fprintf(stderr, "Empty hostname given\n");
			goto jesyn;
		}
		--argc, ++argv;
	}
	++es;

	/* TODO [chroot], pledge/unveil */
	if(chdir("/") == -1){
		fprintf(stderr, "Cannot chdir(2) to /\n");
		goto jleave;
	}
	++es;

	es = srv ? a_server(ctxp, portno, argv[4], argv[5]) : a_client(ctxp, host, port, argv[4]);

jleave:
	if(ctxp != NULL)
		SSL_CTX_free(ctxp);

	return es;

jesyn:
	fprintf(stderr,
		"Synopsis: %s [-v] server serv-privkey-file serv-pubkey-file port cmd-path sigpool-path\n"
		"Synopsis: %s [-v] client [cli-cert-file]   serv-pubkey-file port host data\n",
		prog, prog);
	goto jleave;
}

static int
a_server(SSL_CTX *ctxp, int portno, char const *cmd, char const *sigpool){
	char dbuf[a_SSH_SIG_LEN], nbuf[INET6_ADDRSTRLEN +1];
	char const *argv[7];
	struct sigaction siac;
	struct sockaddr_storage soa_buf;
	union {struct sockaddr_storage *ps; struct sockaddr *p4; struct sockaddr_in6 *p6;} soa;
	socklen_t soal;
	int clifd, sofd, es;
	SSL *sslp;

	sslp = NULL;
	clifd = -1;

	while((sofd = socket(AF_INET6, SOCK_STREAM, 0)) == -1){
		es = errno;
		if(es != EINTR){
			fprintf(stderr, "Server socket creation failed: %s\n", strerror(es));
			goto jleave;
		}
	}

	soa.ps = &soa_buf;
	memset(soa.ps, 0, sizeof(soa_buf));
	soa.p6->sin6_family = AF_INET6;
	soa.p6->sin6_port = htons(portno);
	memcpy(&soa.p6->sin6_addr, &in6addr_any, sizeof soa.p6->sin6_addr);

	while(bind(sofd, (struct sockaddr const*)soa.p6, sizeof(*soa.p6)) == -1){
		es = errno;
		if(es != EINTR){
			fprintf(stderr, "Server socket cannot bind: %s\n", strerror(es));
			goto jleave;
		}
	}

	while(listen(sofd, 1) == -1){
		es = errno;
		if(es != EINTR){
			fprintf(stderr, "Server socket cannot bind: %s\n", strerror(es));
			goto jleave;
		}
	}

        memset(&siac, 0, sizeof siac);
        siac.sa_handler = &a_sig_hdl;
        sigemptyset(&siac.sa_mask);
        sigaction(SIGTERM, &siac, NULL);
	/*if(a_verbose)*/
		sigaction(SIGINT, &siac, NULL);
	siac.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &siac, NULL);
	sigaction(SIGCHLD, &siac, NULL);

	argv[0] = "sh";
	argv[1] = cmd;
	argv[2] = ".";
	argv[3] = sigpool;
	/* [4] = IP, [[5] = SIG] (else block IP); ie, [5] is our trigger */
	argv[4] = nbuf;
	argv[6] = NULL;

	while(!a_sig_seen){
		soal = sizeof(soa_buf);
		clifd = accept(sofd, (struct sockaddr*)soa.ps, &soal);
		if(clifd == -1){
			es = errno;
			if(es == EINTR)
				continue;
			fprintf(stderr, "Cannot accept new client: %s\n", strerror(es));
			es = a_EX_OSERR;
			goto jleave;
		}

		sslp = a_sock_init(ctxp, clifd);
		if(sslp == NULL){
			clifd = -1;
			es = a_EX_UNAVAILABLE;
			goto jleave;
		}

		if(inet_ntop(soa.ps->ss_family, soa.ps, nbuf, sizeof(nbuf)) == NULL){
			fprintf(stderr, "IMPL ERROR: cannot inet_ntop() accept(2)ed client\n");
			goto jclose;
		}
		if(a_verbose)
			fprintf(stderr, "Accepted client: %s\n", nbuf);

		argv[5] = NULL;

		if(SSL_accept(sslp) != 1){
			fprintf(stderr, "Cannot SSL accept client: %s\n", ERR_error_string(ERR_get_error(), NULL));
			goto jfork;
		}

		/* C99 */{
			int yet, still;

			yet = 0;
			still = sizeof(dbuf) -1;

			for(;;){
				es = SSL_read(sslp, &dbuf[(unsigned)yet], still);
				if(es <= 0){
					int e;

					es = SSL_get_error(sslp, es);
					if(es == SSL_ERROR_NONE || es == SSL_ERROR_ZERO_RETURN)
						break;
					e = errno;
					if(es == SSL_ERROR_WANT_WRITE || es == SSL_ERROR_WANT_READ ||
							(es == SSL_ERROR_SYSCALL && e == EINTR))
						continue;
					fprintf(stderr, "Data receive failed after %d bytes: %s: %s\n",
						yet, strerror(e), ERR_error_string(es, NULL));
					/* TODO too dangerous to blacklist: could be attack! */
					goto jfork;
				}

				/* Buffer spaced so excess is error */
				still -= es;
				if(still == 0)
					goto jfork;

				while(es-- > 0){
					char c;

					c = dbuf[(unsigned)yet++];
					if(((unsigned)c & 0x80) || iscntrl(c))
						goto jfork;
				}
			}

			dbuf[(unsigned)yet] = '\0';
		}

		for(;;){
			es = SSL_shutdown(sslp);
			if(es == 1)
				break;
			if(es != 0){
				int e;

				e = errno;
				es = SSL_get_error(sslp, es);
				if(es == SSL_ERROR_WANT_WRITE || es == SSL_ERROR_WANT_READ ||
						(es == SSL_ERROR_SYSCALL && e == EINTR))
					continue; /* XXX select(2) / nanosleep(2)? */
				fprintf(stderr, "SSL shutdown failed: %s: %s\n",
					strerror(e), ERR_error_string(es, NULL));
				/* TODO too dangerous to blacklist: could be attack! */
				goto jfork;
			}
		}

		/* argv[5] tells it like it is */
		if(dbuf[0] != '\0')
			argv[5] = dbuf;
jfork:
		if(a_verbose)
			fprintf(stderr, "execv: " a_BIN_SH " %s %s %s %s %s\n",
				argv[1], argv[2], argv[3], argv[4], (argv[5] != NULL ? argv[5] : ""));
		switch(fork()){
		case -1:
			es = errno;
			fprintf(stderr, "Fork failed: %s\n", strerror(es));
			es = a_EX_OSERR;
			goto jleave;
		default:
			break;
		case 0:
			execv(a_BIN_SH, (char*const*)argv);
			for(;;)
				_exit(a_EX_OSERR);
		}

jclose:
		/* C99 */{
			union {SSL *sslp; int fd;} t;

			t.sslp = sslp;
			sslp = NULL;
			SSL_free(t.sslp);
			t.fd = clifd;
			clifd = -1;
			close(t.fd);
		}
	}

	es = a_EX_OK;
jleave:
	if(sslp != NULL)
		SSL_free(sslp);
	if(clifd != -1)
		close(clifd);
	if(sofd != -1)
		close(sofd);

	return es;
}

static int
a_client(SSL_CTX *ctxp, char const *host, char const *port, char const *data){
	struct addrinfo hints, *res0, *res;
	SSL *sslp;
	int sofd, es;

	memset(&hints, 0, sizeof hints);
	hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED | AI_NUMERICSERV;
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	sofd = -1;
	sslp = NULL;

	res0 = NULL;
	es = getaddrinfo(host, port, &hints, &res0);
	if(es != 0){
		fprintf(stderr, "DNS lookup failed for: %s:%s %s\n", host, port, gai_strerror(es));
		es = a_EX_NOHOST;
		goto jleave;
	}

	for(res = res0; res != NULL; res = res->ai_next){
		for(;;){
			sofd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
			if(sofd != -1)
				goto jso;
			es = errno;
			if(es != EINTR)
				break;
		}
		fprintf(stderr, "Socket creation failed: %s\n", strerror(es));
	}
	es = a_EX_UNAVAILABLE;
	goto jleave;

jso:
	es = connect(sofd, res->ai_addr, res->ai_addrlen);
	if(es == -1){
		es = errno;
		if(es == EINTR)
			goto jso;
		fprintf(stderr, "Cannot connect to %s:%s: %s\n", host, port, strerror(es));
		es = a_EX_UNAVAILABLE;
		goto jleave;
	}

	sslp = a_sock_init(ctxp, sofd);
	if(sslp == NULL){
		sofd = -1;
		es = a_EX_UNAVAILABLE;
		goto jleave;
	}

	SSL_set_tlsext_host_name(sslp, host);

	if(SSL_connect(sslp) != 1){
		fprintf(stderr, "Cannot SSL connect: %s\n", ERR_error_string(ERR_get_error(), NULL));
		es = a_EX_IOERR;
		goto jleave;
	}

	/* C99 */{
		size_t l, yet;

		l = strlen(data);
		yet = 0;

		while(l > 0){
			es = SSL_write(sslp, &data[yet], l);
			if(es <= 0){
				es = SSL_get_error(sslp, es);
				if(es != SSL_ERROR_NONE){
					int e;

					e = errno;
					if(es == SSL_ERROR_WANT_WRITE || es == SSL_ERROR_WANT_READ ||
							(es == SSL_ERROR_SYSCALL && e == EINTR))
						continue;
					fprintf(stderr, "Data transmit failed: %s: %s\n",
						strerror(e), ERR_error_string(es, NULL));
					es = a_EX_IOERR;
					goto jleave;
				}
			}
			yet += es;
			l -= es;
		}
	}

	for(;;){
		es = SSL_shutdown(sslp);
		if(es == 1)
			break;
		if(es != 0){
			int e;

			es = SSL_get_error(sslp, es);
			e = errno;
			if(es == SSL_ERROR_WANT_WRITE || es == SSL_ERROR_WANT_READ ||
					(es == SSL_ERROR_SYSCALL && e == EINTR))
				continue; /* XXX select(2) / nanosleep(2)? */
			fprintf(stderr, "SSL shutdown failed: %s: %s\n", strerror(e), ERR_error_string(es, NULL));
			es = a_EX_IOERR;
			goto jleave;
		}
	}

	es = a_EX_OK;
jleave:
	if(sslp != NULL)
		SSL_free(sslp);
	if(sofd != -1)
		close(sofd);
	return es;
}

static SSL *
a_sock_init(SSL_CTX *ctxp, int sofd){
	struct timeval tv;
	struct linger li;
	SSL *sslp;

	tv.tv_sec = a_TIMEOUT_SECS;
	tv.tv_usec = 0;
	(void)setsockopt(sofd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
	(void)setsockopt(sofd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);

	li.l_onoff = 1;
	li.l_linger = a_TIMEOUT_SECS;
	(void)setsockopt(sofd, SOL_SOCKET, SO_LINGER, &li, sizeof li);

	sslp = SSL_new(ctxp);
	if(sslp == NULL){
		fprintf(stderr, "Cannot create SSL connection object: %s\n", ERR_error_string(ERR_get_error(), NULL));
		goto jleave;
	}

	if(!SSL_set_fd(sslp, sofd)){
		fprintf(stderr, "Cannot correlate file descriptor with SSL: %s\n",
			ERR_error_string(ERR_get_error(), NULL));
		goto jleave;
	}

jleave:
	if(sslp == NULL)
		close(sofd);

	return sslp;
}

static void
a_sig_hdl(int sig){
	(void)sig;
	a_sig_seen = 1;
}

/* s-itt-mode */
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@xxxxxxxxxxx
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux