diff options
author | vvvv <vvvv@yandex-team.com> | 2024-11-07 12:29:36 +0300 |
---|---|---|
committer | vvvv <vvvv@yandex-team.com> | 2024-11-07 13:49:47 +0300 |
commit | d4c258e9431675bab6745c8638df6e3dfd4dca6b (patch) | |
tree | b5efcfa11351152a4c872fccaea35749141c0b11 /yql/essentials/parser/pg_wrapper/postgresql/src/backend/libpq/be-secure-common.c | |
parent | 13a4f274caef5cfdaf0263b24e4d6bdd5521472b (diff) | |
download | ydb-d4c258e9431675bab6745c8638df6e3dfd4dca6b.tar.gz |
Moved other yql/essentials libs YQL-19206
init
commit_hash:7d4c435602078407bbf20dd3c32f9c90d2bbcbc0
Diffstat (limited to 'yql/essentials/parser/pg_wrapper/postgresql/src/backend/libpq/be-secure-common.c')
-rw-r--r-- | yql/essentials/parser/pg_wrapper/postgresql/src/backend/libpq/be-secure-common.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/yql/essentials/parser/pg_wrapper/postgresql/src/backend/libpq/be-secure-common.c b/yql/essentials/parser/pg_wrapper/postgresql/src/backend/libpq/be-secure-common.c new file mode 100644 index 00000000000..ab5e2dfa2bf --- /dev/null +++ b/yql/essentials/parser/pg_wrapper/postgresql/src/backend/libpq/be-secure-common.c @@ -0,0 +1,173 @@ +/*------------------------------------------------------------------------- + * + * be-secure-common.c + * + * common implementation-independent SSL support code + * + * While be-secure.c contains the interfaces that the rest of the + * communications code calls, this file contains support routines that are + * used by the library-specific implementations such as be-secure-openssl.c. + * + * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/libpq/be-secure-common.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include <sys/stat.h> +#include <unistd.h> + +#include "common/percentrepl.h" +#include "common/string.h" +#include "libpq/libpq.h" +#include "storage/fd.h" + +/* + * Run ssl_passphrase_command + * + * prompt will be substituted for %p. is_server_start determines the loglevel + * of error messages. + * + * The result will be put in buffer buf, which is of size size. The return + * value is the length of the actual result. + */ +int +run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size) +{ + int loglevel = is_server_start ? ERROR : LOG; + char *command; + FILE *fh; + int pclose_rc; + size_t len = 0; + + Assert(prompt); + Assert(size > 0); + buf[0] = '\0'; + + command = replace_percent_placeholders(ssl_passphrase_command, "ssl_passphrase_command", "p", prompt); + + fh = OpenPipeStream(command, "r"); + if (fh == NULL) + { + ereport(loglevel, + (errcode_for_file_access(), + errmsg("could not execute command \"%s\": %m", + command))); + goto error; + } + + if (!fgets(buf, size, fh)) + { + if (ferror(fh)) + { + explicit_bzero(buf, size); + ereport(loglevel, + (errcode_for_file_access(), + errmsg("could not read from command \"%s\": %m", + command))); + goto error; + } + } + + pclose_rc = ClosePipeStream(fh); + if (pclose_rc == -1) + { + explicit_bzero(buf, size); + ereport(loglevel, + (errcode_for_file_access(), + errmsg("could not close pipe to external command: %m"))); + goto error; + } + else if (pclose_rc != 0) + { + explicit_bzero(buf, size); + ereport(loglevel, + (errcode_for_file_access(), + errmsg("command \"%s\" failed", + command), + errdetail_internal("%s", wait_result_to_str(pclose_rc)))); + goto error; + } + + /* strip trailing newline and carriage return */ + len = pg_strip_crlf(buf); + +error: + pfree(command); + return len; +} + + +/* + * Check permissions for SSL key files. + */ +bool +check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart) +{ + int loglevel = isServerStart ? FATAL : LOG; + struct stat buf; + + if (stat(ssl_key_file, &buf) != 0) + { + ereport(loglevel, + (errcode_for_file_access(), + errmsg("could not access private key file \"%s\": %m", + ssl_key_file))); + return false; + } + + /* Key file must be a regular file */ + if (!S_ISREG(buf.st_mode)) + { + ereport(loglevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("private key file \"%s\" is not a regular file", + ssl_key_file))); + return false; + } + + /* + * Refuse to load key files owned by users other than us or root, and + * require no public access to the key file. If the file is owned by us, + * require mode 0600 or less. If owned by root, require 0640 or less to + * allow read access through either our gid or a supplementary gid that + * allows us to read system-wide certificates. + * + * Note that roughly similar checks are performed in + * src/interfaces/libpq/fe-secure-openssl.c so any changes here may need + * to be made there as well. The environment is different though; this + * code can assume that we're not running as root. + * + * Ideally we would do similar permissions checks on Windows, but it is + * not clear how that would work since Unix-style permissions may not be + * available. + */ +#if !defined(WIN32) && !defined(__CYGWIN__) + if (buf.st_uid != geteuid() && buf.st_uid != 0) + { + ereport(loglevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("private key file \"%s\" must be owned by the database user or root", + ssl_key_file))); + return false; + } + + if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) || + (buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO))) + { + ereport(loglevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("private key file \"%s\" has group or world access", + ssl_key_file), + errdetail("File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root."))); + return false; + } +#endif + + return true; +} |