Skip to content

Commit 1c21834

Browse files
committed
Extract common bits from OpenSSL implementation
Some things in be-secure-openssl.c and fe-secure-openssl.c were not actually specific to OpenSSL but could also be used by other implementations. In order to avoid copy-and-pasting, move some of that code to common files.
1 parent f966101 commit 1c21834

File tree

5 files changed

+81
-75
lines changed

5 files changed

+81
-75
lines changed

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

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ be_tls_init(bool isServerStart)
7575
{
7676
STACK_OF(X509_NAME) *root_cert_list = NULL;
7777
SSL_CTX *context;
78-
struct stat buf;
7978

8079
/* This stuff need be done only once. */
8180
if (!SSL_initialized)
@@ -133,63 +132,8 @@ be_tls_init(bool isServerStart)
133132
goto error;
134133
}
135134

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

194138
/*
195139
* OK, try to load the private key file.
@@ -516,10 +460,6 @@ be_tls_open_server(Port *port)
516460
port->peer_cert_valid = true;
517461
}
518462

519-
ereport(DEBUG2,
520-
(errmsg("SSL connection from \"%s\"",
521-
port->peer_cn ? port->peer_cn : "(anonymous)")));
522-
523463
/* set up debugging/info callback */
524464
SSL_CTX_set_info_callback(SSL_context, info_cb);
525465

src/backend/libpq/be-secure.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ secure_open_server(Port *port)
114114

115115
#ifdef USE_SSL
116116
r = be_tls_open_server(port);
117+
118+
ereport(DEBUG2,
119+
(errmsg("SSL connection from \"%s\"",
120+
port->peer_cn ? port->peer_cn : "(anonymous)")));
117121
#endif
118122

119123
return r;
@@ -314,3 +318,70 @@ secure_raw_write(Port *port, const void *ptr, size_t len)
314318

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

src/include/libpq/libpq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ extern ssize_t secure_read(Port *port, void *ptr, size_t len);
9090
extern ssize_t secure_write(Port *port, void *ptr, size_t len);
9191
extern ssize_t secure_raw_read(Port *port, void *ptr, size_t len);
9292
extern ssize_t secure_raw_write(Port *port, const void *ptr, size_t len);
93+
extern bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart);
9394

9495
extern bool ssl_loaded_verify_locations;
9596

src/interfaces/libpq/fe-secure-openssl.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,14 +1547,6 @@ SSLerrfree(char *buf)
15471547
/* SSL information functions */
15481548
/* ------------------------------------------------------------ */
15491549

1550-
int
1551-
PQsslInUse(PGconn *conn)
1552-
{
1553-
if (!conn)
1554-
return 0;
1555-
return conn->ssl_in_use;
1556-
}
1557-
15581550
/*
15591551
* Return pointer to OpenSSL object.
15601552
*/

src/interfaces/libpq/fe-secure.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ struct sigpipe_info
129129
/* ------------------------------------------------------------ */
130130

131131

132+
int
133+
PQsslInUse(PGconn *conn)
134+
{
135+
if (!conn)
136+
return 0;
137+
return conn->ssl_in_use;
138+
}
139+
132140
/*
133141
* Exported function to allow application to tell us it's already
134142
* initialized OpenSSL.
@@ -384,12 +392,6 @@ pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
384392
/* Dummy versions of SSL info functions, when built without SSL support */
385393
#ifndef USE_SSL
386394

387-
int
388-
PQsslInUse(PGconn *conn)
389-
{
390-
return 0;
391-
}
392-
393395
void *
394396
PQgetssl(PGconn *conn)
395397
{

0 commit comments

Comments
 (0)