/* tlspool/libtlspool.c -- Library function for starttls go-get-it */
+#include "whoami.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>
+#include <tlspool/starttls.h>
+#include <tlspool/commands.h>
+
+#ifdef WINDOWS_PORT
+#include <winsock2.h>
+#else
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/select.h>
#include <sys/resource.h>
+#endif
-#include <tlspool/starttls.h>
-#include <tlspool/commands.h>
-
-
-#ifdef __CYGWIN__
-#define WEOF ((wint_t)(0xFFFF))
+#if !defined(WINDOWS_PORT)
+#define closesocket(s) close(s)
+#endif
+#ifdef WINDOWS_PORT
#define PIPE_TIMEOUT 5000
#define BUFSIZE 4096
+#define random rand
+#define srandom srand
#define _tprintf printf
-#endif /* __CYGWIN__ */
+#endif /* WINDOWS_PORT */
/* The master thread will run the receiving side of the socket that connects
* to the TLS Pool. The have_master_lock is used with _trylock() and will
unsigned long pid;
if (opt_pidfile == NULL) {
+ opt_pidfile = tlspool_configvar (NULL, "daemon_pidfile");
+ }
+ if (opt_pidfile == NULL) {
opt_pidfile = TLSPOOL_DEFAULT_PIDFILE_PATH;
}
+ assert (opt_pidfile != NULL);
fd = open (opt_pidfile, O_RDONLY);
if (fd != -1) {
len = read (fd, str_pid, sizeof (str_pid) -1);
unsigned int seed;
pid_t me;
if (!path) {
+ path = tlspool_configvar (NULL, "socket_name");
+ }
+ if (!path) {
path = TLSPOOL_DEFAULT_SOCKET_PATH;
}
- if (strlen (path) + 1 > sizeof (((struct sockaddr_un *) NULL)->sun_path)) {
- syslog (LOG_ERR, "TLS Pool path name too long for UNIX domain socket");
- exit (1);
+ assert (path != NULL);
+ fprintf (stderr, "DEBUG: Opening TLS Pool on socket path %s\n", path);
+#ifndef WINDOWS_PORT
+ if (strlen(path) + 1 > sizeof(((struct sockaddr_un *) NULL)->sun_path)) {
+ syslog(LOG_ERR, "TLS Pool path name too long for UNIX domain socket");
+ exit(1);
}
- if (pthread_create (&thr, NULL, master_thread, (void *) path) != 0) {
- syslog (LOG_NOTICE, "Failed to create TLS Pool client master thread");
- pthread_mutex_unlock (&have_master_lock);
- tlspool_close_poolhandle (poolfd);
+#endif
+ if (pthread_create(&thr, NULL, master_thread, (void *)path) != 0) {
+ syslog(LOG_NOTICE, "Failed to create TLS Pool client master thread");
+ pthread_mutex_unlock(&have_master_lock);
+ tlspool_close_poolhandle(poolfd);
poolfd = INVALID_POOL_HANDLE;
return INVALID_POOL_HANDLE;
}
* number of available file descriptors. Note: The result is cached, so
* don't use root to increase beyond max in setrlimit() after calling this.
*/
-int tlspool_simultaneous_starttls (void) {
+int tlspool_simultaneous_starttls(void) {
+#ifdef WINDOWS_PORT
+ return 512;
+#else /* WINDOWS_PORT */
static int simu = -1;
if (simu < 0) {
struct rlimit rlimit_nofile;
simu = rlimit_nofile.rlim_max / 2; // 2 FDs per STARTTLS
}
return simu;
+#endif /* WINDOWS_PORT */
}
pthread_mutex_unlock (®istry_lock);
}
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
static pool_handle_t open_named_pipe (LPCTSTR lpszPipename)
{
HANDLE hPipe;
if (!fSuccess && GetLastError() == ERROR_IO_PENDING )
{
-printf ("DEBUG: Write I/O pending\n");
+// printf ("DEBUG: Write I/O pending\n");
fSuccess = WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_OBJECT_0;
}
if (!fSuccess)
{
_tprintf(TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError());
-#warning better errno
- errno = ENOSYS;
+ errno = EPIPE;
return -1;
} else {
-printf ("DEBUG: Wrote %ld bytes to pipe\n", cbWritten);
+// printf ("DEBUG: Wrote %ld bytes to pipe\n", cbWritten);
}
-printf("DEBUG: Message sent to server, receiving reply as follows:\n");
+// printf("DEBUG: Message sent to server, receiving reply as follows:\n");
return 0;
}
-#endif /* __CYGWIN__ */
+#endif /* WINDOWS_PORT */
/* The master thread issues the recv() commands on the TLS Pool socket, and
* redistributes the result to the registry entries that are waiting for
* TLS Pool anew, using exponential back-off.
*/
static void *master_thread (void *path) {
+#ifndef WINDOWS_PORT
useconds_t usec;
struct sockaddr_un sun;
- struct tlspool_command cmd;
//NOT-USED// char anc [CMSG_SPACE(sizeof (int))];
struct iovec iov;
struct cmsghdr *cmsg;
struct msghdr mh = { 0 };
+#else
+ DWORD usec;
+#endif
+ struct tlspool_command cmd;
+ //NOT-USED// char anc [CMSG_SPACE(sizeof (int))];
struct registry_entry *entry;
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
BOOL fSuccess = FALSE;
DWORD cbRead;
#endif
-#ifndef __CYGWIN__
+#ifndef WINDOWS_PORT
//
// Setup path information -- value and size were checked
- bzero (&sun, sizeof (sun));
+ memset (&sun, 0, sizeof (sun));
strcpy (sun.sun_path, (char *) path);
sun.sun_family = AF_UNIX;
#endif
// with 1s, 2s, 4s, 8s, 16s, 32s, 32s, 32s, ... intervals.
usec = 1000000;
while (poolfd == INVALID_POOL_HANDLE) {
-#ifdef __CYGWIN__
-printf ("DEBUG: path = %s\n", (char *) path);
+#ifdef WINDOWS_PORT
+// printf ("DEBUG: path = %s\n", (char *) path);
pool_handle_t newpoolfd = open_named_pipe ((LPCTSTR) path);
// printf ("DEBUG: newpoolfd = %d\n", newpoolfd);
if (newpoolfd != INVALID_POOL_HANDLE) {
//
// Wait before repeating, with exponential back-off
if (poolfd == INVALID_POOL_HANDLE) {
- usleep (usec);
+#ifdef WINDOWS_PORT
+ Sleep(usec / 1000);
+#else
+ usleep(usec);
+#endif
usec <<= 1;
if (usec > 32000000) {
usec = 32000000;
// back up to the re-connection logic.
while (1) {
int retval;
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
OVERLAPPED overlapped;
memset(&overlapped, 0, sizeof(overlapped));
if (!fSuccess && GetLastError() == ERROR_IO_PENDING )
{
-printf ("DEBUG: Read I/O pending\n");
+// printf ("DEBUG: Read I/O pending\n");
fSuccess = WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_OBJECT_0;
}
_tprintf(TEXT("ReadFile from pipe failed. GLE=%d\n"), GetLastError());
retval = -1;
} else {
-printf ("DEBUG: Read %ld bytes from pipe\n", cbRead);
+// printf ("DEBUG: Read %ld bytes from pipe\n", cbRead);
}
#else
iov.iov_base = &cmd;
// printf ("DEBUG: recvmsg() returned -1 due to: %s\n", strerror (errno));
break;
}
-#endif /* __CYGWIN__ */
+#endif /* WINDOWS_PORT */
//
// Determine where to post the received message
entry = registry [cmd.pio_reqid];
cmd.pio_cmd = PIOC_ERROR_V2;
cmd.pio_data.pioc_error.tlserrno = EPIPE;
strncpy (cmd.pio_data.pioc_error.message, "Client prematurely left TLS Pool negotiations", sizeof (cmd.pio_data.pioc_error.message));
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
np_send_command (&cmd);
#else
sendmsg (poolfd, &mh, MSG_NOSIGNAL);
#endif
// Ignore errors
-printf ("DEBUG: Sent PIOC_ERROR_V2 as callback to TLS Pool\n");
+// printf ("DEBUG: Sent PIOC_ERROR_V2 as callback to TLS Pool\n");
}
// Do not attempt delivery
continue;
struct registry_entry regent = { .sig = &recvwait, .buf = &cmd };
int entry_reqid = -1;
pool_handle_t poolfd = INVALID_POOL_HANDLE;
- struct iovec iov;
- struct msghdr mh = { 0 };
-#ifdef __CYGWIN__
- BOOL fSuccess = FALSE;
- OVERLAPPED overlapped;
-#endif
/* Prepare command structure */
poolfd = tlspool_open_poolhandle (NULL);
-printf ("DEBUG: poolfd = %d\n", poolfd);
+// printf ("DEBUG: poolfd = %d\n", poolfd);
if (poolfd == INVALID_POOL_HANDLE) {
errno = ENODEV;
return -1;
errno = EBUSY;
return -1;
}
- bzero (&cmd, sizeof (cmd)); /* Do not leak old stack info */
+ memset (&cmd, 0, sizeof (cmd)); /* Do not leak old stack info */
cmd.pio_reqid = entry_reqid;
cmd.pio_cbid = 0;
cmd.pio_cmd = PIOC_PING_V2;
memcpy (&cmd.pio_data.pioc_ping, pingdata, sizeof (struct pioc_ping));
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
if (np_send_command (&cmd) == -1) {
// errno inherited from np_send_command ()
registry_update (&entry_reqid, NULL);
}
#else
/* Send the request */
- iov.iov_base = &cmd;
- iov.iov_len = sizeof (cmd);
- mh.msg_iov = &iov;
- mh.msg_iovlen = 1;
- if (sendmsg (poolfd, &mh, MSG_NOSIGNAL) == -1) {
+ if (send (poolfd, &cmd, sizeof (cmd), MSG_NOSIGNAL) == -1) {
// Let SIGPIPE be reported as EPIPE
registry_update (&entry_reqid, NULL);
// errno inherited from sendmsg()
}
}
+#if defined(WINDOWS_PORT)
+static int socket_dup_protocol_info(int fd, int pid, LPWSAPROTOCOL_INFOW lpProtocolInfo)
+{
+ if (WSADuplicateSocketW((SOCKET)fd, pid, lpProtocolInfo) == SOCKET_ERROR) {
+ errno = EPIPE;
+ return -1;
+ } else {
+ return 0;
+ }
+}
+#endif
+
/* The library function for starttls, which is normally called through one
* of the two inline variations below, which start client and server sides.
*
pool_handle_t poolfd = INVALID_POOL_HANDLE;
int plainfd = -1;
int sentfd = -1;
- char anc [CMSG_SPACE(sizeof (int))];
+#ifndef WINDOWS_PORT
struct iovec iov;
struct cmsghdr *cmsg;
struct msghdr mh = { 0 };
+ char anc[CMSG_SPACE(sizeof(int))];
+#endif
int processing;
int renegotiate = 0 != (tlsdata->flags & PIOF_STARTTLS_RENEGOTIATE);
/* Prepare command structure */
poolfd = tlspool_open_poolhandle (NULL);
if (poolfd == INVALID_POOL_HANDLE) {
- close (cryptfd);
+ closesocket(cryptfd);
errno = ENODEV;
return -1;
}
pthread_mutex_lock (&recvwait); // Will await unlock by master
/* Determine the request ID */
if (registry_update (&entry_reqid, ®ent) != 0) {
- close (cryptfd);
+ closesocket(cryptfd);
errno = EBUSY;
return -1;
}
- bzero (&cmd, sizeof (cmd)); /* Do not leak old stack info */
+ memset (&cmd, 0, sizeof (cmd)); /* Do not leak old stack info */
cmd.pio_reqid = entry_reqid;
cmd.pio_cbid = 0;
cmd.pio_cmd = PIOC_STARTTLS_V2;
memcpy (&cmd.pio_data.pioc_starttls, tlsdata, sizeof (struct pioc_starttls));
-#if RAND_MAX < 0xfffff
-# error "Failure on assumption of 16 bits of random material per random() call"
-#endif
-
#if TLSPOOL_CTLKEYLEN != 16
# error "Failure on assumption of 16 bytes per ctlkey"
#endif
if (!renegotiate) {
assert (pthread_mutex_lock (&prng_lock) == 0);
+#if RAND_MAX >= 0xffffffff
+ * (uint32_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 0] = random ();
+ * (uint32_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 4] = random ();
+ * (uint32_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 8] = random ();
+ * (uint32_t *) &cmd.pio_data.pioc_starttls.ctlkey [12] = random ();
+#elif RAND_MAX >= 0xffff
* (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 0] = random ();
* (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 2] = random ();
* (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 4] = random ();
* (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [10] = random ();
* (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [12] = random ();
* (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [14] = random ();
+#elif RAND_MAX >= 0xff
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 0] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 1] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 2] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 3] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 4] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 5] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 6] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 7] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 8] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 9] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [10] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [11] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [12] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [13] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [14] = random ();
+ * (uint8_t *) &cmd.pio_data.pioc_starttls.ctlkey [15] = random ();
+#else
+# error "Unsuitable random() function due to RAND_MAX value < 0xff"
+#endif
pthread_mutex_unlock (&prng_lock);
}
// printf ("DEBUG: ctlkey =");
// printf ("\n");
/* Send the request */
+#ifndef WINDOWS_PORT
iov.iov_base = &cmd;
- iov.iov_len = sizeof (cmd);
+ iov.iov_len = sizeof(cmd);
mh.msg_iov = &iov;
mh.msg_iovlen = 1;
+#endif
if (!renegotiate) {
-#ifndef __CYGWIN__
+#ifndef WINDOWS_PORT
mh.msg_control = anc;
mh.msg_controllen = sizeof (anc);
cmsg = CMSG_FIRSTHDR (&mh);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
- * (int *) CMSG_DATA (cmsg) = cryptfd; /* cannot close it yet */
- cmsg->cmsg_len = CMSG_LEN (sizeof (int));
-#else /* ifdef __CYGWIN__ */
+ *(int *)CMSG_DATA(cmsg) = cryptfd; /* cannot close it yet */
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+#else /* WINDOWS_PORT */
// cmd was already set to 0, including ancilary data simulation
if (1 /*is_sock(wsock)*/) {
// Send a socket
- int pid = tlspool_pid (NULL);
- if (pid == -1) {
- close (cryptfd);
- registry_update (&entry_reqid, NULL);
- // errno inherited from tlspool_pid()
- return -1;
- }
+ LONG pid;
+
+ GetNamedPipeServerProcessId(poolfd, &pid);
cmd.pio_ancil_type = ANCIL_TYPE_SOCKET;
- // printf("DEBUG: pid = %d, cryptfd = %d\n", pid, cryptfd);
- if (cygwin_socket_dup_protocol_info (cryptfd, pid, &cmd.pio_ancil_data.pioa_socket) == -1) {
-#warning set errno
+ printf("DEBUG: pid = %d, cryptfd = %d\n", pid, cryptfd);
+ if (socket_dup_protocol_info(cryptfd, pid, &cmd.pio_ancil_data.pioa_socket) == -1) {
// printf("DEBUG: cygwin_socket_dup_protocol_info error\n");
// Let SIGPIPE be reported as EPIPE
- close (cryptfd);
+ closesocket(cryptfd);
registry_update (&entry_reqid, NULL);
- // errno inherited from sendmsg()
+ // errno inherited from socket_dup_protocol_info()
return -1;
}
//... (..., &cmd.pio_ancil_data.pioa_socket, ...);
cmd.pio_ancil_type = ANCIL_TYPE_FILEHANDLE;
//... (..., &cmd.pio_ancil_data.pioa_filehandle, ...);
}
-#endif /* __CYGWIN__ */
+#endif /* WINDOWS_PORT */
}
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
if (np_send_command (&cmd) == -1) {
close (cryptfd);
registry_update (&entry_reqid, NULL);
// errno inherited from sendmsg()
return -1;
}
-#endif /* __CYGWIN__ */
+#endif /* WINDOWS_PORT */
sentfd = cryptfd; /* Close anytime after response and before fn end */
/* Handle responses until success or error */
//NOTUSED// mh.msg_controllen = sizeof (anc);
registry_recvmsg (®ent);
if (sentfd >= 0) {
- close (sentfd);
+ closesocket(sentfd);
}
sentfd = -1;
switch (cmd.pio_cmd) {
/* default namedconnect() implementation */
plainfd = * (int *) privdata;
if ((plainfd < 0) && (cmd.pio_cmd == PIOC_PLAINTEXT_CONNECT_V2)) {
- int soxx [2];
+#if !defined(WINDOWS_PORT)
+ int soxx[2];
+#else
+ // https://github.com/ncm/selectable-socketpair
+ extern int dumb_socketpair(SOCKET socks[2], int make_overlapped);
+ SOCKET soxx[2];
+#endif
//TODO// Setup for TCP, UDP, SCTP
-#ifndef __CYGWIN__
+#ifndef WINDOWS_PORT
if (socketpair (AF_UNIX, SOCK_SEQPACKET, 0, soxx) == 0) {
-#else /* ifdef __CYGWIN__ */
- if (socketpair (AF_UNIX, SOCK_STREAM, 0, soxx) == 0) {
-#endif /* __CYGWIN__ */
+#else /* WINDOWS_PORT */
+ if (dumb_socketpair(soxx, 1) == 0) {
+#endif /* WINDOWS_PORT */
// printf("DEBUG: socketpair succeeded\n");
/* Socketpair created */
plainfd = soxx [0];
}
/* We may now have a value to send in plainfd */
if (plainfd >= 0) {
-#ifndef __CYGWIN__
+#ifndef WINDOWS_PORT
mh.msg_control = anc;
mh.msg_controllen = sizeof (anc);
cmsg = CMSG_FIRSTHDR (&mh);
cmsg->cmsg_type = SCM_RIGHTS;
* (int *) CMSG_DATA (cmsg) = plainfd;
cmsg->cmsg_len = CMSG_LEN (sizeof (int));
-#else /* ifdef __CYGWIN__ */
+#else /* ifdef WINDOWS_PORT */
// cmd was already set to 0, including ancilary data simulation
if (1 /*is_sock(wsock)*/) {
// Send a socket
- int pid = tlspool_pid (NULL);
- if (pid == -1) {
- close (plainfd);
- registry_update (&entry_reqid, NULL);
- // errno inherited from tlspool_pid()
- return -1;
- }
+ ULONG pid;
+ GetNamedPipeServerProcessId(poolfd, &pid);
cmd.pio_ancil_type = ANCIL_TYPE_SOCKET;
// printf("DEBUG: pid = %d, plainfd = %d\n", pid, plainfd);
- if (cygwin_socket_dup_protocol_info (plainfd, pid, &cmd.pio_ancil_data.pioa_socket) == -1) {
-#warning set errno
+ if (socket_dup_protocol_info(plainfd, pid, &cmd.pio_ancil_data.pioa_socket) == -1) {
// printf("DEBUG: cygwin_socket_dup_protocol_info error\n");
// Let SIGPIPE be reported as EPIPE
- close (plainfd);
+ closesocket(plainfd);
registry_update (&entry_reqid, NULL);
- // errno inherited from cygwin_socket_dup_protocol_info()
+ // errno inherited from socket_dup_protocol_info()
return -1;
}
//... (..., &cmd.pio_ancil_data.pioa_socket, ...);
cmd.pio_ancil_type = ANCIL_TYPE_FILEHANDLE;
//... (..., &cmd.pio_ancil_data.pioa_filehandle, ...);
}
-#endif /* __CYGWIN__ */
+#endif /* WINDOWS_PORT */
}
/* Now supply plainfd in the callback response */
sentfd = plainfd;
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
if (np_send_command (&cmd) == -1) {
if (sentfd >= 0) {
- close (sentfd);
+ closesocket(sentfd);
sentfd = -1;
}
registry_update (&entry_reqid, NULL);
// errno inherited from sendmsg()
return -1;
}
-#endif /* __CYGWIN__ */
+#endif /* WINDOWS_PORT */
break; // Loop around and try again
case PIOC_STARTTLS_V2:
/* Wheee!!! we're done */
/* Close the now-duplicated or now-erradicated plaintext fd */
memcpy (tlsdata, &cmd.pio_data.pioc_starttls, sizeof (struct pioc_starttls));
-printf ("DEBUG: Returning control key %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", tlsdata->ctlkey [0], tlsdata->ctlkey [1], tlsdata->ctlkey [2], tlsdata->ctlkey [3], tlsdata->ctlkey [4], tlsdata->ctlkey [5], tlsdata->ctlkey [6], tlsdata->ctlkey [7], tlsdata->ctlkey [8], tlsdata->ctlkey [9], tlsdata->ctlkey [10], tlsdata->ctlkey [11], tlsdata->ctlkey [12], tlsdata->ctlkey [13], tlsdata->ctlkey [14], tlsdata->ctlkey [15]);
+// printf ("DEBUG: Returning control key %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", tlsdata->ctlkey [0], tlsdata->ctlkey [1], tlsdata->ctlkey [2], tlsdata->ctlkey [3], tlsdata->ctlkey [4], tlsdata->ctlkey [5], tlsdata->ctlkey [6], tlsdata->ctlkey [7], tlsdata->ctlkey [8], tlsdata->ctlkey [9], tlsdata->ctlkey [10], tlsdata->ctlkey [11], tlsdata->ctlkey [12], tlsdata->ctlkey [13], tlsdata->ctlkey [14], tlsdata->ctlkey [15]);
registry_update (&entry_reqid, NULL);
return 0;
}
errno = EBUSY;
return -1;
}
- bzero (&cmd, sizeof (cmd)); /* Do not leak old stack info */
+ memset (&cmd, 0, sizeof (cmd)); /* Do not leak old stack info */
cmd.pio_reqid = entry_reqid;
cmd.pio_cbid = 0;
cmd.pio_cmd = cmdcode;
memcpy (&cmd.pio_data.pioc_control.ctlkey, ctlkey, TLSPOOL_CTLKEYLEN);
// printf ("DEBUG: Using control key %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", cmd.pio_data.pioc_control.ctlkey [0], cmd.pio_data.pioc_control.ctlkey [1], cmd.pio_data.pioc_control.ctlkey [2], cmd.pio_data.pioc_control.ctlkey [3], cmd.pio_data.pioc_control.ctlkey [4], cmd.pio_data.pioc_control.ctlkey [5], cmd.pio_data.pioc_control.ctlkey [6], cmd.pio_data.pioc_control.ctlkey [7], cmd.pio_data.pioc_control.ctlkey [8], cmd.pio_data.pioc_control.ctlkey [9], cmd.pio_data.pioc_control.ctlkey [10], cmd.pio_data.pioc_control.ctlkey [11], cmd.pio_data.pioc_control.ctlkey [12], cmd.pio_data.pioc_control.ctlkey [13], cmd.pio_data.pioc_control.ctlkey [14], cmd.pio_data.pioc_control.ctlkey [15]);
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
if (np_send_command (&cmd) == -1) {
registry_update (&entry_reqid, NULL);
// errno inherited from np_send_command ()
struct registry_entry regent = { .sig = &recvwait, .buf = &cmd };
int entry_reqid = -1;
pool_handle_t poolfd = INVALID_POOL_HANDLE;
- struct iovec iov;
- struct msghdr mh = { 0 };
-
- bzero (prng_buf, prng_len);
+ memset (prng_buf, 0, prng_len);
/* Sanity checks */
if ((prng_len > TLSPOOL_PRNGBUFLEN) ||
errno = EBUSY;
return -1;
}
- bzero (&cmd, sizeof (cmd)); /* Do not leak old stack info */
+ memset (&cmd, 0, sizeof (cmd)); /* Do not leak old stack info */
cmd.pio_reqid = entry_reqid;
cmd.pio_cbid = 0;
cmd.pio_cmd = PIOC_PRNG_V2;
cmd.pio_data.pioc_prng.in2_len = -1;
}
-#ifdef __CYGWIN__
+#ifdef WINDOWS_PORT
if (np_send_command (&cmd) == -1) {
// errno inherited from np_send_command ()
registry_update (&entry_reqid, NULL);
}
#else
/* Send the request */
- iov.iov_base = &cmd;
- iov.iov_len = sizeof (cmd);
- mh.msg_iov = &iov;
- mh.msg_iovlen = 1;
- if (sendmsg (poolfd, &mh, MSG_NOSIGNAL) == -1) {
+ if (send (poolfd, &cmd, sizeof (cmd), MSG_NOSIGNAL) == -1) {
// Let SIGPIPE be reported as EPIPE
registry_update (&entry_reqid, NULL);
// errno inherited from sendmsg()
return -1;
}
}
+
+
+/* Fetch a configuration variable value from the configuration file. This is not
+ * an efficient procedure, at best suited for startup of tools or daemons; it
+ * will iterate over the config file until it reads the desired value. The value
+ * returned is allocated and should be freed by the caller using free().
+ *
+ * When cfgfile is NULL, the environment variable TLSPOOL_CONFIGFILE is
+ * tried first, followed by the default setting from the macro
+ * TLSPOOL_DEFAULT_CONFIG_PATH as defined in <tlspool/starttls.h>.
+ *
+ * The value returned is NULL when the variable is not found, including when this
+ * is due to errors such as not being able to open the file.
+ */
+char *tlspool_configvar (char *cfgfile, char *varname) {
+ FILE *cf;
+ char line [514];
+ int linelen;
+ int eof = 0;
+ char *here;
+ struct cfgopt *curopt;
+ int found;
+ char *retval = NULL;
+
+ if (cfgfile == NULL) {
+ cfgfile = getenv ("TLSPOOL_CFGFILE");
+ }
+ if (cfgfile == NULL) {
+ cfgfile = TLSPOOL_DEFAULT_CONFIG_PATH;
+ }
+
+ assert (cfgfile != NULL);
+ assert (varname != NULL);
+
+ cf = fopen (cfgfile, "r");
+ if (cf == NULL) {
+ perror ("Failed to open configuration file");
+ goto cleanup;
+ }
+
+ while (!eof) {
+ if (!fgets (line, sizeof (line)-1, cf)) {
+ if (feof (cf)) {
+ eof = 1;
+ continue;
+ } else {
+ perror ("Error while reading configuration file");
+ exit (1);
+ }
+ }
+ linelen = strlen (line);
+ if (linelen == 0) {
+ eof = 1;
+ continue;
+ }
+ if (line [linelen-1] == (char) EOF) {
+ linelen--;
+ eof = 1;
+ }
+ if (line [linelen-1] != '\n') {
+ fprintf (stderr, "Configuration line too long\n");
+ goto cleanup;
+ }
+ line [--linelen] = 0;
+ if (linelen == 0) {
+ continue;
+ }
+ if (line [0] == '#') {
+ continue;
+ }
+ here = line;
+ while ((*here) && isspace (*here)) {
+ here++;
+ }
+ if (!*here) {
+ continue;
+ }
+ if (here != line) {
+ fprintf (stderr, "Configuration line starts with whitespace:\n%s\n", line);
+ goto cleanup;
+ }
+ while ((*here) && (*here != ' ')) {
+ here++;
+ }
+ if (!*here) {
+ fprintf (stderr, "Configuration line misses space after keyword:\n%s\n", line);
+ goto cleanup;
+ }
+ *here++ = '\0';
+ if (strcmp (varname, line) == 0) {
+ // Success! We set the return value and end the loop
+ retval = here;
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ if (cf != NULL) {
+ fclose (cf);
+ cf = NULL;
+ }
+ return retval;
+}
+