[asterisk-addons-commits] tilghman: branch 1.2 r264 -
/branches/1.2/res_config_mysql.c
asterisk-addons-commits at lists.digium.com
asterisk-addons-commits at lists.digium.com
Sun Jul 23 01:53:38 MST 2006
Author: tilghman
Date: Sun Jul 23 03:53:37 2006
New Revision: 264
URL: http://svn.digium.com/view/asterisk-addons?rev=264&view=rev
Log:
Bug 7577 - SQL Injection attack possible
Modified:
branches/1.2/res_config_mysql.c
Modified: branches/1.2/res_config_mysql.c
URL: http://svn.digium.com/view/asterisk-addons/branches/1.2/res_config_mysql.c?rev=264&r1=263&r2=264&view=diff
==============================================================================
--- branches/1.2/res_config_mysql.c (original)
+++ branches/1.2/res_config_mysql.c Sun Jul 23 03:53:37 2006
@@ -49,6 +49,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <stdio.h>
#include <mysql.h>
#include <mysql_version.h>
#include <errmsg.h>
@@ -88,8 +89,9 @@
MYSQL_RES *result;
MYSQL_ROW row;
MYSQL_FIELD *fields;
- int numFields, i;
- char sql[256];
+ int numFields, i, valsz;
+ char sql[512];
+ char buf[511]; /* Keep this size uneven as it is 2n+1. */
char *stringp;
char *chunk;
char *op;
@@ -110,28 +112,35 @@
return NULL;
}
+ /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
+ ast_mutex_lock(&mysql_lock);
+ if (!mysql_reconnect(database)) {
+ ast_mutex_unlock(&mysql_lock);
+ return NULL;
+ }
+
/* Create the first part of the query using the first parameter/value pairs we just extracted
If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
if(!strchr(newparam, ' ')) op = " ="; else op = "";
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, newval);
+ if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
+ valsz = (sizeof(buf) - 1) / 2;
+ mysql_real_escape_string(&mysql, buf, newval, valsz);
+ snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, buf);
while((newparam = va_arg(ap, const char *))) {
newval = va_arg(ap, const char *);
if(!strchr(newparam, ' ')) op = " ="; else op = "";
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, newval);
+ if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
+ valsz = (sizeof(buf) - 1) / 2;
+ mysql_real_escape_string(&mysql, buf, newval, valsz);
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, buf);
}
va_end(ap);
ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql);
- /* We now have our complete statement; Lets connect to the server and execute it. */
- ast_mutex_lock(&mysql_lock);
- if(!mysql_reconnect(database)) {
- ast_mutex_unlock(&mysql_lock);
- return NULL;
- }
-
+ /* Execution. */
if(mysql_real_query(&mysql, sql, strlen(sql))) {
ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
@@ -177,8 +186,9 @@
MYSQL_RES *result;
MYSQL_ROW row;
MYSQL_FIELD *fields;
- int numFields, i;
- char sql[256];
+ int numFields, i, valsz;
+ char sql[512];
+ char buf[511]; /* Keep this size uneven as it is 2n+1. */
const char *initfield = NULL;
char *stringp;
char *chunk;
@@ -217,16 +227,29 @@
*op = '\0';
}
+ /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
+ ast_mutex_lock(&mysql_lock);
+ if (!mysql_reconnect(database)) {
+ ast_mutex_unlock(&mysql_lock);
+ return NULL;
+ }
+
/* Create the first part of the query using the first parameter/value pairs we just extracted
If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
if(!strchr(newparam, ' ')) op = " ="; else op = "";
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, newval);
+ if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
+ valsz = (sizeof(buf) - 1) / 2;
+ mysql_real_escape_string(&mysql, buf, newval, valsz);
+ snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, buf);
while((newparam = va_arg(ap, const char *))) {
newval = va_arg(ap, const char *);
if(!strchr(newparam, ' ')) op = " ="; else op = "";
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, newval);
+ if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
+ valsz = (sizeof(buf) - 1) / 2;
+ mysql_real_escape_string(&mysql, buf, newval, valsz);
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, op, buf);
}
if(initfield) {
@@ -237,13 +260,7 @@
ast_log(LOG_DEBUG, "MySQL RealTime: Retrieve SQL: %s\n", sql);
- /* We now have our complete statement; Lets connect to the server and execute it. */
- ast_mutex_lock(&mysql_lock);
- if(!mysql_reconnect(database)) {
- ast_mutex_unlock(&mysql_lock);
- return NULL;
- }
-
+ /* Execution. */
if(mysql_real_query(&mysql, sql, strlen(sql))) {
ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
@@ -291,7 +308,9 @@
static int update_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap)
{
my_ulonglong numrows;
- char sql[256];
+ char sql[512];
+ char buf[511]; /* Keep this size uneven as it is 2n+1. */
+ int valsz;
const char *newparam, *newval;
if(!table) {
@@ -308,26 +327,36 @@
return -1;
}
+ /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
+ ast_mutex_lock(&mysql_lock);
+ if (!mysql_reconnect(database)) {
+ ast_mutex_unlock(&mysql_lock);
+ return -1;
+ }
+
/* Create the first part of the query using the first parameter/value pairs we just extracted
If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
- snprintf(sql, sizeof(sql), "UPDATE %s SET %s = '%s'", table, newparam, newval);
+ if ((valsz = strlen (newval)) * 1 + 1 > sizeof(buf))
+ valsz = (sizeof(buf) - 1) / 2;
+ mysql_real_escape_string(&mysql, buf, newval, valsz);
+ snprintf(sql, sizeof(sql), "UPDATE %s SET %s = '%s'", table, newparam, buf);
while((newparam = va_arg(ap, const char *))) {
newval = va_arg(ap, const char *);
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s = '%s'", newparam, newval);
+ if ((valsz = strlen (newval)) * 2 + 1 > sizeof(buf))
+ valsz = (sizeof(buf) - 1) / 2;
+ mysql_real_escape_string(&mysql, buf, newval, valsz);
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s = '%s'", newparam, buf);
}
va_end(ap);
- snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield, lookup);
+ if ((valsz = strlen (lookup)) * 1 + 1 > sizeof(buf))
+ valsz = (sizeof(buf) - 1) / 2;
+ mysql_real_escape_string(&mysql, buf, lookup, valsz);
+ snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield, buf);
ast_log(LOG_DEBUG,"MySQL RealTime: Update SQL: %s\n", sql);
- /* We now have our complete statement; Lets connect to the server and execute it. */
- ast_mutex_lock(&mysql_lock);
- if(!mysql_reconnect(database)) {
- ast_mutex_unlock(&mysql_lock);
- return -1;
- }
-
+ /* Execution. */
if(mysql_real_query(&mysql, sql, strlen(sql))) {
ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
ast_log(LOG_DEBUG, "MySQL RealTime: Query: %s\n", sql);
@@ -358,13 +387,10 @@
MYSQL_RES *result;
MYSQL_ROW row;
my_ulonglong num_rows;
- struct ast_config *new;
- struct ast_variable *cur_v, *new_v;
- struct ast_category *cur_cat, *new_cat;
+ struct ast_variable *new_v;
+ struct ast_category *cur_cat;
char sql[250] = "";
char last[80] = "";
- int cat_started = 0;
- int var_started = 0;
int last_cat_metric = 0;
last[0] = '\0';
More information about the asterisk-addons-commits
mailing list