Coverage Report

Created: 2023-06-07 06:14

/src/p11-kit/p11-kit/rpc-transport.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2012 Stefan Walter
3
 * Copyright (C) 2013 Red Hat Inc.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 *     * Redistributions of source code must retain the above
10
 *       copyright notice, this list of conditions and the
11
 *       following disclaimer.
12
 *     * Redistributions in binary form must reproduce the
13
 *       above copyright notice, this list of conditions and
14
 *       the following disclaimer in the documentation and/or
15
 *       other materials provided with the distribution.
16
 *     * The names of contributors to this software may not be
17
 *       used to endorse or promote products derived from this
18
 *       software without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31
 * DAMAGE.
32
 *
33
 * Author: Stef Walter <stefw@gnome.org>
34
 */
35
36
#include "config.h"
37
38
#include "argv.h"
39
#include "compat.h"
40
0
#define P11_DEBUG_FLAG P11_DEBUG_RPC
41
#include "debug.h"
42
#include "message.h"
43
#include "pkcs11.h"
44
#include "private.h"
45
#include "rpc.h"
46
#include "rpc-message.h"
47
#include "path.h"
48
49
#include <sys/types.h>
50
51
#include <assert.h>
52
#include <errno.h>
53
#include <fcntl.h>
54
#include <stdint.h>
55
#include <stdio.h>
56
#include <stdlib.h>
57
#include <string.h>
58
59
#ifdef OS_UNIX
60
#include <sys/select.h>
61
#include <sys/socket.h>
62
#include <sys/wait.h>
63
#include <sys/un.h>
64
#include <signal.h>
65
#include <unistd.h>
66
#include <limits.h>
67
#endif
68
69
#ifdef OS_WIN32
70
#include <process.h>
71
#include <signal.h>
72
#include <winsock2.h>
73
#ifndef EWOULDBLOCK
74
#define EWOULDBLOCK WSAEWOULDBLOCK
75
#endif
76
#endif
77
78
#ifndef EPROTO
79
#define EPROTO EIO
80
#endif
81
82
#ifdef ENABLE_NLS
83
#include <libintl.h>
84
0
#define _(x) dgettext(PACKAGE_NAME, x)
85
#else
86
#define _(x) (x)
87
#endif
88
89
typedef struct {
90
  /* Never changes.  On Unix, these are identical, as it is
91
   * backed by a socket.  On Windows, it is another file
92
   * descriptor, as they are backed by two pipes */
93
  int read_fd;
94
  int write_fd;
95
96
  /* Protected by the lock */
97
  p11_mutex_t write_lock;
98
  int refs;
99
  int last_code;
100
101
  /* This data is protected by read mutex */
102
  p11_mutex_t read_lock;
103
#ifdef OS_UNIX
104
        /* Signalled when read_code changes */
105
        p11_cond_t read_code_cond;
106
#endif
107
  uint32_t read_code;
108
  uint32_t read_olen;
109
  uint32_t read_dlen;
110
} rpc_socket;
111
112
static rpc_socket *
113
rpc_socket_new (int fd)
114
0
{
115
0
  rpc_socket *sock;
116
117
0
  sock = calloc (1, sizeof (rpc_socket));
118
0
  return_val_if_fail (sock != NULL, NULL);
119
120
0
  sock->read_fd = fd;
121
0
  sock->write_fd = fd;
122
0
  sock->last_code = 0x10;
123
0
  sock->refs = 1;
124
125
0
  p11_mutex_init (&sock->write_lock);
126
0
  p11_mutex_init (&sock->read_lock);
127
128
0
#ifdef OS_UNIX
129
0
        p11_cond_init (&sock->read_code_cond);
130
0
#endif
131
132
0
  return sock;
133
0
}
134
135
#if 0
136
static rpc_socket *
137
rpc_socket_ref (rpc_socket *sock)
138
{
139
  assert (sock != NULL);
140
141
  p11_mutex_lock (&sock->write_lock);
142
  sock->refs++;
143
  p11_mutex_unlock (&sock->write_lock);
144
145
  return sock;
146
}
147
148
static bool
149
rpc_socket_is_open (rpc_socket *sock)
150
{
151
  assert (sock != NULL);
152
  return sock->read_fd >= 0;
153
}
154
#endif
155
156
static void
157
rpc_socket_close (rpc_socket *sock)
158
0
{
159
0
  assert (sock != NULL);
160
0
  if (sock->read_fd != -1)
161
0
    close (sock->read_fd);
162
0
  sock->read_fd = -1;
163
#ifdef OS_WIN32
164
  if (sock->write_fd != -1)
165
    close (sock->write_fd);
166
  sock->write_fd = -1;
167
#endif
168
0
}
169
170
static void
171
rpc_socket_unref (rpc_socket *sock)
172
0
{
173
0
  int release = 0;
174
175
0
  assert (sock != NULL);
176
177
0
  p11_mutex_lock (&sock->write_lock);
178
0
  if (--sock->refs == 0)
179
0
    release = 1;
180
0
  p11_mutex_unlock (&sock->write_lock);
181
182
0
  if (!release)
183
0
    return;
184
185
0
  assert (sock != NULL);
186
0
  assert (sock->refs == 0);
187
188
0
  rpc_socket_close (sock);
189
0
  p11_mutex_uninit (&sock->write_lock);
190
0
  p11_mutex_uninit (&sock->read_lock);
191
0
#ifdef OS_UNIX
192
0
        p11_cond_uninit (&sock->read_code_cond);
193
0
#endif
194
0
  free (sock);
195
0
}
196
197
static bool
198
write_all (int fd,
199
           unsigned char* data,
200
           size_t len)
201
0
{
202
0
  int r;
203
204
0
  while (len > 0) {
205
0
    r = write (fd, data, len);
206
0
    if (r == -1) {
207
0
      if (errno == EPIPE) {
208
0
        p11_message (_("couldn't send data: closed connection"));
209
0
        return false;
210
0
      } else if (errno != EAGAIN && errno != EINTR) {
211
0
        p11_message_err (errno, _("couldn't send data"));
212
0
        return false;
213
0
      }
214
0
    } else {
215
0
      p11_debug ("wrote %d bytes", r);
216
0
      data += r;
217
0
      len -= r;
218
0
    }
219
0
  }
220
221
0
  return true;
222
0
}
223
224
static bool
225
read_all (int fd,
226
          unsigned char* data,
227
          size_t len)
228
0
{
229
0
  int r;
230
231
0
  while (len > 0) {
232
0
    r = read (fd, data, len);
233
0
    if (r == 0) {
234
0
      p11_message (_("couldn't receive data: closed connection"));
235
0
      return false;
236
0
    } else if (r == -1) {
237
0
      if (errno != EAGAIN && errno != EINTR) {
238
0
        p11_message_err (errno, _("couldn't receive data"));
239
0
        return false;
240
0
      }
241
0
    } else {
242
0
      p11_debug ("read %d bytes", r);
243
0
      data += r;
244
0
      len -= r;
245
0
    }
246
0
  }
247
248
0
  return true;
249
0
}
250
251
static CK_RV
252
rpc_socket_write_inlock (rpc_socket *sock,
253
                         int code,
254
                         p11_buffer *options,
255
                         p11_buffer *buffer)
256
0
{
257
0
  unsigned char header[12];
258
259
  /* The socket is locked and referenced at this point */
260
0
  assert (buffer != NULL);
261
262
0
  p11_rpc_buffer_encode_uint32 (header, code);
263
0
  p11_rpc_buffer_encode_uint32 (header + 4, options->len);
264
0
  p11_rpc_buffer_encode_uint32 (header + 8, buffer->len);
265
266
0
  if (!write_all (sock->write_fd, header, 12) ||
267
0
      !write_all (sock->write_fd, options->data, options->len) ||
268
0
      !write_all (sock->write_fd, buffer->data, buffer->len))
269
0
    return CKR_DEVICE_ERROR;
270
271
0
  return CKR_OK;
272
0
}
273
274
static p11_rpc_status
275
write_at (int fd,
276
          unsigned char *data,
277
          size_t len,
278
          size_t offset,
279
          size_t *at)
280
0
{
281
0
  p11_rpc_status status;
282
0
  ssize_t num;
283
0
  size_t from;
284
0
  int errn;
285
286
0
  assert (*at >= offset);
287
288
0
  if (*at >= offset + len)
289
0
    return P11_RPC_OK;
290
291
0
  from = *at - offset;
292
0
  assert (from < len);
293
294
0
  num = write (fd, data + from, len - from);
295
0
  errn = errno;
296
297
  /* Update state */
298
0
  if (num > 0)
299
0
    *at += num;
300
301
  /* Completely written out this block */
302
0
  if (num == len - from) {
303
0
    p11_debug ("ok: wrote block of %d", (int)num);
304
0
    status = P11_RPC_OK;
305
306
  /* Partially written out this block */
307
0
  } else if (num >= 0) {
308
0
    p11_debug ("again: partial read of %d", (int)num);
309
0
    status = P11_RPC_AGAIN;
310
311
  /* Didn't write out block due to transient issue */
312
0
  } else if (errn == EINTR || errn == EAGAIN || errn == EWOULDBLOCK) {
313
0
    p11_debug ("again: due to %d", errn);
314
0
    status = P11_RPC_AGAIN;
315
316
  /* Failure */
317
0
  } else {
318
0
    p11_debug ("error: due to %d", errn);
319
0
    status = P11_RPC_ERROR;
320
0
  }
321
322
0
  errno = errn;
323
0
  return status;
324
0
}
325
326
p11_rpc_status
327
p11_rpc_transport_write (int fd,
328
                         size_t *state,
329
                         int call_code,
330
                         p11_buffer *options,
331
                         p11_buffer *buffer)
332
0
{
333
0
  unsigned char header[12] = { 0, };
334
0
  p11_rpc_status status;
335
336
0
  assert (state != NULL);
337
0
  assert (options != NULL);
338
0
  assert (buffer != NULL);
339
340
0
  if (*state < 12) {
341
0
    p11_rpc_buffer_encode_uint32 (header, call_code);
342
0
    p11_rpc_buffer_encode_uint32 (header + 4, options->len);
343
0
    p11_rpc_buffer_encode_uint32 (header + 8, buffer->len);
344
0
  }
345
346
0
  status = write_at (fd, header, 12, 0, state);
347
348
0
  if (status == P11_RPC_OK) {
349
0
    status = write_at (fd, options->data, options->len,
350
0
                       12, state);
351
0
  }
352
353
0
  if (status == P11_RPC_OK) {
354
0
    status = write_at (fd, buffer->data, buffer->len,
355
0
                       12 + options->len, state);
356
0
  }
357
358
  /* All done */
359
0
  if (status == P11_RPC_OK)
360
0
    *state = 0;
361
362
0
  return status;
363
0
}
364
365
static void
366
rpc_socket_set_read_code_inlock (rpc_socket *sock,
367
                                 int code)
368
0
{
369
0
        sock->read_code = code;
370
0
#ifdef OS_UNIX
371
0
        p11_cond_broadcast (&sock->read_code_cond);
372
0
#endif
373
0
}
374
375
#ifdef OS_UNIX
376
static void
377
rpc_socket_wait_for_read_code_change_inlock (rpc_socket *sock)
378
0
{
379
0
        p11_cond_wait (&sock->read_code_cond, &sock->read_lock);
380
0
}
381
#endif
382
383
static int
384
rpc_socket_read (rpc_socket *sock,
385
                 int *code,
386
                 p11_buffer *buffer)
