Miscellaneous fixes in the area of SCRAM authentication.
authorMuhammad Usama <m.usama@gmail.com>
Tue, 4 Sep 2018 16:01:26 +0000 (21:01 +0500)
committerMuhammad Usama <m.usama@gmail.com>
Tue, 4 Sep 2018 16:01:26 +0000 (21:01 +0500)
The commit takes care of resource leak warnings reported by coverity
in the authentication module of Pgpool-II, Apart from doing the individual
resource leak fixes I have made the authentication system to use the temporary
memory context which gets deleted after the authentication is done.

In addition to the memory related fixes the commit also contains the following.

-- TEXT prefix support for specifying plain text passwords in configuration
and pool_passwd file.
-- Documentation updates to use plain text passwords with TEXT prefix.
-- Fix for 0000427: pg_enc emits wrong warnings
-- Fix for 0000426: Pgpool-II contines to emit warning messages

12 files changed:
doc/src/sgml/client-auth.sgml
doc/src/sgml/connection-settings.sgml
doc/src/sgml/healthcheck.sgml
doc/src/sgml/online-recovery.sgml
doc/src/sgml/stream-check.sgml
doc/src/sgml/watchdog.sgml
src/auth/auth-scram.c
src/auth/pool_auth.c
src/auth/pool_hba.c
src/auth/pool_passwd.c
src/include/auth/pool_passwd.h
src/protocol/child.c

index cf9886452da697815f96ed869a73645d5ef0dc23..7c65181fb603c76ff0386c8f83e6896b9b9ad120 100644 (file)
 
       <sect3 id="md5-authentication-file-format">
        <title>Authentication file format</title>
-
+     <para>
+      To use the <literal>md5</literal> authentication
+      <xref linkend="guc-pool-passwd"> authentication file
+      must contain the user password in either plain text
+      <literal>md5</literal> or <literal>AES</literal> encrypted format.
+    </para>
        <para>
          The <xref linkend="guc-pool-passwd"> file should contain lines in the following format:
+         <programlisting>
+            "username:plain_text_passwd"
+         </programlisting>
          <programlisting>
             "username:encrypted_passwd"
          </programlisting>
index 7672579e44e7552fd388631da8c673916a81b8cb..7cd7898774293f1598f7382d32c6d83cab59bcc3 100644 (file)
        </term>
        <listitem>
          <para>
-           Specify the password file name for md5 authentication.
+           Specify the password file name for authentication.
            Default value is <literal>"pool_passwd"</literal>.
            Specifying <literal>''</literal> (empty) disables the use
-           of password file.  See <xref linkend="auth-md5"> for more
-           details.
+           of password file.
          </para>
+      <para>
+        Passwords can be stored in the pool_passwd file using three formats.
+        AES256 encrypted format, plain text format and md5 format.
+        <productname>Pgpool-II</productname> identifies the password format type
+        by it's prefix, so each password entry in the pool_passwd must be prefixed
+        as per the password format.
+      </para>
+      <para>
+        To store the password in the plain text format use <literal>TEXT</literal> prefix.
+        For example. to store clear text password string <literal>"mypassword"</literal>
+        in the pool_passwd, prepend the password string with <literal>TEXT</literal> prefix.
+        e.g. <literal>TEXTmypassword</literal>
+      </para>
+      <para>
+        similarly md5 hashed passwords must be prefixed with <literal>md5</literal> and
+        AES256 encrypted password types can be stored using <literal>AES</literal> prefix.
+        see <xref linkend="auth-aes-encrypted-password"> for more details on using
+        AES256 encrypted passwords.
+      </para>
+
+      <para>
+        In the absence of a valid prefix, <productname>Pgpool-II</productname> will
+        be considered the string as a plain text password
+      </para>
          <para>
            This parameter can only be set at server start.
          </para>
