Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * backend_startup.c
4 : * Backend startup code
5 : *
6 : * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/tcop/backend_startup.c
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 :
16 : #include "postgres.h"
17 :
18 : #include <unistd.h>
19 :
20 : #include "access/xlog.h"
21 : #include "common/ip.h"
22 : #include "common/string.h"
23 : #include "libpq/libpq.h"
24 : #include "libpq/libpq-be.h"
25 : #include "libpq/pqformat.h"
26 : #include "libpq/pqsignal.h"
27 : #include "miscadmin.h"
28 : #include "postmaster/postmaster.h"
29 : #include "replication/walsender.h"
30 : #include "storage/fd.h"
31 : #include "storage/ipc.h"
32 : #include "storage/procsignal.h"
33 : #include "storage/proc.h"
34 : #include "tcop/backend_startup.h"
35 : #include "tcop/tcopprot.h"
36 : #include "utils/builtins.h"
37 : #include "utils/injection_point.h"
38 : #include "utils/memutils.h"
39 : #include "utils/ps_status.h"
40 : #include "utils/timeout.h"
41 :
42 : /* GUCs */
43 : bool Trace_connection_negotiation = false;
44 :
45 : static void BackendInitialize(ClientSocket *client_sock, CAC_state cac);
46 : static int ProcessSSLStartup(Port *port);
47 : static int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done);
48 : static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options);
49 : static void process_startup_packet_die(SIGNAL_ARGS);
50 : static void StartupPacketTimeoutHandler(void);
51 :
52 : /*
53 : * Entry point for a new backend process.
54 : *
55 : * Initialize the connection, read the startup packet, authenticate the
56 : * client, and start the main processing loop.
57 : */
58 : void
59 25254 : BackendMain(char *startup_data, size_t startup_data_len)
60 : {
61 25254 : BackendStartupData *bsdata = (BackendStartupData *) startup_data;
62 :
63 : Assert(startup_data_len == sizeof(BackendStartupData));
64 : Assert(MyClientSocket != NULL);
65 :
66 : #ifdef EXEC_BACKEND
67 :
68 : /*
69 : * Need to reinitialize the SSL library in the backend, since the context
70 : * structures contain function pointers and cannot be passed through the
71 : * parameter file.
72 : *
73 : * If for some reason reload fails (maybe the user installed broken key
74 : * files), soldier on without SSL; that's better than all connections
75 : * becoming impossible.
76 : *
77 : * XXX should we do this in all child processes? For the moment it's
78 : * enough to do it in backend children.
79 : */
80 : #ifdef USE_SSL
81 : if (EnableSSL)
82 : {
83 : if (secure_initialize(false) == 0)
84 : LoadedSSL = true;
85 : else
86 : ereport(LOG,
87 : (errmsg("SSL configuration could not be loaded in child process")));
88 : }
89 : #endif
90 : #endif
91 :
92 : /* Perform additional initialization and collect startup packet */
93 25254 : BackendInitialize(MyClientSocket, bsdata->canAcceptConnections);
94 :
95 : /*
96 : * Create a per-backend PGPROC struct in shared memory. We must do this
97 : * before we can use LWLocks or access any shared memory.
98 : */
99 24916 : InitProcess();
100 :
101 : /*
102 : * Make sure we aren't in PostmasterContext anymore. (We can't delete it
103 : * just yet, though, because InitPostgres will need the HBA data.)
104 : */
105 24910 : MemoryContextSwitchTo(TopMemoryContext);
106 :
107 24910 : PostgresMain(MyProcPort->database_name, MyProcPort->user_name);
108 : }
109 :
110 :
111 : /*
112 : * BackendInitialize -- initialize an interactive (postmaster-child)
113 : * backend process, and collect the client's startup packet.
114 : *
115 : * returns: nothing. Will not return at all if there's any failure.
116 : *
117 : * Note: this code does not depend on having any access to shared memory.
118 : * Indeed, our approach to SIGTERM/timeout handling *requires* that
119 : * shared memory not have been touched yet; see comments within.
120 : * In the EXEC_BACKEND case, we are physically attached to shared memory
121 : * but have not yet set up most of our local pointers to shmem structures.
122 : */
123 : static void
124 25254 : BackendInitialize(ClientSocket *client_sock, CAC_state cac)
125 : {
126 : int status;
127 : int ret;
128 : Port *port;
129 : char remote_host[NI_MAXHOST];
130 : char remote_port[NI_MAXSERV];
131 : StringInfoData ps_data;
132 : MemoryContext oldcontext;
133 :
134 : /* Tell fd.c about the long-lived FD associated with the client_sock */
135 25254 : ReserveExternalFD();
136 :
137 : /*
138 : * PreAuthDelay is a debugging aid for investigating problems in the
139 : * authentication cycle: it can be set in postgresql.conf to allow time to
140 : * attach to the newly-forked backend with a debugger. (See also
141 : * PostAuthDelay, which we allow clients to pass through PGOPTIONS, but it
142 : * is not honored until after authentication.)
143 : */
144 25254 : if (PreAuthDelay > 0)
145 0 : pg_usleep(PreAuthDelay * 1000000L);
146 :
147 : /* This flag will remain set until InitPostgres finishes authentication */
148 25254 : ClientAuthInProgress = true; /* limit visibility of log messages */
149 :
150 : /*
151 : * Initialize libpq and enable reporting of ereport errors to the client.
152 : * Must do this now because authentication uses libpq to send messages.
153 : *
154 : * The Port structure and all data structures attached to it are allocated
155 : * in TopMemoryContext, so that they survive into PostgresMain execution.
156 : * We need not worry about leaking this storage on failure, since we
157 : * aren't in the postmaster process anymore.
158 : */
159 25254 : oldcontext = MemoryContextSwitchTo(TopMemoryContext);
160 25254 : port = MyProcPort = pq_init(client_sock);
161 25254 : MemoryContextSwitchTo(oldcontext);
162 :
163 25254 : whereToSendOutput = DestRemote; /* now safe to ereport to client */
164 :
165 : /* set these to empty in case they are needed before we set them up */
166 25254 : port->remote_host = "";
167 25254 : port->remote_port = "";
168 :
169 : /*
170 : * We arrange to do _exit(1) if we receive SIGTERM or timeout while trying
171 : * to collect the startup packet; while SIGQUIT results in _exit(2).
172 : * Otherwise the postmaster cannot shutdown the database FAST or IMMED
173 : * cleanly if a buggy client fails to send the packet promptly.
174 : *
175 : * Exiting with _exit(1) is only possible because we have not yet touched
176 : * shared memory; therefore no outside-the-process state needs to get
177 : * cleaned up.
178 : */
179 25254 : pqsignal(SIGTERM, process_startup_packet_die);
180 : /* SIGQUIT handler was already set up by InitPostmasterChild */
181 25254 : InitializeTimeouts(); /* establishes SIGALRM handler */
182 25254 : sigprocmask(SIG_SETMASK, &StartupBlockSig, NULL);
183 :
184 : /*
185 : * Get the remote host name and port for logging and status display.
186 : */
187 25254 : remote_host[0] = '\0';
188 25254 : remote_port[0] = '\0';
189 25254 : if ((ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
190 : remote_host, sizeof(remote_host),
191 : remote_port, sizeof(remote_port),
192 : (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) != 0)
193 0 : ereport(WARNING,
194 : (errmsg_internal("pg_getnameinfo_all() failed: %s",
195 : gai_strerror(ret))));
196 :
197 : /*
198 : * Save remote_host and remote_port in port structure (after this, they
199 : * will appear in log_line_prefix data for log messages).
200 : */
201 25254 : port->remote_host = MemoryContextStrdup(TopMemoryContext, remote_host);
202 25254 : port->remote_port = MemoryContextStrdup(TopMemoryContext, remote_port);
203 :
204 : /* And now we can issue the Log_connections message, if wanted */
205 25254 : if (Log_connections)
206 : {
207 820 : if (remote_port[0])
208 288 : ereport(LOG,
209 : (errmsg("connection received: host=%s port=%s",
210 : remote_host,
211 : remote_port)));
212 : else
213 532 : ereport(LOG,
214 : (errmsg("connection received: host=%s",
215 : remote_host)));
216 : }
217 :
218 : /* For testing client error handling */
219 : #ifdef USE_INJECTION_POINTS
220 25254 : INJECTION_POINT("backend-initialize");
221 25254 : if (IS_INJECTION_POINT_ATTACHED("backend-initialize-v2-error"))
222 : {
223 : /*
224 : * This simulates an early error from a pre-v14 server, which used the
225 : * version 2 protocol for any errors that occurred before processing
226 : * the startup packet.
227 : */
228 2 : FrontendProtocol = PG_PROTOCOL(2, 0);
229 2 : elog(FATAL, "protocol version 2 error triggered");
230 : }
231 : #endif
232 :
233 : /*
234 : * If we did a reverse lookup to name, we might as well save the results
235 : * rather than possibly repeating the lookup during authentication.
236 : *
237 : * Note that we don't want to specify NI_NAMEREQD above, because then we'd
238 : * get nothing useful for a client without an rDNS entry. Therefore, we
239 : * must check whether we got a numeric IPv4 or IPv6 address, and not save
240 : * it into remote_hostname if so. (This test is conservative and might
241 : * sometimes classify a hostname as numeric, but an error in that
242 : * direction is safe; it only results in a possible extra lookup.)
243 : */
244 25252 : if (log_hostname &&
245 228 : ret == 0 &&
246 228 : strspn(remote_host, "0123456789.") < strlen(remote_host) &&
247 228 : strspn(remote_host, "0123456789ABCDEFabcdef:") < strlen(remote_host))
248 : {
249 228 : port->remote_hostname = MemoryContextStrdup(TopMemoryContext, remote_host);
250 : }
251 :
252 : /*
253 : * Ready to begin client interaction. We will give up and _exit(1) after
254 : * a time delay, so that a broken client can't hog a connection
255 : * indefinitely. PreAuthDelay and any DNS interactions above don't count
256 : * against the time limit.
257 : *
258 : * Note: AuthenticationTimeout is applied here while waiting for the
259 : * startup packet, and then again in InitPostgres for the duration of any
260 : * authentication operations. So a hostile client could tie up the
261 : * process for nearly twice AuthenticationTimeout before we kick him off.
262 : *
263 : * Note: because PostgresMain will call InitializeTimeouts again, the
264 : * registration of STARTUP_PACKET_TIMEOUT will be lost. This is okay
265 : * since we never use it again after this function.
266 : */
267 25252 : RegisterTimeout(STARTUP_PACKET_TIMEOUT, StartupPacketTimeoutHandler);
268 25252 : enable_timeout_after(STARTUP_PACKET_TIMEOUT, AuthenticationTimeout * 1000);
269 :
270 : /* Handle direct SSL handshake */
271 25252 : status = ProcessSSLStartup(port);
272 :
273 : /*
274 : * Receive the startup packet (which might turn out to be a cancel request
275 : * packet).
276 : */
277 25252 : if (status == STATUS_OK)
278 25240 : status = ProcessStartupPacket(port, false, false);
279 :
280 : /*
281 : * If we're going to reject the connection due to database state, say so
282 : * now instead of wasting cycles on an authentication exchange. (This also
283 : * allows a pg_ping utility to be written.)
284 : */
285 25250 : if (status == STATUS_OK)
286 : {
287 25132 : switch (cac)
288 : {
289 200 : case CAC_STARTUP:
290 200 : ereport(FATAL,
291 : (errcode(ERRCODE_CANNOT_CONNECT_NOW),
292 : errmsg("the database system is starting up")));
293 : break;
294 10 : case CAC_NOTCONSISTENT:
295 10 : if (EnableHotStandby)
296 10 : ereport(FATAL,
297 : (errcode(ERRCODE_CANNOT_CONNECT_NOW),
298 : errmsg("the database system is not yet accepting connections"),
299 : errdetail("Consistent recovery state has not been yet reached.")));
300 : else
301 0 : ereport(FATAL,
302 : (errcode(ERRCODE_CANNOT_CONNECT_NOW),
303 : errmsg("the database system is not accepting connections"),
304 : errdetail("Hot standby mode is disabled.")));
305 : break;
306 4 : case CAC_SHUTDOWN:
307 4 : ereport(FATAL,
308 : (errcode(ERRCODE_CANNOT_CONNECT_NOW),
309 : errmsg("the database system is shutting down")));
310 : break;
311 0 : case CAC_RECOVERY:
312 0 : ereport(FATAL,
313 : (errcode(ERRCODE_CANNOT_CONNECT_NOW),
314 : errmsg("the database system is in recovery mode")));
315 : break;
316 2 : case CAC_TOOMANY:
317 2 : ereport(FATAL,
318 : (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
319 : errmsg("sorry, too many clients already")));
320 : break;
321 24916 : case CAC_OK:
322 24916 : break;
323 : }
324 118 : }
325 :
326 : /*
327 : * Disable the timeout, and prevent SIGTERM again.
328 : */
329 25034 : disable_timeout(STARTUP_PACKET_TIMEOUT, false);
330 25034 : sigprocmask(SIG_SETMASK, &BlockSig, NULL);
331 :
332 : /*
333 : * As a safety check that nothing in startup has yet performed
334 : * shared-memory modifications that would need to be undone if we had
335 : * exited through SIGTERM or timeout above, check that no on_shmem_exit
336 : * handlers have been registered yet. (This isn't terribly bulletproof,
337 : * since someone might misuse an on_proc_exit handler for shmem cleanup,
338 : * but it's a cheap and helpful check. We cannot disallow on_proc_exit
339 : * handlers unfortunately, since pq_init() already registered one.)
340 : */
341 25034 : check_on_shmem_exit_lists_are_empty();
342 :
343 : /*
344 : * Stop here if it was bad or a cancel packet. ProcessStartupPacket
345 : * already did any appropriate error reporting.
346 : */
347 25034 : if (status != STATUS_OK)
348 118 : proc_exit(0);
349 :
350 : /*
351 : * Now that we have the user and database name, we can set the process
352 : * title for ps. It's good to do this as early as possible in startup.
353 : */
354 24916 : initStringInfo(&ps_data);
355 24916 : if (am_walsender)
356 2064 : appendStringInfo(&ps_data, "%s ", GetBackendTypeDesc(B_WAL_SENDER));
357 24916 : appendStringInfo(&ps_data, "%s ", port->user_name);
358 24916 : if (port->database_name[0] != '\0')
359 24024 : appendStringInfo(&ps_data, "%s ", port->database_name);
360 24916 : appendStringInfoString(&ps_data, port->remote_host);
361 24916 : if (port->remote_port[0] != '\0')
362 500 : appendStringInfo(&ps_data, "(%s)", port->remote_port);
363 :
364 24916 : init_ps_display(ps_data.data);
365 24916 : pfree(ps_data.data);
366 :
367 24916 : set_ps_display("initializing");
368 24916 : }
369 :
370 : /*
371 : * Check for a direct SSL connection.
372 : *
373 : * This happens before the startup packet so we are careful not to actually
374 : * read any bytes from the stream if it's not a direct SSL connection.
375 : */
376 : static int
377 25252 : ProcessSSLStartup(Port *port)
378 : {
379 : int firstbyte;
380 :
381 : Assert(!port->ssl_in_use);
382 :
383 25252 : pq_startmsgread();
384 25252 : firstbyte = pq_peekbyte();
385 25252 : pq_endmsgread();
386 25252 : if (firstbyte == EOF)
387 : {
388 : /*
389 : * Like in ProcessStartupPacket, if we get no data at all, don't
390 : * clutter the log with a complaint.
391 : */
392 8 : return STATUS_ERROR;
393 : }
394 :
395 25244 : if (firstbyte != 0x16)
396 : {
397 : /* Not an SSL handshake message */
398 25234 : return STATUS_OK;
399 : }
400 :
401 : /*
402 : * First byte indicates standard SSL handshake message
403 : *
404 : * (It can't be a Postgres startup length because in network byte order
405 : * that would be a startup packet hundreds of megabytes long)
406 : */
407 :
408 : #ifdef USE_SSL
409 10 : if (!LoadedSSL || port->laddr.addr.ss_family == AF_UNIX)
410 : {
411 : /* SSL not supported */
412 4 : goto reject;
413 : }
414 :
415 6 : if (secure_open_server(port) == -1)
416 : {
417 : /*
418 : * we assume secure_open_server() sent an appropriate TLS alert
419 : * already
420 : */
421 0 : goto reject;
422 : }
423 : Assert(port->ssl_in_use);
424 :
425 6 : if (!port->alpn_used)
426 : {
427 0 : ereport(COMMERROR,
428 : (errcode(ERRCODE_PROTOCOL_VIOLATION),
429 : errmsg("received direct SSL connection request without ALPN protocol negotiation extension")));
430 0 : goto reject;
431 : }
432 :
433 6 : if (Trace_connection_negotiation)
434 6 : ereport(LOG,
435 : (errmsg("direct SSL connection accepted")));
436 6 : return STATUS_OK;
437 : #else
438 : /* SSL not supported by this build */
439 : goto reject;
440 : #endif
441 :
442 4 : reject:
443 4 : if (Trace_connection_negotiation)
444 4 : ereport(LOG,
445 : (errmsg("direct SSL connection rejected")));
446 4 : return STATUS_ERROR;
447 : }
448 :
449 : /*
450 : * Read a client's startup packet and do something according to it.
451 : *
452 : * Returns STATUS_OK or STATUS_ERROR, or might call ereport(FATAL) and
453 : * not return at all.
454 : *
455 : * (Note that ereport(FATAL) stuff is sent to the client, so only use it
456 : * if that's what you want. Return STATUS_ERROR if you don't want to
457 : * send anything to the client, which would typically be appropriate
458 : * if we detect a communications failure.)
459 : *
460 : * Set ssl_done and/or gss_done when negotiation of an encrypted layer
461 : * (currently, TLS or GSSAPI) is completed. A successful negotiation of either
462 : * encryption layer sets both flags, but a rejected negotiation sets only the
463 : * flag for that layer, since the client may wish to try the other one. We
464 : * should make no assumption here about the order in which the client may make
465 : * requests.
466 : */
467 : static int
468 25762 : ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
469 : {
470 : int32 len;
471 : char *buf;
472 : ProtocolVersion proto;
473 : MemoryContext oldcontext;
474 :
475 25762 : pq_startmsgread();
476 :
477 : /*
478 : * Grab the first byte of the length word separately, so that we can tell
479 : * whether we have no data at all or an incomplete packet. (This might
480 : * sound inefficient, but it's not really, because of buffering in
481 : * pqcomm.c.)
482 : */
483 25762 : if (pq_getbytes((char *) &len, 1) == EOF)
484 : {
485 : /*
486 : * If we get no data at all, don't clutter the log with a complaint;
487 : * such cases often occur for legitimate reasons. An example is that
488 : * we might be here after responding to NEGOTIATE_SSL_CODE, and if the
489 : * client didn't like our response, it'll probably just drop the
490 : * connection. Service-monitoring software also often just opens and
491 : * closes a connection without sending anything. (So do port
492 : * scanners, which may be less benign, but it's not really our job to
493 : * notice those.)
494 : */
495 52 : return STATUS_ERROR;
496 : }
497 :
498 25710 : if (pq_getbytes(((char *) &len) + 1, 3) == EOF)
499 : {
500 : /* Got a partial length word, so bleat about that */
501 0 : if (!ssl_done && !gss_done)
502 0 : ereport(COMMERROR,
503 : (errcode(ERRCODE_PROTOCOL_VIOLATION),
504 : errmsg("incomplete startup packet")));
505 0 : return STATUS_ERROR;
506 : }
507 :
508 25710 : len = pg_ntoh32(len);
509 25710 : len -= 4;
510 :
511 25710 : if (len < (int32) sizeof(ProtocolVersion) ||
512 25710 : len > MAX_STARTUP_PACKET_LENGTH)
513 : {
514 0 : ereport(COMMERROR,
515 : (errcode(ERRCODE_PROTOCOL_VIOLATION),
516 : errmsg("invalid length of startup packet")));
517 0 : return STATUS_ERROR;
518 : }
519 :
520 : /*
521 : * Allocate space to hold the startup packet, plus one extra byte that's
522 : * initialized to be zero. This ensures we will have null termination of
523 : * all strings inside the packet.
524 : */
525 25710 : buf = palloc(len + 1);
526 25710 : buf[len] = '\0';
527 :
528 25710 : if (pq_getbytes(buf, len) == EOF)
529 : {
530 0 : ereport(COMMERROR,
531 : (errcode(ERRCODE_PROTOCOL_VIOLATION),
532 : errmsg("incomplete startup packet")));
533 0 : return STATUS_ERROR;
534 : }
535 25710 : pq_endmsgread();
536 :
537 : /*
538 : * The first field is either a protocol version number or a special
539 : * request code.
540 : */
541 25710 : port->proto = proto = pg_ntoh32(*((ProtocolVersion *) buf));
542 :
543 25710 : if (proto == CANCEL_REQUEST_CODE)
544 : {
545 : /*
546 : * The client has sent a cancel request packet, not a normal
547 : * start-a-new-connection packet. Perform the necessary processing.
548 : * Nothing is sent back to the client.
549 : */
550 : CancelRequestPacket *canc;
551 : int backendPID;
552 : int32 cancelAuthCode;
553 :
554 18 : if (len != sizeof(CancelRequestPacket))
555 : {
556 0 : ereport(COMMERROR,
557 : (errcode(ERRCODE_PROTOCOL_VIOLATION),
558 : errmsg("invalid length of startup packet")));
559 0 : return STATUS_ERROR;
560 : }
561 18 : canc = (CancelRequestPacket *) buf;
562 18 : backendPID = (int) pg_ntoh32(canc->backendPID);
563 18 : cancelAuthCode = (int32) pg_ntoh32(canc->cancelAuthCode);
564 :
565 18 : if (backendPID != 0)
566 18 : SendCancelRequest(backendPID, cancelAuthCode);
567 : /* Not really an error, but we don't want to proceed further */
568 18 : return STATUS_ERROR;
569 : }
570 :
571 25692 : if (proto == NEGOTIATE_SSL_CODE && !ssl_done)
572 : {
573 : char SSLok;
574 :
575 : #ifdef USE_SSL
576 :
577 : /*
578 : * No SSL when disabled or on Unix sockets.
579 : *
580 : * Also no SSL negotiation if we already have a direct SSL connection
581 : */
582 560 : if (!LoadedSSL || port->laddr.addr.ss_family == AF_UNIX || port->ssl_in_use)
583 318 : SSLok = 'N';
584 : else
585 242 : SSLok = 'S'; /* Support for SSL */
586 : #else
587 : SSLok = 'N'; /* No support for SSL */
588 : #endif
589 :
590 560 : if (Trace_connection_negotiation)
591 : {
592 24 : if (SSLok == 'S')
593 16 : ereport(LOG,
594 : (errmsg("SSLRequest accepted")));
595 : else
596 8 : ereport(LOG,
597 : (errmsg("SSLRequest rejected")));
598 : }
599 :
600 560 : while (secure_write(port, &SSLok, 1) != 1)
601 : {
602 0 : if (errno == EINTR)
603 0 : continue; /* if interrupted, just retry */
604 0 : ereport(COMMERROR,
605 : (errcode_for_socket_access(),
606 : errmsg("failed to send SSL negotiation response: %m")));
607 0 : return STATUS_ERROR; /* close the connection */
608 : }
609 :
610 : #ifdef USE_SSL
611 560 : if (SSLok == 'S' && secure_open_server(port) == -1)
612 36 : return STATUS_ERROR;
613 : #endif
614 :
615 : /*
616 : * At this point we should have no data already buffered. If we do,
617 : * it was received before we performed the SSL handshake, so it wasn't
618 : * encrypted and indeed may have been injected by a man-in-the-middle.
619 : * We report this case to the client.
620 : */
621 522 : if (pq_buffer_remaining_data() > 0)
622 0 : ereport(FATAL,
623 : (errcode(ERRCODE_PROTOCOL_VIOLATION),
624 : errmsg("received unencrypted data after SSL request"),
625 : errdetail("This could be either a client-software bug or evidence of an attempted man-in-the-middle attack.")));
626 :
627 : /*
628 : * regular startup packet, cancel, etc packet should follow, but not
629 : * another SSL negotiation request, and a GSS request should only
630 : * follow if SSL was rejected (client may negotiate in either order)
631 : */
632 522 : return ProcessStartupPacket(port, true, SSLok == 'S');
633 : }
634 25132 : else if (proto == NEGOTIATE_GSS_CODE && !gss_done)
635 : {
636 0 : char GSSok = 'N';
637 :
638 : #ifdef ENABLE_GSS
639 : /* No GSSAPI encryption when on Unix socket */
640 : if (port->laddr.addr.ss_family != AF_UNIX)
641 : GSSok = 'G';
642 : #endif
643 :
644 0 : if (Trace_connection_negotiation)
645 : {
646 0 : if (GSSok == 'G')
647 0 : ereport(LOG,
648 : (errmsg("GSSENCRequest accepted")));
649 : else
650 0 : ereport(LOG,
651 : (errmsg("GSSENCRequest rejected")));
652 : }
653 :
654 0 : while (secure_write(port, &GSSok, 1) != 1)
655 : {
656 0 : if (errno == EINTR)
657 0 : continue;
658 0 : ereport(COMMERROR,
659 : (errcode_for_socket_access(),
660 : errmsg("failed to send GSSAPI negotiation response: %m")));
661 0 : return STATUS_ERROR; /* close the connection */
662 : }
663 :
664 : #ifdef ENABLE_GSS
665 : if (GSSok == 'G' && secure_open_gssapi(port) == -1)
666 : return STATUS_ERROR;
667 : #endif
668 :
669 : /*
670 : * At this point we should have no data already buffered. If we do,
671 : * it was received before we performed the GSS handshake, so it wasn't
672 : * encrypted and indeed may have been injected by a man-in-the-middle.
673 : * We report this case to the client.
674 : */
675 0 : if (pq_buffer_remaining_data() > 0)
676 0 : ereport(FATAL,
677 : (errcode(ERRCODE_PROTOCOL_VIOLATION),
678 : errmsg("received unencrypted data after GSSAPI encryption request"),
679 : errdetail("This could be either a client-software bug or evidence of an attempted man-in-the-middle attack.")));
680 :
681 : /*
682 : * regular startup packet, cancel, etc packet should follow, but not
683 : * another GSS negotiation request, and an SSL request should only
684 : * follow if GSS was rejected (client may negotiate in either order)
685 : */
686 0 : return ProcessStartupPacket(port, GSSok == 'G', true);
687 : }
688 :
689 : /* Could add additional special packet types here */
690 :
691 : /*
692 : * Set FrontendProtocol now so that ereport() knows what format to send if
693 : * we fail during startup. We use the protocol version requested by the
694 : * client unless it's higher than the latest version we support. It's
695 : * possible that error message fields might look different in newer
696 : * protocol versions, but that's something those new clients should be
697 : * able to deal with.
698 : */
699 25132 : FrontendProtocol = Min(proto, PG_PROTOCOL_LATEST);
700 :
701 : /* Check that the major protocol version is in range. */
702 25132 : if (PG_PROTOCOL_MAJOR(proto) < PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST) ||
703 25132 : PG_PROTOCOL_MAJOR(proto) > PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST))
704 0 : ereport(FATAL,
705 : (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
706 : errmsg("unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u",
707 : PG_PROTOCOL_MAJOR(proto), PG_PROTOCOL_MINOR(proto),
708 : PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST),
709 : PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST),
710 : PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST))));
711 :
712 : /*
713 : * Now fetch parameters out of startup packet and save them into the Port
714 : * structure.
715 : */
716 25132 : oldcontext = MemoryContextSwitchTo(TopMemoryContext);
717 :
718 : /* Handle protocol version 3 startup packet */
719 : {
720 25132 : int32 offset = sizeof(ProtocolVersion);
721 25132 : List *unrecognized_protocol_options = NIL;
722 :
723 : /*
724 : * Scan packet body for name/option pairs. We can assume any string
725 : * beginning within the packet body is null-terminated, thanks to
726 : * zeroing extra byte above.
727 : */
728 25132 : port->guc_options = NIL;
729 :
730 119188 : while (offset < len)
731 : {
732 119188 : char *nameptr = buf + offset;
733 : int32 valoffset;
734 : char *valptr;
735 :
736 119188 : if (*nameptr == '\0')
737 25132 : break; /* found packet terminator */
738 94056 : valoffset = offset + strlen(nameptr) + 1;
739 94056 : if (valoffset >= len)
740 0 : break; /* missing value, will complain below */
741 94056 : valptr = buf + valoffset;
742 :
743 94056 : if (strcmp(nameptr, "database") == 0)
744 25132 : port->database_name = pstrdup(valptr);
745 68924 : else if (strcmp(nameptr, "user") == 0)
746 25132 : port->user_name = pstrdup(valptr);
747 43792 : else if (strcmp(nameptr, "options") == 0)
748 6336 : port->cmdline_options = pstrdup(valptr);
749 37456 : else if (strcmp(nameptr, "replication") == 0)
750 : {
751 : /*
752 : * Due to backward compatibility concerns the replication
753 : * parameter is a hybrid beast which allows the value to be
754 : * either boolean or the string 'database'. The latter
755 : * connects to a specific database which is e.g. required for
756 : * logical decoding while.
757 : */
758 2078 : if (strcmp(valptr, "database") == 0)
759 : {
760 1172 : am_walsender = true;
761 1172 : am_db_walsender = true;
762 : }
763 906 : else if (!parse_bool(valptr, &am_walsender))
764 0 : ereport(FATAL,
765 : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
766 : errmsg("invalid value for parameter \"%s\": \"%s\"",
767 : "replication",
768 : valptr),
769 : errhint("Valid values are: \"false\", 0, \"true\", 1, \"database\".")));
770 : }
771 35378 : else if (strncmp(nameptr, "_pq_.", 5) == 0)
772 : {
773 : /*
774 : * Any option beginning with _pq_. is reserved for use as a
775 : * protocol-level option, but at present no such options are
776 : * defined.
777 : */
778 : unrecognized_protocol_options =
779 0 : lappend(unrecognized_protocol_options, pstrdup(nameptr));
780 : }
781 : else
782 : {
783 : /* Assume it's a generic GUC option */
784 35378 : port->guc_options = lappend(port->guc_options,
785 35378 : pstrdup(nameptr));
786 35378 : port->guc_options = lappend(port->guc_options,
787 35378 : pstrdup(valptr));
788 :
789 : /*
790 : * Copy application_name to port if we come across it. This
791 : * is done so we can log the application_name in the
792 : * connection authorization message. Note that the GUC would
793 : * be used but we haven't gone through GUC setup yet.
794 : */
795 35378 : if (strcmp(nameptr, "application_name") == 0)
796 : {
797 25130 : port->application_name = pg_clean_ascii(valptr, 0);
798 : }
799 : }
800 94056 : offset = valoffset + strlen(valptr) + 1;
801 : }
802 :
803 : /*
804 : * If we didn't find a packet terminator exactly at the end of the
805 : * given packet length, complain.
806 : */
807 25132 : if (offset != len - 1)
808 0 : ereport(FATAL,
809 : (errcode(ERRCODE_PROTOCOL_VIOLATION),
810 : errmsg("invalid startup packet layout: expected terminator as last byte")));
811 :
812 : /*
813 : * If the client requested a newer protocol version or if the client
814 : * requested any protocol options we didn't recognize, let them know
815 : * the newest minor protocol version we do support and the names of
816 : * any unrecognized options.
817 : */
818 25132 : if (PG_PROTOCOL_MINOR(proto) > PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST) ||
819 : unrecognized_protocol_options != NIL)
820 0 : SendNegotiateProtocolVersion(unrecognized_protocol_options);
821 : }
822 :
823 : /* Check a user name was given. */
824 25132 : if (port->user_name == NULL || port->user_name[0] == '\0')
825 0 : ereport(FATAL,
826 : (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
827 : errmsg("no PostgreSQL user name specified in startup packet")));
828 :
829 : /* The database defaults to the user name. */
830 25132 : if (port->database_name == NULL || port->database_name[0] == '\0')
831 0 : port->database_name = pstrdup(port->user_name);
832 :
833 25132 : if (am_walsender)
834 2078 : MyBackendType = B_WAL_SENDER;
835 : else
836 23054 : MyBackendType = B_BACKEND;
837 :
838 : /*
839 : * Normal walsender backends, e.g. for streaming replication, are not
840 : * connected to a particular database. But walsenders used for logical
841 : * replication need to connect to a specific database. We allow streaming
842 : * replication commands to be issued even if connected to a database as it
843 : * can make sense to first make a basebackup and then stream changes
844 : * starting from that.
845 : */
846 25132 : if (am_walsender && !am_db_walsender)
847 906 : port->database_name[0] = '\0';
848 :
849 : /*
850 : * Done filling the Port structure
851 : */
852 25132 : MemoryContextSwitchTo(oldcontext);
853 :
854 25132 : return STATUS_OK;
855 : }
856 :
857 : /*
858 : * Send a NegotiateProtocolVersion to the client. This lets the client know
859 : * that they have either requested a newer minor protocol version than we are
860 : * able to speak, or at least one protocol option that we don't understand, or
861 : * possibly both. FrontendProtocol has already been set to the version
862 : * requested by the client or the highest version we know how to speak,
863 : * whichever is older. If the highest version that we know how to speak is too
864 : * old for the client, it can abandon the connection.
865 : *
866 : * We also include in the response a list of protocol options we didn't
867 : * understand. This allows clients to include optional parameters that might
868 : * be present either in newer protocol versions or third-party protocol
869 : * extensions without fear of having to reconnect if those options are not
870 : * understood, while at the same time making certain that the client is aware
871 : * of which options were actually accepted.
872 : */
873 : static void
874 0 : SendNegotiateProtocolVersion(List *unrecognized_protocol_options)
875 : {
876 : StringInfoData buf;
877 : ListCell *lc;
878 :
879 0 : pq_beginmessage(&buf, PqMsg_NegotiateProtocolVersion);
880 0 : pq_sendint32(&buf, FrontendProtocol);
881 0 : pq_sendint32(&buf, list_length(unrecognized_protocol_options));
882 0 : foreach(lc, unrecognized_protocol_options)
883 0 : pq_sendstring(&buf, lfirst(lc));
884 0 : pq_endmessage(&buf);
885 :
886 : /* no need to flush, some other message will follow */
887 0 : }
888 :
889 :
890 : /*
891 : * SIGTERM while processing startup packet.
892 : *
893 : * Running proc_exit() from a signal handler would be quite unsafe.
894 : * However, since we have not yet touched shared memory, we can just
895 : * pull the plug and exit without running any atexit handlers.
896 : *
897 : * One might be tempted to try to send a message, or log one, indicating
898 : * why we are disconnecting. However, that would be quite unsafe in itself.
899 : * Also, it seems undesirable to provide clues about the database's state
900 : * to a client that has not yet completed authentication, or even sent us
901 : * a startup packet.
902 : */
903 : static void
904 0 : process_startup_packet_die(SIGNAL_ARGS)
905 : {
906 0 : _exit(1);
907 : }
908 :
909 : /*
910 : * Timeout while processing startup packet.
911 : * As for process_startup_packet_die(), we exit via _exit(1).
912 : */
913 : static void
914 0 : StartupPacketTimeoutHandler(void)
915 : {
916 0 : _exit(1);
917 : }
|