387
0
{
388
0
  CK_RV ret = CKR_DEVICE_ERROR;
389
0
  unsigned char header[12];
390
#ifdef OS_WIN32
391
  HANDLE handle;
392
  DWORD mode;
393
#endif
394
395
0
  assert (code != NULL);
396
0
  assert (buffer != NULL);
397
398
  /*
399
   * We are not in the main socket lock here, but the socket
400
   * is referenced, and won't go away
401
   */
402
403
0
  p11_mutex_lock (&sock->read_lock);
404
405
0
  for (;;) {
406
    /* No message header has been read yet? ... read one in */
407
0
    if (sock->read_code == 0) {
408
0
      if (!read_all (sock->read_fd, header, 12))
409
0
        break;
410
411
      /* Decode and check the message header */
412
0
      rpc_socket_set_read_code_inlock (sock, p11_rpc_buffer_decode_uint32 (header));
413
0
      sock->read_olen = p11_rpc_buffer_decode_uint32 (header + 4);
414
0
      sock->read_dlen = p11_rpc_buffer_decode_uint32 (header + 8);
415
0
      if (sock->read_code == 0) {
416
0
        p11_message (_("received invalid rpc header values: perhaps wrong protocol"));
417
0
        break;
418
0
      }
419
0
    }
420
421
    /* If it's our header (or caller doesn't care), then yay! */
422
0
    if (*code == -1 || sock->read_code == *code) {
423
424
      /* We ignore the options, so read into the same as buffer */
425
0
      if (!p11_buffer_reset (buffer, sock->read_olen) ||
426
0
          !p11_buffer_reset (buffer, sock->read_dlen)) {
427
0
        warn_if_reached ();
428
0
        break;
429
0
      }
430
431
      /* Read in the the options first, and then data */
432
0
      if (!read_all (sock->read_fd, buffer->data, sock->read_olen) ||
433
0
          !read_all (sock->read_fd, buffer->data, sock->read_dlen))
434
0
        break;
435
436
0
      buffer->len = sock->read_dlen;
437
0
      *code = sock->read_code;
438
439
      /* Yay, we got our data, off we go */
440
0
                        rpc_socket_set_read_code_inlock (sock, 0);
441
0
      sock->read_olen = 0;
442
0
      sock->read_dlen = 0;
443
0
      ret = CKR_OK;
444
0
      break;
445
0
    }
446
447
    /* Give another thread the chance to read data for this header */
448
0
    if (sock->read_code != 0) {
449
0
      p11_debug ("received header in wrong thread");
450
451
0
#ifdef OS_UNIX
452
0
                        rpc_socket_wait_for_read_code_change_inlock (sock);
453
0
#endif
454
#ifdef OS_WIN32
455
      /* Used as a simple wait */
456
      p11_mutex_unlock (&sock->read_lock);
457
      handle = (HANDLE) _get_osfhandle (sock->read_fd);
458
      if (!ReadFile (handle, NULL, 0, &mode, NULL))
459
        p11_message (_("couldn't use select to wait on rpc pipe"));
460
      p11_mutex_lock (&sock->read_lock);
461
#endif
462
0
    }
463
0
  }
464
465
0
  p11_mutex_unlock (&sock->read_lock);
466
0
  return ret;
467
0
}
468
469
static p11_rpc_status
470
read_at (int fd,
471
         unsigned char *data,
472
         size_t len,
473
         size_t offset,
474
         size_t *at)
475
0
{
476
0
  p11_rpc_status status;
477
0
  int errn;
478
0
  ssize_t num;
479
0
  size_t from;
480
481
0
  assert (*at >= offset);
482
483
0
  if (*at >= offset + len)
484
0
    return P11_RPC_OK;
485
486
0
  from = *at - offset;
487
0
  assert (from < len);
488
489
0
  num = read (fd, data + from, len - from);
490
0
  errn = errno;
491
492
  /* Update state */
493
0
  if (num > 0)
494
0
    *at += num;
495
496
  /* Completely read out this block */
497
0
  if (num == len - from) {
498
0
    p11_debug ("ok: read block of %d", (int)num);
499
0
    status = P11_RPC_OK;
500
501
  /* Partially read out this block */
502
0
  } else if (num > 0) {
503
0
    p11_debug ("again: partial read of %d", (int)num);
504
0
    status = P11_RPC_AGAIN;
505
506
  /* End of file, valid if at offset zero */
507
0
  } else if (num == 0) {
508
0
    if (offset == 0) {
509
0
      p11_debug ("eof: read zero bytes");
510
0
      status = P11_RPC_EOF;
511
0
    } else {
512
0
      p11_debug ("error: early truncate");
513
0
      errn = EPROTO;
514
0
      status = P11_RPC_ERROR;
515
0
    }
516
517
  /* Didn't read out block due to transient issue */
518
0
  } else if (errn == EINTR || errn == EAGAIN || errn == EWOULDBLOCK) {
519
0
    p11_debug ("again: due to %d", errn);
520
0
    status = P11_RPC_AGAIN;
521
522
  /* Failure */
523
0
  } else {
524
0
    p11_debug ("error: due to %d", errn);
525
0
    status = P11_RPC_ERROR;
526
0
  }
527
528
0
  errno = errn;
529
0
  return status;
530
0
}
531
532
p11_rpc_status
533
p11_rpc_transport_read (int fd,
534
                        size_t *state,
535
                        int *call_code,
536
                        p11_buffer *options,
537
                        p11_buffer *buffer)