index 6db7b0bd95731e49bbb69315abddd11f54b8dbf1..24b660b79898ba089b41e013c85e397f0c0af229 100644 (file)
         <literal>AES</literal> after encrypting (using <literal>aes-256-cbc</literal> algorithm) and
         encoding to <literal>base64</literal>.
       </para>
+        <para>
+            To specify the unencrypted clear text password, prefix the password string with
+            <literal>TEXT</literal>. For example if you want to set <literal>mypass</literal> as
+            a password, you should specify <literal>TEXTmypass</literal> in the password field.
+            In the absence of a valid prefix, <productname>Pgpool-II</productname> will considered
+            the string as a plain text password.
+        </para>
       <para>
         You can also use <xref linkend="PG-ENC"> utility to create the correctly formatted
         <literal>AES</literal> encrypted password strings.
index 6329b7bcd1d521975ccf91172062c4b1a7f23c45..1d271c698da50bdf9fed3f56a35f292ab758558c 100644 (file)
             <literal>AES</literal> after encrypting (using <literal>aes-256-cbc</literal> algorithm) and
             encoding to <literal>base64</literal>.
         </para>
+        <para>
+            To specify the unencrypted clear text password, prefix the password string with
+            <literal>TEXT</literal>. For example if you want to set <literal>mypass</literal> as
+            a password, you should specify <literal>TEXTmypass</literal> in the password field.
+            In the absence of a valid prefix, <productname>Pgpool-II</productname> will considered
+            the string as a plain text password.
+        </para>
         <para>
             You can also use <xref linkend="PG-ENC"> utility to create the correctly formatted
             <literal>AES</literal> encrypted password strings.
index 1e16092e2767cf76406a65a7c97c973f96070435..79205e57e0cfb7fb07fb60157b853b69e7334ad4 100644 (file)
             <literal>AES</literal> after encrypting (using <literal>aes-256-cbc</literal> algorithm) and
             encoding to <literal>base64</literal>.
         </para>
+        <para>
+            To specify the unencrypted clear text password, prefix the password string with
+            <literal>TEXT</literal>. For example if you want to set <literal>mypass</literal> as
+            a password, you should specify <literal>TEXTmypass</literal> in the password field.
+            In the absence of a valid prefix, <productname>Pgpool-II</productname> will considered
+            the string as a plain text password.
+        </para>
         <para>
             You can also use <xref linkend="PG-ENC"> utility to create the correctly formatted
             <literal>AES</literal> encrypted password strings.
index 965fd2872b5e9ae1f4e7bedcc35d92bb063a5f40..ce838d405efe2ddac77ef4677dd5df0c291ee1c0 100644 (file)
         <literal>AES</literal> after encrypting (using <literal>aes-256-cbc</literal> algorithm) and
         encoding to <literal>base64</literal>.
     </para>
+    <para>
+        To specify the unencrypted clear text password, prefix the password string with
+        <literal>TEXT</literal>. For example if you want to set <literal>mypass</literal> as
+        a password, you should specify <literal>TEXTmypass</literal> in the password field.
+        In the absence of a valid prefix, <productname>Pgpool-II</productname> will considered
+        the string as a plain text password.
+    </para>
     <para>
         You can also use <xref linkend="PG-ENC"> utility to create the correctly formatted
         <literal>AES</literal> encrypted password strings.
