Postfix3.3.1
tls_prng_egd.c
[詳解]
1 /*++
2 /* NAME
3 /* tls_prng_egd 3
4 /* SUMMARY
5 /* seed OpenSSL PRNG from EGD server
6 /* SYNOPSIS
7 /* #include <tls_prng_src.h>
8 /*
9 /* TLS_PRNG_SRC *tls_prng_egd_open(name, timeout)
10 /* const char *name;
11 /* int timeout;
12 /*
13 /* ssize_t tls_prng_egd_read(egd, length)
14 /* TLS_PRNG_SRC *egd;
15 /* size_t length;
16 /*
17 /* int tls_prng_egd_close(egd)
18 /* TLS_PRNG_SRC *egd;
19 /* DESCRIPTION
20 /* tls_prng_egd_open() connect to the specified UNIX-domain service
21 /* and returns a handle that should be used with all subsequent
22 /* access.
23 /*
24 /* tls_prng_egd_read() reads the requested number of bytes from
25 /* the EGD server and updates the OpenSSL PRNG.
26 /*
27 /* tls_prng_egd_close() disconnects from the specified EGD server
28 /* and releases memory that was allocated for the handle.
29 /*
30 /* Arguments:
31 /* .IP name
32 /* The UNIX-domain pathname of the EGD service.
33 /* .IP length
34 /* The number of bytes to read from the EGD server.
35 /* Request lengths will be truncated at 255 bytes.
36 /* .IP timeout
37 /* Time limit on individual I/O operations.
38 /* DIAGNOSTICS
39 /* tls_prng_egd_open() returns a null pointer on error.
40 /*
41 /* tls_prng_egd_read() returns -1 on error, the number
42 /* of bytes received on success.
43 /*
44 /* tls_prng_egd_close() returns -1 on error, 0 on success.
45 /*
46 /* In all cases the errno variable indicates the type of error.
47 /* LICENSE
48 /* .ad
49 /* .fi
50 /* The Secure Mailer license must be distributed with this software.
51 /* AUTHOR(S)
52 /* Wietse Venema
53 /* IBM T.J. Watson Research
54 /* P.O. Box 704
55 /* Yorktown Heights, NY 10598, USA
56 /*--*/
57 
58 /* System library. */
59 
60 #include <sys_defs.h>
61 #include <unistd.h>
62 #include <limits.h>
63 
64 #ifndef UCHAR_MAX
65 #define UCHAR_MAX 0xff
66 #endif
67 
68 /* OpenSSL library. */
69 
70 #ifdef USE_TLS
71 #include <openssl/rand.h> /* For the PRNG */
72 
73 /* Utility library. */
74 
75 #include <msg.h>
76 #include <mymalloc.h>
77 #include <connect.h>
78 #include <iostuff.h>
79 
80 /* TLS library. */
81 
82 #include <tls_prng.h>
83 
84 /* tls_prng_egd_open - connect to EGD server */
85 
86 TLS_PRNG_SRC *tls_prng_egd_open(const char *name, int timeout)
87 {
88  const char *myname = "tls_prng_egd_open";
89  TLS_PRNG_SRC *egd;
90  int fd;
91 
92  if (msg_verbose)
93  msg_info("%s: connect to EGD server %s", myname, name);
94 
95  if ((fd = unix_connect(name, BLOCKING, timeout)) < 0) {
96  if (msg_verbose)
97  msg_info("%s: cannot connect to EGD server %s: %m", myname, name);
98  return (0);
99  } else {
100  egd = (TLS_PRNG_SRC *) mymalloc(sizeof(*egd));
101  egd->fd = fd;
102  egd->name = mystrdup(name);
103  egd->timeout = timeout;
104  if (msg_verbose)
105  msg_info("%s: connected to EGD server %s", myname, name);
106  return (egd);
107  }
108 }
109 
110 /* tls_prng_egd_read - update internal PRNG from EGD server */
111 
112 ssize_t tls_prng_egd_read(TLS_PRNG_SRC *egd, size_t len)
113 {
114  const char *myname = "tls_prng_egd_read";
115  unsigned char buffer[UCHAR_MAX];
116  ssize_t count;
117 
118  if (len <= 0)
119  msg_panic("%s: bad length %ld", myname, (long) len);
120 
121  buffer[0] = 1;
122  buffer[1] = (len > UCHAR_MAX ? UCHAR_MAX : len);
123 
124  if (timed_write(egd->fd, buffer, 2, egd->timeout, (void *) 0) != 2) {
125  msg_info("cannot write to EGD server %s: %m", egd->name);
126  return (-1);
127  }
128  if (timed_read(egd->fd, buffer, 1, egd->timeout, (void *) 0) != 1) {
129  msg_info("cannot read from EGD server %s: %m", egd->name);
130  return (-1);
131  }
132  count = buffer[0];
133  if (count > sizeof(buffer))
134  count = sizeof(buffer);
135  if (count == 0) {
136  msg_info("EGD server %s reports zero bytes available", egd->name);
137  return (-1);
138  }
139  if (timed_read(egd->fd, buffer, count, egd->timeout, (void *) 0) != count) {
140  msg_info("cannot read %ld bytes from EGD server %s: %m",
141  (long) count, egd->name);
142  return (-1);
143  }
144  if (msg_verbose)
145  msg_info("%s: got %ld bytes from EGD server %s", myname,
146  (long) count, egd->name);
147  RAND_seed(buffer, count);
148  return (count);
149 }
150 
151 /* tls_prng_egd_close - disconnect from EGD server */
152 
154 {
155  const char *myname = "tls_prng_egd_close";
156  int err;
157 
158  if (msg_verbose)
159  msg_info("%s: close EGD server %s", myname, egd->name);
160  err = close(egd->fd);
161  myfree(egd->name);
162  myfree((void *) egd);
163  return (err);
164 }
165 
166 #endif
int msg_verbose
Definition: msg.c:177
void myfree(void *ptr)
Definition: mymalloc.c:207
char * mystrdup(const char *str)
Definition: mymalloc.c:225
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define UCHAR_MAX
Definition: tls_prng_egd.c:65
char * name
Definition: tls_prng.h:19
int unix_connect(const char *, int, int)
Definition: unix_connect.c:59
ssize_t timed_read(int, void *, size_t, int, void *)
Definition: timed_read.c:60
int tls_prng_egd_close(TLS_PRNG_SRC *)
ssize_t timed_write(int, const void *, size_t, int, void *)
Definition: timed_write.c:60
int timeout
Definition: tls_prng.h:20
ssize_t tls_prng_egd_read(TLS_PRNG_SRC *, size_t)
TLS_PRNG_SRC * tls_prng_egd_open(const char *, int)
#define BLOCKING
Definition: iostuff.h:48
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
void msg_info(const char *fmt,...)
Definition: msg.c:199