~ubuntu-branches/ubuntu/natty/postgresql-8.4/natty-security

« back to all changes in this revision

Viewing changes to src/interfaces/libpq/fe-secure.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-07-01 17:41:41 UTC
  • mfrom: (1.1.4 upstream)
  • mto: This revision was merged to the branch mainline in revision 6.
  • Revision ID: james.westby@ubuntu.com-20090701174141-jfmn9tt8e69m950x
Tags: 8.4.0-1
* Final 8.4.0 release. Major enhancements:
  - Windowing Functions
  - Common Table Expressions and Recursive Queries
  - Default and variadic parameters for functions
  - Parallel Restore
  - Column Permissions
  - Per-database locale settings
  - Improved hash indexes
  - Improved join performance for EXISTS and NOT EXISTS queries
  - Easier-to-use Warm Standby
  - Automatic sizing of the Free Space Map
  - Visibility Map (greatly reduces vacuum overhead for slowly-changing
    tables)
  - Version-aware psql (backslash commands work against older servers)
  - Support SSL certificates for user authentication
  - Per-function runtime statistics
  - Easy editing of functions in psql
  - New contrib modules: pg_stat_statements, auto_explain, citext,
    btree_gin 
  Upload to unstable, 8.4 is the new default. 
* debian/control: Build the versionless metapackages and have them point to
  8.4.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 *
12
12
 *
13
13
 * IDENTIFICATION
14
 
 *        $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.125 2009/05/03 17:16:58 tgl Exp $
 
14
 *        $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.127 2009/06/23 18:13:23 mha Exp $
15
15
 *
16
16
 * NOTES
17
17
 *
31
31
#include "libpq-fe.h"
32
32
#include "fe-auth.h"
33
33
#include "pqsignal.h"
 
34
#include "libpq-int.h"
34
35
 
35
36
#ifdef WIN32
36
37
#include "win32.h"
62
63
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
63
64
#include <openssl/conf.h>
64
65
#endif
65
 
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
 
66
#ifdef USE_SSL_ENGINE
66
67
#include <openssl/engine.h>
67
68
#endif
68
69
 
111
112
static pthread_mutex_t ssl_config_mutex = NULL;
112
113
static long win32_ssl_create_mutex = 0;
113
114
#endif
114
 
 
115
 
#endif  /* ENABLE_THREAD_SAFETY */
116
 
 
117
 
#endif /* SSL */
 
115
#endif   /* ENABLE_THREAD_SAFETY */
 
116
#endif   /* SSL */
118
117
 
119
118
 
120
119
/*
141
140
 
142
141
#define RESTORE_SIGPIPE() \
143
142
        pq_reset_sigpipe(&osigmask, sigpipe_pending, got_epipe)
144
 
 
145
 
#else   /* !ENABLE_THREAD_SAFETY */
 
143
#else                                                   /* !ENABLE_THREAD_SAFETY */
146
144
 
147
145
#define DISABLE_SIGPIPE(failaction) \
148
146
        pqsigfunc       oldsighandler = pqsignal(SIGPIPE, SIG_IGN)
151
149
 
152
150
#define RESTORE_SIGPIPE() \
153
151
        pqsignal(SIGPIPE, oldsighandler)
154
 
 
155
 
#endif  /* ENABLE_THREAD_SAFETY */
156
 
#else   /* WIN32 */
 
152
#endif   /* ENABLE_THREAD_SAFETY */
 
153
#else                                                   /* WIN32 */
157
154
 
158
155
#define DISABLE_SIGPIPE(failaction)
159
156
#define REMEMBER_EPIPE(cond)
160
157
#define RESTORE_SIGPIPE()
161
 
 
162
 
#endif  /* WIN32 */
 
158
#endif   /* WIN32 */
163
159
 
164
160
/* ------------------------------------------------------------ */
165
161
/*                       Procedures common to all secure sessions                       */
180
176
 *      Exported function to allow application to tell us it's already
181
177
 *      initialized OpenSSL and/or libcrypto.
182
178
 */
183
 
void 
 
