1 /*-------------------------------------------------------------------------
2  *
3  * be-secure.c
4  *	  functions related to setting up a secure connection to the frontend.
5  *	  Secure connections are expected to provide confidentiality,
6  *	  message integrity and endpoint authentication.
7  *
8  *
9  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
10  * Portions Copyright (c) 1994, Regents of the University of California
11  *
12  *
13  * IDENTIFICATION
14  *	  src/backend/libpq/be-secure.c
15  *
16  *-------------------------------------------------------------------------
17  */
18 
19 #include "postgres.h"
20 
21 #include <sys/stat.h>
22 #include <signal.h>
23 #include <fcntl.h>
24 #include <ctype.h>
25 #include <sys/socket.h>
26 #include <unistd.h>
27 #include <netdb.h>
28 #include <netinet/in.h>
29 #ifdef HAVE_NETINET_TCP_H
30 #include <netinet/tcp.h>
31 #include <arpa/inet.h>
32 #endif
33 
34 #include "libpq/libpq.h"
35 #include "miscadmin.h"
36 #include "tcop/tcopprot.h"
37 #include "utils/memutils.h"
38 #include "storage/ipc.h"
39 #include "storage/proc.h"
40 
41 
42 char	   *ssl_cert_file;
43 char	   *ssl_key_file;
44 char	   *ssl_ca_file;
45 char	   *ssl_crl_file;
46 
47 #ifdef USE_SSL
48 bool		ssl_loaded_verify_locations = false;
49 #endif
50 
51 /* GUC variable controlling SSL cipher list */
52 char	   *SSLCipherSuites = NULL;
53 
54 /* GUC variable for default ECHD curve. */
55 char	   *SSLECDHCurve;
56 
57 /* GUC variable: if false, prefer client ciphers */
58 bool		SSLPreferServerCiphers;
59 
60 /* ------------------------------------------------------------ */
61 /*			 Procedures common to all secure sessions			*/
62 /* ------------------------------------------------------------ */
63 
64 /*
65  *	Initialize global context
66  */
67 int
secure_initialize(void)68 secure_initialize(void)
69 {
70 #ifdef USE_SSL
71 	be_tls_init();
72 #endif
73 
74 	return 0;
75 }
76 
77 /*
78  * Indicate if we have loaded the root CA store to verify certificates
79  */
80 bool
secure_loaded_verify_locations(void)81 secure_loaded_verify_locations(void)
82 {
83 #ifdef USE_SSL
84 	return ssl_loaded_verify_locations;
85 #else
86 	return false;
87 #endif
88 }
89 
90 /*
91  *	Attempt to negotiate secure session.
92  */
93 int
secure_open_server(Port * port)94 secure_open_server(Port *port)
95 {
96 	int			r = 0;
97 
98 #ifdef USE_SSL
99 	r = be_tls_open_server(port);
100 #endif
101 
102 	return r;
103 }
104 
105 /*
106  *	Close secure session.
107  */
108 void
secure_close(Port * port)109 secure_close(Port *port)
110 {
111 #ifdef USE_SSL
112 	if (port->ssl_in_use)
113 		be_tls_close(port);
114 #endif
115 }
116 
117 /*
118  *	Read data from a secure connection.
119  */
120 ssize_t
secure_read(Port * port,void * ptr,size_t len)121 secure_read(Port *port, void *ptr, size_t len)
122 {
123 	ssize_t		n;
124 	int			waitfor;
125 
126 	/* Deal with any already-pending interrupt condition. */
127 	ProcessClientReadInterrupt(false);
128 
129 retry:
130 #ifdef USE_SSL
131 	waitfor = 0;
132 	if (port->ssl_in_use)
133 	{
134 		n = be_tls_read(port, ptr, len, &waitfor);
135 	}
136 	else
137 #endif
138 	{
139 		n = secure_raw_read(port, ptr, len);
140 		waitfor = WL_SOCKET_READABLE;
141 	}
142 
143 	/* In blocking mode, wait until the socket is ready */
144 	if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
145 	{
146 		WaitEvent	event;
147 
148 		Assert(waitfor);
149 
150 		ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
151 
152 		WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1);
153 
154 		/*
155 		 * If the postmaster has died, it's not safe to continue running,
156 		 * because it is the postmaster's job to kill us if some other backend
157 		 * exists uncleanly.  Moreover, we won't run very well in this state;
158 		 * helper processes like walwriter and the bgwriter will exit, so
159 		 * performance may be poor.  Finally, if we don't exit, pg_ctl will be
160 		 * unable to restart the postmaster without manual intervention, so no
161 		 * new connections can be accepted.  Exiting clears the deck for a
162 		 * postmaster restart.
163 		 *
164 		 * (Note that we only make this check when we would otherwise sleep on
165 		 * our latch.  We might still continue running for a while if the
166 		 * postmaster is killed in mid-query, or even through multiple queries
167 		 * if we never have to wait for read.  We don't want to burn too many
168 		 * cycles checking for this very rare condition, and this should cause
169 		 * us to exit quickly in most cases.)
170 		 */
171 		if (event.events & WL_POSTMASTER_DEATH)
172 			ereport(FATAL,
173 					(errcode(ERRCODE_ADMIN_SHUTDOWN),
174 					 errmsg("terminating connection due to unexpected postmaster exit")));
175 
176 		/* Handle interrupt. */
177 		if (event.events & WL_LATCH_SET)
178 		{
179 			ResetLatch(MyLatch);
180 			ProcessClientReadInterrupt(true);
181 
182 			/*
183 			 * We'll retry the read. Most likely it will return immediately
184 			 * because there's still no data available, and we'll wait for the
185 			 * socket to become ready again.
186 			 */
187 		}
188 		goto retry;
189 	}
190 
191 	/*
192 	 * Process interrupts that happened during a successful (or non-blocking,
193 	 * or hard-failed) read.
194 	 */
195 	ProcessClientReadInterrupt(false);
196 
197 	return n;
198 }
199 
200 ssize_t
secure_raw_read(Port * port,void * ptr,size_t len)201 secure_raw_read(Port *port, void *ptr, size_t len)
202 {
203 	ssize_t		n;
204 
205 	/*
206 	 * Try to read from the socket without blocking. If it succeeds we're
207 	 * done, otherwise we'll wait for the socket using the latch mechanism.
208 	 */
209 #ifdef WIN32
210 	pgwin32_noblock = true;
211 #endif
212 	n = recv(port->sock, ptr, len, 0);
213 #ifdef WIN32
214 	pgwin32_noblock = false;
215 #endif
216 
217 	return n;
218 }
219 
220 
221 /*
222  *	Write data to a secure connection.
223  */
224 ssize_t
secure_write(Port * port,void * ptr,size_t len)225 secure_write(Port *port, void *ptr, size_t len)
226 {
227 	ssize_t		n;
228 	int			waitfor;
229 
230 	/* Deal with any already-pending interrupt condition. */
231 	ProcessClientWriteInterrupt(false);
232 
233 retry:
234 	waitfor = 0;
235 #ifdef USE_SSL
236 	if (port->ssl_in_use)
237 	{
238 		n = be_tls_write(port, ptr, len, &waitfor);
239 	}
240 	else
241 #endif
242 	{
243 		n = secure_raw_write(port, ptr, len);
244 		waitfor = WL_SOCKET_WRITEABLE;
245 	}
246 
247 	if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
248 	{
249 		WaitEvent	event;
250 
251 		Assert(waitfor);
252 
253 		ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
254 
255 		WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1);
256 
257 		/* See comments in secure_read. */
258 		if (event.events & WL_POSTMASTER_DEATH)
259 			ereport(FATAL,
260 					(errcode(ERRCODE_ADMIN_SHUTDOWN),
261 					 errmsg("terminating connection due to unexpected postmaster exit")));
262 
263 		/* Handle interrupt. */
264 		if (event.events & WL_LATCH_SET)
265 		{
266 			ResetLatch(MyLatch);
267 			ProcessClientWriteInterrupt(true);
268 
269 			/*
270 			 * We'll retry the write. Most likely it will return immediately
271 			 * because there's still no buffer space available, and we'll wait
272 			 * for the socket to become ready again.
273 			 */
274 		}
275 		goto retry;
276 	}
277 
278 	/*
279 	 * Process interrupts that happened during a successful (or non-blocking,
280 	 * or hard-failed) write.
281 	 */
282 	ProcessClientWriteInterrupt(false);
283 
284 	return n;
285 }
286 
287 ssize_t
secure_raw_write(Port * port,const void * ptr,size_t len)288 secure_raw_write(Port *port, const void *ptr, size_t len)
289 {
290 	ssize_t		n;
291 
292 #ifdef WIN32
293 	pgwin32_noblock = true;
294 #endif
295 	n = send(port->sock, ptr, len, 0);
296 #ifdef WIN32
297 	pgwin32_noblock = false;
298 #endif
299 
300 	return n;
301 }
302