1 | /* |
---|
2 | * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com> |
---|
3 | * All rights reserved |
---|
4 | * |
---|
5 | * "THE BEER-WARE LICENSE" (Revision 42): |
---|
6 | * Sergey Lyubka wrote this file. As long as you retain this notice you |
---|
7 | * can do whatever you want with this stuff. If we meet some day, and you think |
---|
8 | * this stuff is worth it, you can buy me a beer in return. |
---|
9 | */ |
---|
10 | |
---|
11 | #include "defs.h" |
---|
12 | |
---|
13 | #if !defined(NO_SSL) |
---|
14 | struct ssl_func ssl_sw[] = { |
---|
15 | {"SSL_free", {0}}, |
---|
16 | {"SSL_accept", {0}}, |
---|
17 | {"SSL_connect", {0}}, |
---|
18 | {"SSL_read", {0}}, |
---|
19 | {"SSL_write", {0}}, |
---|
20 | {"SSL_get_error", {0}}, |
---|
21 | {"SSL_set_fd", {0}}, |
---|
22 | {"SSL_new", {0}}, |
---|
23 | {"SSL_CTX_new", {0}}, |
---|
24 | {"SSLv23_server_method", {0}}, |
---|
25 | {"SSL_library_init", {0}}, |
---|
26 | {"SSL_CTX_use_PrivateKey_file", {0}}, |
---|
27 | {"SSL_CTX_use_certificate_file",{0}}, |
---|
28 | {NULL, {0}} |
---|
29 | }; |
---|
30 | |
---|
31 | void |
---|
32 | ssl_handshake(struct stream *stream) |
---|
33 | { |
---|
34 | int n; |
---|
35 | |
---|
36 | if ((n = SSL_accept(stream->chan.ssl.ssl)) == 0) { |
---|
37 | n = SSL_get_error(stream->chan.ssl.ssl, n); |
---|
38 | if (n != SSL_ERROR_WANT_READ && n != SSL_ERROR_WANT_WRITE) |
---|
39 | stream->flags |= FLAG_CLOSED; |
---|
40 | elog(E_LOG, stream->conn, "SSL_accept error %d", n); |
---|
41 | } else { |
---|
42 | DBG(("handshake: SSL accepted")); |
---|
43 | stream->flags |= FLAG_SSL_ACCEPTED; |
---|
44 | } |
---|
45 | } |
---|
46 | |
---|
47 | static int |
---|
48 | read_ssl(struct stream *stream, void *buf, size_t len) |
---|
49 | { |
---|
50 | int nread = 0; |
---|
51 | |
---|
52 | assert(stream->chan.ssl.ssl != NULL); |
---|
53 | |
---|
54 | if (!(stream->flags & FLAG_SSL_ACCEPTED)) |
---|
55 | ssl_handshake(stream); |
---|
56 | |
---|
57 | if (stream->flags & FLAG_SSL_ACCEPTED) |
---|
58 | nread = SSL_read(stream->chan.ssl.ssl, buf, len); |
---|
59 | |
---|
60 | return (nread); |
---|
61 | } |
---|
62 | |
---|
63 | static int |
---|
64 | write_ssl(struct stream *stream, const void *buf, size_t len) |
---|
65 | { |
---|
66 | assert(stream->chan.ssl.ssl != NULL); |
---|
67 | return (SSL_write(stream->chan.ssl.ssl, buf, len)); |
---|
68 | } |
---|
69 | |
---|
70 | static void |
---|
71 | close_ssl(struct stream *stream) |
---|
72 | { |
---|
73 | assert(stream->chan.ssl.sock != -1); |
---|
74 | assert(stream->chan.ssl.ssl != NULL); |
---|
75 | (void) closesocket(stream->chan.ssl.sock); |
---|
76 | SSL_free(stream->chan.ssl.ssl); |
---|
77 | } |
---|
78 | |
---|
79 | const struct io_class io_ssl = { |
---|
80 | "ssl", |
---|
81 | read_ssl, |
---|
82 | write_ssl, |
---|
83 | close_ssl |
---|
84 | }; |
---|
85 | #endif /* !NO_SSL */ |
---|