Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
eb43af32
Commit
eb43af32
authored
Jun 14, 2002
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Back out SSL changes. Newer patch available.
parent
a9bd1761
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
208 additions
and
886 deletions
+208
-886
src/backend/libpq/Makefile
src/backend/libpq/Makefile
+2
-3
src/backend/libpq/pqcomm.c
src/backend/libpq/pqcomm.c
+16
-28
src/backend/postmaster/postmaster.c
src/backend/postmaster/postmaster.c
+82
-14
src/bin/psql/startup.c
src/bin/psql/startup.c
+2
-21
src/include/libpq/libpq-be.h
src/include/libpq/libpq-be.h
+1
-2
src/interfaces/libpq/Makefile
src/interfaces/libpq/Makefile
+2
-2
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-connect.c
+69
-12
src/interfaces/libpq/fe-misc.c
src/interfaces/libpq/fe-misc.c
+33
-17
src/interfaces/libpq/fe-ssl.c
src/interfaces/libpq/fe-ssl.c
+0
-785
src/interfaces/libpq/libpq-int.h
src/interfaces/libpq/libpq-int.h
+1
-2
No files found.
src/backend/libpq/Makefile
View file @
eb43af32
...
...
@@ -4,7 +4,7 @@
# Makefile for libpq subsystem (backend half of libpq interface)
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.3
1 2002/06/14 03:56:4
6 momjian Exp $
# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.3
2 2002/06/14 04:09:3
6 momjian Exp $
#
#-------------------------------------------------------------------------
...
...
@@ -14,8 +14,7 @@ include $(top_builddir)/src/Makefile.global
# be-fsstubs is here for historical reasons, probably belongs elsewhere
OBJS
=
be-fsstubs.o be-ssl.o auth.o crypt.o hba.o md5.o pqcomm.o
\
pqformat.o pqsignal.o
OBJS
=
be-fsstubs.o auth.o crypt.o hba.o md5.o pqcomm.o pqformat.o pqsignal.o
all
:
SUBSYS.o
...
...
src/backend/libpq/pqcomm.c
View file @
eb43af32
...
...
@@ -29,7 +29,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pqcomm.c,v 1.13
4 2002/06/14 03:56:4
6 momjian Exp $
* $Id: pqcomm.c,v 1.13
5 2002/06/14 04:09:3
6 momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -81,14 +81,6 @@
#include "miscadmin.h"
#include "storage/ipc.h"
/* these functions are misnamed - they handle both SSL and non-SSL case */
extern
ssize_t
read_SSL
(
Port
*
,
void
*
ptr
,
size_t
len
);
extern
ssize_t
write_SSL
(
Port
*
,
const
void
*
ptr
,
size_t
len
);
#ifdef USE_SSL
extern
void
close_SSL
(
Port
*
);
#endif
/* USE_SSL */
static
void
pq_close
(
void
);
...
...
@@ -146,9 +138,6 @@ pq_close(void)
{
if
(
MyProcPort
!=
NULL
)
{
#ifdef USE_SSL
close_SSL
(
MyProcPort
);
#endif
/* USE_SSL */
close
(
MyProcPort
->
sock
);
/* make sure any subsequent attempts to do I/O fail cleanly */
MyProcPort
->
sock
=
-
1
;
...
...
@@ -427,7 +416,6 @@ StreamConnection(int server_fd, Port *port)
void
StreamClose
(
int
sock
)
{
/* FIXME - what about closing SSL connections? */
close
(
sock
);
}
...
...
@@ -469,8 +457,14 @@ pq_recvbuf(void)
{
int
r
;
r
=
read_SSL
(
MyProcPort
,
PqRecvBuffer
+
PqRecvLength
,
#ifdef USE_SSL
if
(
MyProcPort
->
ssl
)
r
=
SSL_read
(
MyProcPort
->
ssl
,
PqRecvBuffer
+
PqRecvLength
,
PQ_BUFFER_SIZE
-
PqRecvLength
);
else
#endif
r
=
recv
(
MyProcPort
->
sock
,
PqRecvBuffer
+
PqRecvLength
,
PQ_BUFFER_SIZE
-
PqRecvLength
,
0
);
if
(
r
<
0
)
{
...
...
@@ -486,11 +480,7 @@ pq_recvbuf(void)
elog
(
COMMERROR
,
"pq_recvbuf: recv() failed: %m"
);
return
EOF
;
}
#ifdef USE_SSL
if
(
r
==
0
&&
!
MyProcPort
->
ssl
)
#else
/* USE_SSL */
if
(
r
==
0
)
#endif
/* USE_SSL */
{
/* as above, only write to postmaster log */
elog
(
COMMERROR
,
"pq_recvbuf: unexpected EOF on client connection"
);
...
...
@@ -661,13 +651,14 @@ pq_flush(void)
{
int
r
;
r
=
write_SSL
(
MyProcPort
,
bufptr
,
bufend
-
bufptr
);
#ifdef USE_SSL
if
(
r
<
0
||
(
r
==
0
&&
!
MyProcPort
->
ssl
))
#else
/* USE_SSL */
if
(
MyProcPort
->
ssl
)
r
=
SSL_write
(
MyProcPort
->
ssl
,
bufptr
,
bufend
-
bufptr
);
else
#endif
r
=
send
(
MyProcPort
->
sock
,
bufptr
,
bufend
-
bufptr
,
0
);
if
(
r
<=
0
)
#endif
/* USE_SSL */
{
if
(
errno
==
EINTR
)
continue
;
/* Ok if we were interrupted */
...
...
@@ -712,9 +703,8 @@ int
pq_eof
(
void
)
{
char
x
;
int
res
=
1
;
int
res
;
#ifndef USE_SSL
/* not a good solution, but better than nothing */
res
=
recv
(
MyProcPort
->
sock
,
&
x
,
1
,
MSG_PEEK
);
if
(
res
<
0
)
...
...
@@ -723,8 +713,6 @@ pq_eof(void)
elog
(
COMMERROR
,
"pq_eof: recv() failed: %m"
);
return
EOF
;
}
#endif
/* USE_SSL */
if
(
res
==
0
)
return
EOF
;
else
...
...
src/backend/postmaster/postmaster.c
View file @
eb43af32
...
...
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.27
7 2002/06/14 03:56:47
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.27
8 2002/06/14 04:09:36
momjian Exp $
*
* NOTES
*
...
...
@@ -165,6 +165,10 @@ static int ServerSock_INET = INVALID_SOCK; /* stream socket server */
static
int
ServerSock_UNIX
=
INVALID_SOCK
;
/* stream socket server */
#endif
#ifdef USE_SSL
static
SSL_CTX
*
SSL_context
=
NULL
;
/* Global SSL context */
#endif
/*
* Set by the -o option
*/
...
...
@@ -270,10 +274,8 @@ __attribute__((format(printf, 1, 2)));
#define ShutdownDataBase() SSDataBase(BS_XLOG_SHUTDOWN)
#ifdef USE_SSL
extern
int
initialize_ctx
(
const
char
*
,
void
(
*
err
)(
const
char
*
fmt
,...));
extern
void
destroy_ctx
(
void
);
extern
int
open_SSL_server
(
Port
*
);
extern
void
close_SSL
(
Port
*
);
static
void
InitSSL
(
void
);
static
const
char
*
SSLerrmessage
(
void
);
#endif
...
...
@@ -607,10 +609,7 @@ PostmasterMain(int argc, char *argv[])
ExitPostmaster
(
1
);
}
if
(
EnableSSL
)
{
if
(
initialize_ctx
(
NULL
,
postmaster_error
)
==
-
1
)
ExitPostmaster
(
1
);
}
InitSSL
();
#endif
/*
...
...
@@ -1116,8 +1115,12 @@ ProcessStartupPacket(Port *port, bool SSLdone)
#ifdef USE_SSL
if
(
SSLok
==
'S'
)
{
if
(
open_SSL_server
(
port
)
!=
STATUS_OK
)
if
(
!
(
port
->
ssl
=
SSL_new
(
SSL_context
))
||
!
SSL_set_fd
(
port
->
ssl
,
port
->
sock
)
||
SSL_accept
(
port
->
ssl
)
<=
0
)
{
elog
(
LOG
,
"failed to initialize SSL connection: %s (%m)"
,
SSLerrmessage
());
return
STATUS_ERROR
;
}
}
...
...
@@ -1319,10 +1322,9 @@ static void
ConnFree
(
Port
*
conn
)
{
#ifdef USE_SSL
close_SSL
(
conn
);
if
(
conn
->
ssl
)
SSL_free
(
conn
->
ssl
);
#endif
if
(
conn
->
sock
!=
-
1
)
close
(
conn
->
sock
);
free
(
conn
);
}
...
...
@@ -2422,6 +2424,72 @@ CountChildren(void)
return
cnt
;
}
#ifdef USE_SSL
/*
* Initialize SSL library and structures
*/
static
void
InitSSL
(
void
)
{
char
fnbuf
[
2048
];
SSL_load_error_strings
();
SSL_library_init
();
SSL_context
=
SSL_CTX_new
(
SSLv23_method
());
if
(
!
SSL_context
)
{
postmaster_error
(
"failed to create SSL context: %s"
,
SSLerrmessage
());
ExitPostmaster
(
1
);
}
snprintf
(
fnbuf
,
sizeof
(
fnbuf
),
"%s/server.crt"
,
DataDir
);
if
(
!
SSL_CTX_use_certificate_file
(
SSL_context
,
fnbuf
,
SSL_FILETYPE_PEM
))
{
postmaster_error
(
"failed to load server certificate (%s): %s"
,
fnbuf
,
SSLerrmessage
());
ExitPostmaster
(
1
);
}
snprintf
(
fnbuf
,
sizeof
(
fnbuf
),
"%s/server.key"
,
DataDir
);
if
(
!
SSL_CTX_use_PrivateKey_file
(
SSL_context
,
fnbuf
,
SSL_FILETYPE_PEM
))
{
postmaster_error
(
"failed to load private key file (%s): %s"
,
fnbuf
,
SSLerrmessage
());
ExitPostmaster
(
1
);
}
if
(
!
SSL_CTX_check_private_key
(
SSL_context
))
{
postmaster_error
(
"check of private key failed: %s"
,
SSLerrmessage
());
ExitPostmaster
(
1
);
}
}
/*
* Obtain reason string for last SSL error
*
* Some caution is needed here since ERR_reason_error_string will
* return NULL if it doesn't recognize the error code. We don't
* want to return NULL ever.
*/
static
const
char
*
SSLerrmessage
(
void
)
{
unsigned
long
errcode
;
const
char
*
errreason
;
static
char
errbuf
[
32
];
errcode
=
ERR_get_error
();
if
(
errcode
==
0
)
return
"No SSL error reported"
;
errreason
=
ERR_reason_error_string
(
errcode
);
if
(
errreason
!=
NULL
)
return
errreason
;
snprintf
(
errbuf
,
sizeof
(
errbuf
),
"SSL error code %lu"
,
errcode
);
return
errbuf
;
}
#endif
/* USE_SSL */
/*
* Fire off a subprocess for startup/shutdown/checkpoint.
...
...
src/bin/psql/startup.c
View file @
eb43af32
...
...
@@ -3,7 +3,7 @@
*
* Copyright 2000 by PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.5
8 2002/06/14 03:56:47
momjian Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/startup.c,v 1.5
9 2002/06/14 04:09:36
momjian Exp $
*/
#include "postgres_fe.h"
...
...
@@ -678,33 +678,14 @@ printSSLInfo(void)
{
int
sslbits
=
-
1
;
SSL
*
ssl
;
X509
*
peer
;
char
sn
[
256
];
long
l
;
ssl
=
PQgetssl
(
pset
.
db
);
if
(
!
ssl
)
return
;
/* no SSL */
/* peer = pset.db.peer; */
if
((
peer
=
SSL_get_peer_certificate
(
ssl
))
!=
NULL
)
{
X509_NAME_oneline
(
X509_get_subject_name
(
peer
),
sn
,
sizeof
sn
);
}
else
{
strncpy
(
sn
,
"(anonymous)"
,
sizeof
sn
);
}
printf
(
gettext
(
"SSL connection
\n
"
));
printf
(
gettext
(
"(host: %s)
\n
"
),
sn
);
SSL_get_cipher_bits
(
ssl
,
&
sslbits
);
printf
(
gettext
(
"(protocol: %s)
\n
"
),
SSL_get_version
(
ssl
)),
printf
(
gettext
(
"(cipher: %s, bits: %i)
\n
"
),
printf
(
gettext
(
"SSL connection (cipher: %s, bits: %i)
\n\n
"
),
SSL_get_cipher
(
ssl
),
sslbits
);
l
=
SSL_get_default_timeout
(
ssl
);
printf
(
gettext
(
"(timeout: %ld:%02ld:%02ld)
\n\n
"
),
l
/
3600L
,
(
l
/
60L
)
%
60L
,
l
%
60L
);
}
#endif
src/include/libpq/libpq-be.h
View file @
eb43af32
...
...
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq-be.h,v 1.2
8 2002/06/14 03:56:4
7 momjian Exp $
* $Id: libpq-be.h,v 1.2
9 2002/06/14 04:09:3
7 momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -70,7 +70,6 @@ typedef struct Port
*/
#ifdef USE_SSL
SSL
*
ssl
;
X509
*
peer
;
#endif
}
Port
;
...
...
src/interfaces/libpq/Makefile
View file @
eb43af32
...
...
@@ -4,7 +4,7 @@
#
# Copyright (c) 1994, Regents of the University of California
#
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.6
0 2002/06/14 03:56:4
7 momjian Exp $
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.6
1 2002/06/14 04:09:3
7 momjian Exp $
#
#-------------------------------------------------------------------------
...
...
@@ -20,7 +20,7 @@ SO_MINOR_VERSION= 2
override CPPFLAGS
:
= -I$(srcdir) $(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"'
OBJS
=
fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o
\
pqexpbuffer.o dllist.o md5.o pqsignal.o
fe-ssl.o
\
pqexpbuffer.o dllist.o md5.o pqsignal.o
\
$(INET_ATON)
$(SNPRINTF)
$(STRERROR)
ifdef
MULTIBYTE
...
...
src/interfaces/libpq/fe-connect.c
View file @
eb43af32
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.18
4 2002/06/14 03:56:4
7 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.18
5 2002/06/14 04:09:3
7 momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -62,6 +62,10 @@ inet_aton(const char *cp, struct in_addr * inp)
#endif
#ifdef USE_SSL
static
SSL_CTX
*
SSL_context
=
NULL
;
#endif
#define NOTIFYLIST_INITIAL_SIZE 10
#define NOTIFYLIST_GROWBY 10
...
...
@@ -182,13 +186,8 @@ static char *conninfo_getval(PQconninfoOption *connOptions,
static
void
defaultNoticeProcessor
(
void
*
arg
,
const
char
*
message
);
static
int
parseServiceInfo
(
PQconninfoOption
*
options
,
PQExpBuffer
errorMessage
);
#ifdef USE_SSL
extern
int
initialize_ctx
(
const
char
*
passwd
,
void
(
*
err
)(
const
char
*
fmt
,...),
PGconn
*
);
extern
void
destroy_ctx
(
PGconn
*
);
extern
int
open_SSL_client
(
PGconn
*
);
extern
void
close_SSL
(
PGconn
*
);
extern
SSL
*
PQgetssl
(
PGconn
*
);
static
const
char
*
SSLerrmessage
(
void
);
#endif
...
...
@@ -970,10 +969,28 @@ retry2:
}
if
(
SSLok
==
'S'
)
{
if
(
initialize_ctx
(
NULL
,
NULL
,
conn
)
==
-
1
)
if
(
!
SSL_context
)
{
SSL_load_error_strings
();
SSL_library_init
();
SSL_context
=
SSL_CTX_new
(
SSLv23_method
());
if
(
!
SSL_context
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not create SSL context: %s
\n
"
),
SSLerrmessage
());
goto
connect_errReturn
;
if
(
open_SSL_client
(
conn
)
==
-
1
)
}
}
if
(
!
(
conn
->
ssl
=
SSL_new
(
SSL_context
))
||
!
SSL_set_fd
(
conn
->
ssl
,
conn
->
sock
)
||
SSL_connect
(
conn
->
ssl
)
<=
0
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not establish SSL connection: %s
\n
"
),
SSLerrmessage
());
goto
connect_errReturn
;
}
/* SSL connection finished. Continue to send startup packet */
}
else
if
(
SSLok
==
'E'
)
...
...
@@ -998,7 +1015,7 @@ retry2:
goto
connect_errReturn
;
}
}
if
(
conn
->
require_ssl
&&
!
PQgetssl
(
conn
)
)
if
(
conn
->
require_ssl
&&
!
conn
->
ssl
)
{
/* Require SSL, but server does not support/want it */
printfPQExpBuffer
(
&
conn
->
errorMessage
,
...
...
@@ -1897,7 +1914,8 @@ freePGconn(PGconn *conn)
return
;
pqClearAsyncResult
(
conn
);
/* deallocate result and curTuple */
#ifdef USE_SSL
close_SSL
(
conn
);
if
(
conn
->
ssl
)
SSL_free
(
conn
->
ssl
);
#endif
if
(
conn
->
sock
>=
0
)
{
...
...
@@ -2623,6 +2641,35 @@ PQconninfoFree(PQconninfoOption *connOptions)
}
#ifdef USE_SSL
/*
* Obtain reason string for last SSL error
*
* Some caution is needed here since ERR_reason_error_string will
* return NULL if it doesn't recognize the error code. We don't
* want to return NULL ever.
*/
static
const
char
*
SSLerrmessage
(
void
)
{
unsigned
long
errcode
;
const
char
*
errreason
;
static
char
errbuf
[
32
];
errcode
=
ERR_get_error
();
if
(
errcode
==
0
)
return
"No SSL error reported"
;
errreason
=
ERR_reason_error_string
(
errcode
);
if
(
errreason
!=
NULL
)
return
errreason
;
snprintf
(
errbuf
,
sizeof
(
errbuf
),
"SSL error code %lu"
,
errcode
);
return
errbuf
;
}
#endif
/* USE_SSL */
/* =========== accessor functions for PGconn ========= */
char
*
PQdb
(
const
PGconn
*
conn
)
...
...
@@ -2767,6 +2814,16 @@ PQsetClientEncoding(PGconn *conn, const char *encoding)
}
#endif
#ifdef USE_SSL
SSL
*
PQgetssl
(
PGconn
*
conn
)
{
if
(
!
conn
)
return
NULL
;
return
conn
->
ssl
;
}
#endif
void
PQtrace
(
PGconn
*
conn
,
FILE
*
debug_port
)
{
...
...
src/interfaces/libpq/fe-misc.c
View file @
eb43af32
...
...
@@ -25,7 +25,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.7
1 2002/06/14 03:56:4
7 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.7
2 2002/06/14 04:09:3
7 momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -55,13 +55,6 @@
#include "mb/pg_wchar.h"
#endif
/* these functions are misnamed - they handle both SSL and non-SSL case */
extern
ssize_t
read_SSL
(
PGconn
*
,
void
*
ptr
,
size_t
);
extern
ssize_t
write_SSL
(
PGconn
*
,
const
void
*
ptr
,
size_t
);
#ifdef USE_SSL
extern
ssize_t
close_SSL
(
PGconn
*
);
#endif
#define DONOTICE(conn,message) \
((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
...
...
@@ -484,8 +477,14 @@ pqReadData(PGconn *conn)
/* OK, try to read some data */
retry3:
nread
=
read_SSL
(
conn
,
conn
->
inBuffer
+
conn
->
inEnd
,
#ifdef USE_SSL
if
(
conn
->
ssl
)
nread
=
SSL_read
(
conn
->
ssl
,
conn
->
inBuffer
+
conn
->
inEnd
,
conn
->
inBufSize
-
conn
->
inEnd
);
else
#endif
nread
=
recv
(
conn
->
sock
,
conn
->
inBuffer
+
conn
->
inEnd
,
conn
->
inBufSize
-
conn
->
inEnd
,
0
);
if
(
nread
<
0
)
{
if
(
SOCK_ERRNO
==
EINTR
)
...
...
@@ -564,8 +563,14 @@ retry3:
* arrived.
*/
retry4:
nread
=
read_SSL
(
conn
,
conn
->
inBuffer
+
conn
->
inEnd
,
#ifdef USE_SSL
if
(
conn
->
ssl
)
nread
=
SSL_read
(
conn
->
ssl
,
conn
->
inBuffer
+
conn
->
inEnd
,
conn
->
inBufSize
-
conn
->
inEnd
);
else
#endif
nread
=
recv
(
conn
->
sock
,
conn
->
inBuffer
+
conn
->
inEnd
,
conn
->
inBufSize
-
conn
->
inEnd
,
0
);
if
(
nread
<
0
)
{
if
(
SOCK_ERRNO
==
EINTR
)
...
...
@@ -606,9 +611,6 @@ definitelyFailed:
"
\t
This probably means the server terminated abnormally
\n
"
"
\t
before or while processing the request.
\n
"
));
conn
->
status
=
CONNECTION_BAD
;
/* No more connection to backend */
#ifdef USE_SSL
close_SSL
(
conn
);
#endif
#ifdef WIN32
closesocket
(
conn
->
sock
);
#else
...
...
@@ -648,9 +650,23 @@ pqSendSome(PGconn *conn)
/* while there's still data to send */
while
(
len
>
0
)
{
/* Prevent being SIGPIPEd if backend has closed the connection. */
#ifndef WIN32
pqsigfunc
oldsighandler
=
pqsignal
(
SIGPIPE
,
SIG_IGN
);
#endif
int
sent
;
sent
=
write_SSL
(
conn
,
ptr
,
len
);
#ifdef USE_SSL
if
(
conn
->
ssl
)
sent
=
SSL_write
(
conn
->
ssl
,
ptr
,
len
);
else
#endif
sent
=
send
(
conn
->
sock
,
ptr
,
len
,
0
);
#ifndef WIN32
pqsignal
(
SIGPIPE
,
oldsighandler
);
#endif
if
(
sent
<
0
)
{
...
...
@@ -716,7 +732,7 @@ pqSendSome(PGconn *conn)
*/
#ifdef USE_SSL
/* can't do anything for our SSL users yet */
if
(
PQgetssl
(
conn
)
==
NULL
)
if
(
conn
->
ssl
==
NULL
)
{
#endif
if
(
pqIsnonblocking
(
conn
))
...
...
src/interfaces/libpq/fe-ssl.c
deleted
100644 → 0
View file @
a9bd1761
#include "postgres_fe.h"
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <pwd.h>
#include "libpq-fe.h"
#include "libpq-int.h"
#include "fe-auth.h"
#include "pqsignal.h"
#ifdef WIN32
#include "win32.h"
#else
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#include <arpa/inet.h>
#endif
#ifdef USE_SSL
#include <openssl/ssl.h>
#include <openssl/rand.h>
#include <openssl/e_os.h>
int
initialize_ctx
(
const
char
*
,
void
(
*
err
)(
const
char
*
fmt
,...),
PGconn
*
);
void
destroy_ctx
(
void
);
int
open_SSL_client
(
PGconn
*
);
void
close_SSL
(
PGconn
*
);
SSL
PGgetssl
(
PGconn
*
);
static
int
clientCert_cb
(
SSL
*
ssl
,
X509
**
x509
,
EVP_PKEY
**
pkey
);
static
int
verify_cb
(
int
,
X509_STORE_CTX
*
);
static
void
info_cb
(
SSL
*
ssl
,
int
type
,
int
args
);
static
void
load_hardcoded_certs
(
void
);
static
X509
*
load_cert_buffer
(
const
char
*
buf
,
size_t
len
);
static
const
char
*
SSLerrmessage
(
void
);
#endif
ssize_t
read_SSL
(
PGconn
*
,
void
*
,
size_t
);
ssize_t
write_SSL
(
PGconn
*
,
const
void
*
,
size_t
);
extern
int
h_error
;
#ifdef USE_SSL
static
SSL_CTX
*
ctx
=
NULL
;
#endif
#define PING() fprintf(stderr,"%s, line %d, %s\n", __FILE__, __LINE__, __func__)
/*
* Read data from network.
*/
ssize_t
read_SSL
(
PGconn
*
conn
,
void
*
ptr
,
size_t
len
)
{
ssize_t
n
;
#ifdef USE_SSL
if
(
conn
->
ssl
)
{
n
=
SSL_read
(
conn
->
ssl
,
ptr
,
len
);
switch
(
SSL_get_error
(
conn
->
ssl
,
n
))
{
case
SSL_ERROR_NONE
:
break
;
case
SSL_ERROR_WANT_READ
:
break
;
case
SSL_ERROR_SYSCALL
:
SOCK_ERRNO
=
get_last_socket_error
();
break
;
case
SSL_ERROR_SSL
:
// log error...
SOCK_ERRNO
=
ECONNRESET
;
break
;
case
SSL_ERROR_ZERO_RETURN
:
SOCK_ERRNO
=
ECONNRESET
;
break
;
}
}
else
#endif
/* USE_SSL */
n
=
recv
(
conn
->
sock
,
ptr
,
len
,
0
);
return
n
;
}
/*
* Write data to network.
*/
ssize_t
write_SSL
(
PGconn
*
conn
,
const
void
*
ptr
,
size_t
len
)
{
ssize_t
n
;
/* prevent being SIGPIPEd if backend has closed the connection. */
#ifndef WIN32
pqsigfunc
oldsighandler
=
pqsignal
(
SIGPIPE
,
SIG_IGN
);
#endif
#ifdef USE_SSL
if
(
conn
->
ssl
)
{
n
=
SSL_write
(
conn
->
ssl
,
ptr
,
len
);
switch
(
SSL_get_error
(
conn
->
ssl
,
n
))
{
case
SSL_ERROR_NONE
:
break
;
case
SSL_ERROR_WANT_WRITE
:
break
;
case
SSL_ERROR_SYSCALL
:
SOCK_ERRNO
=
get_last_socket_error
();
break
;
case
SSL_ERROR_SSL
:
fprintf
(
stderr
,
"ssl error
\n
"
);
// log error...
SOCK_ERRNO
=
ECONNRESET
;
break
;
case
SSL_ERROR_ZERO_RETURN
:
fprintf
(
stderr
,
"zero bytes
\n
"
);
SOCK_ERRNO
=
ECONNRESET
;
break
;
}
}
else
#endif
n
=
send
(
conn
->
sock
,
ptr
,
len
,
0
);
#ifndef WIN32
pqsignal
(
SIGPIPE
,
oldsighandler
);
#endif
return
n
;
}
#ifdef USE_SSL
/*
* Null authentication callback
*/
static
int
verify_cb
(
int
ok
,
X509_STORE_CTX
*
ctx
)
{
char
sn
[
256
],
buf
[
256
];
X509
*
cert
;
int
err
,
depth
,
n
;
BIO
*
bio
;
cert
=
X509_STORE_CTX_get_current_cert
(
ctx
);
err
=
X509_STORE_CTX_get_error
(
ctx
);
depth
=
X509_STORE_CTX_get_error_depth
(
ctx
);
X509_NAME_oneline
(
X509_get_subject_name
(
cert
),
sn
,
sizeof
sn
);
if
(
!
ok
)
{
switch
(
err
)
{
/* accept self-signed certs */
// case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
// ok = 1;
// break;
default:
fprintf
(
stderr
,
"client cert %s: %s"
,
sn
,
X509_verify_cert_error_string
(
err
));
}
}
switch
(
ctx
->
error
)
{
case
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
:
X509_NAME_oneline
(
X509_get_issuer_name
(
cert
),
buf
,
sizeof
buf
);
fprintf
(
stderr
,
"client cert %s: cannot find issuer %s"
,
sn
,
buf
);
break
;
case
X509_V_ERR_CERT_NOT_YET_VALID
:
case
X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
:
bio
=
BIO_new
(
BIO_s_mem
());
ASN1_TIME_print
(
bio
,
X509_get_notBefore
(
cert
));
BIO_flush
(
bio
);
n
=
BIO_read
(
bio
,
buf
,
sizeof
buf
-
1
);
buf
[
n
]
=
'\0'
;
fprintf
(
stderr
,
"client cert %s: not valid until %s"
,
sn
,
buf
);
break
;
case
X509_V_ERR_CERT_HAS_EXPIRED
:
case
X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
:
bio
=
BIO_new
(
BIO_s_mem
());
ASN1_TIME_print
(
bio
,
X509_get_notAfter
(
cert
));
BIO_flush
(
bio
);
n
=
BIO_read
(
bio
,
buf
,
sizeof
buf
-
1
);
buf
[
n
]
=
'\0'
;
fprintf
(
stderr
,
"client cert %s: not valid after %s
\n
"
,
sn
,
buf
);
break
;
}
return
ok
;
}
/*
* Callback used by SSL to provide information messages.
*/
static
void
info_cb
(
SSL
*
ssl
,
int
type
,
int
args
)
{
PGconn
*
conn
=
NULL
;
conn
=
(
PGconn
*
)
SSL_get_app_data
(
ssl
);
if
(
conn
==
NULL
||
conn
->
Pfdebug
==
NULL
)
return
;
switch
(
type
)
{
case
SSL_CB_HANDSHAKE_START
:
fprintf
(
conn
->
Pfdebug
,
"Handshake start
\n
"
);
break
;
case
SSL_CB_HANDSHAKE_DONE
:
fprintf
(
conn
->
Pfdebug
,
"Handshake done
\n
"
);
break
;
case
SSL_CB_ACCEPT_LOOP
:
fprintf
(
conn
->
Pfdebug
,
"Accept loop...
\n
"
);
break
;
case
SSL_CB_ACCEPT_EXIT
:
fprintf
(
conn
->
Pfdebug
,
"Accept exit (%d)
\n
"
,
args
);
break
;
case
SSL_CB_CONNECT_LOOP
:
fprintf
(
conn
->
Pfdebug
,
"Connect loop...
\n
"
);
break
;
case
SSL_CB_CONNECT_EXIT
:
fprintf
(
conn
->
Pfdebug
,
"Connect exit (%d)
\n
"
,
args
);
break
;
case
SSL_CB_READ_ALERT
:
fprintf
(
conn
->
Pfdebug
,
"Read alert (0x%04x)
\n
"
,
args
);
break
;
case
SSL_CB_WRITE_ALERT
:
fprintf
(
conn
->
Pfdebug
,
"Write alert (0x%04x)
\n
"
,
args
);
break
;
}
}
/*
* Callback used by SSL to load client cert and key.
* At the current time we require the cert and key to be
* located in the .postgresql directory under the user's
* home directory, and the files must be named 'postgresql.crt'
* and 'postgresql.key' respectively.
*
* returns 1 on success, 0 on no data, -1 on error.
*/
static
int
clientCert_cb
(
SSL
*
ssl
,
X509
**
x509
,
EVP_PKEY
**
pkey
)
{
uid_t
uid
;
struct
passwd
*
pwd
;
char
fnbuf
[
2048
];
struct
stat
buf
,
buf1
;
FILE
*
fp
;
int
(
*
cb
)()
=
NULL
;
if
((
uid
=
getuid
())
==
-
1
)
{
fprintf
(
stderr
,
"can't get current uid
\n
"
);
return
-
1
;
}
if
((
pwd
=
getpwuid
(
uid
))
==
NULL
||
!
pwd
->
pw_dir
)
{
fprintf
(
stderr
,
"can't get passwd entry
\n
"
);
return
-
1
;
}
/*
* if $HOME/.postgresql does not exist, 'no data' case.
* otherwise, it must be a directory, owned by current user,
* and not group- or world-accessible.
*/
snprintf
(
fnbuf
,
sizeof
fnbuf
,
"%s/.postgresql"
,
pwd
->
pw_dir
);
if
(
lstat
(
fnbuf
,
&
buf
)
==
-
1
)
return
0
;
if
(
!
S_ISDIR
(
buf
.
st_mode
)
||
buf
.
st_uid
!=
uid
||
(
buf
.
st_mode
&
(
S_IRWXG
|
S_IRWXO
))
!=
0
)
{
fprintf
(
stderr
,
"$HOME/.postgresql directory has wrong ownership or permissions
\n
"
);
return
-
1
;
}
/*
* make sure $HOME/.postgresql/postgresql.crt file exists,
* is regular file and owned by current user.
*/
snprintf
(
fnbuf
,
sizeof
fnbuf
,
"%s/.postgresql/postgresql.crt"
,
pwd
->
pw_dir
);
if
(
lstat
(
fnbuf
,
&
buf
)
==
-
1
)
return
0
;
if
(
!
S_ISREG
(
buf
.
st_mode
)
||
buf
.
st_uid
!=
uid
)
{
fprintf
(
stderr
,
"certificate file has wrong ownership or permissions
\n
"
);
return
-
1
;
}
if
((
fp
=
fopen
(
fnbuf
,
"r"
))
==
NULL
)
{
fprintf
(
stderr
,
"can't open certificate file (%s)
\n
"
,
strerror
(
errno
));
return
-
1
;
}
if
(
PEM_read_X509
(
fp
,
x509
,
NULL
,
NULL
)
==
NULL
)
{
fprintf
(
stderr
,
"can't read certificate %s
\n
"
,
SSLerrmessage
());
fclose
(
fp
);
return
-
1
;
}
fclose
(
fp
);
/*
* make sure $HOME/.postgresql/postgresql.key file exists,
* is regular file, owned by current user, and not group-
* or world-accessable.
*/
snprintf
(
fnbuf
,
sizeof
fnbuf
,
"%s/.postgresql/postgresql.key"
,
pwd
->
pw_dir
);
if
(
lstat
(
fnbuf
,
&
buf
)
==
-
1
)
{
fprintf
(
stderr
,
"certificate file exists, but no private key
\n
"
);
SSL_use_certificate
(
ssl
,
NULL
);
return
-
1
;
}
if
(
!
S_ISREG
(
buf
.
st_mode
)
||
buf
.
st_uid
!=
uid
||
(
buf
.
st_mode
&
(
S_IRWXG
|
S_IRWXO
))
!=
0
)
{
fprintf
(
stderr
,
"private key file has wrong ownership or permissions
\n
"
);
SSL_use_certificate
(
ssl
,
NULL
);
return
-
1
;
}
if
((
fp
=
fopen
(
fnbuf
,
"r"
))
==
NULL
)
{
fprintf
(
stderr
,
"error opening private key file: %s
\n
"
,
strerror
(
errno
));
SSL_use_certificate
(
ssl
,
NULL
);
return
-
1
;
}
if
(
fstat
(
fileno
(
fp
),
&
buf1
)
==
-
1
||
buf
.
st_dev
!=
buf1
.
st_dev
||
buf
.
st_ino
!=
buf1
.
st_ino
)
{
fprintf
(
stderr
,
"private key changed under us!
\n
"
);
fclose
(
fp
);
SSL_use_certificate
(
ssl
,
NULL
);
return
-
1
;
}
if
(
PEM_read_PrivateKey
(
fp
,
pkey
,
cb
,
NULL
)
==
NULL
)
{
fprintf
(
stderr
,
"can't read private key %s
\n
"
,
SSLerrmessage
());
fclose
(
fp
);
SSL_use_certificate
(
ssl
,
NULL
);
return
-
1
;
}
fclose
(
fp
);
return
1
;
}
/*
* Load a root cert from a buffer. This allows us to avoid
* needing to copy the root cert to deployed systems.
*/
static
X509
*
load_cert_buffer
(
const
char
*
buf
,
size_t
len
)
{
BIO
*
bio
;
X509
*
x
;
bio
=
BIO_new_mem_buf
((
char
*
)
buf
,
len
);
x
=
PEM_read_bio_X509
(
bio
,
NULL
,
NULL
,
NULL
);
BIO_free
(
bio
);
return
x
;
}
/*
* Initialize global SSL context.
*
* We want to use 'err' for errors, same as the corresponding
* function on the server, but for now we use legacy error handler
* in PGconn.
*/
int
initialize_ctx
(
const
char
*
password
,
void
(
*
err
)(
const
char
*
fmt
,...),
PGconn
*
conn
)
{
SSL_METHOD
*
meth
=
NULL
;
struct
stat
buf
;
struct
passwd
*
pwd
;
char
fnbuf
[
2048
];
if
(
!
ctx
)
{
SSL_library_init
();
SSL_load_error_strings
();
// meth = SSLv23_method();
meth
=
TLSv1_method
();
ctx
=
SSL_CTX_new
(
meth
);
if
(
!
ctx
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not create SSL context: %s
\n
"
),
SSLerrmessage
());
return
-
1
;
}
}
/* load any hard-coded root cert */
load_hardcoded_certs
();
/* load the CAs we trust */
if
((
pwd
=
getpwuid
(
getuid
()))
!=
NULL
)
{
snprintf
(
fnbuf
,
sizeof
fnbuf
,
"%s/.postgresql/root.crt"
,
pwd
->
pw_dir
);
if
(
stat
(
fnbuf
,
&
buf
)
!=
-
1
)
{
if
(
!
SSL_CTX_load_verify_locations
(
ctx
,
fnbuf
,
0
))
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not read CA list (%s): %s
\n
"
),
fnbuf
,
SSLerrmessage
());
return
-
1
;
}
}
}
/* load randomness */
#ifdef RANDOM
if
(
!
RAND_load_file
(
RANDOM
,
1024
*
1024
))
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not load randomness (%s): %s
\n
"
),
RANDOM
,
SSLerrmessage
());
return
-
1
;
}
#else
/* RANDOM */
if
(
lstat
(
"/dev/urandom"
,
&
buf
)
==
0
&&
S_ISCHR
(
buf
.
st_mode
))
{
if
(
!
RAND_load_file
(
"/dev/urandom"
,
16
*
1024
))
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not load randomness (%s): %s
\n
"
),
"/dev/urandom"
,
SSLerrmessage
());
return
-
1
;
}
}
#endif
/* RANDOM */
SSL_CTX_set_verify
(
ctx
,
SSL_VERIFY_PEER
,
verify_cb
);
SSL_CTX_set_verify_depth
(
ctx
,
1
);
SSL_CTX_set_info_callback
(
ctx
,
info_cb
);
SSL_CTX_set_client_cert_cb
(
ctx
,
clientCert_cb
);
return
0
;
}
/*
* Destroy the global SSL context.
*/
void
destroy_ctx
(
void
)
{
SSL_CTX_free
(
ctx
);
ctx
=
NULL
;
}
/*
* Open a SSL connection.
*/
int
open_SSL_client
(
PGconn
*
conn
)
{
char
peerName
[
256
];
struct
sockaddr
addr
;
struct
sockaddr_in
*
sin1
,
*
sin2
;
socklen_t
len
;
struct
hostent
*
h
;
const
char
*
reason
;
char
**
s
;
int
r
;
if
(
!
(
conn
->
ssl
=
SSL_new
(
ctx
))
||
!
SSL_set_app_data
(
conn
->
ssl
,
conn
)
||
!
SSL_set_fd
(
conn
->
ssl
,
conn
->
sock
)
||
SSL_connect
(
conn
->
ssl
)
<=
0
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not establish SSL connection: %s
\n
"
),
SSLerrmessage
());
return
-
1
;
}
/* check the certificate chain */
/* for now, we allow self-signed server certs */
r
=
SSL_get_verify_result
(
conn
->
ssl
);
// if (r != X509_V_OK && r != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
if
(
r
!=
X509_V_OK
)
{
switch
(
r
)
{
case
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
:
reason
=
"unable to get issuer cert"
;
break
;
case
X509_V_ERR_UNABLE_TO_GET_CRL
:
reason
=
"unable to get CRL"
;
break
;
case
X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE
:
reason
=
"unable to decrypt cert signature"
;
break
;
case
X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE
:
reason
=
"unable to decrypt CRL signature"
;
break
;
case
X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
:
reason
=
"unable to decode issuer public key"
;
break
;
case
X509_V_ERR_CERT_SIGNATURE_FAILURE
:
reason
=
"cert signature failure"
;
break
;
case
X509_V_ERR_CRL_SIGNATURE_FAILURE
:
reason
=
"CRL signature failure"
;
break
;
case
X509_V_ERR_CERT_NOT_YET_VALID
:
reason
=
"cert is not yet valid"
;
break
;
case
X509_V_ERR_CERT_HAS_EXPIRED
:
reason
=
"cert has expired"
;
break
;
case
X509_V_ERR_CRL_NOT_YET_VALID
:
reason
=
"CRL not yet valid"
;
break
;
case
X509_V_ERR_CRL_HAS_EXPIRED
:
reason
=
"CRL has expired"
;
break
;
case
X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
:
reason
=
"error in cert notBefore field"
;
break
;
case
X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
:
reason
=
"error in cert notAfter field"
;
break
;
case
X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD
:
reason
=
"error in CRL last update field"
;
break
;
case
X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD
:
reason
=
"error in CRL next update field"
;
break
;
case
X509_V_ERR_OUT_OF_MEM
:
reason
=
"out of memory"
;
break
;
case
X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
:
reason
=
"depth zero self-signed cert"
;
break
;
case
X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
:
reason
=
"self-signed cert in chain"
;
break
;
case
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
:
reason
=
"unable to get issuer cert locally"
;
break
;
case
X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
:
reason
=
"unable to verify leaf signature"
;
break
;
case
X509_V_ERR_CERT_CHAIN_TOO_LONG
:
reason
=
"cert chain too long"
;
break
;
case
X509_V_ERR_CERT_REVOKED
:
reason
=
"cert revoked"
;
break
;
case
X509_V_ERR_INVALID_CA
:
reason
=
"invalid CA"
;
break
;
case
X509_V_ERR_PATH_LENGTH_EXCEEDED
:
reason
=
"path length exceeded"
;
break
;
case
X509_V_ERR_INVALID_PURPOSE
:
reason
=
"invalid purpose"
;
break
;
case
X509_V_ERR_CERT_UNTRUSTED
:
reason
=
"cert untrusted"
;
break
;
case
X509_V_ERR_CERT_REJECTED
:
reason
=
"cert rejected"
;
break
;
/* These are 'informational' when looking for issuer cert */
case
X509_V_ERR_SUBJECT_ISSUER_MISMATCH
:
reason
=
"cert issuer/issuer subject mismatch"
;
break
;
case
X509_V_ERR_AKID_SKID_MISMATCH
:
reason
=
"cert akid/issuer skid mismatch"
;
break
;
case
X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH
:
reason
=
"cert akid/issuer serial mismatch"
;
break
;
case
X509_V_ERR_KEYUSAGE_NO_CERTSIGN
:
reason
=
"keyusage no certsign"
;
break
;
/* The application is not happy */
case
X509_V_ERR_APPLICATION_VERIFICATION
:
reason
=
"application-specific verification error"
;
break
;
default:
reason
=
"unknown reason"
;
}
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"certificate could not be verified: %s (%d)
\n
"
),
reason
,
r
);
return
-
1
;
}
/* do a reverse lookup on the server */
len
=
sizeof
(
addr
);
if
(
getpeername
(
conn
->
sock
,
&
addr
,
&
len
)
==
-
1
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"error querying socket: %s
\n
"
),
strerror
(
errno
));
return
-
1
;
}
if
(
addr
.
sa_family
!=
AF_INET
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"not on IPv4 socket
\n
"
));
return
-
1
;
}
/* check the cert common name */
conn
->
peer
=
SSL_get_peer_certificate
(
conn
->
ssl
);
X509_NAME_get_text_by_NID
(
X509_get_subject_name
(
conn
->
peer
),
NID_commonName
,
peerName
,
sizeof
peerName
);
if
((
h
=
gethostbyname2
(
peerName
,
addr
.
sa_family
))
==
NULL
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"error looking up address %s: %s
\n
"
),
peerName
,
hstrerror
(
h_errno
));
return
-
1
;
}
/* check for a match on actual socket address */
sin1
=
(
struct
sockaddr_in
*
)
&
addr
;
for
(
s
=
h
->
h_addr_list
;
*
s
!=
NULL
;
s
++
)
{
sin2
=
(
struct
sockaddr_in
*
)
*
s
;
if
(
sin1
->
sin_addr
.
s_addr
==
sin2
->
sin_addr
.
s_addr
)
break
;
}
/* if that failed, check for a match on alias */
if
(
*
s
==
NULL
)
{
if
(
strcasecmp
(
peerName
,
conn
->
pghost
)
==
0
)
;
else
{
for
(
s
=
h
->
h_aliases
;
*
s
!=
NULL
;
s
++
)
{
if
(
strcasecmp
(
peerName
,
*
s
)
==
0
)
break
;
}
if
(
*
s
==
NULL
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"certificate name (%s) does not match peer address
\n
"
),
peerName
);
return
-
1
;
}
}
}
return
0
;
}
/*
* Close a SSL connection.
*/
void
close_SSL
(
PGconn
*
conn
)
{
if
(
conn
->
ssl
)
{
SSL_shutdown
(
conn
->
ssl
);
SSL_free
(
conn
->
ssl
);
conn
->
ssl
=
NULL
;
}
}
/*
* Accessor function that retrieves SSL connection pointer.
*/
SSL
*
PQgetssl
(
PGconn
*
conn
)
{
if
(
!
conn
)
return
NULL
;
return
conn
->
ssl
;
}
/*
* Obtain reason string for last SSL error
*
* Some caution is needed here since ERR_reason_error_string will
* return NULL if it doesn't recognize the error code. We don't
* want to return NULL ever.
*/
static
const
char
*
SSLerrmessage
(
void
)
{
unsigned
long
errcode
;
const
char
*
errreason
;
static
char
errbuf
[
32
];
errcode
=
ERR_get_error
();
if
(
errcode
==
0
)
return
"No SSL error reported"
;
errreason
=
ERR_reason_error_string
(
errcode
);
if
(
errreason
!=
NULL
)
return
errreason
;
snprintf
(
errbuf
,
sizeof
(
errbuf
),
"SSL error code %lu"
,
errcode
);
return
errbuf
;
}
/*
* The following conditional block shows how to embedded
* one or more root certs into the libpq library. This
* eliminates any need to copy the file to the clients, but
* obviously must be done on a per-site basis.
*/
#if 0
/*
* The cert file, in PEM format, copied into a string buffer.
*/
static const char root1[] =
"-----BEGIN CERTIFICATE-----\n\
MIIEqDCCBGagAwIBAgIBADALBgcqhkjOOAQDBQAwgYwxEzARBgoJkiaJk/IsZAEZ\n\
EwNjb20xGjAYBgoJkiaJk/IsZAEZEwpjb3lvdGVzb25nMRIwEAYDVQQKEwlTbmFr\n\
ZSBPaWwxHTAbBgNVBAMTFFBvc3RncmVTUUwgUm9vdCBDZXJ0MSYwJAYJKoZIhvcN\n\
AQkBFhdwb3N0Z3Jlc0Bjb3lvdGVzb25nLmNvbTAeFw0wMjA1MjEwMDE4MDZaFw0w\n\
MjA2MjAwMDE4MDZaMIGMMRMwEQYKCZImiZPyLGQBGRMDY29tMRowGAYKCZImiZPy\n\
LGQBGRMKY295b3Rlc29uZzESMBAGA1UEChMJU25ha2UgT2lsMR0wGwYDVQQDExRQ\n\
b3N0Z3JlU1FMIFJvb3QgQ2VydDEmMCQGCSqGSIb3DQEJARYXcG9zdGdyZXNAY295\n\
b3Rlc29uZy5jb20wggG2MIIBKwYHKoZIzjgEATCCAR4CgYEAxgmwTdzv7eSqUjcS\n\
8fdT/3lm+On8LmHL+CkmF7IlvZKm2kwIiQqjcrG6JqgXBdBTIzeqSZV8cGrc0/f5\n\
zMh6rDVxuSrEwCh8DtAC9LdwWyHp7Tw79z9khkZNTAlBonwOLvm0BJaroH5FLK9S\n\
PvAHmjmLA1zd/2K8o+CqFFJasTkCFQDXfI1tnskPUtPXz/W88wRg5y5zpQKBgGwk\n\
3a+tfWmw2mMDXh2sSHoGwVlzwqKZnDfk97I7Tz/zmGOLEGdA7s+2YqKKfW7F0S8p\n\
Ho/cYDNE2lyaGqaxl2pscqdIhEmKYjJtjgaOOkQwfaYXs5GY0zkiSaxxtvJTj0WK\n\
OQ+J/0iunsyyukYc3+TiosHENz4Y2ZgaGseJTMz0A4GEAAKBgFG5WK5/64gjuJ7D\n\
D4RQ7QZtZ+wxP4s3oEqphz4hPGpGOPYlHdo2PhHMEAVrgMnX44yqUAnwmG5LT1RI\n\
5KPCDwgyxBQVq2FDJrYoRb/AVbqMQ8cyJZ1etd7J1ies31b3fHp+uYSFHuCmLfFp\n\
RO8wLplYM6XmJ5X5BF8zlclDxIj/o4IBVTCCAVEwHQYDVR0OBBYEFMO7rhIEVsrn\n\
6k/gxKR5bCdEo8jZMIG5BgNVHSMEgbEwga6AFMO7rhIEVsrn6k/gxKR5bCdEo8jZ\n\
oYGSpIGPMIGMMRMwEQYKCZImiZPyLGQBGRMDY29tMRowGAYKCZImiZPyLGQBGRMK\n\
Y295b3Rlc29uZzESMBAGA1UEChMJU25ha2UgT2lsMR0wGwYDVQQDExRQb3N0Z3Jl\n\
U1FMIFJvb3QgQ2VydDEmMCQGCSqGSIb3DQEJARYXcG9zdGdyZXNAY295b3Rlc29u\n\
Zy5jb22CAQAwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwEQYJYIZIAYb4QgEB\n\
BAQDAgEGMCIGA1UdEQQbMBmBF3Bvc3RncmVzQGNveW90ZXNvbmcuY29tMCIGA1Ud\n\
EgQbMBmBF3Bvc3RncmVzQGNveW90ZXNvbmcuY29tMAsGByqGSM44BAMFAAMvADAs\n\
AhUAhcafaeM39bK2z2tgRD8OLbrr3fICEwdVqUy9ykb9Hc7SjcKB51lUJ9s=\n\
-----END CERTIFICATE-----\n";
static void
load_hardcoded_certs(void)
{
X509_STORE *store;
X509 *x;
store = SSL_CTX_get_cert_store(ctx);
if (store != NULL)
{
x = load_cert_buffer(root1, sizeof (root1));
X509_STORE_add_cert(store, x);
X509_free(x);
/* repeat as necessary.... */
}
}
#else
static
void
load_hardcoded_certs
(
void
)
{
}
#endif
#endif
/* USE_SSL */
src/interfaces/libpq/libpq-int.h
View file @
eb43af32
...
...
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq-int.h,v 1.4
7 2002/06/14 03:56:4
7 momjian Exp $
* $Id: libpq-int.h,v 1.4
8 2002/06/14 04:09:3
7 momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -270,7 +270,6 @@ struct pg_conn
bool
allow_ssl_try
;
/* Allowed to try SSL negotiation */
bool
require_ssl
;
/* Require SSL to make connection */
SSL
*
ssl
;
/* SSL status, if have SSL connection */
X509
*
peer
;
/* server certificate */
#endif
/* Buffer for current error message */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment