You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gentoo-overlay/www-apache/mod_auth_pgsql/files/mod_auth_pgsql-2.0.3-encodi...

284 lines
9.2 KiB

From: Marco Nenciarini <mnencia@debian.org>
Date: Sat, 10 Aug 2013 16:26:41 +0200
Subject: encoding
---
mod_auth_pgsql.c | 144 +++++++++++++++++++++++++++++++---------------------
mod_auth_pgsql.html | 9 ++++
2 files changed, 94 insertions(+), 59 deletions(-)
diff --git a/mod_auth_pgsql.c b/mod_auth_pgsql.c
index f13c166..639537d 100644
--- a/mod_auth_pgsql.c
+++ b/mod_auth_pgsql.c
@@ -151,6 +151,7 @@ typedef struct {
const char *auth_pg_port;
const char *auth_pg_options;
const char *auth_pg_user;
+ const char *auth_pg_charset;
const char *auth_pg_pwd;
const char *auth_pg_pwd_table;
const char *auth_pg_uname_field;
@@ -181,6 +182,8 @@ typedef struct {
} pg_auth_config_rec;
+static PGconn *pg_conn;
+
static apr_pool_t *auth_pgsql_pool = NULL;
static apr_pool_t *auth_pgsql_pool_base64 = NULL;
@@ -220,6 +223,7 @@ static void *create_pg_auth_dir_config(apr_pool_t * p, char *d)
new_rec->auth_pg_port = NULL;
new_rec->auth_pg_options = NULL;
new_rec->auth_pg_user = NULL;
+ new_rec->auth_pg_charset = NULL;
new_rec->auth_pg_pwd = NULL;
new_rec->auth_pg_pwd_table = NULL;
new_rec->auth_pg_uname_field = NULL;
@@ -324,6 +328,10 @@ static const command_rec pg_auth_cmds[] = {
(void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_user),
OR_AUTHCFG,
"user name connect as"),
+ AP_INIT_TAKE1("Auth_PG_charset", ap_set_string_slot,
+ (void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_charset),
+ OR_AUTHCFG,
+ "charset to use for connection"),
AP_INIT_TAKE1("Auth_PG_pwd", ap_set_string_slot,
(void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_pwd),
OR_AUTHCFG,
@@ -462,53 +470,51 @@ static char *auth_pg_base64(char *pw)
}
+PGconn *pg_connect(pg_auth_config_rec *sec)
+{
+ PGconn *conn;
-/* Got from POstgreSQL 7.2 */
-/* ---------------
- * Escaping arbitrary strings to get valid SQL strings/identifiers.
- *
- * Replaces "\\" with "\\\\" and "'" with "''".
- * length is the length of the buffer pointed to by
- * from. The buffer at to must be at least 2*length + 1 characters
- * long. A terminating NUL character is written.
- * ---------------
- */
+ conn = PQsetdbLogin(sec->auth_pg_host, sec->auth_pg_port,
+ sec->auth_pg_options, NULL, sec->auth_pg_database,
+ sec->auth_pg_user, sec->auth_pg_pwd);
+ if (PQstatus(conn) != CONNECTION_OK) {
+ PQreset(conn);
+ apr_snprintf(pg_errstr, MAX_STRING_LEN,
+ "mod_auth_pgsql database connection error resetting %s",
+ PQerrorMessage(conn));
+ if (PQstatus(conn) != CONNECTION_OK) {
+ apr_snprintf(pg_errstr, MAX_STRING_LEN,
+ "mod_auth_pgsql database connection error reset failed %s",
+ PQerrorMessage(conn));
+ PQfinish(conn);
+ return NULL;
+ }
+ }
+ return conn;
+}
-static size_t pg_check_string(char *to, const char *from, size_t length)
-{
- const char *source = from;
- char *target = to;
- unsigned int remaining = length;
-
- while (remaining > 0) {
- switch (*source) {
- case '\\':
- *target = '\\';
- target++;
- *target = '\\';
- /* target and remaining are updated below. */
- break;
- case '\'':
- *target = '\'';
- target++;
- *target = '\'';
- /* target and remaining are updated below. */
- break;
+static size_t pg_check_string(char *to, const char *from, size_t length, request_rec * r, pg_auth_config_rec *sec)
+{
+ int error;
- default:
- *target = *source;
- /* target and remaining are updated below. */
+ if (!pg_conn) {
+ if (!(pg_conn = pg_connect(sec))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot connect to database");
+ ap_note_basic_auth_failure(r);
+ return -1;
}
- source++;
- target++;
- remaining--;
}
- /* Write the terminating NUL character. */
- *target = '\0';
+ PQescapeStringConn(pg_conn, to, from, length, &error);
+
+ if (error) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot escape string");
+ ap_note_basic_auth_failure(r);
+ return -1;
+ }
- return target - to;
+ return 0;
}
@@ -518,7 +524,6 @@ static size_t pg_check_string(char *to, const char *from, size_t length)
char *do_pg_query(request_rec * r, char *query, pg_auth_config_rec * sec)
{
PGresult *pg_result;
- PGconn *pg_conn;
char *val;
char *result = NULL;
@@ -530,19 +535,10 @@ char *do_pg_query(request_rec * r, char *query, pg_auth_config_rec * sec)
sec->auth_pg_database);
#endif /* DEBUG_AUTH_PGSQL */
- pg_conn = PQsetdbLogin(sec->auth_pg_host, sec->auth_pg_port,
- sec->auth_pg_options, NULL, sec->auth_pg_database,
- sec->auth_pg_user, sec->auth_pg_pwd);
- if (PQstatus(pg_conn) != CONNECTION_OK) {
- PQreset(pg_conn);
- apr_snprintf(pg_errstr, MAX_STRING_LEN,
- "mod_auth_pgsql database connection error resetting %s",
- PQerrorMessage(pg_conn));
- if (PQstatus(pg_conn) != CONNECTION_OK) {
- apr_snprintf(pg_errstr, MAX_STRING_LEN,
- "mod_auth_pgsql database connection error reset failed %s",
- PQerrorMessage(pg_conn));
- PQfinish(pg_conn);
+ if (!pg_conn) {
+ if (!(pg_conn = pg_connect(sec))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot connect to database");
+ ap_note_basic_auth_failure(r);
return NULL;
}
}
@@ -552,6 +548,21 @@ char *do_pg_query(request_rec * r, char *query, pg_auth_config_rec * sec)
query);
#endif /* DEBUG_AUTH_PGSQL */
+ if (sec->auth_pg_charset) {
+ const char *check;
+
+ PQsetClientEncoding(pg_conn, sec->auth_pg_charset);
+
+ check = pg_encoding_to_char(PQclientEncoding(pg_conn));
+
+ if (!check || strcmp(sec->auth_pg_charset, check)) {
+ apr_snprintf(pg_errstr, MAX_STRING_LEN,
+ "mod_auth_pgsql database character set encoding %s");
+ PQfinish(pg_conn);
+ return NULL;
+ }
+ }
+
pg_result = PQexec(pg_conn, query);
if (pg_result == NULL) {
@@ -610,7 +621,7 @@ char *get_pg_pw(request_rec * r, char *user, pg_auth_config_rec * sec)
int n;
safe_user = apr_palloc(r->pool, 1 + 2 * strlen(user));
- pg_check_string(safe_user, user, strlen(user));
+ pg_check_string(safe_user, user, strlen(user), r, sec);
#ifdef DEBUG_AUTH_PGSQL
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
@@ -685,8 +696,8 @@ static char *get_pg_grp(request_rec * r, char *group, char *user,
#endif /* DEBUG_AUTH_PGSQL */
query[0] = '\0';
- pg_check_string(safe_user, user, strlen(user));
- pg_check_string(safe_group, group, strlen(group));
+ pg_check_string(safe_user, user, strlen(user), r, sec);
+ pg_check_string(safe_group, group, strlen(group), r, sec);
if ((!sec->auth_pg_grp_table) ||
(!sec->auth_pg_grp_group_field) || (!sec->auth_pg_grp_user_field))
@@ -777,6 +788,14 @@ static int pg_authenticate_basic_user(request_rec * r)
}
pg_errstr[0] = '\0';
+ if (!pg_conn) {
+ if (!(pg_conn = pg_connect(sec))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot connect to database");
+ ap_note_basic_auth_failure(r);
+ return HTTP_UNAUTHORIZED;
+ }
+ }
+
if (sec->auth_pg_cache_passwords
&& (!apr_is_empty_table(sec->cache_pass_table))) {
val = (char *) apr_table_get(sec->cache_pass_table, user);
@@ -904,6 +923,13 @@ static int pg_check_auth(request_rec * r)
#endif /* DEBUG_AUTH_PGSQL */
+ if (!pg_conn) {
+ if (!(pg_conn = pg_connect(sec))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot connect to database");
+ ap_note_basic_auth_failure(r);
+ return HTTP_UNAUTHORIZED;
+ }
+ }
/* if we cannot do it; leave it to some other guy
*/
@@ -1015,9 +1041,9 @@ pg_log_auth_user(request_rec * r, pg_auth_config_rec * sec, char *user,
}
/* AUD: MAX_STRING_LEN probably isn't always correct */
- pg_check_string(safe_user, user, strlen(user));
- pg_check_string(safe_pw, sent_pw, strlen(sent_pw));
- pg_check_string(safe_req, r->the_request, strlen(r->the_request));
+ pg_check_string(safe_user, user, strlen(user), r, sec);
+ pg_check_string(safe_pw, sent_pw, strlen(sent_pw), r, sec);
+ pg_check_string(safe_req, r->the_request, strlen(r->the_request), r, sec);
if (sec->auth_pg_lowercaseuid) {
diff --git a/mod_auth_pgsql.html b/mod_auth_pgsql.html
index d35768b..5474314 100644
--- a/mod_auth_pgsql.html
+++ b/mod_auth_pgsql.html
@@ -48,6 +48,7 @@ Notes</a> |<a href="#Changelog"> Changelog</a> </p>
<li><a href="#host">Auth_PG_host</a> </li>
<li><a href="#port">Auth_PG_port</a> </li>
<li><a href="#options">Auth_PG_options</a> </li>
+ <li><a href="#charset">Auth_PG_charset</a> </li>
<li><a href="#database">Auth_PG_database</a> </li>
<li><a href="#user">Auth_PG_user</a> </li>
<li><a href="#pwd">Auth_PG_pwd</a> </li>
@@ -104,6 +105,14 @@ be found. </p>
<p>Specifies an option string to be passed to the postgreSQL backend
process. Refer to the PostgreSQL user manual for a description of the
available options. </p>
+<h2><a name="charset"></a> Auth_PG_charset</h2>
+<b>Syntax:</b> Auth_PG_options <i>option string</i><br>
+<b>Context:</b> directory, .htaccess <br>
+<b>Override:</b> AuthConfig <br>
+<b>Status:</b> Extension
+<p>Specifies the name of an encoding to be set for the PostgreSQL
+backend process. Refer to the PostgreSQL user manual for a description
+of the available options. </p>
<h2><a name="database"></a> Auth_PG_database</h2>
<b>Syntax:</b> Auth_PG_database <i>database name</i><br>
<b>Context:</b> directory, .htaccess <br>