1 /*
2 ratproxy - SSL worker
3 ---------------------
4
5 This helper process is launched on CONNECT requests to act as a
6 SSL MITM intermediary.
7
8 Author: Michal Zalewski <lcamtuf@google.com>
9
10 Copyright 2007, 2008 by Google Inc. All Rights Reserved.
11
12 Licensed under the Apache License, Version 2.0 (the "License");
13 you may not use this file except in compliance with the License.
14 You may obtain a copy of the License at
15
16 http://www.apache.org/licenses/LICENSE-2.0
17
18 Unless required by applicable law or agreed to in writing, software
19 distributed under the License is distributed on an "AS IS" BASIS,
20 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 See the License for the specific language governing permissions and
22 limitations under the License.
23
24 */
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <string.h>
35 #include <sys/wait.h>
36 #include <ctype.h>
37 #include <netdb.h>
38 #include <openssl/ssl.h>
39 #include <openssl/err.h>
40 #include <time.h>
41
42 #include "config.h"
43 #include "types.h"
44 #include "debug.h"
45 #include "ssl.h"
46
47 _s32 ssl_cli_tap, /* Client traffic tap */
48 ssl_srv_tap; /* Server traffic tap */
49
50 static _s32 ssl_cli_tap_b, /* Rear end of client tap */
51 ssl_srv_tap_b, /* Rear end of server tap */
52 ssl_pid; /* SSL worker PID */
53
54
55 static _u8 rdbuf[MAXLINE], /* Internal I/O buffer */
56 init_ok; /* Initialization state */
57
58
59 /* Prepare pipes for SSL worker */
ssl_setup(void)60 void ssl_setup(void) {
61 int p[2];
62
63 if (init_ok) fatal("ssl_setup() called twice");
64 init_ok = 1;
65
66 if (socketpair(AF_UNIX,SOCK_STREAM,0,p)) pfatal("socketpair() failed");
67
68 ssl_cli_tap = p[0];
69 ssl_cli_tap_b = p[1];
70
71 if (socketpair(AF_UNIX,SOCK_STREAM,0,p)) pfatal("socketpair() failed");
72
73 ssl_srv_tap = p[0];
74 ssl_srv_tap_b = p[1];
75
76 }
77
78
79 /* Clean up SSL worker */
ssl_shutdown(void)80 void ssl_shutdown(void) {
81 int st;
82
83 if (init_ok != 2) fatal("ssl_shutdown() called prior to ssl_start()");
84 init_ok = 0;
85
86 if (ssl_pid > 0) {
87 ssl_pid = 0;
88 close(ssl_cli_tap);
89 close(ssl_srv_tap);
90 wait(&st);
91 }
92
93 }
94
95
96 /* Display SSL-enabled error message */
97
98 #define ssl_fatal(reason,err) do { \
99 if (init_ok == 2) \
100 ERR_print_errors(err); \
101 fatal("%s", reason); \
102 } while (1)
103
104
105 /* Start SSL worker and do the dirty job */
ssl_start(_s32 srv_fd,_s32 cli_fd)106 void ssl_start(_s32 srv_fd, _s32 cli_fd) {
107 SSL_CTX *cli_ctx, *srv_ctx;
108 SSL *cli_ssl, *srv_ssl;
109 BIO* err;
110 _s32 i;
111 _u8 no_client = (cli_fd < 0);
112
113 if (!init_ok || init_ok == 2) fatal("ssl_start() called out of order");
114 init_ok = 2;
115
116 ssl_pid = fork();
117
118 if (ssl_pid < 0) pfatal("fork() failed");
119
120 /* Make sure that each endpoint has just the right set of pipes */
121
122 if (ssl_pid) {
123
124 close(ssl_cli_tap_b);
125 close(ssl_srv_tap_b);
126 ssl_cli_tap_b = -1;
127 ssl_srv_tap_b = -1;
128 return;
129
130 }
131
132 close(ssl_cli_tap);
133 close(ssl_srv_tap);
134 ssl_cli_tap = -1;
135 ssl_srv_tap = -1;
136
137 SSL_library_init();
138 SSL_load_error_strings();
139
140 err = BIO_new_fp(stderr,BIO_NOCLOSE);
141 srv_ctx = SSL_CTX_new(SSLv23_client_method()); /* To server */
142 cli_ctx = SSL_CTX_new(SSLv23_server_method()); /* To client */
143
144 if (!srv_ctx || !cli_ctx || !err) ssl_fatal("unable to create SSL CTX or BIO", err);
145
146 if (SSL_CTX_use_certificate_chain_file(cli_ctx,"keyfile.pem") != 1)
147 ssl_fatal("certificate load failed", err);
148
149 if (SSL_CTX_use_PrivateKey_file(cli_ctx,"keyfile.pem",SSL_FILETYPE_PEM) != 1)
150 ssl_fatal("private key load failed", err);
151
152 cli_ssl = SSL_new(cli_ctx);
153 srv_ssl = SSL_new(srv_ctx);
154
155 if (!srv_ssl || !cli_ssl) ssl_fatal("unable to create SSL objects", err);
156
157 SSL_set_fd(srv_ssl, srv_fd);
158 if (SSL_connect(srv_ssl) != 1) ssl_fatal("server SSL handshake failed", err);
159
160 if (!no_client) {
161 SSL_set_fd(cli_ssl, cli_fd);
162 if (SSL_accept(cli_ssl) != 1) ssl_fatal("client SSL handshake failed", err);
163 }
164
165 while (1) {
166 _s32 fmax = 0;
167
168 fd_set fds;
169
170 FD_ZERO(&fds);
171
172 if (!no_client) {
173 FD_SET(cli_fd,&fds);
174 fmax = cli_fd;
175 FD_SET(ssl_cli_tap_b,&fds);
176 if (ssl_cli_tap_b > fmax) fmax = ssl_cli_tap_b;
177 }
178
179 if (ssl_srv_tap_b > 0) {
180 FD_SET(srv_fd,&fds);
181 if (srv_fd > fmax) fmax = srv_fd;
182 FD_SET(ssl_srv_tap_b,&fds);
183 if (ssl_srv_tap_b > fmax) fmax = ssl_srv_tap_b;
184 }
185
186 if (select(1 + fmax, &fds, 0, 0, 0) <= 0) exit(0);
187
188 /* Real client sending - send to cli_tap socket. */
189 if (!no_client && FD_ISSET(cli_fd,&fds)) {
190 i = SSL_read(cli_ssl,rdbuf,sizeof(rdbuf));
191 if (i <= 0) exit(0);
192 if (write(ssl_cli_tap_b,rdbuf,i) != i)
193 pfatal("short write to client tap");
194 }
195
196 /* Real server sending - send to srv_tap socket. */
197 if (ssl_srv_tap_b > 0 && FD_ISSET(srv_fd,&fds)) {
198 i = SSL_read(srv_ssl,rdbuf,sizeof(rdbuf));
199 if (i <= 0) {
200
201 /* In no_client mode, server shutdown means end of work. */
202
203 if (no_client) exit(0);
204
205 /* In client mode, we still want to relay proxy-processed
206 client response before exiting. Just let the proxy
207 know by shutting down the server tap. */
208
209 close(ssl_srv_tap_b);
210 ssl_srv_tap_b = -1;
211 } else {
212 if (write(ssl_srv_tap_b,rdbuf,i) != i)
213 pfatal("short write to server tap");
214 }
215 }
216
217 /* Data from srv_tap socket - send to server. */
218 if (ssl_srv_tap_b > 0 && FD_ISSET(ssl_srv_tap_b,&fds)) {
219 i = read(ssl_srv_tap_b,rdbuf,sizeof(rdbuf));
220 if (i <= 0) exit(0);
221 if (SSL_write(srv_ssl,rdbuf,i) != i) exit(0);
222 }
223
224 /* Data from cli_tap socket - send to client. */
225 if (!no_client && FD_ISSET(ssl_cli_tap_b,&fds)) {
226 i = read(ssl_cli_tap_b,rdbuf,sizeof(rdbuf));
227 if (i <= 0) exit(0);
228 if (SSL_write(cli_ssl,rdbuf,i) != i) exit(0);
229 }
230
231 }
232
233 }
234