index d857eab01f9aea39af9d7fa887f216c4d28241a3..953c341386d465b7232db3fa3db32cddfc6ec9b3 100644 (file)
@@ -484,7 +484,6 @@ scram_verify_plain_password(const char *username, const char *password,
        uint8           stored_key[SCRAM_KEY_LEN];
        uint8           server_key[SCRAM_KEY_LEN];
        uint8           computed_key[SCRAM_KEY_LEN];
-       char       *prep_password = NULL;
 
        if (!parse_scram_verifier(verifier, &iterations, &encoded_salt,
                                                          stored_key, server_key))
@@ -510,13 +509,11 @@ scram_verify_plain_password(const char *username, const char *password,
        scram_SaltedPassword(password, salt, saltlen, iterations, salted_password);
        scram_ServerKey(salted_password, computed_key);
 
-       if (prep_password)
-               pfree(prep_password);
-
        /*
         * Compare the verifier's Server Key with the one computed from the
         * user-supplied password.
         */
+       pfree(encoded_salt);
        return memcmp(computed_key, server_key, SCRAM_KEY_LEN) == 0;
 }
 
@@ -572,6 +569,8 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt,
         */
        decoded_salt_buf = palloc(pg_b64_dec_len(strlen(salt_str)));
        decoded_len = pg_b64_decode(salt_str, strlen(salt_str), decoded_salt_buf);
+       pfree(decoded_salt_buf);
+
        if (decoded_len < 0)
                goto invalid_verifier;
        *salt = pstrdup(salt_str);
@@ -1132,6 +1131,7 @@ build_server_final_message(scram_state *state)
        char       *server_signature_base64;
        int                     siglen;
        scram_HMAC_ctx ctx;
+       char *res;
 
        /* calculate ServerSignature */
        scram_HMAC_init(&ctx, state->ServerKey, SCRAM_KEY_LEN);
@@ -1164,7 +1164,9 @@ build_server_final_message(scram_state *state)
         *
         *------
         */
-       return psprintf("v=%s", server_signature_base64);
+       res = psprintf("v=%s", server_signature_base64);
+       pfree(server_signature_base64);
+       return res;
 }
 
 
index a786d91704b755e0092227e338f2812c2f20665f..598b03bfeb75708c8d7585a089d442cee12f12a5 100644 (file)
@@ -216,7 +216,6 @@ connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password)
                }
                ereport(DEBUG1,
                                (errmsg("SCRAM authentication successful for user:%s", cp->sp->user)));
-
        }
        else
        {
@@ -481,8 +480,8 @@ pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp)
        /* md5 authentication? */
        else if (authkind == AUTH_REQ_MD5)
        {
-               char       *password;
-               PasswordType passwordType;
+               char       *password = NULL;
+               PasswordType passwordType = PASSWORD_TYPE_UNKNOWN;
 
                /*
                 * check if we can use md5 authentication.
@@ -970,6 +969,10 @@ authenticate_frontend_clear_text(POOL_CONNECTION * frontend)
                                         errdetail("unable to decrypt password from pool_passwd"),
                                         errhint("verify the valid pool_key exists")));
        }
+       else if (frontend->passwordMapping->pgpoolUser.passwordType == PASSWORD_TYPE_TEXT_PREFIXED)
+       {
+               storedPassword = frontend->passwordMapping->pgpoolUser.password + strlen(PASSWORD_TEXT_PREFIX);
+       }
        else if (frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_PLAINTEXT)
        {
                ereport(ERROR,
@@ -1002,41 +1005,37 @@ do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, in
        static int      size;
        char       *pwd = NULL;
        int                     kind;
+       PasswordType passwordType = PASSWORD_TYPE_UNKNOWN;
 
        if (reauth && frontend->frontend_authenticated)
        {
                /* frontend and backend are both authenticated already */
                return 0;
        }
-
-       /* get the password */
-       if (frontend->pwd_size > 0)
+       if (get_auth_password(backend, frontend, reauth, &pwd, &passwordType) == false)
        {
-               pwd = frontend->password;
-               size = frontend->pwd_size;
+               ereport(FATAL,
+                               (return_code(2),
+                                errmsg("clear text password authentication failed"),
+                                errdetail("unable to get the password for user: \"%s\"", frontend->username)));
        }
-       else if (frontend->passwordMapping)
+
+       if (passwordType == PASSWORD_TYPE_AES)
        {
-               if (frontend->passwordMapping->pgpoolUser.passwordType == PASSWORD_TYPE_PLAINTEXT)
-               {
-                       pwd = frontend->passwordMapping->pgpoolUser.password;
-                       size = pwd ? strlen(pwd) : 0;
-               }
-               else if (frontend->passwordMapping->pgpoolUser.passwordType == PASSWORD_TYPE_AES)
-               {
-                       /*
-                        * decrypt the stored AES password for comparing it
-                        */
-                       pwd = get_decrypted_password(frontend->passwordMapping->pgpoolUser.password);
-                       if (pwd == NULL)
-                               ereport(ERROR,
-                                               (errmsg("clear text password authentication failed"),
-                                                errdetail("unable to decrypt password from pool_passwd"),
-                                                errhint("verify the valid pool_key exists")));
-                       size = strlen(pwd);
-               }
+               /*
+                * decrypt the stored AES password for comparing it
+                */
+               pwd = get_decrypted_password(pwd);
+               if (pwd == NULL)
+                       ereport(ERROR,
+                                       (errmsg("clear text password authentication failed"),
+                                        errdetail("unable to decrypt password from pool_passwd"),
+                                        errhint("verify the valid pool_key exists")));
+               /* we have converted the password to plain text */
+               passwordType = PASSWORD_TYPE_PLAINTEXT;
        }
-       if (pwd == NULL)
+
+       if (pwd == NULL || passwordType != PASSWORD_TYPE_PLAINTEXT)
        {
                /* If we still do not have a password. we can't proceed */
                ereport(ERROR,
@@ -1045,6 +1044,8 @@ do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, in
                return 0;
        }
 
+       size = pwd ? strlen(pwd) : 0;
+
        /* connection reusing? */
        if (reauth)
        {
@@ -1250,29 +1251,12 @@ authenticate_frontend_SCRAM(POOL_CONNECTION * backend, POOL_CONNECTION * fronten
        PasswordType storedPasswordType = PASSWORD_TYPE_UNKNOWN;
        char       *storedPassword = NULL;
 
-       if (!frontend->passwordMapping)
-               frontend->passwordMapping = pool_get_user_credentials(frontend->username);
-
-       if (!frontend->passwordMapping)
-       {
-               /* see if we have a password stored in the backend for this */
-               if (reauth && backend->pwd_size)
-               {
-                       storedPasswordType = backend->passwordType;
-                       storedPassword = backend->password;
-               }
-               else
-               {
-                       ereport(FATAL,
-                                       (return_code(2),
-                                        errmsg("SCRAM authentication failed"),
-                                        errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username)));
-               }
-       }
-       else
+       if (get_auth_password(backend, frontend, reauth,&storedPassword, &storedPasswordType) == false)
        {
-               storedPasswordType = frontend->passwordMapping->pgpoolUser.passwordType;
-               storedPassword = frontend->passwordMapping->pgpoolUser.password;
+               ereport(FATAL,
+                               (return_code(2),
+                                errmsg("SCRAM authentication failed"),
+                                errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username)));
        }
 
        if (storedPasswordType == PASSWORD_TYPE_AES)
@@ -1515,29 +1499,13 @@ authenticate_frontend_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend,
                        do_md5_single_backend(backend, frontend, reauth, protoMajor);
                return;                                 /* This will be handled later */
        }
-       if (!frontend->passwordMapping)
-               frontend->passwordMapping = pool_get_user_credentials(frontend->username);
 
-       if (!frontend->passwordMapping)
+       if (get_auth_password(backend, frontend, reauth,&storedPassword, &storedPasswordType) == false)
        {
-               /* see if we have a password stored in the backend for this */
-               if (reauth && backend->pwd_size)
-               {
-                       storedPasswordType = backend->passwordType;
-                       storedPassword = backend->password;
-               }
-               else
-               {
-                       ereport(FATAL,
-                                       (return_code(2),
-                                        errmsg("md5 authentication failed"),
-                                        errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username)));
-               }
-       }
-       else
-       {
-               storedPasswordType = frontend->passwordMapping->pgpoolUser.passwordType;
-               storedPassword = frontend->passwordMapping->pgpoolUser.password;
+               ereport(FATAL,
+                               (return_code(2),
+                                errmsg("md5 authentication failed"),
+                                errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username)));
        }
 
        pool_random_salt(salt);
