]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/rand/rand_egd.c
4ea6846ccbd032d211c2db92d5b5c500419d0a1d
2 * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/opensslconf.h>
12 #include <openssl/crypto.h>
13 #include <openssl/e_os2.h>
14 #include <openssl/rand.h>
20 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_UEFI)
21 int RAND_query_egd_bytes(const char *path
, unsigned char *buf
, int bytes
)
26 int RAND_egd(const char *path
)
31 int RAND_egd_bytes(const char *path
, int bytes
)
40 # include <sys/types.h>
41 # include <sys/socket.h>
43 # ifdef OPENSSL_SYS_VXWORKS
44 # include <streams/un.h>
50 short sun_family
; /* AF_UNIX */
51 char sun_path
[108]; /* path name (gag) */
53 # endif /* NO_SYS_UN_H */
57 # if defined(OPENSSL_SYS_TANDEM)
61 * Our current MQ 5.3 EGD requies compatability-mode sockets
62 * This code forces the mode to compatibility if required
63 * and then restores the mode.
67 * The better long-term solution is to either run two EGD's each in one of
68 * the two modes or revise the EGD code to listen on two different sockets
69 * (each in one of the two modes).
72 int hpns_socket(int family
,
78 char current_transport
[20];
80 # define AF_UNIX_PORTABILITY "$ZAFN2"
81 # define AF_UNIX_COMPATIBILITY "$ZPLS"
83 if (!_arg_present(transport
) || transport
== NULL
|| transport
[0] == '\0')
84 return socket(family
, type
, protocol
);
86 socket_transport_name_get(AF_UNIX
, current_transport
, 20);
88 if (strcmp(current_transport
, transport
) == 0)
89 return socket(family
, type
, protocol
);
91 /* set the requested socket transport */
92 if (socket_transport_name_set(AF_UNIX
, transport
))
95 socket_rc
= socket(family
, type
, protocol
);
97 /* set mode back to what it was */
98 if (socket_transport_name_set(AF_UNIX
, current_transport
))
104 /*#define socket(a,b,c,...) hpns_socket(a,b,c,__VA_ARGS__) */
106 static int hpns_connect_attempt
= 0;
108 # endif /* defined(OPENSSL_SYS_HPNS) */
111 int RAND_query_egd_bytes(const char *path
, unsigned char *buf
, int bytes
)
114 struct sockaddr_un addr
;
115 int mybuffer
, ret
= -1, i
, numbytes
, fd
;
116 unsigned char tempbuf
[255];
118 if (bytes
> (int)sizeof(tempbuf
))
122 memset(&addr
, 0, sizeof(addr
));
123 addr
.sun_family
= AF_UNIX
;
124 if (strlen(path
) >= sizeof(addr
.sun_path
))
126 strcpy(addr
.sun_path
, path
);
127 i
= offsetof(struct sockaddr_un
, sun_path
) + strlen(path
);
128 #if defined(OPENSSL_SYS_TANDEM)
129 fd
= hpns_socket(AF_UNIX
, SOCK_STREAM
, 0, AF_UNIX_COMPATIBILITY
);
131 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
133 if (fd
== -1 || (fp
= fdopen(fd
, "r+")) == NULL
)
139 if (connect(fd
, (struct sockaddr
*)&addr
, i
) == 0)
142 if (errno
== EISCONN
)
158 /* No error, try again */
161 # if defined(OPENSSL_SYS_TANDEM)
162 if (hpns_connect_attempt
== 0) {
163 /* try the other kind of AF_UNIX socket */
165 fd
= hpns_socket(AF_UNIX
, SOCK_STREAM
, 0, AF_UNIX_PORTABILITY
);
168 ++hpns_connect_attempt
;
169 break; /* try the connect again */
178 /* Make request, see how many bytes we can get back. */
181 if (fwrite(tempbuf
, sizeof(char), 2, fp
) != 2 || fflush(fp
) == EOF
)
183 if (fread(tempbuf
, sizeof(char), 1, fp
) != 1 || tempbuf
[0] == 0)
185 numbytes
= tempbuf
[0];
187 /* Which buffer are we using? */
188 mybuffer
= buf
== NULL
;
193 i
= fread(buf
, sizeof(char), numbytes
, fp
);
198 RAND_add(tempbuf
, i
, i
);
206 int RAND_egd_bytes(const char *path
, int bytes
)
210 num
= RAND_query_egd_bytes(path
, NULL
, bytes
);
213 if (RAND_status() != 1)
218 int RAND_egd(const char *path
)
220 return RAND_egd_bytes(path
, 255);