Postfix3.3.1
tls_prng_exch.c
[詳解]
1 /*++
2 /* NAME
3 /* tls_prng_exch 3
4 /* SUMMARY
5 /* maintain PRNG exchange file
6 /* SYNOPSIS
7 /* #include <tls_prng_src.h>
8 /*
9 /* TLS_PRNG_SRC *tls_prng_exch_open(name, timeout)
10 /* const char *name;
11 /* int timeout;
12 /*
13 /* void tls_prng_exch_update(fh, length)
14 /* TLS_PRNG_SRC *fh;
15 /* size_t length;
16 /*
17 /* void tls_prng_exch_close(fh)
18 /* TLS_PRNG_SRC *fh;
19 /* DESCRIPTION
20 /* tls_prng_exch_open() opens the specified PRNG exchange file
21 /* and returns a handle that should be used with all subsequent
22 /* access.
23 /*
24 /* tls_prng_exch_update() reads the requested number of bytes
25 /* from the PRNG exchange file, updates the OpenSSL PRNG, and
26 /* writes the requested number of bytes to the exchange file.
27 /* The file is locked for exclusive access.
28 /*
29 /* tls_prng_exch_close() closes the specified PRNG exchange
30 /* file and releases memory that was allocated for the handle.
31 /*
32 /* Arguments:
33 /* .IP name
34 /* The name of the PRNG exchange file.
35 /* .IP length
36 /* The number of bytes to read from/write to the entropy file.
37 /* .IP timeout
38 /* Time limit on individual I/O operations.
39 /* DIAGNOSTICS
40 /* All errors are fatal.
41 /* LICENSE
42 /* .ad
43 /* .fi
44 /* The Secure Mailer license must be distributed with this software.
45 /* AUTHOR(S)
46 /* Wietse Venema
47 /* IBM T.J. Watson Research
48 /* P.O. Box 704
49 /* Yorktown Heights, NY 10598, USA
50 /*--*/
51 
52 /* System library. */
53 
54 #include <sys_defs.h>
55 #include <fcntl.h>
56 #include <unistd.h>
57 #include <limits.h>
58 
59 /* OpenSSL library. */
60 
61 #ifdef USE_TLS
62 #include <openssl/rand.h> /* For the PRNG */
63 
64 /* Utility library. */
65 
66 #include <msg.h>
67 #include <mymalloc.h>
68 #include <iostuff.h>
69 #include <myflock.h>
70 
71 /* TLS library. */
72 
73 #include <tls_prng.h>
74 
75 /* Application specific. */
76 
77 #define TLS_PRNG_EXCH_SIZE 1024 /* XXX Why not configurable? */
78 
79 /* tls_prng_exch_open - open PRNG exchange file */
80 
81 TLS_PRNG_SRC *tls_prng_exch_open(const char *name)
82 {
83  const char *myname = "tls_prng_exch_open";
84  TLS_PRNG_SRC *eh;
85  int fd;
86 
87  if ((fd = open(name, O_RDWR | O_CREAT, 0600)) < 0)
88  msg_fatal("%s: cannot open PRNG exchange file %s: %m", myname, name);
89  eh = (TLS_PRNG_SRC *) mymalloc(sizeof(*eh));
90  eh->fd = fd;
91  eh->name = mystrdup(name);
92  eh->timeout = 0;
93  if (msg_verbose)
94  msg_info("%s: opened PRNG exchange file %s", myname, name);
95  return (eh);
96 }
97 
98 /* tls_prng_exch_update - update PRNG exchange file */
99 
101 {
102  unsigned char buffer[TLS_PRNG_EXCH_SIZE];
103  ssize_t count;
104 
105  /*
106  * Update the PRNG exchange file. Since other processes may have added
107  * entropy, we use a read-stir-write cycle.
108  */
109  if (myflock(eh->fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) != 0)
110  msg_fatal("cannot lock PRNG exchange file %s: %m", eh->name);
111  if (lseek(eh->fd, 0, SEEK_SET) < 0)
112  msg_fatal("cannot seek PRNG exchange file %s: %m", eh->name);
113  if ((count = read(eh->fd, buffer, sizeof(buffer))) < 0)
114  msg_fatal("cannot read PRNG exchange file %s: %m", eh->name);
115 
116  if (count > 0)
117  RAND_seed(buffer, count);
118  RAND_bytes(buffer, sizeof(buffer));
119 
120  if (lseek(eh->fd, 0, SEEK_SET) < 0)
121  msg_fatal("cannot seek PRNG exchange file %s: %m", eh->name);
122  if (write(eh->fd, buffer, sizeof(buffer)) != sizeof(buffer))
123  msg_fatal("cannot write PRNG exchange file %s: %m", eh->name);
124  if (myflock(eh->fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) != 0)
125  msg_fatal("cannot unlock PRNG exchange file %s: %m", eh->name);
126 }
127 
128 /* tls_prng_exch_close - close PRNG exchange file */
129 
131 {
132  const char *myname = "tls_prng_exch_close";
133 
134  if (close(eh->fd) < 0)
135  msg_fatal("close PRNG exchange file %s: %m", eh->name);
136  if (msg_verbose)
137  msg_info("%s: closed PRNG exchange file %s", myname, eh->name);
138  myfree(eh->name);
139  myfree((void *) eh);
140 }
141 
142 #endif
int msg_verbose
Definition: msg.c:177
void myfree(void *ptr)
Definition: mymalloc.c:207
TLS_PRNG_SRC * tls_prng_exch_open(const char *)
char * mystrdup(const char *str)
Definition: mymalloc.c:225
#define MYFLOCK_OP_EXCLUSIVE
Definition: myflock.h:30
char * name
Definition: tls_prng.h:19
void tls_prng_exch_close(TLS_PRNG_SRC *)
int myflock(int fd, int lock_style, int operation)
Definition: myflock.c:87
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
#define MYFLOCK_OP_NONE
Definition: myflock.h:28
int timeout
Definition: tls_prng.h:20
void tls_prng_exch_update(TLS_PRNG_SRC *)
void * mymalloc(ssize_t len)
Definition: mymalloc.c:150
void msg_info(const char *fmt,...)
Definition: msg.c:199