1 /* tlspool/libfun.c -- Library function for starttls go-get-it */
13 #include <tlspool/starttls.h>
14 #include <tlspool/commands.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
22 #include <sys/select.h>
23 #include <sys/resource.h>
27 static void tlspool_pin_service_closepool (void *poolfdptr) {
28 int poolfd = * (int *) poolfdptr;
35 /* The library function to service PIN entry callbacks. It registers
36 * with the TLS Pool and will service callback requests until it is no
37 * longer welcomed. Of course, if another process already has a claim on
38 * this functionality, the service offering will not be welcome from the
41 * This function differs from most other TLS Pool library functions in
42 * setting up a private socket. This helps to avoid the overhead in the
43 * foreseeable applications that only do this; it also helps to close
44 * down the exclusive claim on local identity resolution when (part of)
45 * the program is torn down. The function has been built to cleanup
46 * properly when it is subjected to pthread_cancel().
48 * The path parameter offers a mechanism to specify the socket path. When
49 * set to NULL, the library's compiled-in default path will be used.
51 * In terms of linking, this routine is a separate archive object. This
52 * minimizes the amount of code carried around in statically linked binaries.
54 * This function returns -1 on error, or 0 on success.
56 int tlspool_pin_service (char *path, uint32_t regflags, int responsetimeout_usec, void (*cb) (struct pioc_pinentry *entry, void *data), void *data) {
57 struct sockaddr_un sun;
59 struct tlspool_command cmd;
61 /* Access the TLS Pool socket */
63 path = tlspool_configvar (NULL, "daemon_pidfile");
66 path = TLSPOOL_DEFAULT_SOCKET_PATH;
68 if (strlen (path) + 1 > sizeof (sun.sun_path)) {
72 memset (&sun, 0, sizeof (sun));
73 sun.sun_family = AF_UNIX;
74 strcpy (sun.sun_path, path);
75 pthread_cleanup_push (tlspool_pin_service_closepool, &poolfd);
76 poolfd = socket (AF_UNIX, SOCK_STREAM, 0);
80 if (connect (poolfd, (struct sockaddr *) &sun, sizeof (sun)) == -1) {
86 /* Prepare command structure */
87 memset (&cmd, 0, sizeof (cmd)); /* Do not leak old stack info */
89 cmd.pio_cmd = PIOC_PINENTRY_V2;
90 cmd.pio_data.pioc_pinentry.flags = regflags;
91 cmd.pio_data.pioc_pinentry.timeout_us = responsetimeout_usec;
93 /* Loop forever... or until an error occurs */
96 /* send the request or, when looping, the callback result */
97 //DEBUG// printf ("DEBUG: PINENTRY command 0x%08lx with cbid=%d and flags 0x%08lx\n", cmd.pio_cmd, cmd.pio_cbid, cmd.pio_data.pioc_pinentry.flags);
98 if (send (poolfd, &cmd, sizeof (cmd), MSG_NOSIGNAL) == -1) {
99 // errno inherited from send()
100 // let SIGPIPE be reported as EPIPE
105 /* Erase the password that has just been sent */
106 memset (&cmd.pio_data.pioc_pinentry.pin,
108 sizeof (cmd.pio_data.pioc_pinentry.pin));
110 /* receive and process the response */
111 if (recv (poolfd, &cmd, sizeof (cmd), MSG_NOSIGNAL) == -1) {
112 // Let SIGPIPE be reported as EPIPE
113 // errno inherited from recv()
117 //DEBUG// printf ("DEBUG: PINENTRY callback command 0x%08lx with cbid=%d and flags 0x%08lx\n", cmd.pio_cmd, cmd.pio_cbid, cmd.pio_data.pioc_pinentry.flags);
118 switch (cmd.pio_cmd) {
119 case PIOC_PINENTRY_V2:
120 (*cb) (&cmd.pio_data.pioc_pinentry, data);
121 //TODO// Claim on regent lost?
124 errno = cmd.pio_data.pioc_error.tlserrno;
125 syslog (LOG_INFO, "TLS Pool error to tlspool_localid_service(): %s", cmd.pio_data.pioc_error.message);
135 /* Never end up here... */
136 pthread_cleanup_pop (1);