@@ -1703,8 +1671,17 @@ get_auth_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int rea
        }
        else
        {
-               *password = frontend->passwordMapping->pgpoolUser.password;
-               *passwordType = frontend->passwordMapping->pgpoolUser.passwordType;
+               if (frontend->passwordMapping->pgpoolUser.passwordType == PASSWORD_TYPE_TEXT_PREFIXED)
+               {
+                       /* convert the TEXT prefixed password to plain text password */
+                       *passwordType = PASSWORD_TYPE_PLAINTEXT;
+                       *password = frontend->passwordMapping->pgpoolUser.password + strlen(PASSWORD_TEXT_PREFIX);
+               }
+               else
+               {
+                       *password = frontend->passwordMapping->pgpoolUser.password;
+                       *passwordType = frontend->passwordMapping->pgpoolUser.passwordType;
+               }
                return true;
        }
        return false;
@@ -2326,6 +2303,8 @@ do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor,
                        case AUTH_REQ_OK:
                                /* Save the auth info in backend */
                                backend->auth_kind = AUTH_REQ_SASL;
+                               if (sasl_state)
+                                       pg_fe_scram_free(sasl_state);
                                return true;
                                break;
                        case AUTH_REQ_SASL:
index 7a28ae0604ff40ec2799f24acd5f94b1a405198e..2d7bbac6dc93c3b81eb426383a4f8c161d2d075f 100644 (file)
@@ -480,6 +480,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel)
                                                                        str, gai_strerror(ret));
                                if (gai_result)
                                        freeaddrinfo_all(hints.ai_family, gai_result);
+                               pfree(str);
                                return NULL;
                        }
 
@@ -498,6 +499,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel)
                                                                                line_num, HbaFileName)));
                                        *err_msg = psprintf("specifying both host name and CIDR mask is invalid: \"%s\"",
                                                                                token->string);
+                                       pfree(str);
                                        return NULL;
                                }
 
@@ -512,6 +514,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel)
                                                                                line_num, HbaFileName)));
                                        *err_msg = psprintf("invalid CIDR mask in address \"%s\"",
                                                                                token->string);
+                                       pfree(str);
                                        return NULL;
                                }
                                pfree(str);
