]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Be safe; use parameters. Detect bad ODBC drivers and refuse to load.
authorMichael Giagnocavo <mgg@giagnocavo.net>
Wed, 29 Jul 2009 08:32:20 +0000 (08:32 +0000)
committerMichael Giagnocavo <mgg@giagnocavo.net>
Wed, 29 Jul 2009 08:32:20 +0000 (08:32 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14409 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/languages/mod_managed/managed/examples/easyroute/App.config
src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.fs

index 2b5a86e71f913d7d2b113672216e3cd2a08d9f02..b2310e2f816efca7b37215b3a7225b9401080a53 100644 (file)
@@ -4,12 +4,8 @@
     <add key="connectionString" value="DSN=easyroute;User=root;Pwd=;" />\r
     <add key="defaultProfile" value="sofia/default"/>\r
     <add key="defaultGateway" value="192.168.1.1"/>\r
-    <!-- query can be changed, but fields must be in the same order, and the number parameter must be %number% -->\r
-    <add key="query" value="SELECT gateways.gateway_ip, gateways.group, gateways.limit, gateways.techprofile, numbers.acctcode, numbers.translated from gateways, numbers where numbers.number = %number% and numbers.gateway_id = gateways.gateway_id;" />\r
-    \r
-    <!-- MySQL and other DBs improperly consider \ to be an escape character. easyroute will remove all backslashes from queries to be safe. \r
-         if you can handle backlashes properly, set keepBackslashes to true. -->\r
-    <!-- <add key="keepBackslashes" value="false" -->\r
+    <!-- query can be changed, but fields must be in the same order, and the number parameter must be ? -->\r
+    <add key="query" value="SELECT gateways.gateway_ip, gateways.group, gateways.limit, gateways.techprofile, numbers.acctcode, numbers.translated from gateways, numbers where numbers.number = ? and numbers.gateway_id = gateways.gateway_id;" />\r
     \r
     <!-- To avoid other injections, the incoming number will remove characters matching this regex. Default [^0-9#\*] allows only digits, # and *.-->\r
     <add key="numberRegexFilter" value="[^0-9#\*]" />\r
index 1907d4b2453f43cc3dda9ffbb637c1944f6ebc13..3779190b17ba1eb0541122a686ac9157ffe04f30 100644 (file)
@@ -6,15 +6,25 @@ open FreeSWITCH
 type QueryResult = { dialstring: string; group: string; acctcode: string; limit: int; translated: string }\r
 \r
 module easyroute =\r
+    // Basic config\r
     let defaultStr def = function null | "" -> def | s -> s\r
     let getAppSetting (name:string) = match Configuration.ConfigurationManager.AppSettings.Get name with null -> "" | x -> x\r
     let connString      = getAppSetting "connectionString"\r
     let defaultProfile  = getAppSetting "defaultProfile"\r
     let defaultGateway  = getAppSetting "defaultGateway"\r
-    let query = getAppSetting "query"\r
+    let query           = getAppSetting "query"\r
     let configOk = [ connString; defaultProfile; defaultGateway; query; ] |> List.forall (String.IsNullOrEmpty >> not)\r
-    let keepBackslashes = defaultStr "false" (getAppSetting "keepBackslashes") = "true"\r
     let numberRegexFilter = defaultStr "[^0-9#]" (getAppSetting "numberRegexFilter")\r
+    \r
+    // Determine if ODBC driver quotes parameters properly - MySQL < 3.51.16 apparently does not\r
+    // We'll select the string "'" -- if quoting works, we'll get ' back. Otherwise, it'll fail, and we'll refuse to load\r
+    // Error 1064 seems to be the syntax error code MySQL returns. Otherwise, the exception will still stop it from loading, just less gracefully.\r
+    let odbcOk = use conn = new Odbc.OdbcConnection(connString)\r
+                 use comm = new Odbc.OdbcCommand("SELECT ?", conn)\r
+                 comm.Parameters.AddWithValue("@test", "'") |> ignore\r
+                 conn.Open()\r
+                 try string (comm.ExecuteScalar()) = "'" \r
+                 with :? Odbc.OdbcException as ex when ex.Errors.Count > 0 && ex.Errors.[0].NativeError = 1064 -> false\r
                 \r
     let formatDialstring number gateway profile separator = \r
         match separator with \r
@@ -39,11 +49,9 @@ module easyroute =
     let lookup (number: string) sep =\r
         try\r
             let number = if numberRegexFilter = "" then number else Text.RegularExpressions.Regex.Replace(number, numberRegexFilter, "", regexOpts)\r
-            let number = if keepBackslashes        then number else number.Replace("\\", "") \r
-            let query = query.Replace("%number%", sprintf "'%s'" (number.Replace("'", "''"))) // Don't use params cause some odbc drivers are awesome\r
-            Log.WriteLine(LogLevel.Debug, "EasyRoute query prepared: {0}", query)\r
             use conn = new Odbc.OdbcConnection(connString)\r
             use comm = new Odbc.OdbcCommand(query, conn)\r
+            comm.Parameters.AddWithValue("@number", number) |> ignore\r
             conn.Open()\r
             use reader = comm.ExecuteReader CommandBehavior.SingleRow\r
             match reader.Read() with\r
@@ -67,7 +75,8 @@ type EasyRoute() =
     interface ILoadNotificationPlugin with\r
         member x.Load() = \r
             if not configOk then Log.WriteLine(LogLevel.Alert, "EasyRoute configuration is missing values.")\r
-            configOk\r
+            if not odbcOk   then Log.WriteLine(LogLevel.Critical, "ODBC driver doesn't handle quoting properly; upgrade driver.")\r
+            configOk && odbcOk\r
         \r
     interface IApiPlugin with\r
         member x.ExecuteBackground ctx = \r