538
0
{
539
0
  unsigned char *header;
540
0
  p11_rpc_status status;
541
0
  size_t len;
542
543
0
  assert (state != NULL);
544
0
  assert (call_code != NULL);
545
0
  assert (options != NULL);
546
0
  assert (buffer != NULL);
547
548
  /* Reading the header, we read it into @buffer */
549
0
  if (*state < 12) {
550
0
    if (!p11_buffer_reset (buffer, 12))
551
0
      return_val_if_reached (P11_RPC_ERROR);
552
0
    status = read_at (fd, buffer->data, 12, 0, state);
553
0
    if (status != P11_RPC_OK)
554
0
      return status;
555
556
    /* Parse out the header */
557
0
    header = buffer->data;
558
0
    *call_code = p11_rpc_buffer_decode_uint32 (header);
559
0
    len = p11_rpc_buffer_decode_uint32 (header + 4);
560
0
    if (!p11_buffer_reset (options, len))
561
0
      return_val_if_reached (P11_RPC_ERROR);
562
0
    options->len = len;
563
0
    len = p11_rpc_buffer_decode_uint32 (header + 8);
564
0
    if (!p11_buffer_reset (buffer, len))
565
0
      return_val_if_reached (P11_RPC_ERROR);
566
0
    buffer->len = len;
567
0
  }
568
569
  /* At this point options has a valid len field */
570
0
  status = read_at (fd, options->data, options->len, 12, state);
571
0
  if (status == P11_RPC_OK) {
572
0
    status = read_at (fd, buffer->data, buffer->len,
573
0
                      12 + options->len, state);
574
0
  }
575
576
0
  if (status == P11_RPC_OK)
577
0
    *state = 0;
578
579
0
  return status;
580
0
}
581
582
struct _p11_rpc_transport {
583
  p11_rpc_client_vtable vtable;
584
  p11_destroyer destroyer;
585
  rpc_socket *socket;
586
  p11_buffer options;
587
};
588
589
static void
590
rpc_transport_disconnect (p11_rpc_client_vtable *vtable,
591
                          void *init_reserved)
592
0
{
593
0
  p11_rpc_transport *rpc = (p11_rpc_transport *)vtable;
594
595
0
  if (rpc->socket) {
596
0
    rpc_socket_close (rpc->socket);
597
0
    rpc_socket_unref (rpc->socket);
598
0
    rpc->socket = NULL;
599
0
  }
600
0
}
601
602
static bool
603
rpc_transport_init (p11_rpc_transport *rpc,
604
                    const char *module_name,
605
                    p11_destroyer destroyer)
606
0
{
607
0
  rpc->destroyer = destroyer;
608
609
0
  p11_buffer_init_null (&rpc->options, 0);
610
0
  p11_buffer_add (&rpc->options, module_name, -1);
611
0
  return_val_if_fail (p11_buffer_ok (&rpc->options), false);
612
613
0
  return true;
614
0
}
615
616
static void
617
rpc_transport_uninit (p11_rpc_transport *rpc)
618
0
{
619
0
  p11_buffer_uninit (&rpc->options);
620
0
}
621
622
static CK_RV
623
rpc_transport_authenticate (p11_rpc_client_vtable *vtable,
624
          uint8_t *version)
625
0
{
626
0
  p11_rpc_transport *rpc = (p11_rpc_transport *)vtable;
627
0
  rpc_socket *sock;
628
629
0
  assert (rpc != NULL);
630
0
  assert (version != NULL);
631
632
0
  sock = rpc->socket;
633
0
  assert (sock != NULL);
634
635
0
  if (sock->read_fd == -1) {
636
0
    return CKR_DEVICE_ERROR;
637
0
  }
638
#ifdef OS_WIN32
639
  if (sock->write_fd == -1) {
640
    return CKR_DEVICE_ERROR;
641
  }
642
#endif
643
644
0
  p11_debug ("authenticating with version %u", *version);
645
646
  /* Place holder byte, will later carry unix credentials (on some systems) */
647
0
  if (write_all (sock->write_fd, version, 1) != 1) {
648
0
    p11_message_err (errno, _("couldn't send socket credentials"));
649
0
    return CKR_DEVICE_ERROR;
650
0
  }
651
652
0
  if (read_all (sock->read_fd, version, 1) != 1) {
653
0
    p11_message_err (errno, _("couldn't receive socket credentials"));
654
0
    return CKR_DEVICE_ERROR;
655
0
  }
656
657
#if P11_RPC_PROTOCOL_VERSION_MINIMUM > 0
658
  if (*version < P11_RPC_PROTOCOL_VERSION_MINIMUM) {
659
    p11_message_err (errno, _("peer protocol version is too old"));
660
    return CKR_DEVICE_ERROR;
661
  }
662
#endif
663
664
0
  return CKR_OK;
665
0
}
666
667
static CK_RV
668
rpc_transport_buffer (p11_rpc_client_vtable *vtable,
669
                      p11_buffer *request,
670
                      p11_buffer *response)