@@ -761,6 +764,7 @@ void
 ClientAuthentication(POOL_CONNECTION * frontend)
 {
        POOL_STATUS status = POOL_END;
+       MemoryContext oldContext;
 
        PG_TRY();
        {
@@ -774,8 +778,15 @@ ClientAuthentication(POOL_CONNECTION * frontend)
                /*
                 * Get the password for the user if it is stored in the pool_password
                 * file
+                * authentication process is called in the temporary memory
+                * context, but password mappings has to live till the life time
+                * of frontend connection, so call the pool_get_user_credentials in
+                * ProcessLoopContext memory context
                 */
+               oldContext = MemoryContextSwitchTo(ProcessLoopContext);
                frontend->passwordMapping = pool_get_user_credentials(frontend->username);
+               MemoryContextSwitchTo(oldContext);
+
                switch (frontend->pool_hba->auth_method)
                {
                        case uaImplicitReject:
@@ -791,32 +802,28 @@ ClientAuthentication(POOL_CONNECTION * frontend)
                                         * We're merely helping out the less clueful good guys.
                                         */
                                        char            hostinfo[NI_MAXHOST];
-                                       char       *errmessage;
-                                       int                     messagelen;
 
                                        getnameinfo_all(&frontend->raddr.addr, frontend->raddr.salen,
                                                                        hostinfo, sizeof(hostinfo),
                                                                        NULL, 0,
                                                                        NI_NUMERICHOST);
 
-                                       messagelen = sizeof(hostinfo) +
-                                               strlen(frontend->username) + strlen(frontend->database) + 80;
-                                       errmessage = (char *) palloc(messagelen + 1);
 #ifdef USE_SSL
-                                       snprintf(errmessage, messagelen + 7,    /* +7 is for "SSL off" */
-                                                        "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
-                                                        hostinfo, frontend->username, frontend->database,
-                                                        frontend->ssl ? "SSL on" : "SSL off");
+                                       ereport(FATAL,
+                                               (return_code(2),
+                                                        errmsg("client authentication failed"),
+                                                        errdetail("no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
+                                                                          hostinfo, frontend->username, frontend->database,
+                                                                          frontend->ssl ? "SSL on" : "SSL off"),
+                                                        errhint("see pgpool log for details")));
 #else
-                                       snprintf(errmessage, messagelen,
-                                                        "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
-                                                        hostinfo, frontend->username, frontend->database);
-#endif
                                        ereport(FATAL,
                                                        (return_code(2),
                                                         errmsg("client authentication failed"),
-                                                        errdetail("%s", errmessage),
+                                                        errdetail("no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
+                                                                          hostinfo, frontend->username, frontend->database),
                                                         errhint("see pgpool log for details")));
+#endif
                                        break;
                                }
 
@@ -847,6 +854,7 @@ ClientAuthentication(POOL_CONNECTION * frontend)
                                                         errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username)));
                                if (frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_PLAINTEXT &&
                                        frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_MD5 &&
+                                       frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_TEXT_PREFIXED &&
                                        frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_AES)
                                        ereport(FATAL,
                                                        (return_code(2),
@@ -861,6 +869,7 @@ ClientAuthentication(POOL_CONNECTION * frontend)
                                                         errmsg("SCRAM authentication failed"),
                                                         errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username)));
                                if (frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_PLAINTEXT &&
+                                       frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_TEXT_PREFIXED &&
                                        frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_SCRAM_SHA_256 &&
                                        frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_AES)
                                        ereport(FATAL,
index 68af68225c5ebdc45cb8479e9459d28a329a60e5..d9033290d640d352f38828c20aa0cdbbabf6bd77 100644 (file)
@@ -502,7 +502,15 @@ get_pgpool_config_user_password(char *username, char *password_in_config)
                }
        }
 
-       if (passwordType != PASSWORD_TYPE_PLAINTEXT)
+       if (passwordType == PASSWORD_TYPE_TEXT_PREFIXED)
+       {
+               /* convert the TEXT prefixed password to plain text password */
+               passwordType = PASSWORD_TYPE_PLAINTEXT;
+               if (password)
+                       password = (char*)(password + strlen(PASSWORD_TEXT_PREFIX));
+       }
+
+       if (password && strlen(password) && passwordType != PASSWORD_TYPE_PLAINTEXT)
        {
                ereport(WARNING,
                                (errmsg("could not get the password for user:%s", username),
@@ -577,6 +585,8 @@ get_password_type(const char *shadow_pass)
                return PASSWORD_TYPE_AES;
        if (strncmp(shadow_pass, PASSWORD_SCRAM_PREFIX, strlen(PASSWORD_SCRAM_PREFIX)) == 0)
                return PASSWORD_TYPE_SCRAM_SHA_256;
+       if (strncmp(shadow_pass, PASSWORD_TEXT_PREFIX, strlen(PASSWORD_TEXT_PREFIX)) == 0)
+               return PASSWORD_TYPE_TEXT_PREFIXED;
 
        return PASSWORD_TYPE_PLAINTEXT;
 }
@@ -605,16 +615,13 @@ read_pool_key(char *key_file_path)
        if (!S_ISREG(stat_buf.st_mode))
        {
                ereport(WARNING,
-                               (errmsg("pool key file \"%s\" is not a text file\n", key_file_path)));
+                               (errmsg("pool key file \"%s\" is not a plain file\n", key_file_path)));
                return NULL;
        }
 
        /* If password file is insecure, alert the user. */
        if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
        {
-               ereport(WARNING,
-                               (errmsg("pool key file \"%s\" is not a text file\n", key_file_path)));
-
                ereport(WARNING,
                                (errmsg("pool key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n",
                                                key_file_path)));
index 796b595861b991aed1aa8a44ab566e3b0744e1a9..c00cb960a1f066b51080eab888328ab730478e53 100644 (file)
@@ -54,7 +54,8 @@ typedef enum PasswordType
        PASSWORD_TYPE_PLAINTEXT,
        PASSWORD_TYPE_MD5,
        PASSWORD_TYPE_AES,
-       PASSWORD_TYPE_SCRAM_SHA_256
+       PASSWORD_TYPE_SCRAM_SHA_256,
+       PASSWORD_TYPE_TEXT_PREFIXED
 } PasswordType;
 
 typedef struct UserPassword
index ef0ffda0e8a98beb887e75f8569490dfb9dc20d4..13c6da92e32ea2d855cb7f57d177eeaf18dcfb95 100644 (file)
@@ -662,6 +662,8 @@ connect_using_existing_connection(POOL_CONNECTION * frontend,
        int                     i,
                                freed = 0;
        StartupPacket *topmem_sp = NULL;
+       MemoryContext oldContext;
+       MemoryContext frontend_auth_cxt;
 
        /*
         * Save startup packet info
@@ -672,7 +674,7 @@ connect_using_existing_connection(POOL_CONNECTION * frontend,
                {
                        if (!freed)
                        {
-                               MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
+                               oldContext = MemoryContextSwitchTo(TopMemoryContext);
 
                                topmem_sp = StartupPacketCopy(sp);
                                MemoryContextSwitchTo(oldContext);
@@ -687,9 +689,16 @@ connect_using_existing_connection(POOL_CONNECTION * frontend,
        }
 
        /* Reuse existing connection to backend */
+       frontend_auth_cxt = AllocSetContextCreate(CurrentMemoryContext,
+                                                                                                                       "frontend_auth",
+                                                                                                                       ALLOCSET_DEFAULT_SIZES);
+       oldContext = MemoryContextSwitchTo(frontend_auth_cxt);
 
        pool_do_reauth(frontend, backend);
 
+       MemoryContextSwitchTo(oldContext);
+       MemoryContextDelete(frontend_auth_cxt);
+
        if (MAJOR(backend) == 3)
        {
                char            command_buf[1024];
@@ -896,6 +905,7 @@ static POOL_CONNECTION_POOL * connect_backend(StartupPacket *sp, POOL_CONNECTION
 
        PG_TRY();
        {
+               MemoryContext frontend_auth_cxt;
                MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext);
 
                topmem_sp = StartupPacketCopy(sp);
@@ -927,7 +937,16 @@ static POOL_CONNECTION_POOL * connect_backend(StartupPacket *sp, POOL_CONNECTION
                /*
                 * do authentication stuff
                 */
+               frontend_auth_cxt = AllocSetContextCreate(CurrentMemoryContext,
+                                                                                                                               "frontend_auth",
+                                                                                                                               ALLOCSET_DEFAULT_SIZES);
+               oldContext = MemoryContextSwitchTo(frontend_auth_cxt);
+
                pool_do_auth(frontend, backend);
+
+               MemoryContextSwitchTo(oldContext);
+               MemoryContextDelete(frontend_auth_cxt);
+
        }
        PG_CATCH();
        {
@@ -2158,8 +2177,15 @@ retry_startup:
                 * do client authentication. Note that ClientAuthentication does not
                 * return if frontend was rejected; it simply terminates this process.
                 */
+               MemoryContext frontend_auth_cxt = AllocSetContextCreate(CurrentMemoryContext,
+                                                                               "frontend_auth",
+                                                                               ALLOCSET_DEFAULT_SIZES);
+               MemoryContext oldContext = MemoryContextSwitchTo(frontend_auth_cxt);
 
                ClientAuthentication(frontend);
+
+               MemoryContextSwitchTo(oldContext);
+               MemoryContextDelete(frontend_auth_cxt);
        }
 
        /*