Skip to content

Commit 2764d5d

Browse files
committed
Make be-secure-common.c more consistent for future SSL implementations
Recent commit 8a3d942 has introduced be-secure-common.c, which is aimed at including backend-side APIs that can be used by any SSL implementation. The purpose is similar to fe-secure-common.c for the frontend-side APIs. However, this has forgotten to include check_ssl_key_file_permissions() in the move, which causes a double dependency between be-secure.c and be-secure-openssl.c. Refactor the code in a more logical way. This also puts into light an API which is usable by future SSL implementations for permissions on SSL key files. Author: Michael Paquier <michael@paquier.xyz>
1 parent 7e0d64c commit 2764d5d

File tree

3 files changed

+76
-70
lines changed

3 files changed

+76
-70
lines changed

src/backend/libpq/be-secure-common.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
#include "postgres.h"
2121

22+
#include <sys/stat.h>
23+
#include <unistd.h>
24+
2225
#include "libpq/libpq.h"
2326
#include "storage/fd.h"
2427

@@ -118,3 +121,74 @@ run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf,
118121
pfree(command.data);
119122
return len;
120123
}
124+
125+
126+
/*
127+
* Check permissions for SSL key files.
128+
*/
129+
bool
130+
check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)
131+
{
132+
int loglevel = isServerStart ? FATAL : LOG;
133+
struct stat buf;
134+
135+
if (stat(ssl_key_file, &buf) != 0)
136+
{
137+
ereport(loglevel,
138+
(errcode_for_file_access(),
139+
errmsg("could not access private key file \"%s\": %m",
140+
ssl_key_file)));
141+
return false;
142+
}
143+
144+
if (!S_ISREG(buf.st_mode))
145+
{
146+
ereport(loglevel,
147+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
148+
errmsg("private key file \"%s\" is not a regular file",
149+
ssl_key_file)));
150+
return false;
151+
}
152+
153+
/*
154+
* Refuse to load key files owned by users other than us or root.
155+
*
156+
* XXX surely we can check this on Windows somehow, too.
157+
*/
158+
#if !defined(WIN32) && !defined(__CYGWIN__)
159+
if (buf.st_uid != geteuid() && buf.st_uid != 0)
160+
{
161+
ereport(loglevel,
162+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
163+
errmsg("private key file \"%s\" must be owned by the database user or root",
164+
ssl_key_file)));
165+
return false;
166+
}
167+
#endif
168+
169+
/*
170+
* Require no public access to key file. If the file is owned by us,
171+
* require mode 0600 or less. If owned by root, require 0640 or less to
172+
* allow read access through our gid, or a supplementary gid that allows
173+
* to read system-wide certificates.
174+
*
175+
* XXX temporarily suppress check when on Windows, because there may not
176+
* be proper support for Unix-y file permissions. Need to think of a
177+
* reasonable check to apply on Windows. (See also the data directory
178+
* permission check in postmaster.c)
179+
*/
180+
#if !defined(WIN32) && !defined(__CYGWIN__)
181+
if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
182+
(buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
183+
{
184+
ereport(loglevel,
185+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
186+
errmsg("private key file \"%s\" has group or world access",
187+
ssl_key_file),
188+
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.")));
189+
return false;
190+
}
191+
#endif
192+
193+
return true;
194+
}

src/backend/libpq/be-secure.c

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@
1818

1919
#include "postgres.h"
2020

21-
#include <sys/stat.h>
2221
#include <signal.h>
2322
#include <fcntl.h>
2423
#include <ctype.h>
2524
#include <sys/socket.h>
26-
#include <unistd.h>
2725
#include <netdb.h>
2826
#include <netinet/in.h>
2927
#ifdef HAVE_NETINET_TCP_H
@@ -320,70 +318,3 @@ secure_raw_write(Port *port, const void *ptr, size_t len)
320318

321319
return n;
322320
}
323-
324-
bool
325-
check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)
326-
{
327-
int loglevel = isServerStart ? FATAL : LOG;
328-
struct stat buf;
329-
330-
if (stat(ssl_key_file, &buf) != 0)
331-
{
332-
ereport(loglevel,
333-
(errcode_for_file_access(),
334-
errmsg("could not access private key file \"%s\": %m",
335-
ssl_key_file)));
336-
return false;
337-
}
338-
339-
if (!S_ISREG(buf.st_mode))
340-
{
341-
ereport(loglevel,
342-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
343-
errmsg("private key file \"%s\" is not a regular file",
344-
ssl_key_file)));
345-
return false;
346-
}
347-
348-
/*
349-
* Refuse to load key files owned by users other than us or root.
350-
*
351-
* XXX surely we can check this on Windows somehow, too.
352-
*/
353-
#if !defined(WIN32) && !defined(__CYGWIN__)
354-
if (buf.st_uid != geteuid() && buf.st_uid != 0)
355-
{
356-
ereport(loglevel,
357-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
358-
errmsg("private key file \"%s\" must be owned by the database user or root",
359-
ssl_key_file)));
360-
return false;
361-
}
362-
#endif
363-
364-
/*
365-
* Require no public access to key file. If the file is owned by us,
366-
* require mode 0600 or less. If owned by root, require 0640 or less to
367-
* allow read access through our gid, or a supplementary gid that allows
368-
* to read system-wide certificates.
369-
*
370-
* XXX temporarily suppress check when on Windows, because there may not
371-
* be proper support for Unix-y file permissions. Need to think of a
372-
* reasonable check to apply on Windows. (See also the data directory
373-
* permission check in postmaster.c)
374-
*/
375-
#if !defined(WIN32) && !defined(__CYGWIN__)
376-
if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
377-
(buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
378-
{
379-
ereport(loglevel,
380-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
381-
errmsg("private key file \"%s\" has group or world access",
382-
ssl_key_file),
383-
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.")));
384-
return false;
385-
}
386-
#endif
387-
388-
return true;
389-
}

src/include/libpq/libpq.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ extern ssize_t secure_read(Port *port, void *ptr, size_t len);
9292
extern ssize_t secure_write(Port *port, void *ptr, size_t len);
9393
extern ssize_t secure_raw_read(Port *port, void *ptr, size_t len);
9494
extern ssize_t secure_raw_write(Port *port, const void *ptr, size_t len);
95-
extern bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart);
9695

9796
extern bool ssl_loaded_verify_locations;
9897

@@ -108,5 +107,7 @@ extern bool SSLPreferServerCiphers;
108107
*/
109108
extern int run_ssl_passphrase_command(const char *prompt, bool is_server_start,
110109
char *buf, int size);
110+
extern bool check_ssl_key_file_permissions(const char *ssl_key_file,
111+
bool isServerStart);
111112

112113
#endif /* LIBPQ_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy