diff options
| author | Bruce Momjian | 1999-09-27 03:13:16 +0000 |
|---|---|---|
| committer | Bruce Momjian | 1999-09-27 03:13:16 +0000 |
| commit | e0e7daef6daf9a760c9c90bc7fe5b9ba4349267f (patch) | |
| tree | 37489845f4c86ef613737986142354fd8562c0d9 /src/backend | |
| parent | 3114f92122d3aa3588e89c166f69b44204d5b3db (diff) | |
Lots of patches coming in from me today :-)
When drawing up a very simple "text-drawing" of how the negotiation is done,
I realised I had done this last part (fallback) in a very stupid way. Patch
#4 fixes this, and does it in a much better way.
Included is also the simple text-drawing of how the negotiation is done.
//Magnus
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/libpq/auth.c | 6 | ||||
| -rw-r--r-- | src/backend/libpq/hba.c | 77 | ||||
| -rw-r--r-- | src/backend/libpq/pg_hba.conf.sample | 12 | ||||
| -rw-r--r-- | src/backend/libpq/pqcomm.c | 22 | ||||
| -rw-r--r-- | src/backend/libpq/pqpacket.c | 29 | ||||
| -rw-r--r-- | src/backend/postmaster/postmaster.c | 171 |
6 files changed, 252 insertions, 65 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index d42503f3c18..97d21cb68bc 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.40 1999/07/17 20:17:00 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.41 1999/09/27 03:12:58 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -452,8 +452,7 @@ be_recvauth(Port *port) * an error message into the postmaster logfile if it failed. */ - if (hba_getauthmethod(&port->raddr, port->user, port->database, - port->auth_arg, &port->auth_method) != STATUS_OK) + if (hba_getauthmethod(port) != STATUS_OK) PacketSendError(&port->pktInfo, "Missing or erroneous pg_hba.conf file, see postmaster log for details"); @@ -470,7 +469,6 @@ be_recvauth(Port *port) AuthRequest areq = AUTH_REQ_OK; PacketDoneProc auth_handler = NULL; - switch (port->auth_method) { case uaReject: diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 5012d22263a..14291560322 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -5,7 +5,7 @@ * wherein you authenticate a user by seeing what IP address the system * says he comes from and possibly using ident). * - * $Id: hba.c,v 1.47 1999/07/17 20:17:02 momjian Exp $ + * $Id: hba.c,v 1.48 1999/09/27 03:12:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -146,9 +146,7 @@ read_hba_entry2(FILE *file, UserAuth *userauth_p, char *auth_arg, static void -process_hba_record(FILE *file, SockAddr *raddr, const char *user, - const char *database, bool *matches_p, bool *error_p, - UserAuth *userauth_p, char *auth_arg) +process_hba_record(FILE *file, hbaPort *port, bool *matches_p, bool *error_p) { /*--------------------------------------------------------------------------- Process the non-comment record in the config file that is next on the file. @@ -182,16 +180,16 @@ process_hba_record(FILE *file, SockAddr *raddr, const char *user, /* Read the rest of the line. */ - read_hba_entry2(file, userauth_p, auth_arg, error_p); + read_hba_entry2(file, &port->auth_method, port->auth_arg, error_p); /* * For now, disallow methods that need AF_INET sockets to work. */ if (!*error_p && - (*userauth_p == uaIdent || - *userauth_p == uaKrb4 || - *userauth_p == uaKrb5)) + (port->auth_method == uaIdent || + port->auth_method == uaKrb4 || + port->auth_method == uaKrb5)) *error_p = true; if (*error_p) @@ -202,15 +200,33 @@ process_hba_record(FILE *file, SockAddr *raddr, const char *user, * sort of connection, ignore it. */ - if ((strcmp(db, database) != 0 && strcmp(db, "all") != 0 && - (strcmp(db, "sameuser") != 0 || strcmp(database, user) != 0)) || - raddr->sa.sa_family != AF_UNIX) + if ((strcmp(db, port->database) != 0 && strcmp(db, "all") != 0 && + (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || + port->raddr.sa.sa_family != AF_UNIX) return; } - else if (strcmp(buf, "host") == 0) + else if (strcmp(buf, "host") == 0 || strcmp(buf, "hostssl") == 0) { struct in_addr file_ip_addr, mask; + bool discard = 0; /* Discard this entry */ + +#ifdef USE_SSL + /* If SSL, then check that we are on SSL */ + if (strcmp(buf, "hostssl") == 0) { + if (!port->ssl) + discard = 1; + + /* Placeholder to require specific SSL level, perhaps? */ + /* Or a client certificate */ + + /* Since we were on SSL, proceed as with normal 'host' mode */ + } +#else + /* If not SSL, we don't support this */ + if (strcmp(buf,"hostssl") == 0) + goto syntax; +#endif /* Get the database. */ @@ -252,20 +268,27 @@ process_hba_record(FILE *file, SockAddr *raddr, const char *user, * info from it. */ - read_hba_entry2(file, userauth_p, auth_arg, error_p); + read_hba_entry2(file, &port->auth_method, port->auth_arg, error_p); if (*error_p) goto syntax; /* + * If told to discard earlier. Moved down here so we don't get + * "out of sync" with the file. + */ + if (discard) + return; + + /* * If this record isn't for our database, or this is the wrong * sort of connection, ignore it. */ - if ((strcmp(db, database) != 0 && strcmp(db, "all") != 0 && - (strcmp(db, "sameuser") != 0 || strcmp(database, user) != 0)) || - raddr->sa.sa_family != AF_INET || - ((file_ip_addr.s_addr ^ raddr->in.sin_addr.s_addr) & mask.s_addr) != 0x0000) + if ((strcmp(db, port->database) != 0 && strcmp(db, "all") != 0 && + (strcmp(db, "sameuser") != 0 || strcmp(port->database, port->user) != 0)) || + port->raddr.sa.sa_family != AF_INET || + ((file_ip_addr.s_addr ^ port->raddr.in.sin_addr.s_addr) & mask.s_addr) != 0x0000) return; } else @@ -291,9 +314,7 @@ syntax: static void -process_open_config_file(FILE *file, SockAddr *raddr, const char *user, - const char *database, bool *hba_ok_p, - UserAuth *userauth_p, char *auth_arg) +process_open_config_file(FILE *file, hbaPort *port, bool *hba_ok_p) { /*--------------------------------------------------------------------------- This function does the same thing as find_hba_entry, only with @@ -316,8 +337,7 @@ process_open_config_file(FILE *file, SockAddr *raddr, const char *user, if (c == '#') read_through_eol(file); else - process_hba_record(file, raddr, user, database, - &found_entry, &error, userauth_p, auth_arg); + process_hba_record(file, port, &found_entry, &error); } } @@ -326,7 +346,7 @@ process_open_config_file(FILE *file, SockAddr *raddr, const char *user, /* If no matching entry was found, synthesize 'reject' entry. */ if (!found_entry) - *userauth_p = uaReject; + port->auth_method = uaReject; *hba_ok_p = true; } @@ -335,8 +355,7 @@ process_open_config_file(FILE *file, SockAddr *raddr, const char *user, static void -find_hba_entry(SockAddr *raddr, const char *user, const char *database, - bool *hba_ok_p, UserAuth *userauth_p, char *auth_arg) +find_hba_entry(hbaPort *port, bool *hba_ok_p) { /* * Read the config file and find an entry that allows connection from @@ -412,8 +431,7 @@ find_hba_entry(SockAddr *raddr, const char *user, const char *database, } else { - process_open_config_file(file, raddr, user, database, hba_ok_p, - userauth_p, auth_arg); + process_open_config_file(file, port, hba_ok_p); FreeFile(file); } pfree(conf_file); @@ -1057,8 +1075,7 @@ GetCharSetByHost(char *TableName, int host, const char *DataDir) #endif int -hba_getauthmethod(SockAddr *raddr, char *user, char *database, - char *auth_arg, UserAuth *auth_method) +hba_getauthmethod(hbaPort *port) { /*--------------------------------------------------------------------------- Determine what authentication method should be used when accessing database @@ -1070,7 +1087,7 @@ hba_getauthmethod(SockAddr *raddr, char *user, char *database, ----------------------------------------------------------------------------*/ bool hba_ok = false; - find_hba_entry(raddr, user, database, &hba_ok, auth_method, auth_arg); + find_hba_entry(port, &hba_ok); return hba_ok ? STATUS_OK : STATUS_ERROR; } diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample index e53f505b4a3..ced8df757cc 100644 --- a/src/backend/libpq/pg_hba.conf.sample +++ b/src/backend/libpq/pg_hba.conf.sample @@ -79,6 +79,18 @@ # # krb5: Kerberos V5 authentication is used. +# Record type "hostssl" +# --------------------- +# +# This record identifies the authentication to use when connecting to a +# particular database via TCP/IP sockets over SSL. Note that normal +# "host" records are also matched - "hostssl" records can be used to +# require a SSL connection. +# This keyword is only available if the server is compiled with SSL support +# enabled. +# +# The format of this record is identical to that of "host". + # Record type "local" # ------------------ # diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 60b2f2e32b5..38ddcd28d3f 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -28,7 +28,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: pqcomm.c,v 1.83 1999/09/08 22:57:12 tgl Exp $ + * $Id: pqcomm.c,v 1.84 1999/09/27 03:12:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -436,8 +436,16 @@ pq_recvbuf(void) /* Can fill buffer from PqRecvLength and upwards */ for (;;) { - int r = recv(MyProcPort->sock, PqRecvBuffer + PqRecvLength, - PQ_BUFFER_SIZE - PqRecvLength, 0); + int r; + +#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) { @@ -604,7 +612,13 @@ pq_flush(void) while (bufptr < bufend) { - int r = send(MyProcPort->sock, bufptr, bufend - bufptr, 0); + int r; +#ifdef 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) { diff --git a/src/backend/libpq/pqpacket.c b/src/backend/libpq/pqpacket.c index 160944cc5fb..591867e0a9a 100644 --- a/src/backend/libpq/pqpacket.c +++ b/src/backend/libpq/pqpacket.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.22 1999/07/17 20:17:03 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/pqpacket.c,v 1.23 1999/09/27 03:12:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -50,13 +50,20 @@ PacketReceiveSetup(Packet *pkt, PacketDoneProc iodone, void *arg) */ int -PacketReceiveFragment(Packet *pkt, int sock) +PacketReceiveFragment(Port *port) { int got; - - if ((got = read(sock, pkt->ptr, pkt->nrtodo)) > 0) + Packet *pkt = &port->pktInfo; + +#ifdef USE_SSL + if (port->ssl) + got = SSL_read(port->ssl, pkt->ptr, pkt->nrtodo); + else +#endif + got = read(port->sock, pkt->ptr, pkt->nrtodo); + if (got > 0) { - pkt->nrtodo -= got; + pkt->nrtodo -= got; pkt->ptr += got; /* See if we have got what we need for the packet length. */ @@ -132,11 +139,19 @@ PacketSendSetup(Packet *pkt, int nbytes, PacketDoneProc iodone, void *arg) */ int -PacketSendFragment(Packet *pkt, int sock) +PacketSendFragment(Port *port) { int done; + Packet *pkt = &port->pktInfo; + +#ifdef USE_SSL + if (port->ssl) + done = SSL_write(port->ssl, pkt->ptr, pkt->nrtodo); + else +#endif + done = write(port->sock, pkt->ptr, pkt->nrtodo); - if ((done = write(sock, pkt->ptr, pkt->nrtodo)) > 0) + if (done > 0) { pkt->nrtodo -= done; pkt->ptr += done; diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 67ac6ce9c30..a44fe726bfd 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.116 1999/09/21 20:58:19 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.117 1999/09/27 03:13:05 momjian Exp $ * * NOTES * @@ -183,6 +183,10 @@ 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 */ @@ -200,6 +204,8 @@ static int SendStop = false; static bool NetServer = false; /* if not zero, postmaster listen for * non-local connections */ +static bool SecureNetServer = false; /* if not zero, postmaster listens for only SSL + * non-local connections */ /* @@ -233,6 +239,7 @@ extern int optind, */ static void pmdaemonize(void); static Port *ConnCreate(int serverFd); +static void ConnFree(Port *port); static void reset_shared(unsigned short port); static void pmdie(SIGNAL_ARGS); static void reaper(SIGNAL_ARGS); @@ -250,6 +257,9 @@ static long PostmasterRandom(void); static void RandomSalt(char *salt); static void SignalChildren(SIGNAL_ARGS); static int CountChildren(void); +#ifdef USE_SSL +static void InitSSL(void); +#endif #ifdef CYR_RECODE void GetCharSetByHost(char *, int, char *); @@ -393,7 +403,7 @@ PostmasterMain(int argc, char *argv[]) DataDir = getenv("PGDATA"); /* default value */ opterr = 0; - while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:dim:MN:no:p:Ss")) != EOF) + while ((opt = getopt(nonblank_argc, argv, "A:a:B:b:D:i::dm:MN:no:p:Ss")) != EOF) { switch (opt) { @@ -456,6 +466,10 @@ PostmasterMain(int argc, char *argv[]) break; case 'i': NetServer = true; +#ifdef USE_SSL + if (optarg && !strcasecmp(optarg,"s")) + SecureNetServer = true; +#endif break; case 'm': /* Multiplexed backends no longer supported. */ @@ -557,16 +571,21 @@ PostmasterMain(int argc, char *argv[]) exit(1); } +#ifdef USE_SSL + InitSSL(); +#endif + if (NetServer) { - status = StreamServerPort(hostName, PostPortName, &ServerSock_INET); - if (status != STATUS_OK) - { - fprintf(stderr, "%s: cannot create INET stream port\n", - progname); - exit(1); - } + status = StreamServerPort(hostName, PostPortName, &ServerSock_INET); + if (status != STATUS_OK) + { + fprintf(stderr, "%s: cannot create INET stream port\n", + progname); + exit(1); + } } + #ifndef __CYGWIN32__ status = StreamServerPort(NULL, PostPortName, &ServerSock_UNIX); if (status != STATUS_OK) @@ -655,6 +674,9 @@ usage(const char *progname) fprintf(stderr, "\t-b backend\tuse a specific backend server executable\n"); fprintf(stderr, "\t-d [1|2|3]\tset debugging level\n"); fprintf(stderr, "\t-i \t\tlisten on TCP/IP sockets as well as Unix domain socket\n"); +#ifdef USE_SSL + fprintf(stderr," \t-is\t\tlisten on TCP/IP sockets as above, but only SSL connections\n"); +#endif fprintf(stderr, "\t-N nprocs\tset max number of backends (1..%d, default %d)\n", MAXBACKENDS, DEF_MAXBACKENDS); fprintf(stderr, "\t-n \t\tdon't reinitialize shared memory after abnormal exit\n"); @@ -690,6 +712,9 @@ ServerLoop(void) Port *port; fd_set rmask, wmask; +#ifdef USE_SSL + int no_select = 0; +#endif #ifdef HAVE_SIGPROCMASK sigprocmask(SIG_SETMASK, &oldsigmask, 0); @@ -699,6 +724,18 @@ ServerLoop(void) memmove((char *) &rmask, (char *) &readmask, sizeof(fd_set)); memmove((char *) &wmask, (char *) &writemask, sizeof(fd_set)); + +#ifdef USE_SSL + for (curr = DLGetHead(PortList); curr; curr = DLGetSucc(curr)) + if (((Port *)DLE_VAL(curr))->ssl && + SSL_pending(((Port *)DLE_VAL(curr))->ssl) > 0) { + no_select = 1; + break; + } + if (no_select) + FD_ZERO(&rmask); /* So we don't accept() anything below */ + else +#endif if (select(nSockets, &rmask, &wmask, (fd_set *) NULL, (struct timeval *) NULL) < 0) { @@ -743,18 +780,20 @@ ServerLoop(void) #ifndef __CYGWIN32__ if (ServerSock_UNIX != INVALID_SOCK && FD_ISSET(ServerSock_UNIX, &rmask) && - (port = ConnCreate(ServerSock_UNIX)) != NULL) - PacketReceiveSetup(&port->pktInfo, + (port = ConnCreate(ServerSock_UNIX)) != NULL) { + PacketReceiveSetup(&port->pktInfo, readStartupPacket, (void *) port); + } #endif if (ServerSock_INET != INVALID_SOCK && - FD_ISSET(ServerSock_INET, &rmask) && - (port = ConnCreate(ServerSock_INET)) != NULL) + FD_ISSET(ServerSock_INET, &rmask) && + (port = ConnCreate(ServerSock_INET)) != NULL) { PacketReceiveSetup(&port->pktInfo, readStartupPacket, (void *) port); + } /* Build up new masks for select(). */ @@ -767,14 +806,26 @@ ServerLoop(void) Port *port = (Port *) DLE_VAL(curr); int status = STATUS_OK; Dlelem *next; + int readyread = 0; + +#ifdef USE_SSL + if (port->ssl) { + if (SSL_pending(port->ssl) || + FD_ISSET(port->sock, &rmask)) + readyread = 1; + } + else +#endif + if (FD_ISSET(port->sock, &rmask)) + readyread = 1; - if (FD_ISSET(port->sock, &rmask)) + if (readyread) { if (DebugLvl > 1) fprintf(stderr, "%s: ServerLoop:\t\thandling reading %d\n", progname, port->sock); - if (PacketReceiveFragment(&port->pktInfo, port->sock) != STATUS_OK) + if (PacketReceiveFragment(port) != STATUS_OK) status = STATUS_ERROR; } @@ -784,7 +835,7 @@ ServerLoop(void) fprintf(stderr, "%s: ServerLoop:\t\thandling writing %d\n", progname, port->sock); - if (PacketSendFragment(&port->pktInfo, port->sock) != STATUS_OK) + if (PacketSendFragment(port) != STATUS_OK) status = STATUS_ERROR; } @@ -827,7 +878,7 @@ ServerLoop(void) { StreamClose(port->sock); DLRemove(curr); - free(port); + ConnFree(port); DLFreeElem(curr); } else @@ -896,7 +947,7 @@ readStartupPacket(void *arg, PacketLen len, void *pkt) port = (Port *) arg; si = (StartupPacket *) pkt; - + /* * The first field is either a protocol version number or a special * request code. @@ -907,8 +958,45 @@ readStartupPacket(void *arg, PacketLen len, void *pkt) if (port->proto == CANCEL_REQUEST_CODE) return processCancelRequest(port, len, pkt); + if (port->proto == NEGOTIATE_SSL_CODE) { + char SSLok; + +#ifdef USE_SSL + SSLok = 'S'; /* Support for SSL */ +#else + SSLok = 'N'; /* No support for SSL */ +#endif + if (send(port->sock, &SSLok, 1, 0) != 1) { + perror("Failed to send SSL negotiation response"); + return STATUS_ERROR; /* Close connection */ + } + +#ifdef USE_SSL + if (!(port->ssl = SSL_new(SSL_context)) || + !SSL_set_fd(port->ssl, port->sock) || + SSL_accept(port->ssl) <= 0) + { + fprintf(stderr,"Failed to initialize SSL connection: %s, errno: %d (%s)\n", + ERR_reason_error_string(ERR_get_error()), errno, strerror(errno)); + return STATUS_ERROR; + } +#endif + /* ready for the normal startup packet */ + PacketReceiveSetup(&port->pktInfo, + readStartupPacket, + (void *)port); + return STATUS_OK; /* Do not close connection */ + } + /* Could add additional special packet types here */ + /* Any SSL negotiation must have taken place here, so drop the connection + * ASAP if we require SSL */ + if (SecureNetServer && !port->ssl) { + PacketSendError(&port->pktInfo, "Backend requires secure connection."); + return STATUS_OK; + } + /* Check we can handle the protocol the frontend is using. */ if (PG_PROTOCOL_MAJOR(port->proto) < PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST) || @@ -952,7 +1040,6 @@ readStartupPacket(void *arg, PacketLen len, void *pkt) return STATUS_OK; /* don't close the connection yet */ } - /* * The client has sent a cancel request packet, not a normal * start-a-new-backend packet. Perform the necessary processing. @@ -1040,6 +1127,20 @@ ConnCreate(int serverFd) } /* + * ConnFree -- cree a local connection data structure + */ +void +ConnFree(Port *conn) +{ +#ifdef USE_SSL + if (conn->ssl) { + SSL_free(conn->ssl); + } +#endif + free(conn); +} + +/* * reset_shared -- reset shared memory and semaphores */ static void @@ -1502,7 +1603,7 @@ DoBackend(Port *port) sigprocmask(SIG_SETMASK, &oldsigmask, 0); /* Close the postmaster sockets */ - if (NetServer) + if (NetServer) StreamClose(ServerSock_INET); #ifndef __CYGWIN32__ StreamClose(ServerSock_UNIX); @@ -1729,3 +1830,33 @@ CountChildren(void) } return cnt; } + + +/* + * 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) { + fprintf(stderr, "Failed to create SSL context: %s\n",ERR_reason_error_string(ERR_get_error())); + exit(1); + } + snprintf(fnbuf,sizeof(fnbuf),"%s/server.crt", DataDir); + if (!SSL_CTX_use_certificate_file(SSL_context, fnbuf, SSL_FILETYPE_PEM)) { + fprintf(stderr, "Failed to load server certificate (%s): %s\n",fnbuf,ERR_reason_error_string(ERR_get_error())); + exit(1); + } + snprintf(fnbuf,sizeof(fnbuf),"%s/server.key", DataDir); + if (!SSL_CTX_use_PrivateKey_file(SSL_context, fnbuf, SSL_FILETYPE_PEM)) { + fprintf(stderr, "Failed to load private key file (%s): %s\n",fnbuf,ERR_reason_error_string(ERR_get_error())); + exit(1); + } + if (!SSL_CTX_check_private_key(SSL_context)) { + fprintf(stderr, "Check of private key failed: %s\n",ERR_reason_error_string(ERR_get_error())); + exit(1); + } +} |