671
0
{
672
0
  p11_rpc_transport *rpc = (p11_rpc_transport *)vtable;
673
0
  CK_RV rv = CKR_OK;
674
0
  rpc_socket *sock;
675
0
  int call_code;
676
677
0
  assert (rpc != NULL);
678
0
  assert (request != NULL);
679
0
  assert (response != NULL);
680
681
0
  sock = rpc->socket;
682
0
  assert (sock != NULL);
683
684
0
  p11_mutex_lock (&sock->write_lock);
685
0
  assert (sock->refs > 0);
686
0
  sock->refs++;
687
688
  /* Get the next socket reply code */
689
0
  call_code = sock->last_code++;
690
691
0
  if (sock->read_fd == -1)
692
0
    rv = CKR_DEVICE_ERROR;
693
#ifdef OS_WIN32
694
  if (sock->write_fd == -1)
695
    rv = CKR_DEVICE_ERROR;
696
#endif
697
0
  if (rv == CKR_OK)
698
0
    rv = rpc_socket_write_inlock (sock, call_code, &rpc->options, request);
699
700
  /* We unlock the socket mutex while reading a response */
701
0
  if (rv == CKR_OK) {
702
0
    p11_mutex_unlock (&sock->write_lock);
703
704
0
    rv = rpc_socket_read (sock, &call_code, response);
705
706
0
    p11_mutex_lock (&sock->write_lock);
707
0
  }
708
709
0
  if (rv != CKR_OK && sock->read_fd != -1) {
710
0
    p11_message (_("closing socket due to protocol failure"));
711
0
    close (sock->read_fd);
712
0
    sock->read_fd = -1;
713
0
  }
714
#ifdef OS_WIN32
715
  if (rv != CKR_OK && sock->write_fd != -1) {
716
    p11_message (_("closing socket due to protocol failure"));
717
    close (sock->write_fd);
718
    sock->write_fd = -1;
719
  }
720
#endif
721
722
0
  sock->refs--;
723
0
  assert (sock->refs > 0);
724
0
  p11_mutex_unlock (&sock->write_lock);
725
726
0
  return rv;
727
0
}
728
729
#ifdef OS_UNIX
730
731
typedef struct {
732
  p11_rpc_transport base;
733
  p11_array *argv;
734
  pid_t pid;
735
} rpc_exec;
736
737
static void
738
rpc_exec_wait_or_terminate (pid_t pid)
739
0
{
740
0
  bool terminated = false;
741
0
  int status;
742
0
  int sig;
743
0
  int ret;
744
0
  int i;
745
746
747
0
  for (i = 0; i < 3 * 1000; i += 100) {
748
0
    ret = waitpid (pid, &status, WNOHANG);
749
0
    if (ret != 0)
750
0
      break;
751
0
    p11_sleep_ms (100);
752
0
  }
753
754
0
  if (ret == 0) {
755
0
    p11_message (_("process %d did not exit, terminating"), (int)pid);
756
0
    kill (pid, SIGTERM);
757
0
    terminated = true;
758
0
    ret = waitpid (pid, &status, 0);
759
0
  }
760
761
0
  if (ret < 0) {
762
0
    p11_message_err (errno, _("failed to wait for executed child: %d"), (int)pid);
763
0
    status = 0;
764
0
  } else if (WIFEXITED (status)) {
765
0
    status = WEXITSTATUS (status);
766
0
    if (status == 0)
767
0
      p11_debug ("process %d exited with status 0", (int)pid);
768
0
    else
769
0
      p11_message (_("process %d exited with status %d"), (int)pid, status);
770
0
  } else if (WIFSIGNALED (status)) {
771
0
    sig = WTERMSIG (status);
772
0
    if (!terminated || sig != SIGTERM)
773
0
      p11_message (_("process %d was terminated with signal %d"), (int)pid, sig);
774
0
  }
775
0
}
776
777
static void
778
rpc_exec_disconnect (p11_rpc_client_vtable *vtable,
779
                     void *fini_reserved)
780
0
{
781
0
  rpc_exec *rex = (rpc_exec *)vtable;
782
783
0
  if (rex->base.socket)
784
0
    rpc_socket_close (rex->base.socket);
785
786
0
  if (rex->pid)
787
0
    rpc_exec_wait_or_terminate (rex->pid);
788
0
  rex->pid = 0;
789
790
  /* Do the common disconnect stuff */
791
0
  rpc_transport_disconnect (vtable, fini_reserved);
792
0
}
793
794
static int
795
set_cloexec_on_fd (void *data,
796
                   int fd)
797
0
{
798
0
  int *max_fd = data;
799
0
  if (fd >= *max_fd)
800
0
    fcntl (fd, F_SETFD, FD_CLOEXEC);
801
0
  return 0;
802
0
}
803
804
static CK_RV
805
rpc_exec_connect (p11_rpc_client_vtable *vtable,
806
                  void *init_reserved)
807
0
{
808
0
  rpc_exec *rex = (rpc_exec *)vtable;
809
0
  pid_t pid;
810
0
  int max_fd;
811
0
  int fds[2];
812
0
  int errn;
813
814
0
  p11_debug ("executing rpc transport: %s", (char *)rex->argv->elem[0]);
815
816
0
  if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
817
0
    p11_message_err (errno, _("failed to create pipe for remote"));
818
0
    return CKR_DEVICE_ERROR;
819
0
  }
820
821
0
  pid = fork ();
822
0
  switch (pid) {
823
824
  /* Failure */
825
0
  case -1:
826
0
    close (fds[0]);
827
0
    close (fds[1]);
828
0
    p11_message_err (errno, _("failed to fork for remote"));
829
0
    return CKR_DEVICE_ERROR;
830
831
  /* Child */
832
0
  case 0:
833
0
    if (dup2 (fds[1], STDIN_FILENO) < 0 ||
834
0
        dup2 (fds[1], STDOUT_FILENO) < 0) {
835
0
      errn = errno;
836
0
      p11_message_err (errn, "couldn't dup file descriptors in remote child");
837
0
      _exit (errn);
838
0
    }
839
840
    /* Close file descriptors, except for above on exec */
841
0
    max_fd = STDERR_FILENO + 1;
842
0
    fdwalk (set_cloexec_on_fd, &max_fd);
843
0
    execvp (rex->argv->elem[0], (char **)rex->argv->elem);
844
845
0
    errn = errno;
846
0
    p11_message_err (errn, "couldn't execute program for rpc: %s",
847
0
                     (char *)rex->argv->elem[0]);
848
0
    _exit (errn);
849
850
  /* The parent */
851
0
  default:
852
0
    break;
853
0
  }
854
855
0
  close (fds[1]);
856
0
  rex->pid = pid;
857
0
  rex->base.socket = rpc_socket_new (fds[0]);
858
0
  return_val_if_fail (rex->base.socket != NULL, CKR_GENERAL_ERROR);
859
860
0
  return CKR_OK;
861
0
}
862
863
#endif /* OS_UNIX */
864
865
#ifdef OS_WIN32
866
867
typedef struct {
868
  p11_rpc_transport base;
869
  p11_array *argv;
870
  HANDLE pid;
871
} rpc_exec;
872
873
static void
874
rpc_exec_wait_or_terminate (HANDLE pid)
875
{
876
  DWORD status;
877
  int ret;
878
  int i;
879
880
881
  for (i = 0; i < 3 * 1000; i += 100) {
882
    ret = WaitForSingleObject (pid, 10000);
883
    if (ret == WAIT_OBJECT_0)
884
      break;
885
  }
886
887
  if (ret != WAIT_OBJECT_0) {
888
    p11_message (_("process %p did not exit, terminating"), pid);
889
    if (!TerminateProcess (pid, SIGTERM))
890
      p11_message (_("couldn't terminate process %p"), pid);
891
    ret = WaitForSingleObject (pid, 0);
892
  }
893
894
  if (ret != WAIT_OBJECT_0) {
895
    p11_message (_("failed to wait for executed child: %p"), pid);
896
    status = 0;
897
  } else if (!GetExitCodeProcess (pid, &status)) {
898
    p11_message (_("failed to get the exit status of %p"), pid);
899
  } else if (status == 0) {
900
    p11_debug ("process %p exited with status 0", pid);
901
  } else {
902
    p11_message (_("process %p exited with status %lu"), pid, status);
903
  }
904
905
  CloseHandle (pid);
906
}
907
908
static void
909
rpc_exec_disconnect (p11_rpc_client_vtable *vtable,
910
                     void *fini_reserved)
911
{
912
  rpc_exec *rex = (rpc_exec *)vtable;
913
914
  if (rex->base.socket)
915
    rpc_socket_close (rex->base.socket);
916
917
  if (rex->pid != INVALID_HANDLE_VALUE)
918
    rpc_exec_wait_or_terminate (rex->pid);
919
  rex->pid = INVALID_HANDLE_VALUE;
920
921
  /* Do the common disconnect stuff */
922
  rpc_transport_disconnect (vtable, fini_reserved);
923
}
924
925
static int
926
set_cloexec_on_fd (int fd)
927
{
928
  HANDLE handle;
929
930
  handle = (HANDLE) _get_osfhandle (fd);
931
  if (!SetHandleInformation (handle, HANDLE_FLAG_INHERIT, 0))
932
    return -1;
933
934
  return 0;
935
}
936
937
static CK_RV
938
rpc_exec_connect (p11_rpc_client_vtable *vtable,
939
                  void *init_reserved)
940
{
941
  rpc_exec *rex = (rpc_exec *)vtable;
942
  intptr_t pid = -1;
943
  int pw[2] = { -1, -1 }, pr[2] = { -1, -1 };
944
  int fds[2] = { -1, -1 };
945
  CK_RV rv = CKR_OK;
946
947
  p11_debug ("executing rpc transport: %s", (char *)rex->argv->elem[0]);
948
949
  setvbuf (stdout, NULL, _IONBF, 0 );
950
951
  if (_pipe (pw, 256, _O_BINARY) == -1 ||
952
      set_cloexec_on_fd (pw[1]) == -1) {
953
    p11_message_err (errno, _("failed to create pipe for remote"));
954
    rv = CKR_DEVICE_ERROR;
955
    goto out;
956
  }
957
958
  if (_pipe (pr, 256, _O_BINARY) == -1 ||
959
      set_cloexec_on_fd (pr[0]) == -1) {
960
    p11_message_err (errno, _("failed to create pipe for remote"));
961
    rv = CKR_DEVICE_ERROR;
962
    goto out;
963
  }
964
965
  /* Save the original stdin and stdout */
966
  fds[0] = dup (STDIN_FILENO);
967
  if (fds[0] == -1) {
968
    p11_message_err (errno, _("failed to duplicate stdin"));
969
    rv = CKR_DEVICE_ERROR;
970
    goto out;
971
  }
972
973
  fds[1] = dup (STDOUT_FILENO);
974
  if (fds[1] == -1) {
975
    p11_message_err (errno, _("failed to duplicate stdout"));
976
    rv = CKR_DEVICE_ERROR;
977
    goto out;
978
  }
979
980
  /* Temporarily redirect pipe descriptors to stdin/stdout for child */
981
  if (dup2 (pw[0], STDIN_FILENO) == -1 ||
982
      dup2 (pr[1], STDOUT_FILENO) == -1) {
983
    p11_message_err (errno, _("failed to duplicate child end of pipe"));
984
    rv = CKR_DEVICE_ERROR;
985
    goto out;
986
  }
987
988
  pid = _spawnv (P_NOWAIT,
989
           rex->argv->elem[0],
990
           (const char * const *)rex->argv->elem);
991
992
  if (pid == -1) {
993
    p11_message_err (errno, _("failed to spawn remote"));
994
    rv = CKR_DEVICE_ERROR;
995
    goto out;
996
  }
997
998
  close (pw[0]);
999
  pw[0] = -1;
1000
  close (pr[1]);
1001
  pr[1] = -1;
1002
1003
  /* Restore the original stdin and stdout */
1004
  if (dup2 (fds[0], STDIN_FILENO) == -1 ||
1005
      dup2 (fds[1], STDOUT_FILENO) == -1) {
1006
    p11_message_err (errno, _("failed to restore file descriptors"));
1007
    rv = CKR_DEVICE_ERROR;
1008
    goto out;
1009
  }
1010
1011
  close (fds[0]);
1012
  fds[0] = -1;
1013
  close (fds[1]);
1014
  fds[1] = -1;
1015
1016
  rex->pid = (HANDLE) pid;
1017
  rex->base.socket = rpc_socket_new (pr[0]);
1018
  return_val_if_fail (rex->base.socket != NULL, CKR_GENERAL_ERROR);
1019
  rex->base.socket->write_fd = pw[1];
1020
1021
 out:
1022
  if (rv != CKR_OK) {
1023
    if (pid != -1) {
1024
      TerminateProcess ((HANDLE) pid, SIGTERM);
1025
      CloseHandle ((HANDLE) pid);
1026
    }
1027
    if (pw[0] != -1)
1028
      close (pw[0]);
1029
    if (pw[1] != -1)
1030
      close (pw[1]);
1031
    if (pr[0] != -1)
1032
      close (pr[0]);
1033
    if (pr[1] != -1)
1034
      close (pr[1]);
1035
    if (fds[0] != -1)
1036
      close (fds[0]);
1037
    if (fds[1] != -1)
1038
      close (fds[1]);
1039
  }
1040
1041
  return rv;
1042
}
1043
1044
#endif /* OS_WIN32 */
1045
1046
static void
1047
rpc_exec_free (void *data)
1048
0
{
1049
0
  rpc_exec *rex = data;
1050
0
  rpc_exec_disconnect (data, NULL);
1051
0
  rpc_transport_uninit (&rex->base);
1052
0
  p11_array_free (rex->argv);
1053
0
  free (rex);
1054
0
}
1055
1056
static void
1057
on_argv_parsed (char *argument,
1058
                void *data)
