windows
[tlspool] / lib / libtlspool.c
1 /* tlspool/libtlspool.c -- Library function for starttls go-get-it */
2
3
4 #include <stdlib.h>
5 #include <errno.h>
6 #include <string.h>
7 #include <syslog.h>
8 #include <assert.h>
9 #include <stdint.h>
10 #include <fcntl.h>
11
12 #include <unistd.h>
13 #include <pthread.h>
14
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <sys/un.h>
18 #include <sys/select.h>
19 #include <sys/resource.h>
20
21 #include <tlspool/starttls.h>
22 #include <tlspool/commands.h>
23
24
25
26 /* The master thread will run the receiving side of the socket that connects
27  * to the TLS Pool.  The have_master_lock is used with _trylock() and will
28  * succeed to lock once, thereby approving the creation of the master thread.
29  */
30
31 static pthread_mutex_t have_master_lock = PTHREAD_MUTEX_INITIALIZER;
32
33 static void *master_thread (void *path);
34
35 static int poolfd = -1;         /* Blocked retrieval with tlspool_socket() */
36
37 static pthread_cond_t updated_poolfd = PTHREAD_COND_INITIALIZER;
38
39 static pthread_mutex_t prng_lock = PTHREAD_MUTEX_INITIALIZER;
40
41 /*
42  * Quick and dirty function to get the PID of the tlspool daemon
43  */
44
45 int tlspool_getpid () {
46         int fd;
47
48         if ((fd = open("/var/run/tlspool.pid", O_RDONLY)) != -1) {
49                 char str_pid[256];
50
51                 if (read(fd, str_pid, sizeof(str_pid)) != -1) {
52                         return atoi(str_pid);
53                 }
54         }
55         return -1;
56 }
57
58 /* The library function for starttls, which is normally called through one
59  * of the two inline variations below, which start client and server sides.
60  *
61  * As a side effect, this routine ensures that a master thread is running
62  * on the poolfd.  This is the process that actually contacts the TLS Pool
63  * and sets up the poolfd socket.
64  */
65 int tlspool_socket (char *path) {
66         int poolfdsample = poolfd;
67         if (poolfdsample < 0) {
68                 pthread_mutex_t local_cond_wait = PTHREAD_MUTEX_INITIALIZER;
69                 //
70                 // Now that we have established a (first) poolfd, start up
71                 // the master thread that will recv() from it, and distribute.
72                 if (pthread_mutex_trylock (&have_master_lock) == 0) {
73                         pthread_t thr;
74                         unsigned int seed;
75                         pid_t me;
76                         if (!path) {
77                                 path = TLSPOOL_DEFAULT_SOCKET_PATH;
78                         }
79                         if (strlen (path) + 1 > sizeof (((struct sockaddr_un *) NULL)->sun_path)) {
80                                 syslog (LOG_ERR, "TLS Pool path name too long for UNIX domain socket");
81                                 exit (1);
82                         }
83                         if (pthread_create (&thr, NULL, master_thread, (void *) path) != 0) {
84                                 syslog (LOG_NOTICE, "Failed to create TLS Pool client master thread");
85                                 pthread_mutex_unlock (&have_master_lock);
86                                 close (poolfd);
87                                 poolfd = -1;
88                                 return -1;
89                         }
90                         pthread_detach (thr);
91                         //
92                         // We need enough randomness to avoid clashing ctlkeys
93                         me = getpid ();
94                         seed = ((unsigned int) time (NULL)) ^ (((unsigned int) me) << 16);
95                         srandom (seed);
96                 }
97                 //
98                 // Wait until the master thread signals that it updated the
99                 // poolfd, as long as it is invalid.
100                 //
101                 // The cond_wait requires a mutex to wait on; the specs leave
102                 // room for different mutexes for each waiter (otherwise it
103                 // would not have been supplied with each pthread_cond_wait()
104                 // call) and that helps to avoid threads to contend on a
105                 // shared mutex -- which is why we use a local mutex per
106                 // thread: we don't need to wait for unique access.
107                 assert (pthread_mutex_lock (&local_cond_wait) == 0);
108                 while (poolfdsample = poolfd, poolfdsample < 0) {
109                         pthread_cond_wait (&updated_poolfd, &local_cond_wait);
110                 }
111                 pthread_mutex_unlock (&local_cond_wait);
112         }
113         return poolfdsample;
114 }
115
116
117 /* Determine an upper limit for simultaneous STARTTLS threads, based on the
118  * number of available file descriptors.  Note: The result is cached, so
119  * don't use root to increase beyond max in setrlimit() after calling this.
120  */
121 int tlspool_simultaneous_starttls (void) {
122         static int simu = -1;
123         if (simu < 0) {
124                 struct rlimit rlimit_nofile;
125                 if (getrlimit (RLIMIT_NOFILE, &rlimit_nofile) == -1) {
126                         syslog (LOG_NOTICE, "Failed to determine simultaneous STARTTLS: %s", strerror (errno));
127                         rlimit_nofile.rlim_max = 1024;  // Pick something
128                 }
129                 simu = rlimit_nofile.rlim_max / 2;  // 2 FDs per STARTTLS
130         }
131         return simu;
132 }
133
134
135 /* The request registry is an array of pointers, filled by the starttls_xxx()
136  * functions for as long as they have requests standing out.  The registry
137  * permits instant lookup of a mutex to signal, so the receiving end may
138  * pickup the message in its also-registered tlspool command buffer.
139  */
140
141 struct registry_entry {
142         pthread_mutex_t *sig;           /* Wait for master thread's recvmsg() */
143         struct tlspool_command *buf;    /* Buffer to hold received command */
144         int pfd;                        /* Client thread's assumed poolfd */
145 };
146
147 static struct registry_entry **registry;
148
149 static pthread_mutex_t registry_lock = PTHREAD_MUTEX_INITIALIZER;
150
151
152 /* Register a request handling structure under a request ID.  Registers the
153  * registry entry at the given reqid; if reqid is -1, a new one, mappable to
154  * the uint16_t type for the field is allocated and set in *reqid.  When the
155  * registry entry is NULL, it will be removed from the registry and the reqid
156  * is reset to -1.
157  *
158  * The return value is 0 on success, or -1 on failure; the most probable
159  * cause for failure is 
160  */
161 static int registry_update (int *reqid, struct registry_entry *entry) {
162         static int simu = -1;
163         static uint16_t pos = 0;
164         int ctr;
165         if (registry == NULL) {
166                 simu = tlspool_simultaneous_starttls ();
167                 registry = calloc (simu, sizeof (struct registry_entry *));
168                 if (registry == NULL) {
169                         syslog (LOG_NOTICE, "Failed to allocate TLS Pool request registry");
170                         return -1;
171                 }
172         }
173         if (entry != NULL) {
174                 /* Set the entry in the given entry */
175                 if (*reqid < 0) {
176                         /* Allocate an entry in the registry */
177                         assert (pthread_mutex_lock (&registry_lock) == 0);
178                         ctr = simu;
179                         while (ctr-- > 0) {
180                                 if (registry [pos] == NULL) {
181                                         registry [pos] = entry;
182                                         *reqid = pos;
183                                         break;
184                                 }
185                                 pos++;
186                                 if (pos >= simu) {
187                                         pos = 0;
188                                 }
189                         }
190                         pthread_mutex_unlock (&registry_lock);
191                 }
192                 if (*reqid < 0) {
193                         return -1;
194                 }
195         } else {
196                 if ((*reqid < 0) || (*reqid >= simu)) {
197                         return -1;
198                 }
199                 /* Remove the entry from the given entry */
200                 assert (pthread_mutex_lock (&registry_lock) == 0);
201                 registry [*reqid] = NULL;       /* may not be atomic */
202                 *reqid = -1;
203                 pthread_mutex_unlock (&registry_lock);
204         }
205         return 0;
206 }
207
208
209 /* Flush registry entries with an older poolfd value; this is used after
210  * reconnecting to the TLS Pool, presumably having closed the old poolfd.
211  * Any outstanding registry entries will be sent an ERROR value at this
212  * time.
213  */
214 static void registry_flush (int poolfd) {
215         int regid = tlspool_simultaneous_starttls ();
216         assert (pthread_mutex_lock (&registry_lock) == 0);
217         while (regid-- > 0) {
218                 struct registry_entry *entry = registry [regid];
219                 if ((entry != NULL) && (entry->pfd != poolfd)) {
220                         // Fill the cmd buffer with an error message
221                         entry->buf->pio_cmd = PIOC_ERROR_V2;
222                         entry->buf->pio_data.pioc_error.tlserrno = EPIPE;
223                         strncpy (entry->buf->pio_data.pioc_error.message,
224                                 "No reply from TLS Pool",
225                                 sizeof (entry->buf->pio_data.pioc_error.message));
226                         // Signal continuation to the recipient
227                         pthread_mutex_unlock (entry->sig);
228                         // Do not remove the entry; the recipient will do this
229                 }
230         }
231         pthread_mutex_unlock (&registry_lock);
232 }
233
234
235 /* The master thread issues the recv() commands on the TLS Pool socket, and
236  * redistributes the result to the registry entries that are waiting for
237  * the data.  The thread is started when the poolfd is first requested.
238  *
239  * Having a dedicated master thread is a great design simplification over
240  * temporary promotion of one of the application threads to a master status.
241  * The locking involved in the distinct state without a master, and the
242  * raceconditions while establishing the first on-demand master are dreadful.
243  *
244  * An additional advantage of a separate master thread is that it will
245  * instantly notice when the TLS Pool goes offline.  At this time, it will
246  * lock the registry and cancel any requests in the registry that are
247  * waiting for the older connection.  Subsequent attempts to receive are
248  * stopped immediately.  The TLS Pool then tries to reconnect to the
249  * TLS Pool anew, using exponential back-off.
250  */
251 static void *master_thread (void *path) {
252         useconds_t usec;
253         struct sockaddr_un sun;
254         struct tlspool_command cmd;
255         //NOT-USED// char anc [CMSG_SPACE(sizeof (int))];
256         struct iovec iov;
257         struct cmsghdr *cmsg;
258         struct msghdr mh = { 0 };
259         struct registry_entry *entry;
260
261         //
262         // Setup path information -- value and size were checked
263         bzero (&sun, sizeof (sun));
264         strcpy (sun.sun_path, (char *) path);
265         sun.sun_family = AF_UNIX;
266         //
267         // Service forever
268         while (1) {
269                 //
270                 // If any old socket clients persist, tell them that the
271                 // TLS Pool has been disconnected.
272                 if (poolfd >= 0) {
273                         int poolfdcopy = poolfd;
274 // printf ("DEBUG: Removing old poolfd %d\n", poolfd);
275                         poolfd = -1;
276                         registry_flush (-1);
277                         close (poolfdcopy);
278                 }
279                 //
280                 // First, connect to the TLS Pool; upon failure, retry
281                 // with 1s, 2s, 4s, 8s, 16s, 32s, 32s, 32s, ... intervals.
282                 usec = 1000000;
283                 while (poolfd < 0) {
284                         int newpoolfd = socket (AF_UNIX, SOCK_STREAM, 0);
285                         if (newpoolfd != -1) {
286                                 if (connect (newpoolfd, (struct sockaddr *) &sun, SUN_LEN (&sun)) == 0) {
287 // printf ("DEBUG: Succeeded connect() to TLS Pool\n");
288                                         poolfd = newpoolfd;
289                                 } else {
290                                         close (newpoolfd);
291                                         newpoolfd = -1;
292                                 }
293                         }
294 // printf ("DEBUG: Trying new poolfd %d for path %s\n", poolfd, sun.sun_path);
295                         //
296                         // Signal a newly set poolfd value to all waiting.
297                         // Note that we do not need to claim a mutex first;
298                         // there is always one writer to poolfd (namely, this
299                         // master_thread) and the rest simply reads it.  This
300                         // makes a silent assumption of atomic writes to the
301                         // poolfd, which seems fair because the size of an
302                         // fd table has been smaller than the size of the
303                         // data bus since the times of ZX Spectrum and CP/M.
304                         pthread_cond_broadcast (&updated_poolfd);
305 // printf ("DEBUG: Signalled slave threads with poolfd %d\n", poolfd);
306                         //
307                         // Wait before repeating, with exponential back-off
308                         if (poolfd < 0) {
309                                 usleep (usec);
310                                 usec <<= 1;
311                                 if (usec > 32000000) {
312                                         usec = 32000000;
313                                 }
314                         }
315                 }
316                 //
317                 // We now have an established link to the TLS Pool, until
318                 // further notice -- that is, until the TLS Pool terminates.
319                 // At that time, a break ends the following loop and jumps
320                 // back up to the re-connection logic.
321                 while (1) {
322                         int retval;
323                         iov.iov_base = &cmd;
324                         iov.iov_len = sizeof (cmd);
325                         mh.msg_iov = &iov;
326                         mh.msg_iovlen = 1;
327                         //NOT-USED// mh.msg_control = anc;
328                         //NOT-USED// mh.msg_controllen = sizeof (anc);
329                         retval = recvmsg (poolfd, &mh, MSG_NOSIGNAL);
330                         if ((retval == -1) && (errno = EINTR)) {
331                                 continue;       // Badly masked user signal
332                         }
333                         if (retval == 0) {
334                                 errno = EPIPE;
335                                 retval = -1;
336                         }
337                         if (retval == -1) {
338                                 // This includes EPIPE, or EOF, for detached
339                                 // TLS Pool; the treatment is to reconnect.
340 // printf ("DEBUG: recvmsg() returned -1 due to: %s\n", strerror (errno));
341                                 break;
342                         }
343                         //
344                         // Determine where to post the received message
345                         entry = registry [cmd.pio_reqid];
346                         if (entry == NULL) {
347                                 // Protocol error!  Client detached!
348 // printf ("DEBUG: Client detached! poolfd=%d, cmd=0x%08x, reqid=%d, cbid=%d\n", poolfd, cmd.pio_cmd, cmd.pio_reqid, cmd.pio_cbid);
349                                 if ((cmd.pio_cbid != 0) && (cmd.pio_cmd != PIOC_ERROR_V2)) {
350 // printf ("DEBUG: Will send PIOC_ERROR_V2 as callback to TLS Pool\n");
351                                         // TLS Pool is waiting for a callback;
352                                         // Send it an ERROR message instead.
353                                         cmd.pio_cmd = PIOC_ERROR_V2;
354                                         cmd.pio_data.pioc_error.tlserrno = EPIPE;
355                                         strncpy (cmd.pio_data.pioc_error.message, "Client prematurely left TLS Pool negotiations", sizeof (cmd.pio_data.pioc_error.message));
356                                         sendmsg (poolfd, &mh, MSG_NOSIGNAL);
357                                         // Ignore errors
358 printf ("DEBUG: Sent      PIOC_ERROR_V2 as callback to TLS Pool\n");
359                                 }
360                                 // Do not attempt delivery
361                                 continue;
362                         }
363                         if (entry->pfd != poolfd) {
364 // printf ("DEBUG: Registry entry has older poolfd %d not %d, flushing registry\n", entry->pfd, poolfd);
365                                 registry_flush (poolfd);
366                         }
367                         memcpy (entry->buf, &cmd, sizeof (cmd));
368                         //NOT-USED// deliver anc or passfd to recipient
369                         pthread_mutex_unlock (entry->sig);
370 // printf ("DEBUG: Signalled slave with new message in place\n");
371                 }
372         }
373 }
374
375
376 /* Consider handling the message reception interface, if no other thread is
377  * doing that yet.  Then, wait until a message has been received.
378  */
379 static void registry_recvmsg (struct registry_entry *entry) {
380         static int lastpoolfd = -1;
381         //
382         // Detect poolfd socket change for potential dangling recipients
383         if (entry->pfd != lastpoolfd) {
384                 lastpoolfd = tlspool_socket (NULL);
385                 if ((entry->pfd != lastpoolfd) && (lastpoolfd != -1)) {
386                         // Signal PIOC_ERROR to outdated recipients.
387                         // (That will include the current recipient.)
388                         registry_flush (lastpoolfd);
389                 }
390         }
391         //
392         // Now wait for the registered command structure to be filled
393         // by the master thread.  Note that the call to tlspool_socket()
394         // above is made when this function is first called, and that
395         // routine ensures running of the master thread.
396         assert (pthread_mutex_lock (entry->sig) == 0);
397 }
398
399
400 /* The library function for ping, which is called to establish the API
401  * version and a list of facilities supported by the TLS Pool.  The data
402  * supplied to the TLS Pool should represent the environment of the
403  * application, which is why no defaults are provided by this function
404  * but the application should supply all ping data.
405  *
406  * The pioc_ping structure will be copied into the command structure,
407  * and upon completion it will be copied back.  Normally, the application
408  * would set YYYYMMDD_producer to TLSPOOL_IDENTITY_V2, and facilities
409  * to PIOF_FACILITY_ALL_CURRENT.  The TLS Pool overwrites the former and
410  * resets unsupported bits in the latter.  Note that facilities may be
411  * unsupported due to the compile-time environment of the TLS Pool or
412  * because it was configured without the requested support.
413  *
414  * This function returns zero on success, and -1 on failure.  In case of
415  * failure, errno will be set.
416  */
417 int tlspool_ping (pingpool_t *pingdata) {
418         struct tlspool_command cmd;
419         pthread_mutex_t recvwait = PTHREAD_MUTEX_INITIALIZER;
420         struct registry_entry regent = { .sig = &recvwait, .buf = &cmd };
421         int entry_reqid = -1;
422         int poolfd = -1;
423         struct iovec iov;
424         struct msghdr mh = { 0 };
425
426         /* Prepare command structure */
427         poolfd = tlspool_socket (NULL);
428         if (poolfd == -1) {
429                 errno = ENODEV;
430                 return -1;
431         }
432         /* Finish setting up the registry entry */
433         regent.pfd = poolfd;
434         pthread_mutex_lock (&recvwait);         // Will await unlock by master
435         /* Determine the request ID */
436         if (registry_update (&entry_reqid, &regent) != 0) {
437                 errno = EBUSY;
438                 return -1;
439         }
440         bzero (&cmd, sizeof (cmd));     /* Do not leak old stack info */
441         cmd.pio_reqid = entry_reqid;
442         cmd.pio_cbid = 0;
443         cmd.pio_cmd = PIOC_PING_V2;
444         memcpy (&cmd.pio_data.pioc_ping, pingdata, sizeof (struct pioc_ping));
445
446         /* Send the request */
447         iov.iov_base = &cmd;
448         iov.iov_len = sizeof (cmd);
449         mh.msg_iov = &iov;
450         mh.msg_iovlen = 1;
451         if (sendmsg (poolfd, &mh, MSG_NOSIGNAL) == -1) {
452                 // Let SIGPIPE be reported as EPIPE
453                 registry_update (&entry_reqid, NULL);
454                 // errno inherited from sendmsg()
455                 return -1;
456         }
457
458         /* Await response and process it */
459         registry_recvmsg (&regent);
460         registry_update (&entry_reqid, NULL);
461         switch (cmd.pio_cmd) {
462         case PIOC_ERROR_V2:
463                 /* Bad luck, we failed */
464                 syslog (LOG_INFO, "TLS Pool error to tlspool_ping(): %s", cmd.pio_data.pioc_error.message);
465                 errno = cmd.pio_data.pioc_error.tlserrno;
466                 return -1;
467         case PIOC_PING_V2:
468                 /* Wheee!!! we're done */
469                 memcpy (pingdata, &cmd.pio_data.pioc_ping, sizeof (pingpool_t));
470                 return 0;
471         default:
472                 /* V2 protocol error */
473                 errno = EPROTO;
474                 return -1;
475         }
476 }
477
478
479 /* The library function for starttls, which is normally called through one
480  * of the two inline variations below, which start client and server sides.
481  *
482  * The cryptfd handle supplies the TLS connection that is assumed to have
483  * been setup.  When the function ends, either in success or failure, this
484  * handle will no longer be available to the caller; the responsibility of
485  * closing it is passed on to the function and/or the TLS Pool.
486  *
487  * The tlsdata structure will be copied into the command structure,
488  * and upon completion it will be copied back.  You can use it to
489  * communicate flags, protocols and other parameters, including the
490  * most important settings -- local and remote identifiers.  See
491  * the socket protocol document for details.
492  *
493  * The privdata handle is used in conjunction with the namedconnect() call;
494  * it is passed on to connect the latter to the context from which it was
495  * called and is not further acted upon by this function.
496  *
497  * The namedconnect() function is called when the identities have been
498  * exchanged, and established, in the TLS handshake.  This is the point
499  * at which a connection to the plaintext side is needed, and a callback
500  * to namedconnect() is made to find a handle for it.  The function is
501  * called with a version of the tlsdata that has been updated by the
502  * TLS Pool to hold the local and remote identities.  The return value
503  * should be -1 on error, with errno set, or it should be a valid file
504  * handle that can be passed back to the TLS Pool to connect to.
505  *
506  * When the namedconnect argument passed is NULL, default behaviour is
507  * triggered.  This interprets the privdata handle as an (int *) holding
508  * a file descriptor.  If its value is valid, that is, >= 0, it will be
509  * returned directly; otherwise, a socketpair is constructed, one of the
510  * sockets is stored in privdata for use by the caller and the other is
511  * returned as the connected file descriptor for use by the TLS Pool.
512  * This means that the privdata must be properly initialised for this
513  * use, with either -1 (to create a socketpair) or the TLS Pool's
514  * plaintext file descriptor endpoint.  The file handle returned in
515  * privdata, if it is >= 0, should be closed by the caller, both in case
516  * of success and failure.
517  *
518  * This function returns zero on success, and -1 on failure.  In case of
519  * failure, errno will be set.
520  */
521 int tlspool_starttls (int cryptfd, starttls_t *tlsdata,
522                         void *privdata,
523                         int (*namedconnect) (starttls_t *tlsdata,void *privdata)) {
524         struct tlspool_command cmd;
525         pthread_mutex_t recvwait = PTHREAD_MUTEX_INITIALIZER;
526         struct registry_entry regent = { .sig = &recvwait, .buf = &cmd };
527         int entry_reqid = -1;
528         int poolfd = -1;
529         int plainfd = -1;
530         int sentfd = -1;
531         char anc [CMSG_SPACE(sizeof (int))];
532         struct iovec iov;
533         struct cmsghdr *cmsg;
534         struct msghdr mh = { 0 };
535         int processing;
536         int renegotiate = 0 != (tlsdata->flags & PIOF_STARTTLS_RENEGOTIATE);
537
538         /* Prepare command structure */
539         poolfd = tlspool_socket (NULL);
540         if (poolfd == -1) {
541                 close (cryptfd);
542                 errno = ENODEV;
543                 return -1;
544         }
545         /* Finish setting up the registry entry */
546         regent.pfd = poolfd;
547         pthread_mutex_lock (&recvwait);         // Will await unlock by master
548         /* Determine the request ID */
549         if (registry_update (&entry_reqid, &regent) != 0) {
550                 close (cryptfd);
551                 errno = EBUSY;
552                 return -1;
553         }
554         bzero (&cmd, sizeof (cmd));     /* Do not leak old stack info */
555         cmd.pio_reqid = entry_reqid;
556         cmd.pio_cbid = 0;
557         cmd.pio_cmd = PIOC_STARTTLS_V2;
558         memcpy (&cmd.pio_data.pioc_starttls, tlsdata, sizeof (struct pioc_starttls));
559
560 #if RAND_MAX < 0xfffff
561 #  error "Failure on assumption of 16 bits of random material per random() call"
562 #endif
563
564 #if TLSPOOL_CTLKEYLEN != 16
565 #  error "Failure on assumption of 16 bytes per ctlkey"
566 #endif
567
568         if (!renegotiate) {
569                 assert (pthread_mutex_lock (&prng_lock) == 0);
570                 * (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 0] = random ();
571                 * (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 2] = random ();
572                 * (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 4] = random ();
573                 * (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 6] = random ();
574                 * (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [ 8] = random ();
575                 * (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [10] = random ();
576                 * (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [12] = random ();
577                 * (uint16_t *) &cmd.pio_data.pioc_starttls.ctlkey [14] = random ();
578                 pthread_mutex_unlock (&prng_lock);
579         }
580 // printf ("DEBUG: ctlkey =");
581 // {int i; for (i=0;i<16;i++) printf (" %02x", cmd.pio_data.pioc_starttls.ctlkey [i]);}
582 // printf ("\n");
583
584         /* Send the request */
585         iov.iov_base = &cmd;
586         iov.iov_len = sizeof (cmd);
587         mh.msg_iov = &iov;
588         mh.msg_iovlen = 1;
589         if (!renegotiate) {
590 #ifndef WINDOWS
591                 mh.msg_control = anc;
592                 mh.msg_controllen = sizeof (anc);
593                 cmsg = CMSG_FIRSTHDR (&mh);
594                 cmsg->cmsg_level = SOL_SOCKET;
595                 cmsg->cmsg_type = SCM_RIGHTS;
596                 * (int *) CMSG_DATA (cmsg) = cryptfd;   /* cannot close it yet */
597                 cmsg->cmsg_len = CMSG_LEN (sizeof (int));
598 #else /* ifdef WINDOWS */
599                 BOOL tmp;
600                 int len = sizeof(tmp);
601
602                 // cmd was already set to 0, including ancilary data simulation
603                 if (getsockopt ((SOCKET) cryptfd, SOL_SOCKET, SO_DONTLINGER, (char *) &tmp, &len) != SOCKET_ERROR || WSAGetLastError () != WSAENOTSOCK) {
604                         // Send a socket
605                         int pid = tlspool_getpid();
606
607                         cmd.pio_ancil_type = ANCIL_TYPE_SOCKET;
608                         WSADuplicateSocket(cryptfd, pid, &cmd.pio_ancil_data.pioa_socket);                      
609                         //... (..., &cmd.pio_ancil_data.pioa_socket, ...);
610                 } else {
611                         // Send a file handle
612                         cmd.pio_ancil_type = ANCIL_TYPE_FILEHANDLE;
613                         //... (..., &cmd.pio_ancil_data.pioa_filehandle, ...);
614                 }
615 #endif /* WINDOWS */
616         }
617         if (sendmsg (poolfd, &mh, MSG_NOSIGNAL) == -1) {
618                 // Let SIGPIPE be reported as EPIPE
619                 close (cryptfd);
620                 registry_update (&entry_reqid, NULL);
621                 // errno inherited from sendmsg()
622                 return -1;
623         }
624         sentfd = cryptfd;  /* Close anytime after response and before fn end */
625
626         /* Handle responses until success or error */
627         processing = 1;
628         while (processing) {
629                 //NOTUSED// mh.msg_control = anc;
630                 //NOTUSED// mh.msg_controllen = sizeof (anc);
631                 registry_recvmsg (&regent);
632                 if (sentfd >= 0) {
633                         close (sentfd);
634                 }
635                 sentfd = -1;
636                 switch (cmd.pio_cmd) {
637                 case PIOC_ERROR_V2:
638                         /* Bad luck, we failed */
639                         syslog (LOG_INFO, "TLS Pool error to tlspool_starttls(): %s", cmd.pio_data.pioc_error.message);
640                         registry_update (&entry_reqid, NULL);
641                         errno = cmd.pio_data.pioc_error.tlserrno;
642                         return -1;
643                 case PIOC_STARTTLS_LOCALID_V2:
644                 case PIOC_PLAINTEXT_CONNECT_V2:
645                         if (namedconnect) {
646                                 plainfd = (*namedconnect) (tlsdata, privdata);
647                         } else {
648                                 /* default namedconnect() implementation */
649                                 plainfd = * (int *) privdata;
650                                 if ((plainfd < 0) && (cmd.pio_cmd == PIOC_PLAINTEXT_CONNECT_V2)) {
651                                         int soxx [2];
652                                         //TODO// Setup for TCP, UDP, SCTP
653                                         if (socketpair (AF_UNIX, SOCK_SEQPACKET, 0, soxx) == 0) {
654                                                 /* Socketpair created */
655                                                 plainfd = soxx [0];
656                                                 * (int *) privdata = soxx [1];
657                                         } else {
658                                                 /* Socketpair failed */
659                                                 cmd.pio_cmd = PIOC_ERROR_V2;
660                                                 cmd.pio_data.pioc_error.tlserrno = errno;
661                                                 plainfd = -1;
662                                         }
663                                 }
664                         }
665                         /* We may now have a value to send in plainfd */
666                         if (plainfd >= 0) {
667 #ifndef WINDOWS
668                                 mh.msg_control = anc;
669                                 mh.msg_controllen = sizeof (anc);
670                                 cmsg = CMSG_FIRSTHDR (&mh);
671                                 cmsg->cmsg_level = SOL_SOCKET;
672                                 cmsg->cmsg_type = SCM_RIGHTS;
673                                 * (int *) CMSG_DATA (cmsg) = plainfd;
674                                 cmsg->cmsg_len = CMSG_LEN (sizeof (int));
675 #else /* ifdef WINDOWS */
676                                 BOOL tmp;
677                                 int len = sizeof(tmp);
678
679                                 // cmd was already set to 0, including ancilary data simulation
680                                 if (getsockopt ((SOCKET) cryptfd, SOL_SOCKET, SO_DONTLINGER, (char *) &tmp, &len) != SOCKET_ERROR || WSAGetLastError () != WSAENOTSOCK) {
681                                         // Send a socket
682                                         int pid = tlspool_getpid();
683
684                                         cmd.pio_ancil_type = ANCIL_TYPE_SOCKET;
685                                         WSADuplicateSocket(cryptfd, pid, &cmd.pio_ancil_data.pioa_socket);                      
686                                         //... (..., &cmd.pio_ancil_data.pioa_socket, ...);
687                                 } else {
688                                         // Send a file handle
689                                         cmd.pio_ancil_type = ANCIL_TYPE_FILEHANDLE;
690                                         //... (..., &cmd.pio_ancil_data.pioa_filehandle, ...);
691                                 }
692 #endif /* WINDOWS */
693                         }
694                         /* Now supply plainfd in the callback response */
695                         sentfd = plainfd;
696                         if (sendmsg (poolfd, &mh, MSG_NOSIGNAL) == -1) {
697                                 // Let SIGPIPE be reported as EPIPE
698                                 if (sentfd >= 0) {
699                                         close (sentfd);
700                                         sentfd = -1;
701                                 }
702                                 registry_update (&entry_reqid, NULL);
703                                 // errno inherited from sendmsg()
704                                 return -1;
705                         }
706                         break;  // Loop around and try again
707                 case PIOC_STARTTLS_V2:
708                         /* Wheee!!! we're done */
709                         processing = 0;
710                         break;
711                 default:
712                         /* V2 protocol error */
713                         registry_update (&entry_reqid, NULL);
714                         errno = EPROTO;
715                         return -1;
716                 }
717         }
718
719         /* Close the now-duplicated or now-erradicated plaintext fd */
720
721         memcpy (tlsdata, &cmd.pio_data.pioc_starttls, sizeof (struct pioc_starttls));
722 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]);
723         registry_update (&entry_reqid, NULL);
724         return 0;
725 }
726
727
728 /* The library function to send a control connection command, notably
729  * TLSPOOL_CONTROL_DETACH and TLSPOOL_CONTROL_REATTACH.
730  *
731  * This function returns zero on success, and -1 on failure.  In case of
732  * failure, errno will be set.
733  */
734 int _tlspool_control_command (int cmdcode, uint8_t *ctlkey) {
735         struct tlspool_command cmd;
736         pthread_mutex_t recvwait = PTHREAD_MUTEX_INITIALIZER;
737         struct registry_entry regent = { .sig = &recvwait, .buf = &cmd };
738         int entry_reqid = -1;
739         int retval;
740
741         /* Prepare command structure */
742         poolfd = tlspool_socket (NULL);
743         if (poolfd == -1) {
744                 errno = ENODEV;
745                 return -1;
746         }
747         /* Finish setting up the registry entry */
748         regent.pfd = poolfd;
749         pthread_mutex_lock (&recvwait);         // Will await unlock by master
750         /* Determine the request ID */
751         if (registry_update (&entry_reqid, &regent) != 0) {
752                 errno = EBUSY;
753                 return -1;
754         }
755         bzero (&cmd, sizeof (cmd));     /* Do not leak old stack info */
756         cmd.pio_reqid = entry_reqid;
757         cmd.pio_cbid = 0;
758         cmd.pio_cmd = cmdcode;
759         memcpy (&cmd.pio_data.pioc_control.ctlkey, ctlkey, TLSPOOL_CTLKEYLEN);
760 // 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]);
761
762         /* Send the request */
763         if (send (poolfd, &cmd, sizeof (cmd), MSG_NOSIGNAL) == -1) {
764                 // Let SIGPIPE be reported as EPIPE
765                 registry_update (&entry_reqid, NULL);
766                 // errno inherited from send()
767                 return -1;
768         }
769
770         /* Receive the response */
771         registry_recvmsg (&regent);
772         switch (cmd.pio_cmd) {
773         case PIOC_SUCCESS_V2:
774                 retval = 0;
775                 break;
776         case PIOC_ERROR_V2:
777                 retval = -1;
778                 errno = cmd.pio_data.pioc_error.tlserrno;
779                 break;
780         default:
781                 errno = EPROTO;
782                 retval = -1;
783                 break;
784         }
785         return retval;
786 }
787
788 /* Generate a pseudo-random sequence based on session cryptographic keys.
789  *
790  * In the case of TLS, this adheres to RFC 5705; other protocols may or
791  * may not support a similar mechanism, in which case an error is returned.
792  *
793  * This leans on access privileges to an existing connection at a meta-level,
794  * for which we use the customary ctlkey verification mechanism introduced with
795  * tlspool_starttls ().  Note that random material may be used for security
796  * purposes, such as finding the same session key for both sides deriving from
797  * prior key negotiation; the protection of a ctlkey for such applications is
798  * important.
799  * 
800  * The inputs to this function must adhere to the following restrictions:
801  *  - label must not be a NULL pointer, but opt_ctxvalue may be set to NULL
802  *    to bypass the use of a context value.  Note that passing an empty string
803  *    in opt_ctxvalue is different from not providing the string at all by
804  *    setting it to NULL.
805  *  - label  and  opt_ctxvalue  (if non-NULL) refer to ASCII strings with
806  *    printable characters, terminated with a NUL character.  The maximum
807  *    string length of each is 254 bytes.
808  *  - prng_len holds the requested number of pseudo-random bytes
809  *  - prng_buf points is a non-NULL pointer to a buffer that can hold
810  *    prng_len bytes.
811  *
812  * If the operation succeeds, then prng_buf holds prng_len bytes of random
813  * material, and zero is returned.  If the operation fails, then prng_buf
814  * is filled with zero bytes (to make it stand out as a rather rare case of
815  * a random byte string) and -1 is returned.
816  *
817  * Note a few restrictions to the generality of this function, as a result of
818  * the underlying packet format for the communication with the TLS Pool; but
819  * the dimensions have been choosen such that these restrictions would not
820  * typically be a problem in practice:
821  *  - it constrains the string lengths of label and opt_ctxvalue
822  *  - it constrains prng_len to a maximum value of TLSPOOL_PRNGBUFLEN
823  *
824  * The TLS Pool may limit certain TLS PRNG labels, in adherence to the
825  * IANA-maintained TLS Exporter Label Registry.  It additionally supports
826  * the EXPERIMENTAL label prefix specified in RFC 5705.
827  *
828  * Be advised that the maximum size of buffer may increase in future releases.
829  * So, be sure to use TLSPOOL_PRNGBUFLEN which holds the header-file defined
830  * size.
831  */
832 int tlspool_prng (char *label, char *opt_ctxvalue,
833                 uint16_t prng_len, uint8_t *prng_buf,
834                 uint8_t *ctlkey) {
835         struct tlspool_command cmd;
836         pthread_mutex_t recvwait = PTHREAD_MUTEX_INITIALIZER;
837         struct registry_entry regent = { .sig = &recvwait, .buf = &cmd };
838         int entry_reqid = -1;
839         int poolfd = -1;
840         struct iovec iov;
841         struct msghdr mh = { 0 };
842
843         bzero (prng_buf, prng_len);
844
845         /* Sanity checks */
846         if ((prng_len > TLSPOOL_PRNGBUFLEN) ||
847                         (label == NULL) || (strlen (label) > 254) ||
848                         ((opt_ctxvalue != NULL) &&
849                                 ((strlen (opt_ctxvalue) > 254) ||
850                                         (strlen (label) + strlen (opt_ctxvalue) > TLSPOOL_PRNGBUFLEN - TLSPOOL_CTLKEYLEN)))) {
851                 errno = EINVAL;
852                 return -1;
853         }
854         
855
856         /* Prepare command structure */
857         poolfd = tlspool_socket (NULL);
858         if (poolfd == -1) {
859                 errno = ENODEV;
860                 return -1;
861         }
862         /* Finish setting up the registry entry */
863         regent.pfd = poolfd;
864         pthread_mutex_lock (&recvwait);         // Will await unlock by master
865         /* Determine the request ID */
866         if (registry_update (&entry_reqid, &regent) != 0) {
867                 errno = EBUSY;
868                 return -1;
869         }
870         bzero (&cmd, sizeof (cmd));     /* Do not leak old stack info */
871         cmd.pio_reqid = entry_reqid;
872         cmd.pio_cbid = 0;
873         cmd.pio_cmd = PIOC_PRNG_V2;
874         cmd.pio_data.pioc_prng.prng_len = prng_len;
875         memcpy (cmd.pio_data.pioc_prng.buffer, ctlkey, TLSPOOL_CTLKEYLEN);
876         cmd.pio_data.pioc_prng.in1_len = strlen (label);
877         memcpy (cmd.pio_data.pioc_prng.buffer + TLSPOOL_CTLKEYLEN, label, cmd.pio_data.pioc_prng.in1_len);
878         if (opt_ctxvalue != NULL) {
879                 cmd.pio_data.pioc_prng.in2_len = strlen (opt_ctxvalue);
880                 memcpy (cmd.pio_data.pioc_prng.buffer + TLSPOOL_CTLKEYLEN + cmd.pio_data.pioc_prng.in1_len, opt_ctxvalue, cmd.pio_data.pioc_prng.in2_len);
881         } else {
882                 cmd.pio_data.pioc_prng.in2_len = -1;
883         }
884
885         /* Send the request */
886         iov.iov_base = &cmd;
887         iov.iov_len = sizeof (cmd);
888         mh.msg_iov = &iov;
889         mh.msg_iovlen = 1;
890         if (sendmsg (poolfd, &mh, MSG_NOSIGNAL) == -1) {
891                 // Let SIGPIPE be reported as EPIPE
892                 registry_update (&entry_reqid, NULL);
893                 // errno inherited from sendmsg()
894                 return -1;
895         }
896
897         /* Await response and process it */
898         registry_recvmsg (&regent);
899         registry_update (&entry_reqid, NULL);
900         switch (cmd.pio_cmd) {
901         case PIOC_ERROR_V2:
902                 /* Bad luck, we failed */
903                 syslog (LOG_INFO, "TLS Pool error to tlspool_ping(): %s", cmd.pio_data.pioc_error.message);
904                 errno = cmd.pio_data.pioc_error.tlserrno;
905                 return -1;
906         case PIOC_PRNG_V2:
907                 /* Wheee!!! we're done */
908                 memcpy (prng_buf, cmd.pio_data.pioc_prng.buffer, prng_len);
909                 return 0;
910         default:
911                 /* V2 protocol error */
912                 errno = EPROTO;
913                 return -1;
914         }
915 }
916