1 /*-------------------------------------------------------------------------
2 *
3 * fe-auth.c
4 * The front-end (client) authorization routines
5 *
6 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * IDENTIFICATION
10 * src/interfaces/libpq/fe-auth.c
11 *
12 *-------------------------------------------------------------------------
13 */
14
15 /*
16 * INTERFACE ROUTINES
17 * frontend (client) routines:
18 * pg_fe_sendauth send authentication information
19 * pg_fe_getauthname get user's name according to the client side
20 * of the authentication system
21 */
22
23 #include "postgres_fe.h"
24
25 #ifdef WIN32
26 #include "win32.h"
27 #else
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <sys/param.h> /* for MAXHOSTNAMELEN on most */
31 #include <sys/socket.h>
32 #ifdef HAVE_SYS_UCRED_H
33 #include <sys/ucred.h>
34 #endif
35 #ifndef MAXHOSTNAMELEN
36 #include <netdb.h> /* for MAXHOSTNAMELEN on some */
37 #endif
38 #include <pwd.h>
39 #endif
40
41 #include "common/md5.h"
42 #include "common/scram-common.h"
43 #include "fe-auth.h"
44 #include "libpq-fe.h"
45
46 #ifdef ENABLE_GSS
47 /*
48 * GSSAPI authentication system.
49 */
50
51 #include "fe-gssapi-common.h"
52
53 /*
54 * Continue GSS authentication with next token as needed.
55 */
56 static int
pg_GSS_continue(PGconn * conn,int payloadlen)57 pg_GSS_continue(PGconn *conn, int payloadlen)
58 {
59 OM_uint32 maj_stat,
60 min_stat,
61 lmin_s;
62 gss_buffer_desc ginbuf;
63 gss_buffer_desc goutbuf;
64
65 /*
66 * On first call, there's no input token. On subsequent calls, read the
67 * input token into a GSS buffer.
68 */
69 if (conn->gctx != GSS_C_NO_CONTEXT)
70 {
71 ginbuf.length = payloadlen;
72 ginbuf.value = malloc(payloadlen);
73 if (!ginbuf.value)
74 {
75 printfPQExpBuffer(&conn->errorMessage,
76 libpq_gettext("out of memory allocating GSSAPI buffer (%d)\n"),
77 payloadlen);
78 return STATUS_ERROR;
79 }
80 if (pqGetnchar(ginbuf.value, payloadlen, conn))
81 {
82 /*
83 * Shouldn't happen, because the caller should've ensured that the
84 * whole message is already in the input buffer.
85 */
86 free(ginbuf.value);
87 return STATUS_ERROR;
88 }
89 }
90 else
91 {
92 ginbuf.length = 0;
93 ginbuf.value = NULL;
94 }
95
96 maj_stat = gss_init_sec_context(&min_stat,
97 GSS_C_NO_CREDENTIAL,
98 &conn->gctx,
99 conn->gtarg_nam,
100 GSS_C_NO_OID,
101 GSS_C_MUTUAL_FLAG,
102 0,
103 GSS_C_NO_CHANNEL_BINDINGS,
104 (ginbuf.value == NULL) ? GSS_C_NO_BUFFER : &ginbuf,
105 NULL,
106 &goutbuf,
107 NULL,
108 NULL);
109
110 if (ginbuf.value)
111 free(ginbuf.value);
112
113 if (goutbuf.length != 0)
114 {
115 /*
116 * GSS generated data to send to the server. We don't care if it's the
117 * first or subsequent packet, just send the same kind of password
118 * packet.
119 */
120 if (pqPacketSend(conn, 'p',
121 goutbuf.value, goutbuf.length) != STATUS_OK)
122 {
123 gss_release_buffer(&lmin_s, &goutbuf);
124 return STATUS_ERROR;
125 }
126 }
127 gss_release_buffer(&lmin_s, &goutbuf);
128
129 if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
130 {
131 pg_GSS_error(libpq_gettext("GSSAPI continuation error"),
132 conn,
133 maj_stat, min_stat);
134 gss_release_name(&lmin_s, &conn->gtarg_nam);
135 if (conn->gctx)
136 gss_delete_sec_context(&lmin_s, &conn->gctx, GSS_C_NO_BUFFER);
137 return STATUS_ERROR;
138 }
139
140 if (maj_stat == GSS_S_COMPLETE)
141 gss_release_name(&lmin_s, &conn->gtarg_nam);
142
143 return STATUS_OK;
144 }
145
146 /*
147 * Send initial GSS authentication token
148 */
149 static int
pg_GSS_startup(PGconn * conn,int payloadlen)150 pg_GSS_startup(PGconn *conn, int payloadlen)
151 {
152 int ret;
153 char *host = conn->connhost[conn->whichhost].host;
154
155 if (!(host && host[0] != '\0'))
156 {
157 printfPQExpBuffer(&conn->errorMessage,
158 libpq_gettext("host name must be specified\n"));
159 return STATUS_ERROR;
160 }
161
162 if (conn->gctx)
163 {
164 printfPQExpBuffer(&conn->errorMessage,
165 libpq_gettext("duplicate GSS authentication request\n"));
166 return STATUS_ERROR;
167 }
168
169 ret = pg_GSS_load_servicename(conn);
170 if (ret != STATUS_OK)
171 return ret;
172
173 /*
174 * Initial packet is the same as a continuation packet with no initial
175 * context.
176 */
177 conn->gctx = GSS_C_NO_CONTEXT;
178
179 return pg_GSS_continue(conn, payloadlen);
180 }
181 #endif /* ENABLE_GSS */
182
183
184 #ifdef ENABLE_SSPI
185 /*
186 * SSPI authentication system (Windows only)
187 */
188
189 static void
pg_SSPI_error(PGconn * conn,const char * mprefix,SECURITY_STATUS r)190 pg_SSPI_error(PGconn *conn, const char *mprefix, SECURITY_STATUS r)
191 {
192 char sysmsg[256];
193
194 if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
195 FORMAT_MESSAGE_FROM_SYSTEM,
196 NULL, r, 0,
197 sysmsg, sizeof(sysmsg), NULL) == 0)
198 printfPQExpBuffer(&conn->errorMessage, "%s: SSPI error %x\n",
199 mprefix, (unsigned int) r);
200 else
201 printfPQExpBuffer(&conn->errorMessage, "%s: %s (%x)\n",
202 mprefix, sysmsg, (unsigned int) r);
203 }
204
205 /*
206 * Continue SSPI authentication with next token as needed.
207 */
208 static int
pg_SSPI_continue(PGconn * conn,int payloadlen)209 pg_SSPI_continue(PGconn *conn, int payloadlen)
210 {
211 SECURITY_STATUS r;
212 CtxtHandle newContext;
213 ULONG contextAttr;
214 SecBufferDesc inbuf;
215 SecBufferDesc outbuf;
216 SecBuffer OutBuffers[1];
217 SecBuffer InBuffers[1];
218 char *inputbuf = NULL;
219
220 if (conn->sspictx != NULL)
221 {
222 /*
223 * On runs other than the first we have some data to send. Put this
224 * data in a SecBuffer type structure.
225 */
226 inputbuf = malloc(payloadlen);
227 if (!inputbuf)
228 {
229 printfPQExpBuffer(&conn->errorMessage,
230 libpq_gettext("out of memory allocating SSPI buffer (%d)\n"),
231 payloadlen);
232 return STATUS_ERROR;
233 }
234 if (pqGetnchar(inputbuf, payloadlen, conn))
235 {
236 /*
237 * Shouldn't happen, because the caller should've ensured that the
238 * whole message is already in the input buffer.
239 */
240 free(inputbuf);
241 return STATUS_ERROR;
242 }
243
244 inbuf.ulVersion = SECBUFFER_VERSION;
245 inbuf.cBuffers = 1;
246 inbuf.pBuffers = InBuffers;
247 InBuffers[0].pvBuffer = inputbuf;
248 InBuffers[0].cbBuffer = payloadlen;
249 InBuffers[0].BufferType = SECBUFFER_TOKEN;
250 }
251
252 OutBuffers[0].pvBuffer = NULL;
253 OutBuffers[0].BufferType = SECBUFFER_TOKEN;
254 OutBuffers[0].cbBuffer = 0;
255 outbuf.cBuffers = 1;
256 outbuf.pBuffers = OutBuffers;
257 outbuf.ulVersion = SECBUFFER_VERSION;
258
259 r = InitializeSecurityContext(conn->sspicred,
260 conn->sspictx,
261 conn->sspitarget,
262 ISC_REQ_ALLOCATE_MEMORY,
263 0,
264 SECURITY_NETWORK_DREP,
265 (conn->sspictx == NULL) ? NULL : &inbuf,
266 0,
267 &newContext,
268 &outbuf,
269 &contextAttr,
270 NULL);
271
272 /* we don't need the input anymore */
273 if (inputbuf)
274 free(inputbuf);
275
276 if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED)
277 {
278 pg_SSPI_error(conn, libpq_gettext("SSPI continuation error"), r);
279
280 return STATUS_ERROR;
281 }
282
283 if (conn->sspictx == NULL)
284 {
285 /* On first run, transfer retrieved context handle */
286 conn->sspictx = malloc(sizeof(CtxtHandle));
287 if (conn->sspictx == NULL)
288 {
289 printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
290 return STATUS_ERROR;
291 }
292 memcpy(conn->sspictx, &newContext, sizeof(CtxtHandle));
293 }
294
295 /*
296 * If SSPI returned any data to be sent to the server (as it normally
297 * would), send this data as a password packet.
298 */
299 if (outbuf.cBuffers > 0)
300 {
301 if (outbuf.cBuffers != 1)
302 {
303 /*
304 * This should never happen, at least not for Kerberos
305 * authentication. Keep check in case it shows up with other
306 * authentication methods later.
307 */
308 printfPQExpBuffer(&conn->errorMessage, "SSPI returned invalid number of output buffers\n");
309 return STATUS_ERROR;
310 }
311
312 /*
313 * If the negotiation is complete, there may be zero bytes to send.
314 * The server is at this point not expecting any more data, so don't
315 * send it.
316 */
317 if (outbuf.pBuffers[0].cbBuffer > 0)
318 {
319 if (pqPacketSend(conn, 'p',
320 outbuf.pBuffers[0].pvBuffer, outbuf.pBuffers[0].cbBuffer))
321 {
322 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
323 return STATUS_ERROR;
324 }
325 }
326 FreeContextBuffer(outbuf.pBuffers[0].pvBuffer);
327 }
328
329 /* Cleanup is handled by the code in freePGconn() */
330 return STATUS_OK;
331 }
332
333 /*
334 * Send initial SSPI authentication token.
335 * If use_negotiate is 0, use kerberos authentication package which is
336 * compatible with Unix. If use_negotiate is 1, use the negotiate package
337 * which supports both kerberos and NTLM, but is not compatible with Unix.
338 */
339 static int
pg_SSPI_startup(PGconn * conn,int use_negotiate,int payloadlen)340 pg_SSPI_startup(PGconn *conn, int use_negotiate, int payloadlen)
341 {
342 SECURITY_STATUS r;
343 TimeStamp expire;
344 char *host = conn->connhost[conn->whichhost].host;
345
346 if (conn->sspictx)
347 {
348 printfPQExpBuffer(&conn->errorMessage,
349 libpq_gettext("duplicate SSPI authentication request\n"));
350 return STATUS_ERROR;
351 }
352
353 /*
354 * Retrieve credentials handle
355 */
356 conn->sspicred = malloc(sizeof(CredHandle));
357 if (conn->sspicred == NULL)
358 {
359 printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
360 return STATUS_ERROR;
361 }
362
363 r = AcquireCredentialsHandle(NULL,
364 use_negotiate ? "negotiate" : "kerberos",
365 SECPKG_CRED_OUTBOUND,
366 NULL,
367 NULL,
368 NULL,
369 NULL,
370 conn->sspicred,
371 &expire);
372 if (r != SEC_E_OK)
373 {
374 pg_SSPI_error(conn, libpq_gettext("could not acquire SSPI credentials"), r);
375 free(conn->sspicred);
376 conn->sspicred = NULL;
377 return STATUS_ERROR;
378 }
379
380 /*
381 * Compute target principal name. SSPI has a different format from GSSAPI,
382 * but not more complex. We can skip the @REALM part, because Windows will
383 * fill that in for us automatically.
384 */
385 if (!(host && host[0] != '\0'))
386 {
387 printfPQExpBuffer(&conn->errorMessage,
388 libpq_gettext("host name must be specified\n"));
389 return STATUS_ERROR;
390 }
391 conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(host) + 2);
392 if (!conn->sspitarget)
393 {
394 printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
395 return STATUS_ERROR;
396 }
397 sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, host);
398
399 /*
400 * Indicate that we're in SSPI authentication mode to make sure that
401 * pg_SSPI_continue is called next time in the negotiation.
402 */
403 conn->usesspi = 1;
404
405 return pg_SSPI_continue(conn, payloadlen);
406 }
407 #endif /* ENABLE_SSPI */
408
409 /*
410 * Initialize SASL authentication exchange.
411 */
412 static int
pg_SASL_init(PGconn * conn,int payloadlen)413 pg_SASL_init(PGconn *conn, int payloadlen)
414 {
415 char *initialresponse = NULL;
416 int initialresponselen;
417 bool done;
418 bool success;
419 const char *selected_mechanism;
420 PQExpBufferData mechanism_buf;
421 char *password;
422
423 initPQExpBuffer(&mechanism_buf);
424
425 if (conn->channel_binding[0] == 'r' && /* require */
426 !conn->ssl_in_use)
427 {
428 printfPQExpBuffer(&conn->errorMessage,
429 libpq_gettext("channel binding required, but SSL not in use\n"));
430 goto error;
431 }
432
433 if (conn->sasl_state)
434 {
435 printfPQExpBuffer(&conn->errorMessage,
436 libpq_gettext("duplicate SASL authentication request\n"));
437 goto error;
438 }
439
440 /*
441 * Parse the list of SASL authentication mechanisms in the
442 * AuthenticationSASL message, and select the best mechanism that we
443 * support. SCRAM-SHA-256-PLUS and SCRAM-SHA-256 are the only ones
444 * supported at the moment, listed by order of decreasing importance.
445 */
446 selected_mechanism = NULL;
447 for (;;)
448 {
449 if (pqGets(&mechanism_buf, conn))
450 {
451 printfPQExpBuffer(&conn->errorMessage,
452 "fe_sendauth: invalid authentication request from server: invalid list of authentication mechanisms\n");
453 goto error;
454 }
455 if (PQExpBufferDataBroken(mechanism_buf))
456 goto oom_error;
457
458 /* An empty string indicates end of list */
459 if (mechanism_buf.data[0] == '\0')
460 break;
461
462 /*
463 * Select the mechanism to use. Pick SCRAM-SHA-256-PLUS over anything
464 * else if a channel binding type is set and if the client supports it
465 * (and did not set channel_binding=disable). Pick SCRAM-SHA-256 if
466 * nothing else has already been picked. If we add more mechanisms, a
467 * more refined priority mechanism might become necessary.
468 */
469 if (strcmp(mechanism_buf.data, SCRAM_SHA_256_PLUS_NAME) == 0)
470 {
471 if (conn->ssl_in_use)
472 {
473 /* The server has offered SCRAM-SHA-256-PLUS. */
474
475 #ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
476 /*
477 * The client supports channel binding, which is chosen if
478 * channel_binding is not disabled.
479 */
480 if (conn->channel_binding[0] != 'd') /* disable */
481 selected_mechanism = SCRAM_SHA_256_PLUS_NAME;
482 #else
483 /*
484 * The client does not support channel binding. If it is
485 * required, complain immediately instead of the error below
486 * which would be confusing as the server is publishing
487 * SCRAM-SHA-256-PLUS.
488 */
489 if (conn->channel_binding[0] == 'r') /* require */
490 {
491 printfPQExpBuffer(&conn->errorMessage,
492 libpq_gettext("channel binding is required, but client does not support it\n"));
493 goto error;
494 }
495 #endif
496 }
497 else
498 {
499 /*
500 * The server offered SCRAM-SHA-256-PLUS, but the connection
501 * is not SSL-encrypted. That's not sane. Perhaps SSL was
502 * stripped by a proxy? There's no point in continuing,
503 * because the server will reject the connection anyway if we
504 * try authenticate without channel binding even though both
505 * the client and server supported it. The SCRAM exchange
506 * checks for that, to prevent downgrade attacks.
507 */
508 printfPQExpBuffer(&conn->errorMessage,
509 libpq_gettext("server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n"));
510 goto error;
511 }
512 }
513 else if (strcmp(mechanism_buf.data, SCRAM_SHA_256_NAME) == 0 &&
514 !selected_mechanism)
515 selected_mechanism = SCRAM_SHA_256_NAME;
516 }
517
518 if (!selected_mechanism)
519 {
520 printfPQExpBuffer(&conn->errorMessage,
521 libpq_gettext("none of the server's SASL authentication mechanisms are supported\n"));
522 goto error;
523 }
524
525 if (conn->channel_binding[0] == 'r' && /* require */
526 strcmp(selected_mechanism, SCRAM_SHA_256_PLUS_NAME) != 0)
527 {
528 printfPQExpBuffer(&conn->errorMessage,
529 libpq_gettext("channel binding is required, but server did not offer an authentication method that supports channel binding\n"));
530 goto error;
531 }
532
533 /*
534 * Now that the SASL mechanism has been chosen for the exchange,
535 * initialize its state information.
536 */
537
538 /*
539 * First, select the password to use for the exchange, complaining if
540 * there isn't one. Currently, all supported SASL mechanisms require a
541 * password, so we can just go ahead here without further distinction.
542 */
543 conn->password_needed = true;
544 password = conn->connhost[conn->whichhost].password;
545 if (password == NULL)
546 password = conn->pgpass;
547 if (password == NULL || password[0] == '\0')
548 {
549 printfPQExpBuffer(&conn->errorMessage,
550 PQnoPasswordSupplied);
551 goto error;
552 }
553
554 /*
555 * Initialize the SASL state information with all the information gathered
556 * during the initial exchange.
557 *
558 * Note: Only tls-unique is supported for the moment.
559 */
560 conn->sasl_state = pg_fe_scram_init(conn,
561 password,
562 selected_mechanism);
563 if (!conn->sasl_state)
564 goto oom_error;
565
566 /* Get the mechanism-specific Initial Client Response, if any */
567 pg_fe_scram_exchange(conn->sasl_state,
568 NULL, -1,
569 &initialresponse, &initialresponselen,
570 &done, &success);
571
572 if (done && !success)
573 goto error;
574
575 /*
576 * Build a SASLInitialResponse message, and send it.
577 */
578 if (pqPutMsgStart('p', true, conn))
579 goto error;
580 if (pqPuts(selected_mechanism, conn))
581 goto error;
582 if (initialresponse)
583 {
584 if (pqPutInt(initialresponselen, 4, conn))
585 goto error;
586 if (pqPutnchar(initialresponse, initialresponselen, conn))
587 goto error;
588 }
589 if (pqPutMsgEnd(conn))
590 goto error;
591 if (pqFlush(conn))
592 goto error;
593
594 termPQExpBuffer(&mechanism_buf);
595 if (initialresponse)
596 free(initialresponse);
597
598 return STATUS_OK;
599
600 error:
601 termPQExpBuffer(&mechanism_buf);
602 if (initialresponse)
603 free(initialresponse);
604 return STATUS_ERROR;
605
606 oom_error:
607 termPQExpBuffer(&mechanism_buf);
608 if (initialresponse)
609 free(initialresponse);
610 printfPQExpBuffer(&conn->errorMessage,
611 libpq_gettext("out of memory\n"));
612 return STATUS_ERROR;
613 }
614
615 /*
616 * Exchange a message for SASL communication protocol with the backend.
617 * This should be used after calling pg_SASL_init to set up the status of
618 * the protocol.
619 */
620 static int
pg_SASL_continue(PGconn * conn,int payloadlen,bool final)621 pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
622 {
623 char *output;
624 int outputlen;
625 bool done;
626 bool success;
627 int res;
628 char *challenge;
629
630 /* Read the SASL challenge from the AuthenticationSASLContinue message. */
631 challenge = malloc(payloadlen + 1);
632 if (!challenge)
633 {
634 printfPQExpBuffer(&conn->errorMessage,
635 libpq_gettext("out of memory allocating SASL buffer (%d)\n"),
636 payloadlen);
637 return STATUS_ERROR;
638 }
639
640 if (pqGetnchar(challenge, payloadlen, conn))
641 {
642 free(challenge);
643 return STATUS_ERROR;
644 }
645 /* For safety and convenience, ensure the buffer is NULL-terminated. */
646 challenge[payloadlen] = '\0';
647
648 pg_fe_scram_exchange(conn->sasl_state,
649 challenge, payloadlen,
650 &output, &outputlen,
651 &done, &success);
652 free(challenge); /* don't need the input anymore */
653
654 if (final && !done)
655 {
656 if (outputlen != 0)
657 free(output);
658
659 printfPQExpBuffer(&conn->errorMessage,
660 libpq_gettext("AuthenticationSASLFinal received from server, but SASL authentication was not completed\n"));
661 return STATUS_ERROR;
662 }
663 if (outputlen != 0)
664 {
665 /*
666 * Send the SASL response to the server.
667 */
668 res = pqPacketSend(conn, 'p', output, outputlen);
669 free(output);
670
671 if (res != STATUS_OK)
672 return STATUS_ERROR;
673 }
674
675 if (done && !success)
676 return STATUS_ERROR;
677
678 return STATUS_OK;
679 }
680
681 /*
682 * Respond to AUTH_REQ_SCM_CREDS challenge.
683 *
684 * Note: this is dead code as of Postgres 9.1, because current backends will
685 * never send this challenge. But we must keep it as long as libpq needs to
686 * interoperate with pre-9.1 servers. It is believed to be needed only on
687 * Debian/kFreeBSD (ie, FreeBSD kernel with Linux userland, so that the
688 * getpeereid() function isn't provided by libc).
689 */
690 static int
pg_local_sendauth(PGconn * conn)691 pg_local_sendauth(PGconn *conn)
692 {
693 #ifdef HAVE_STRUCT_CMSGCRED
694 char buf;
695 struct iovec iov;
696 struct msghdr msg;
697 struct cmsghdr *cmsg;
698 union
699 {
700 struct cmsghdr hdr;
701 unsigned char buf[CMSG_SPACE(sizeof(struct cmsgcred))];
702 } cmsgbuf;
703
704 /*
705 * The backend doesn't care what we send here, but it wants exactly one
706 * character to force recvmsg() to block and wait for us.
707 */
708 buf = '\0';
709 iov.iov_base = &buf;
710 iov.iov_len = 1;
711
712 memset(&msg, 0, sizeof(msg));
713 msg.msg_iov = &iov;
714 msg.msg_iovlen = 1;
715
716 /* We must set up a message that will be filled in by kernel */
717 memset(&cmsgbuf, 0, sizeof(cmsgbuf));
718 msg.msg_control = &cmsgbuf.buf;
719 msg.msg_controllen = sizeof(cmsgbuf.buf);
720 cmsg = CMSG_FIRSTHDR(&msg);
721 cmsg->cmsg_len = CMSG_LEN(sizeof(struct cmsgcred));
722 cmsg->cmsg_level = SOL_SOCKET;
723 cmsg->cmsg_type = SCM_CREDS;
724
725 if (sendmsg(conn->sock, &msg, 0) == -1)
726 {
727 char sebuf[PG_STRERROR_R_BUFLEN];
728
729 printfPQExpBuffer(&conn->errorMessage,
730 "pg_local_sendauth: sendmsg: %s\n",
731 strerror_r(errno, sebuf, sizeof(sebuf)));
732 return STATUS_ERROR;
733 }
734 return STATUS_OK;
735 #else
736 printfPQExpBuffer(&conn->errorMessage,
737 libpq_gettext("SCM_CRED authentication method not supported\n"));
738 return STATUS_ERROR;
739 #endif
740 }
741
742 static int
pg_password_sendauth(PGconn * conn,const char * password,AuthRequest areq)743 pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
744 {
745 int ret;
746 char *crypt_pwd = NULL;
747 const char *pwd_to_send;
748 char md5Salt[4];
749
750 /* Read the salt from the AuthenticationMD5Password message. */
751 if (areq == AUTH_REQ_MD5)
752 {
753 if (pqGetnchar(md5Salt, 4, conn))
754 return STATUS_ERROR; /* shouldn't happen */
755 }
756
757 /* Encrypt the password if needed. */
758
759 switch (areq)
760 {
761 case AUTH_REQ_MD5:
762 {
763 char *crypt_pwd2;
764
765 /* Allocate enough space for two MD5 hashes */
766 crypt_pwd = malloc(2 * (MD5_PASSWD_LEN + 1));
767 if (!crypt_pwd)
768 {
769 printfPQExpBuffer(&conn->errorMessage,
770 libpq_gettext("out of memory\n"));
771 return STATUS_ERROR;
772 }
773
774 crypt_pwd2 = crypt_pwd + MD5_PASSWD_LEN + 1;
775 if (!pg_md5_encrypt(password, conn->pguser,
776 strlen(conn->pguser), crypt_pwd2))
777 {
778 free(crypt_pwd);
779 return STATUS_ERROR;
780 }
781 if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"), md5Salt,
782 4, crypt_pwd))
783 {
784 free(crypt_pwd);
785 return STATUS_ERROR;
786 }
787
788 pwd_to_send = crypt_pwd;
789 break;
790 }
791 case AUTH_REQ_PASSWORD:
792 pwd_to_send = password;
793 break;
794 default:
795 return STATUS_ERROR;
796 }
797 /* Packet has a message type as of protocol 3.0 */
798 if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
799 ret = pqPacketSend(conn, 'p', pwd_to_send, strlen(pwd_to_send) + 1);
800 else
801 ret = pqPacketSend(conn, 0, pwd_to_send, strlen(pwd_to_send) + 1);
802 if (crypt_pwd)
803 free(crypt_pwd);
804 return ret;
805 }
806
807 /*
808 * Verify that the authentication request is expected, given the connection
809 * parameters. This is especially important when the client wishes to
810 * authenticate the server before any sensitive information is exchanged.
811 */
812 static bool
check_expected_areq(AuthRequest areq,PGconn * conn)813 check_expected_areq(AuthRequest areq, PGconn *conn)
814 {
815 bool result = true;
816
817 /*
818 * When channel_binding=require, we must protect against two cases: (1) we
819 * must not respond to non-SASL authentication requests, which might leak
820 * information such as the client's password; and (2) even if we receive
821 * AUTH_REQ_OK, we still must ensure that channel binding has happened in
822 * order to authenticate the server.
823 */
824 if (conn->channel_binding[0] == 'r' /* require */ )
825 {
826 switch (areq)
827 {
828 case AUTH_REQ_SASL:
829 case AUTH_REQ_SASL_CONT:
830 case AUTH_REQ_SASL_FIN:
831 break;
832 case AUTH_REQ_OK:
833 if (!pg_fe_scram_channel_bound(conn->sasl_state))
834 {
835 printfPQExpBuffer(&conn->errorMessage,
836 libpq_gettext("channel binding required, but server authenticated client without channel binding\n"));
837 result = false;
838 }
839 break;
840 default:
841 printfPQExpBuffer(&conn->errorMessage,
842 libpq_gettext("channel binding required but not supported by server's authentication request\n"));
843 result = false;
844 break;
845 }
846 }
847
848 return result;
849 }
850
851 /*
852 * pg_fe_sendauth
853 * client demux routine for processing an authentication request
854 *
855 * The server has sent us an authentication challenge (or OK). Send an
856 * appropriate response. The caller has ensured that the whole message is
857 * now in the input buffer, and has already read the type and length of
858 * it. We are responsible for reading any remaining extra data, specific
859 * to the authentication method. 'payloadlen' is the remaining length in
860 * the message.
861 */
862 int
pg_fe_sendauth(AuthRequest areq,int payloadlen,PGconn * conn)863 pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
864 {
865 if (!check_expected_areq(areq, conn))
866 return STATUS_ERROR;
867
868 switch (areq)
869 {
870 case AUTH_REQ_OK:
871 break;
872
873 case AUTH_REQ_KRB4:
874 printfPQExpBuffer(&conn->errorMessage,
875 libpq_gettext("Kerberos 4 authentication not supported\n"));
876 return STATUS_ERROR;
877
878 case AUTH_REQ_KRB5:
879 printfPQExpBuffer(&conn->errorMessage,
880 libpq_gettext("Kerberos 5 authentication not supported\n"));
881 return STATUS_ERROR;
882
883 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
884 case AUTH_REQ_GSS:
885 #if !defined(ENABLE_SSPI)
886 /* no native SSPI, so use GSSAPI library for it */
887 case AUTH_REQ_SSPI:
888 #endif
889 {
890 int r;
891
892 pglock_thread();
893
894 /*
895 * If we have both GSS and SSPI support compiled in, use SSPI
896 * support by default. This is overridable by a connection
897 * string parameter. Note that when using SSPI we still leave
898 * the negotiate parameter off, since we want SSPI to use the
899 * GSSAPI kerberos protocol. For actual SSPI negotiate
900 * protocol, we use AUTH_REQ_SSPI.
901 */
902 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
903 if (conn->gsslib && (pg_strcasecmp(conn->gsslib, "gssapi") == 0))
904 r = pg_GSS_startup(conn, payloadlen);
905 else
906 r = pg_SSPI_startup(conn, 0, payloadlen);
907 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
908 r = pg_GSS_startup(conn, payloadlen);
909 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
910 r = pg_SSPI_startup(conn, 0, payloadlen);
911 #endif
912 if (r != STATUS_OK)
913 {
914 /* Error message already filled in. */
915 pgunlock_thread();
916 return STATUS_ERROR;
917 }
918 pgunlock_thread();
919 }
920 break;
921
922 case AUTH_REQ_GSS_CONT:
923 {
924 int r;
925
926 pglock_thread();
927 #if defined(ENABLE_GSS) && defined(ENABLE_SSPI)
928 if (conn->usesspi)
929 r = pg_SSPI_continue(conn, payloadlen);
930 else
931 r = pg_GSS_continue(conn, payloadlen);
932 #elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI)
933 r = pg_GSS_continue(conn, payloadlen);
934 #elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI)
935 r = pg_SSPI_continue(conn, payloadlen);
936 #endif
937 if (r != STATUS_OK)
938 {
939 /* Error message already filled in. */
940 pgunlock_thread();
941 return STATUS_ERROR;
942 }
943 pgunlock_thread();
944 }
945 break;
946 #else /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
947 /* No GSSAPI *or* SSPI support */
948 case AUTH_REQ_GSS:
949 case AUTH_REQ_GSS_CONT:
950 printfPQExpBuffer(&conn->errorMessage,
951 libpq_gettext("GSSAPI authentication not supported\n"));
952 return STATUS_ERROR;
953 #endif /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
954
955 #ifdef ENABLE_SSPI
956 case AUTH_REQ_SSPI:
957
958 /*
959 * SSPI has its own startup message so libpq can decide which
960 * method to use. Indicate to pg_SSPI_startup that we want SSPI
961 * negotiation instead of Kerberos.
962 */
963 pglock_thread();
964 if (pg_SSPI_startup(conn, 1, payloadlen) != STATUS_OK)
965 {
966 /* Error message already filled in. */
967 pgunlock_thread();
968 return STATUS_ERROR;
969 }
970 pgunlock_thread();
971 break;
972 #else
973
974 /*
975 * No SSPI support. However, if we have GSSAPI but not SSPI
976 * support, AUTH_REQ_SSPI will have been handled in the codepath
977 * for AUTH_REQ_GSS above, so don't duplicate the case label in
978 * that case.
979 */
980 #if !defined(ENABLE_GSS)
981 case AUTH_REQ_SSPI:
982 printfPQExpBuffer(&conn->errorMessage,
983 libpq_gettext("SSPI authentication not supported\n"));
984 return STATUS_ERROR;
985 #endif /* !define(ENABLE_GSS) */
986 #endif /* ENABLE_SSPI */
987
988
989 case AUTH_REQ_CRYPT:
990 printfPQExpBuffer(&conn->errorMessage,
991 libpq_gettext("Crypt authentication not supported\n"));
992 return STATUS_ERROR;
993
994 case AUTH_REQ_MD5:
995 case AUTH_REQ_PASSWORD:
996 {
997 char *password;
998
999 conn->password_needed = true;
1000 password = conn->connhost[conn->whichhost].password;
1001 if (password == NULL)
1002 password = conn->pgpass;
1003 if (password == NULL || password[0] == '\0')
1004 {
1005 printfPQExpBuffer(&conn->errorMessage,
1006 PQnoPasswordSupplied);
1007 return STATUS_ERROR;
1008 }
1009 if (pg_password_sendauth(conn, password, areq) != STATUS_OK)
1010 {
1011 printfPQExpBuffer(&conn->errorMessage,
1012 "fe_sendauth: error sending password authentication\n");
1013 return STATUS_ERROR;
1014 }
1015 break;
1016 }
1017
1018 case AUTH_REQ_SASL:
1019
1020 /*
1021 * The request contains the name (as assigned by IANA) of the
1022 * authentication mechanism.
1023 */
1024 if (pg_SASL_init(conn, payloadlen) != STATUS_OK)
1025 {
1026 /* pg_SASL_init already set the error message */
1027 return STATUS_ERROR;
1028 }
1029 break;
1030
1031 case AUTH_REQ_SASL_CONT:
1032 case AUTH_REQ_SASL_FIN:
1033 if (conn->sasl_state == NULL)
1034 {
1035 printfPQExpBuffer(&conn->errorMessage,
1036 "fe_sendauth: invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL\n");
1037 return STATUS_ERROR;
1038 }
1039 if (pg_SASL_continue(conn, payloadlen,
1040 (areq == AUTH_REQ_SASL_FIN)) != STATUS_OK)
1041 {
1042 /* Use error message, if set already */
1043 if (conn->errorMessage.len == 0)
1044 printfPQExpBuffer(&conn->errorMessage,
1045 "fe_sendauth: error in SASL authentication\n");
1046 return STATUS_ERROR;
1047 }
1048 break;
1049
1050 case AUTH_REQ_SCM_CREDS:
1051 if (pg_local_sendauth(conn) != STATUS_OK)
1052 return STATUS_ERROR;
1053 break;
1054
1055 default:
1056 printfPQExpBuffer(&conn->errorMessage,
1057 libpq_gettext("authentication method %u not supported\n"), areq);
1058 return STATUS_ERROR;
1059 }
1060
1061 return STATUS_OK;
1062 }
1063
1064
1065 /*
1066 * pg_fe_getauthname
1067 *
1068 * Returns a pointer to malloc'd space containing whatever name the user
1069 * has authenticated to the system. If there is an error, return NULL,
1070 * and put a suitable error message in *errorMessage if that's not NULL.
1071 */
1072 char *
pg_fe_getauthname(PQExpBuffer errorMessage)1073 pg_fe_getauthname(PQExpBuffer errorMessage)
1074 {
1075 char *result = NULL;
1076 const char *name = NULL;
1077
1078 #ifdef WIN32
1079 /* Microsoft recommends buffer size of UNLEN+1, where UNLEN = 256 */
1080 char username[256 + 1];
1081 DWORD namesize = sizeof(username);
1082 #else
1083 uid_t user_id = geteuid();
1084 char pwdbuf[BUFSIZ];
1085 struct passwd pwdstr;
1086 struct passwd *pw = NULL;
1087 int pwerr;
1088 #endif
1089
1090 /*
1091 * Some users are using configure --enable-thread-safety-force, so we
1092 * might as well do the locking within our library to protect
1093 * pqGetpwuid(). In fact, application developers can use getpwuid() in
1094 * their application if they use the locking call we provide, or install
1095 * their own locking function using PQregisterThreadLock().
1096 */
1097 pglock_thread();
1098
1099 #ifdef WIN32
1100 if (GetUserName(username, &namesize))
1101 name = username;
1102 else if (errorMessage)
1103 printfPQExpBuffer(errorMessage,
1104 libpq_gettext("user name lookup failure: error code %lu\n"),
1105 GetLastError());
1106 #else
1107 pwerr = pqGetpwuid(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw);
1108 if (pw != NULL)
1109 name = pw->pw_name;
1110 else if (errorMessage)
1111 {
1112 if (pwerr != 0)
1113 printfPQExpBuffer(errorMessage,
1114 libpq_gettext("could not look up local user ID %d: %s\n"),
1115 (int) user_id,
1116 strerror_r(pwerr, pwdbuf, sizeof(pwdbuf)));
1117 else
1118 printfPQExpBuffer(errorMessage,
1119 libpq_gettext("local user with ID %d does not exist\n"),
1120 (int) user_id);
1121 }
1122 #endif
1123
1124 if (name)
1125 {
1126 result = strdup(name);
1127 if (result == NULL && errorMessage)
1128 printfPQExpBuffer(errorMessage,
1129 libpq_gettext("out of memory\n"));
1130 }
1131
1132 pgunlock_thread();
1133
1134 return result;
1135 }
1136
1137
1138 /*
1139 * PQencryptPassword -- exported routine to encrypt a password with MD5
1140 *
1141 * This function is equivalent to calling PQencryptPasswordConn with
1142 * "md5" as the encryption method, except that this doesn't require
1143 * a connection object. This function is deprecated, use
1144 * PQencryptPasswordConn instead.
1145 */
1146 char *
PQencryptPassword(const char * passwd,const char * user)1147 PQencryptPassword(const char *passwd, const char *user)
1148 {
1149 char *crypt_pwd;
1150
1151 crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
1152 if (!crypt_pwd)
1153 return NULL;
1154
1155 if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd))
1156 {
1157 free(crypt_pwd);
1158 return NULL;
1159 }
1160
1161 return crypt_pwd;
1162 }
1163
1164 /*
1165 * PQencryptPasswordConn -- exported routine to encrypt a password
1166 *
1167 * This is intended to be used by client applications that wish to send
1168 * commands like ALTER USER joe PASSWORD 'pwd'. The password need not
1169 * be sent in cleartext if it is encrypted on the client side. This is
1170 * good because it ensures the cleartext password won't end up in logs,
1171 * pg_stat displays, etc. We export the function so that clients won't
1172 * be dependent on low-level details like whether the encryption is MD5
1173 * or something else.
1174 *
1175 * Arguments are a connection object, the cleartext password, the SQL
1176 * name of the user it is for, and a string indicating the algorithm to
1177 * use for encrypting the password. If algorithm is NULL, this queries
1178 * the server for the current 'password_encryption' value. If you wish
1179 * to avoid that, e.g. to avoid blocking, you can execute
1180 * 'show password_encryption' yourself before calling this function, and
1181 * pass it as the algorithm.
1182 *
1183 * Return value is a malloc'd string. The client may assume the string
1184 * doesn't contain any special characters that would require escaping.
1185 * On error, an error message is stored in the connection object, and
1186 * returns NULL.
1187 */
1188 char *
PQencryptPasswordConn(PGconn * conn,const char * passwd,const char * user,const char * algorithm)1189 PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
1190 const char *algorithm)
1191 {
1192 #define MAX_ALGORITHM_NAME_LEN 50
1193 char algobuf[MAX_ALGORITHM_NAME_LEN + 1];
1194 char *crypt_pwd = NULL;
1195
1196 if (!conn)
1197 return NULL;
1198
1199 /* If no algorithm was given, ask the server. */
1200 if (algorithm == NULL)
1201 {
1202 PGresult *res;
1203 char *val;
1204
1205 res = PQexec(conn, "show password_encryption");
1206 if (res == NULL)
1207 {
1208 /* PQexec() should've set conn->errorMessage already */
1209 return NULL;
1210 }
1211 if (PQresultStatus(res) != PGRES_TUPLES_OK)
1212 {
1213 /* PQexec() should've set conn->errorMessage already */
1214 PQclear(res);
1215 return NULL;
1216 }
1217 if (PQntuples(res) != 1 || PQnfields(res) != 1)
1218 {
1219 PQclear(res);
1220 printfPQExpBuffer(&conn->errorMessage,
1221 libpq_gettext("unexpected shape of result set returned for SHOW\n"));
1222 return NULL;
1223 }
1224 val = PQgetvalue(res, 0, 0);
1225
1226 if (strlen(val) > MAX_ALGORITHM_NAME_LEN)
1227 {
1228 PQclear(res);
1229 printfPQExpBuffer(&conn->errorMessage,
1230 libpq_gettext("password_encryption value too long\n"));
1231 return NULL;
1232 }
1233 strcpy(algobuf, val);
1234 PQclear(res);
1235
1236 algorithm = algobuf;
1237 }
1238
1239 /*
1240 * Also accept "on" and "off" as aliases for "md5", because
1241 * password_encryption was a boolean before PostgreSQL 10. We refuse to
1242 * send the password in plaintext even if it was "off".
1243 */
1244 if (strcmp(algorithm, "on") == 0 ||
1245 strcmp(algorithm, "off") == 0)
1246 algorithm = "md5";
1247
1248 /*
1249 * Ok, now we know what algorithm to use
1250 */
1251 if (strcmp(algorithm, "scram-sha-256") == 0)
1252 {
1253 crypt_pwd = pg_fe_scram_build_secret(passwd);
1254 }
1255 else if (strcmp(algorithm, "md5") == 0)
1256 {
1257 crypt_pwd = malloc(MD5_PASSWD_LEN + 1);
1258 if (crypt_pwd)
1259 {
1260 if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd))
1261 {
1262 free(crypt_pwd);
1263 crypt_pwd = NULL;
1264 }
1265 }
1266 }
1267 else
1268 {
1269 printfPQExpBuffer(&conn->errorMessage,
1270 libpq_gettext("unrecognized password encryption algorithm \"%s\"\n"),
1271 algorithm);
1272 return NULL;
1273 }
1274
1275 if (!crypt_pwd)
1276 printfPQExpBuffer(&conn->errorMessage,
1277 libpq_gettext("out of memory\n"));
1278
1279 return crypt_pwd;
1280 }
1281