1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#ifndef IOSTREAM_OPENSSL_H
#define IOSTREAM_OPENSSL_H
#include "iostream-ssl-private.h"
#include <openssl/ssl.h>
#ifndef HAVE_ASN1_STRING_GET0_DATA
# define ASN1_STRING_get0_data(str) ASN1_STRING_data(str)
#endif
enum openssl_iostream_sync_type {
OPENSSL_IOSTREAM_SYNC_TYPE_NONE,
OPENSSL_IOSTREAM_SYNC_TYPE_FIRST_READ,
OPENSSL_IOSTREAM_SYNC_TYPE_CONTINUE_READ,
OPENSSL_IOSTREAM_SYNC_TYPE_WRITE,
OPENSSL_IOSTREAM_SYNC_TYPE_HANDSHAKE
};
struct ssl_iostream_context {
int refcount;
SSL_CTX *ssl_ctx;
pool_t pool;
struct ssl_iostream_settings set;
int username_nid;
bool client_ctx:1;
};
struct ssl_iostream {
int refcount;
struct ssl_iostream_context *ctx;
SSL *ssl;
BIO *bio_ext;
struct istream *plain_input;
struct ostream *plain_output;
struct istream *ssl_input;
struct ostream *ssl_output;
/* SSL clients: host where we connected to */
char *connected_host;
/* SSL servers: host requested by the client via SNI */
char *sni_host;
char *last_error;
char *log_prefix;
char *plain_stream_errstr;
int plain_stream_errno;
/* copied settings */
bool verbose, verbose_invalid_cert, allow_invalid_cert;
int username_nid;
ssl_iostream_handshake_callback_t *handshake_callback;
void *handshake_context;
ssl_iostream_sni_callback_t *sni_callback;
void *sni_context;
bool handshaked:1;
bool handshake_failed:1;
bool cert_received:1;
bool cert_broken:1;
bool want_read:1;
bool ostream_flush_waiting_input:1;
bool closed:1;
bool destroyed:1;
};
extern int dovecot_ssl_extdata_index;
struct istream *openssl_i_stream_create_ssl(struct ssl_iostream *ssl_io);
struct ostream *openssl_o_stream_create_ssl(struct ssl_iostream *ssl_io);
int openssl_iostream_global_init(const struct ssl_iostream_settings *set,
const char **error_r);
int openssl_iostream_context_init_client(const struct ssl_iostream_settings *set,
struct ssl_iostream_context **ctx_r,
const char **error_r);
int openssl_iostream_context_init_server(const struct ssl_iostream_settings *set,
struct ssl_iostream_context **ctx_r,
const char **error_r);
void openssl_iostream_context_ref(struct ssl_iostream_context *ctx);
void openssl_iostream_context_unref(struct ssl_iostream_context *ctx);
void openssl_iostream_global_deinit(void);
int openssl_iostream_load_key(const struct ssl_iostream_cert *set,
const char *set_name,
EVP_PKEY **pkey_r, const char **error_r);
bool openssl_cert_match_name(SSL *ssl, const char *verify_name,
const char **reason_r);
#define OPENSSL_ALL_PROTOCOL_OPTIONS \
(SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1)
/* opt_r is used with SSL_set_options() and version_r is used with
SSL_set_min_proto_version(). Using either method should enable the same SSL
protocol versions. */
int openssl_min_protocol_to_options(const char *min_protocol, long *opt_r,
int *version_r) ATTR_NULL(2,3);
/* Sync plain_input/plain_output streams with BIOs. Returns 1 if at least
one byte was read/written, 0 if nothing was written, and -1 if an error
occurred. */
int openssl_iostream_bio_sync(struct ssl_iostream *ssl_io,
enum openssl_iostream_sync_type type);
/* Returns 1 if the operation should be retried (we read/wrote more data),
0 if the operation should retried later once more data has been
read/written, -1 if a fatal error occurred (errno is set). */
int openssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret,
enum openssl_iostream_sync_type type,
const char *func_name);
/* Perform clean shutdown for the connection. */
void openssl_iostream_shutdown(struct ssl_iostream *ssl_io);
void openssl_iostream_set_error(struct ssl_iostream *ssl_io, const char *str);
const char *openssl_iostream_error(void);
const char *openssl_iostream_key_load_error(void);
const char *
openssl_iostream_use_certificate_error(const char *cert, const char *set_name);
void openssl_iostream_clear_errors(void);
void ssl_iostream_openssl_init(void);
void ssl_iostream_openssl_deinit(void);
#endif
|