179
void
184
180
PQinitOpenSSL(int do_ssl, int do_crypto)
185
181
{
186
182
#ifdef USE_SSL
187
183
#ifdef ENABLE_THREAD_SAFETY
 
184
 
188
185
        /*
189
 
         * Disallow changing the flags while we have open connections, else
190
 
         * we'd get completely confused.
 
186
         * Disallow changing the flags while we have open connections, else we'd
 
187
         * get completely confused.
191
188
         */
192
189
        if (ssl_open_connections != 0)
193
190
                return;
473
470
 * Check if a wildcard certificate matches the server hostname.
474
471
 *
475
472
 * The rule for this is:
476
 
 *  1. We only match the '*' character as wildcard
477
 
 *  2. We match only wildcards at the start of the string
478
 
 *  3. The '*' character does *not* match '.', meaning that we match only
479
 
 *     a single pathname component.
480
 
 *  4. We don't support more than one '*' in a single pattern.
 
473
 *      1. We only match the '*' character as wildcard
 
474
 *      2. We match only wildcards at the start of the string
 
475
 *      3. The '*' character does *not* match '.', meaning that we match only
 
476
 *         a single pathname component.
 
477
 *      4. We don't support more than one '*' in a single pattern.
481
478
 *
482
479
 * This is roughly in line with RFC2818, but contrary to what most browsers
483
480
 * appear to be implementing (point 3 being the difference)
487
484
static int
488
485
wildcard_certificate_match(const char *pattern, const char *string)
489
486
{
490
 
        int lenpat = strlen(pattern);
491
 
        int lenstr = strlen(string);
 
487
        int                     lenpat = strlen(pattern);
 
488
        int                     lenstr = strlen(string);
492
489
 
493
490
        /* If we don't start with a wildcard, it's not a match (rule 1 & 2) */
494
491
        if (lenpat < 3 ||
500
497
                /* If pattern is longer than the string, we can never match */
501
498
                return 0;
502
499
 
503
 
        if (pg_strcasecmp(pattern+1, string+lenstr-lenpat+1) != 0)
504
 
                /* If string does not end in pattern (minus the wildcard), we don't match */
 
500
        if (pg_strcasecmp(pattern + 1, string + lenstr - lenpat + 1) != 0)
 
501
 
 
502
                /*
 
503
                 * If string does not end in pattern (minus the wildcard), we don't
 
504
                 * match
 
505
                 */
505
506
                return 0;
506
507
 
507
 
        if (strchr(string, '.') < string+lenstr-lenpat)
508
 
                /* If there is a dot left of where the pattern started to match, we don't match (rule 3) */
 
508
        if (strchr(string, '.') < string + lenstr - lenpat)
 
509
 
 
510
                /*
 
511
                 * If there is a dot left of where the pattern started to match, we
 
512
                 * don't match (rule 3)
 
513
                 */
509
514
                return 0;
510
515
 
511
516
        /* String ended with pattern, and didn't have a dot before, so we match */
520
525
verify_peer_name_matches_certificate(PGconn *conn)
521
526
{
522
527
        /*
523
 
         * If told not to verify the peer name, don't do it. Return
524
 
         * 0 indicating that the verification was successful.
 
528
         * If told not to verify the peer name, don't do it. Return 0 indicating
 
529
         * that the verification was successful.
525
530
         */
526
531
        if (strcmp(conn->sslmode, "verify-full") != 0)
527
532
                return true;
650
655
        BIO_free(bio);
651
656
 
652
657
        /*
653
 
         * Read the SSL key. If a key is specified, treat it as an engine:key combination
654
 
         * if there is colon present - we don't support files with colon in the name. The
655
 
         * exception is if the second character is a colon, in which case it can be a Windows
656
 
         * filename with drive specification.
 
658
         * Read the SSL key. If a key is specified, treat it as an engine:key
 
659
         * combination if there is colon present - we don't support files with
 
660
         * colon in the name. The exception is if the second character is a colon,
 
661
         * in which case it can be a Windows filename with drive specification.
657
662
         */
658
663
        if (conn->sslkey && strlen(conn->sslkey) > 0)
659
664
        {
660
 
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
 
665
#ifdef USE_SSL_ENGINE
661
666
                if (strchr(conn->sslkey, ':')
662
667
#ifdef WIN32
663
668
                        && conn->sslkey[1] != ':'
664
669
#endif
665
 
                   )
 
670
                        )
666
671
                {
667
672
                        /* Colon, but not in second character, treat as engine:key */
668
 
                        ENGINE     *engine_ptr;
669
673
                        char       *engine_str = strdup(conn->sslkey);
670
674
                        char       *engine_colon = strchr(engine_str, ':');
671
675
 
672
 
                        *engine_colon = '\0';   /* engine_str now has engine name */
673
 
                        engine_colon++;                 /* engine_colon now has key name */
674
 
 
675
 
                        engine_ptr = ENGINE_by_id(engine_str);
676
 
                        if (engine_ptr == NULL)
677
 
                        {
678
 
                                char       *err = SSLerrmessage();
679
 
 
680
 
                                printfPQExpBuffer(&conn->errorMessage,
681
 
                                                                  libpq_gettext("could not load SSL engine \"%s\": %s\n"),
682
 
                                                                  engine_str, err);
683
 
                                SSLerrfree(err);
684
 
                                free(engine_str);
685
 
                                ERR_pop_to_mark();
686
 
                                return 0;
687
 
                        }
688
 
 
689
 
                        *pkey = ENGINE_load_private_key(engine_ptr, engine_colon,
 
676
                        *engine_colon = '\0';           /* engine_str now has engine name */
 
677
                        engine_colon++;         /* engine_colon now has key name */
 
678
 
 
679
                        conn->engine = ENGINE_by_id(engine_str);
 
680
                        if (conn->engine == NULL)
 
681
                        {
 
682
                                char       *err = SSLerrmessage();
 
683
 
 
684
                                printfPQExpBuffer(&conn->errorMessage,
 
685
                                         libpq_gettext("could not load SSL engine \"%s\": %s\n"),
 
686
                                                                  engine_str, err);
 
687
                                SSLerrfree(err);
 
688
                                free(engine_str);
 
689
                                ERR_pop_to_mark();
 
690
                                return 0;
 
691
                        }
 
692
 
 
693
                        if (ENGINE_init(conn->engine) == 0)
 
694
                        {
 
695
                                char       *err = SSLerrmessage();
 
696
 
 
697
                                printfPQExpBuffer(&conn->errorMessage,
 
698
                                         libpq_gettext("could not initialize SSL engine \"%s\": %s\n"),
 
699
                                                                  engine_str, err);
 
700
                                SSLerrfree(err);
 
701
                                ENGINE_free(conn->engine);
 
702
                                conn->engine = NULL;
 
703
                                free(engine_str);
 
704
                                ERR_pop_to_mark();
 
705
                                return 0;
 
706
                        }
 
707
 
 
708
                        *pkey = ENGINE_load_private_key(conn->engine, engine_colon,
690
709
                                                                                        NULL, NULL);
691
710
                        if (*pkey == NULL)
692
711
                        {
696
715
                                                                  libpq_gettext("could not read private SSL key \"%s\" from engine \"%s\": %s\n"),
697
716
                                                                  engine_colon, engine_str, err);
698
717
                                SSLerrfree(err);
 
718
                                ENGINE_finish(conn->engine);
 
719
                                ENGINE_free(conn->engine);
 
720
                                conn->engine = NULL;
699
721
                                free(engine_str);
700
722
                                ERR_pop_to_mark();
701
723
                                return 0;
702
724
                        }
703
725
                        free(engine_str);
704
726
 
705
 
                        fnbuf[0] = '\0'; /* indicate we're not going to load from a file */
 
727
                        fnbuf[0] = '\0';        /* indicate we're not going to load from a
 
728
                                                                 * file */
706
729
                }
707
730
                else
708
 
#endif /* support for SSL engines */
 
731
#endif   /* support for SSL engines */
709
732
                {
710
733
                        /* PGSSLKEY is not an engine, treat it as a filename */
711
734
                        strncpy(fnbuf, conn->sslkey, sizeof(fnbuf));
733
756
                if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
734
757
                {
735
758
                        printfPQExpBuffer(&conn->errorMessage,
736
 
                        libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
 
759
                                                          libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
737
760
                                                          fnbuf);
738
761
                        ERR_pop_to_mark();
739
762
                        return 0;
869
892
                 */
870
893
                if (pq_lockarray == NULL)
871
894
                {
872
 
                        int i;
 
895
                        int                     i;
873
896
 
874
897
                        pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
875
898
                        if (!pq_lockarray)
896
919
                        CRYPTO_set_locking_callback(pq_lockingcallback);
897
920
                }
898
921
        }
899
 
#endif /* ENABLE_THREAD_SAFETY */
 
922
#endif   /* ENABLE_THREAD_SAFETY */
900
923
 
901
924
        if (!SSL_context)
902
925
        {
959
982
                CRYPTO_set_id_callback(NULL);
960
983
 
961
984
                /*
962
 
                 * We don't free the lock array. If we get another connection
963
 
                 * in this process, we will just re-use it with the existing
964
 
                 * mutexes.
 
985
                 * We don't free the lock array. If we get another connection in this
 
986
                 * process, we will just re-use it with the existing mutexes.
965
987
                 *
966
 
                 * This means we leak a little memory on repeated load/unload
967
 
                 * of the library.
 
988
                 * This means we leak a little memory on repeated load/unload of the
 
989
                 * library.
968
990
                 */
969
991
        }
970
992
 
991
1013
         * verification. If set to "verify-full" we will also do further
992
1014
         * verification after the connection has been completed.
993
1015
         *
994
 
         * If we are going to look for either root certificate or CRL in the home directory,
995
 
         * we need pqGetHomeDirectory() to succeed. In other cases, we don't need to
996
 
         * get the home directory explicitly.
 
1016
         * If we are going to look for either root certificate or CRL in the home
 
1017
         * directory, we need pqGetHomeDirectory() to succeed. In other cases, we
 
1018
         * don't need to get the home directory explicitly.
997
1019
         */
998
1020
        if (!conn->sslrootcert || !conn->sslcrl)
999
1021
        {
1000
1022
                if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
1001
1023
                {
1002
 
                        if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
 
1024
                        if (conn->sslmode[0] == 'v')            /* "verify-ca" or
 
1025
                                                                                                 * "verify-full" */
1003
1026
                        {
1004
1027
                                printfPQExpBuffer(&conn->errorMessage,
1005
1028
                                                                  libpq_gettext("could not get home directory to locate root certificate file"));
1044
1067
/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
1045
1068
#ifdef X509_V_FLAG_CRL_CHECK
1046
1069
                                X509_STORE_set_flags(cvstore,
1047
 
                                          X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
 
1070
                                                  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1048
1071
                        /* if not found, silently ignore;  we do not require CRL */
1049
1072
#else
1050
1073
                        {
1064
1087
        else
1065
1088
        {
1066
1089
                /* stat() failed; assume cert file doesn't exist */
1067
 
                if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
 
1090
                if (conn->sslmode[0] == 'v')    /* "verify-ca" or "verify-full" */
1068
1091
                {
1069
1092
                        printfPQExpBuffer(&conn->errorMessage,
1070
 
                                                          libpq_gettext("root certificate file \"%s\" does not exist\n"
 
1093
                                libpq_gettext("root certificate file \"%s\" does not exist\n"
1071
1094
                                                          "Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);
1072
1095
                        return -1;
1073
1096
                }
1153
1176
        }
1154
1177
 
1155
1178
        /*
1156
 
         * We already checked the server certificate in initialize_SSL()
1157
 
         * using SSL_CTX_set_verify() if root.crt exists.
 
1179
         * We already checked the server certificate in initialize_SSL() using
 
1180
         * SSL_CTX_set_verify() if root.crt exists.
1158
1181
         */
1159
1182
 
1160
1183
        /* pull out server distinguished and common names */
1212
1235
                X509_free(conn->peer);
1213
1236
                conn->peer = NULL;
1214
1237
        }
 
1238
 
 
1239
#ifdef USE_SSL_ENGINE
 
1240
        if (conn->engine)
 
1241
        {
 
1242
                ENGINE_finish(conn->engine);
 
1243
                ENGINE_free(conn->engine);
 
1244
                conn->engine = NULL;
 
1245
        }
 
1246
#endif
1215
1247
}
1216
1248
 
1217
1249
/*