1059
0
{
1060
0
  p11_array *argv = data;
1061
1062
0
  if (!p11_array_push (argv, strdup (argument)))
1063
0
    return_if_reached ();
1064
0
}
1065
1066
static p11_rpc_transport *
1067
rpc_exec_init (const char *remote,
1068
               const char *name)
1069
0
{
1070
0
  p11_array *argv;
1071
0
  rpc_exec *rex;
1072
1073
0
  argv = p11_array_new (free);
1074
0
  if (!p11_argv_parse (remote, on_argv_parsed, argv) || argv->num < 1) {
1075
0
    p11_message (_("invalid remote command line: %s"), remote);
1076
0
    p11_array_free (argv);
1077
0
    return NULL;
1078
0
  }
1079
1080
0
  rex = calloc (1, sizeof (rpc_exec));
1081
0
  return_val_if_fail (rex != NULL, NULL);
1082
1083
0
  p11_array_push (argv, NULL);
1084
0
  rex->argv = argv;
1085
#ifdef OS_WIN32
1086
  rex->pid = INVALID_HANDLE_VALUE;
1087
#endif
1088
1089
0
  rex->base.vtable.connect = rpc_exec_connect;
1090
0
  rex->base.vtable.disconnect = rpc_exec_disconnect;
1091
0
  rex->base.vtable.authenticate = rpc_transport_authenticate;
1092
0
  rex->base.vtable.transport = rpc_transport_buffer;
1093
0
  rpc_transport_init (&rex->base, name, rpc_exec_free);
1094
1095
0
  p11_debug ("initialized rpc exec: %s", remote);
1096
0
  return &rex->base;
1097
0
}
1098
1099
#ifdef OS_UNIX
1100
1101
typedef struct {
1102
  p11_rpc_transport base;
1103
  struct sockaddr_un sa;
1104
} rpc_unix;
1105
1106
static CK_RV
1107
rpc_unix_connect (p11_rpc_client_vtable *vtable,
1108
        void *init_reserved)
1109
0
{
1110
0
  rpc_unix *run = (rpc_unix *)vtable;
1111
0
  int fd;
1112
1113
0
  fd = socket (AF_UNIX, SOCK_STREAM, 0);
1114
0
  if (fd < 0) {
1115
0
    p11_message_err (errno, _("failed to create socket for remote"));
1116
0
    return CKR_GENERAL_ERROR;
1117
0
  }
1118
1119
0
  if (connect (fd, (struct sockaddr *)&run->sa, sizeof (run->sa)) < 0) {
1120
0
    p11_debug_err (errno, "failed to connect to socket");
1121
0
    close (fd);
1122
0
    return CKR_DEVICE_REMOVED;
1123
0
  }
1124
1125
0
  run->base.socket = rpc_socket_new (fd);
1126
0
  return_val_if_fail (run->base.socket != NULL, CKR_GENERAL_ERROR);
1127
1128
0
  return CKR_OK;
1129
0
}
1130
1131
static void
1132
rpc_unix_disconnect (p11_rpc_client_vtable *vtable,
1133
                     void *fini_reserved)
1134
0
{
1135
0
  rpc_unix *run = (rpc_unix *)vtable;
1136
1137
0
  if (run->base.socket)
1138
0
    rpc_socket_close (run->base.socket);
1139
1140
  /* Do the common disconnect stuff */
1141
0
  rpc_transport_disconnect (vtable, fini_reserved);
1142
0
}
1143
1144
static void
1145
rpc_unix_free (void *data)
1146
0
{
1147
0
  rpc_unix *run = data;
1148
0
  rpc_unix_disconnect (data, NULL);
1149
0
  rpc_transport_uninit (&run->base);
1150
0
  free (run);
1151
0
}
1152
1153
static p11_rpc_transport *
1154
rpc_unix_init (const char *remote,
1155
         const char *name)
1156
0
{
1157
0
  rpc_unix *run;
1158
1159
0
  run = calloc (1, sizeof (rpc_unix));
1160
0
  return_val_if_fail (run != NULL, NULL);
1161
1162
0
  memset (&run->sa, 0, sizeof (run->sa));
1163
0
  run->sa.sun_family = AF_UNIX;
1164
0
  snprintf (run->sa.sun_path, sizeof (run->sa.sun_path), "%s", remote);
1165
1166
0
  run->base.vtable.connect = rpc_unix_connect;
1167
0
  run->base.vtable.disconnect = rpc_unix_disconnect;
1168
0
  run->base.vtable.authenticate = rpc_transport_authenticate;
1169
0
  run->base.vtable.transport = rpc_transport_buffer;
1170
0
  rpc_transport_init (&run->base, name, rpc_unix_free);
1171
1172
0
  p11_debug ("initialized rpc socket: %s", remote);
1173
0
  return &run->base;
1174
0
}
1175
1176
#endif /* OS_UNIX */
1177
1178
#ifdef HAVE_VSOCK
1179
#include <linux/vm_sockets.h>
1180
#include <vsock.h>
1181
1182
typedef struct {
1183
  p11_rpc_transport base;
1184
  struct sockaddr_vm sa;
1185
} rpc_vsock;
1186
1187
static CK_RV
1188
rpc_vsock_connect (p11_rpc_client_vtable *vtable,
1189
       void *init_reserved)
