Hi list,

according to bug #258 we don't use the string character escaping functions from mysql client library to ensure the safety of the SQL statements.

Attached is a patch for gw/dlr_mysql.c:dlr_mysql_add() which uses a static mysql_escaipe() that does this. Please review and vote for commitment. This should be also extended to the other SQL statements, right?

Actually this is a bit "glitchy", since we have to consume the DBPoolConn* _before_ passing the strings to the mysql_real_escape_string() routine. It expects a mysql connection in order to ensure that it gets the right character set encoding.

Anyone having a better "way" in doing this? I don't feel it's the "smoothes" code for it, but it safes at least a sub-sequential consumption of DBPoolConn's while doing the string escaping.

Any improvments welcome.

Stipe

mailto:stolj_{at}_wapme-group.de
-------------------------------------------------------------------
Wapme Systems AG

Vogelsanger Weg 80
40470 Düsseldorf, NRW, Germany

phone: +49.211.74845.0
fax: +49.211.74845.299

mailto:info_{at}_wapme-systems.de
http://www.wapme-systems.de/
-------------------------------------------------------------------
Index: gw/dlr_mysql.c
===================================================================
RCS file: /home/cvs/gateway/gw/dlr_mysql.c,v
retrieving revision 1.10
diff -u -r1.10 dlr_mysql.c
--- gw/dlr_mysql.c      21 Sep 2005 02:01:22 -0000      1.10
+++ gw/dlr_mysql.c      26 Sep 2005 17:04:14 -0000
@@ -58,12 +58,12 @@
  * dlr_mysql.c
  *
  * Implementation of handling delivery reports (DLRs)
- * for MySql database
+ * for MySQL database
  *
  * Andreas Fink <[EMAIL PROTECTED]>, 18.08.2001
  * Stipe Tolj <[EMAIL PROTECTED]>, 22.03.2002
  * Alexander Malysh <[EMAIL PROTECTED]> 2003
-*/
+ */
 
 #include "gwlib/gwlib.h"
 #include "gwlib/dbpool.h"
@@ -84,19 +84,20 @@
 static struct dlr_db_fields *fields = NULL;
 
 
-static void mysql_update(const Octstr *sql)
+static void mysql_update(DBPoolConn *pc, const Octstr *sql)
 {
     int        state;
-    DBPoolConn *pc;
 
 #if defined(DLR_TRACE)
-     debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
+    debug("dlr.mysql", 0, "SQL: %s", octstr_get_cstr(sql));
 #endif
 
-    pc = dbpool_conn_consume(pool);
+    /* if none connection has been passed get one */
     if (pc == NULL) {
-        error(0, "MYSQL: Database pool got no connection! DB update failed!");
-        return;
+        if ((pc = dbpool_conn_consume(pool)) == NULL) {
+            error(0, "MYSQL: Database pool got no connection! DB update 
failed!");
+            return;
+        }
     }
 
     state = mysql_query(pc->conn, octstr_get_cstr(sql));
@@ -106,19 +107,20 @@
     dbpool_conn_produce(pc);
 }
 
-static MYSQL_RES* mysql_select(const Octstr *sql)
+
+static MYSQL_RES *mysql_select(const Octstr *sql)
 {
     int        state;
     MYSQL_RES *result = NULL;
     DBPoolConn *pc;
 
 #if defined(DLR_TRACE)
-    debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
+    debug("dlr.mysql", 0, "SQL: %s", octstr_get_cstr(sql));
 #endif
 
     pc = dbpool_conn_consume(pool);
     if (pc == NULL) {
-        error(0, "MYSQL: Database pool got no connection! DB update failed!");
+        error(0, "MYSQL: Database pool got no connection! DB select failed!");
         return NULL;
     }
 
@@ -134,16 +136,58 @@
     return result;
 }
 
+
+static Octstr *mysql_escape(DBPoolConn *pc, const Octstr *os)
+{
+    Octstr *sql_safe_os;
+    char *sql_safe;
+    
+    /* The worst case is that every char is escaped to two bytes, 
+     * plus the trailing \0 character. */
+    sql_safe = gw_malloc(octstr_len(os) * 2 + 1);
+    gw_assert(sql_safe != NULL);
+    
+    mysql_real_escape_string(pc->conn, sql_safe, octstr_get_cstr(os), 
octstr_len(os));
+    
+    sql_safe_os = sql_safe ? octstr_create(sql_safe) : NULL;
+    gw_free(sql_safe);
+    
+    return sql_safe_os;
+}
+
+
 static void dlr_mysql_shutdown()
 {
     dbpool_destroy(pool);
     dlr_db_fields_destroy(fields);
 }
 
+
 static void dlr_mysql_add(struct dlr_entry *entry)
 {
     Octstr *sql;
+    Octstr *smsc, *timestamp, *source, *destination, *service, *url, *boxc_id;
+    DBPoolConn *pc;
+    
+    /* We need to aquire a mysql connction prior due to the call to
+     * mysql_real_escape_string(), which requires the connection in order 
+     * to determine used character set. */
+    if ((pc = dbpool_conn_consume(pool)) == NULL) {
+        error(0, "MYSQL: Database pool got no connection! DB update failed!");
+        goto error;
+    }
+    
+    /* For the sake of safety: make sure we escape all strings 
+     * that come arround from outside */
+    smsc = mysql_escape(pc, entry->smsc);
+    timestamp = mysql_escape(pc, entry->timestamp);
+    source = mysql_escape(pc, entry->source);
+    destination = mysql_escape(pc, entry->destination);
+    service = mysql_escape(pc, entry->service);
+    url = mysql_escape(pc, entry->url);
+    boxc_id = mysql_escape(pc, entry->boxc_id);        
 
+    /* prepare insert statement */    
     sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s) 
VALUES "
                         "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', 
'%d');",
                         octstr_get_cstr(fields->table), 
octstr_get_cstr(fields->field_smsc),
@@ -152,35 +196,45 @@
                         octstr_get_cstr(fields->field_serv), 
octstr_get_cstr(fields->field_url),
                         octstr_get_cstr(fields->field_mask), 
octstr_get_cstr(fields->field_boxc),
                         octstr_get_cstr(fields->field_status),
-                        octstr_get_cstr(entry->smsc), 
octstr_get_cstr(entry->timestamp), 
octstr_get_cstr(entry->source),
-                        octstr_get_cstr(entry->destination), 
octstr_get_cstr(entry->service), 
octstr_get_cstr(entry->url),
-                        entry->mask, octstr_get_cstr(entry->boxc_id), 0);
+                        octstr_get_cstr(smsc), octstr_get_cstr(timestamp), 
octstr_get_cstr(source),
+                        octstr_get_cstr(destination), 
octstr_get_cstr(service), octstr_get_cstr(url),
+                        entry->mask, octstr_get_cstr(boxc_id), 0);
+
+    octstr_destroy(smsc);
+    octstr_destroy(timestamp);
+    octstr_destroy(source);
+    octstr_destroy(destination);
+    octstr_destroy(service);
+    octstr_destroy(url);
+    octstr_destroy(boxc_id);
 
+    mysql_update(pc, sql);
 
-    mysql_update(sql);
-
+error:
     octstr_destroy(sql);
     dlr_entry_destroy(entry);
 }
 
-static struct dlr_entry* dlr_mysql_get(const Octstr *smsc, const Octstr *ts, 
const Octstr *dst)
+
+static struct dlr_entry *dlr_mysql_get(const Octstr *smsc, const Octstr *ts, 
const Octstr *dst)
 {
     struct dlr_entry *res = NULL;
     Octstr *sql;
-    MYSQL_RES *result;
+    MYSQL_RES *result = NULL;
     MYSQL_ROW row;
-
+    
     sql = octstr_format("SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE %s='%s' 
AND %s='%s';",
                         octstr_get_cstr(fields->field_mask), 
octstr_get_cstr(fields->field_serv),
                         octstr_get_cstr(fields->field_url), 
octstr_get_cstr(fields->field_src),
                         octstr_get_cstr(fields->field_dst), 
octstr_get_cstr(fields->field_boxc),
                         octstr_get_cstr(fields->table), 
octstr_get_cstr(fields->field_smsc),
-                        octstr_get_cstr(smsc), 
octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
-
+                        octstr_get_cstr(smsc), 
octstr_get_cstr(fields->field_ts), 
+                        octstr_get_cstr(ts));
 
     result = mysql_select(sql);
     octstr_destroy(sql);
 
+error:
     if (result == NULL) {
         return NULL;
     }
@@ -214,6 +268,7 @@
     return res;
 }
 
+
 static void dlr_mysql_remove(const Octstr *smsc, const Octstr *ts, const 
Octstr *dst)
 {
     Octstr *sql;
@@ -224,11 +279,12 @@
                         octstr_get_cstr(smsc), 
octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
 
 
-    mysql_update(sql);
+    mysql_update(NULL, sql);
 
     octstr_destroy(sql);
 }
 
+
 static void dlr_mysql_update(const Octstr *smsc, const Octstr *ts, const 
Octstr *dst, int status)
 {
     Octstr *sql;
@@ -240,7 +296,7 @@
                         octstr_get_cstr(fields->field_smsc), 
octstr_get_cstr(smsc),
                         octstr_get_cstr(fields->field_ts), 
octstr_get_cstr(ts));
 
-    mysql_update(sql);
+    mysql_update(NULL, sql);
 
     octstr_destroy(sql);
 }
@@ -278,16 +334,18 @@
     return res;
 }
 
+
 static void dlr_mysql_flush(void)
 {
     Octstr *sql;
 
     sql = octstr_format("DELETE FROM %s;", octstr_get_cstr(fields->table));
 
-    mysql_update(sql);
+    mysql_update(NULL, sql);
     octstr_destroy(sql);
 }
 
+
 static struct dlr_storage handles = {
     .type = "mysql",
     .dlr_add = dlr_mysql_add,
@@ -299,6 +357,7 @@
     .dlr_flush = dlr_mysql_flush
 };
 
+
 struct dlr_storage *dlr_init_mysql(Cfg *cfg)
 {
     CfgGroup *grp;

Reply via email to