1190
0
{
1191
0
  rpc_vsock *run = (rpc_vsock *)vtable;
1192
0
  int fd;
1193
1194
0
  fd = socket (AF_VSOCK, SOCK_STREAM, 0);
1195
0
  if (fd < 0) {
1196
0
    p11_message_err (errno, _("failed to create socket for remote"));
1197
0
    return CKR_GENERAL_ERROR;
1198
0
  }
1199
1200
0
  if (connect (fd, (struct sockaddr *)&run->sa, sizeof (run->sa)) < 0) {
1201
0
    p11_debug_err (errno, "failed to connect to socket");
1202
0
    close (fd);
1203
0
    return CKR_DEVICE_REMOVED;
1204
0
  }
1205
1206
0
  run->base.socket = rpc_socket_new (fd);
1207
0
  return_val_if_fail (run->base.socket != NULL, CKR_GENERAL_ERROR);
1208
1209
0
  return CKR_OK;
1210
0
}
1211
1212
static void
1213
rpc_vsock_disconnect (p11_rpc_client_vtable *vtable,
1214
                      void *fini_reserved)
1215
0
{
1216
0
  rpc_vsock *run = (rpc_vsock *)vtable;
1217
1218
0
  if (run->base.socket)
1219
0
    rpc_socket_close (run->base.socket);
1220
1221
  /* Do the common disconnect stuff */
1222
0
  rpc_transport_disconnect (vtable, fini_reserved);
1223
0
}
1224
1225
static void
1226
rpc_vsock_free (void *data)
1227
0
{
1228
0
  rpc_vsock *run = data;
1229
0
  rpc_vsock_disconnect (data, NULL);
1230
0
  rpc_transport_uninit (&run->base);
1231
0
  free (run);
1232
0
}
1233
1234
static p11_rpc_transport *
1235
rpc_vsock_init (unsigned int cid,
1236
    unsigned int port,
1237
    const char *name)
1238
0
{
1239
0
  rpc_vsock *run;
1240
1241
0
  run = calloc (1, sizeof (rpc_vsock));
1242
0
  return_val_if_fail (run != NULL, NULL);
1243
1244
0
  memset (&run->sa, 0, sizeof (run->sa));
1245
0
  run->sa.svm_family = AF_VSOCK;
1246
0
  run->sa.svm_cid = cid;
1247
0
  run->sa.svm_port = port;
1248
1249
0
  run->base.vtable.connect = rpc_vsock_connect;
1250
0
  run->base.vtable.disconnect = rpc_vsock_disconnect;
1251
0
  run->base.vtable.authenticate = rpc_transport_authenticate;
1252
0
  run->base.vtable.transport = rpc_transport_buffer;
1253
0
  rpc_transport_init (&run->base, name, rpc_vsock_free);
1254
1255
0
  p11_debug ("initialized rpc socket: vsock:cid=%u;port=%u",
1256
0
       cid, port);
1257
0
  return &run->base;
1258
0
}
1259
1260
#endif /* HAVE_VSOCK */
1261
1262
p11_rpc_transport *
1263
p11_rpc_transport_new (p11_virtual *virt,
1264
                       const char *remote,
1265
                       const char *name)
1266
0
{
1267
0
  p11_rpc_transport *rpc = NULL;
1268
1269
0
  return_val_if_fail (virt != NULL, NULL);
1270
0
  return_val_if_fail (remote != NULL, NULL);
1271
0
  return_val_if_fail (name != NULL, NULL);
1272
1273
  /* This is a command we can execute */
1274
0
  if (remote[0] == '|') {
1275
0
    rpc = rpc_exec_init (remote + 1, name);
1276
1277
0
#ifdef OS_UNIX
1278
0
  } else if (strncmp (remote, "unix:path=/", 11) == 0) {
1279
    /* Only absolute path is supported */
1280
0
    char *path;
1281
1282
0
    path = p11_path_decode (remote + 10);
1283
0
    return_val_if_fail (path != NULL, NULL);
1284
0
    rpc = rpc_unix_init (path, name);
1285
0
    free (path);
1286
0
#endif /* OS_UNIX */
1287
0
#ifdef HAVE_VSOCK
1288
0
  } else if (strncmp (remote, "vsock:", 6) == 0) {
1289
0
    unsigned int cid = 0, port = 0;
1290
1291
0
    if (!p11_vsock_parse_addr (remote + 6, &cid, &port) ||
1292
0
        cid == VMADDR_CID_ANY) {
1293
0
      p11_message (_("failed to parse vsock address: '%s'"),
1294
0
             remote + 6);
1295
0
      return NULL;
1296
0
    }
1297
1298
0
    rpc = rpc_vsock_init (cid, port, name);
1299
0
#endif /* HAVE_VSOCK */
1300
0
  } else {
1301
0
    p11_message (_("remote not supported: %s"), remote);
1302
0
    return NULL;
1303
0
  }
1304
1305
0
  return_val_if_fail (rpc != NULL, NULL);
1306
1307
0
  if (!p11_rpc_client_init (virt, &rpc->vtable))
1308
0
    return_val_if_reached (NULL);
1309
1310
0
  return rpc;
1311
0
}
1312
1313
void
1314
p11_rpc_transport_free (void *data)
1315
0
{
1316
0
  p11_rpc_transport *rpc = data;
1317
1318
0
  if (rpc != NULL) {
1319
0
    assert (rpc->destroyer);
1320
0
    (rpc->destroyer) (data);
1321
0
  }
1322
0
}