From a384b4865adac65d41bc79464c611c41d42175b0 Mon Sep 17 00:00:00 2001 From: Michael Giagnocavo Date: Wed, 29 Jul 2009 04:39:14 +0000 Subject: [PATCH] Add some default security git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14407 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../managed/examples/easyroute/App.config | 13 ++++++++++--- .../managed/examples/easyroute/EasyRoute.suo | Bin 9728 -> 10752 bytes .../managed/examples/easyroute/easyroute.dll | Bin 19968 -> 20480 bytes .../examples/easyroute/easyroute.dll.config | 13 ++++++++++--- .../managed/examples/easyroute/easyroute.fs | 17 ++++++++++------- .../managed/examples/easyroute/easyroute.pdb | Bin 22016 -> 22016 bytes 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/mod/languages/mod_managed/managed/examples/easyroute/App.config b/src/mod/languages/mod_managed/managed/examples/easyroute/App.config index 214f616f9e..2b5a86e71f 100644 --- a/src/mod/languages/mod_managed/managed/examples/easyroute/App.config +++ b/src/mod/languages/mod_managed/managed/examples/easyroute/App.config @@ -1,10 +1,17 @@  - + - - + + + + + + + + \ No newline at end of file diff --git a/src/mod/languages/mod_managed/managed/examples/easyroute/EasyRoute.suo b/src/mod/languages/mod_managed/managed/examples/easyroute/EasyRoute.suo index 354e68d20154e37c13f57bad4f5f347db8854ed7..f9b5b5c2dfda936d6cf8774bc106e02e108164b3 100644 GIT binary patch delta 1701 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 QLu_lE_OJUbPc=IK4ROYn_5c6? diff --git a/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.dll.config b/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.dll.config index 214f616f9e..2b5a86e71f 100644 --- a/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.dll.config +++ b/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.dll.config @@ -1,10 +1,17 @@  - + - - + + + + + + + + \ No newline at end of file diff --git a/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.fs b/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.fs index d3806b4711..1907d4b245 100644 --- a/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.fs +++ b/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.fs @@ -6,14 +6,15 @@ open FreeSWITCH type QueryResult = { dialstring: string; group: string; acctcode: string; limit: int; translated: string } module easyroute = + let defaultStr def = function null | "" -> def | s -> s let getAppSetting (name:string) = match Configuration.ConfigurationManager.AppSettings.Get name with null -> "" | x -> x let connString = getAppSetting "connectionString" let defaultProfile = getAppSetting "defaultProfile" let defaultGateway = getAppSetting "defaultGateway" - let query = match getAppSetting "customQuery" with - | "" -> "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;" - | x -> x + let query = getAppSetting "query" let configOk = [ connString; defaultProfile; defaultGateway; query; ] |> List.forall (String.IsNullOrEmpty >> not) + let keepBackslashes = defaultStr "false" (getAppSetting "keepBackslashes") = "true" + let numberRegexFilter = defaultStr "[^0-9#]" (getAppSetting "numberRegexFilter") let formatDialstring number gateway profile separator = match separator with @@ -25,19 +26,21 @@ module easyroute = limit = 9999; group = ""; acctcode = ""; translated = number; } let readResult (r: IDataReader) number sep = - let defString def = function null | "" -> def | s -> s - let gw = defString defaultGateway <| r.GetString(0) + let gw = defaultStr defaultGateway <| r.GetString(0) let group = r.GetString(1) let limit = match r.GetInt32(2) with 0 -> 9999 | x -> x - let profile = defString defaultProfile <| r.GetString(3) + let profile = defaultStr defaultProfile <| r.GetString(3) let acctcode = r.GetString(4) let translated = r.GetString(5) let dialstring = formatDialstring number gw profile sep { dialstring = dialstring; limit = limit; group = group; acctcode = acctcode; translated = translated; } + let regexOpts = Text.RegularExpressions.RegexOptions.Compiled ||| Text.RegularExpressions.RegexOptions.CultureInvariant let lookup (number: string) sep = try - let query = query.Replace("%number%", sprintf "'%s'" (number.Replace(@"\'", "'").Replace("'", "''"))) // Don't use params cause some odbc drivers are awesome + let number = if numberRegexFilter = "" then number else Text.RegularExpressions.Regex.Replace(number, numberRegexFilter, "", regexOpts) + let number = if keepBackslashes then number else number.Replace("\\", "") + let query = query.Replace("%number%", sprintf "'%s'" (number.Replace("'", "''"))) // Don't use params cause some odbc drivers are awesome Log.WriteLine(LogLevel.Debug, "EasyRoute query prepared: {0}", query) use conn = new Odbc.OdbcConnection(connString) use comm = new Odbc.OdbcCommand(query, conn) diff --git a/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.pdb b/src/mod/languages/mod_managed/managed/examples/easyroute/easyroute.pdb index 010b2d60fd33ccad51ea54039855380610add9f5..c449eba6908ccad175130bb7f918e1e411f84a4f 100644 GIT binary patch delta 3518 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 AL;wH) delta 3406 zcmaJ^du&tJ89&GPn!Isv5)wOL=V3b`Bz`4!(xhPLMG^uH5Jo73HG?!T9(fP;jEmZd zZ7p5$bsbb2De*JP*sIUZMNTc?{UUfX-E3* z@0{;_&*Qu2#?Q<6c{yWF%b%Ya?2tl;e|Fx_nmcv3W4i3gYklwkyev_ec1KI~q(X$| zNn~67rmU8ueTRk)_K)sr=^Op(mc(PrFG-8t`}e7jmL;-sET)OmhPM7J7s7HpMF@5- zs`l&|8ypcPVG$o;co1aBq)6H<1@8$Ew=^N*R$w~N3CsXi0W*P{fLXvV0G9##fY6O= zqCQ_}qE4r55fKIA6ObL_BZ)nE+vFRCvrFVU`kk|)pb`2=O)%yuTmfvNTvtS{r;V

6X% z0OGyknc@+=qZ{O*`>t)-h!=Ojb_cKo_&D_zm3aKioQ76_109W zOT(;MOyn*tDKJ@##MogibPEyqGH?m?mHMQYCh^=rZ{s;g_e!@~Fb9^mEY#r+T9CWt zs)dfZi|tn*^6~;a95o5?6L|TPg?{O-k{`oO30XZEayhN^_@tjUdbVnA*pJgWPek*e z=cHR6hcwY=o(dBJtoE)>HM~mk3MQsRj?+`#3hAWRy%En%#CQO*B2F173hDt3fu03T zgMML3$dpgyRNgMRlX~+UmiNHCW76j|&s-E1tFw`zXy6AL=6JDT^IKk|-Zdo!?(KW> zGLtqoN6R%pf7)P?zeMewz5P#a9UIwycpw_&rQ)L;RBtgyn=5T~Inb_5YLE2y?cLHp zI(~3WpM?;!RVER#B%EAO-q>Bp57+DY_o({C$%+7hTTw;<9CCXBtJi|kMBcuJXk%3VoUJpDp zL&o|^9ggxW_)+i&z;B?UfH!LzoCa`Ez(hBnSUU{`QZlcBT?=*_*gNT&Kt$tB`6A5+ z9ObC~dL3rO_7RL;u^$Kjn_>iu$+euT(FJ-m=t#xZiI-uNLw!M8sS}fQPgQF8Ih+mG{xEw_%Bw9o(iv6SD8GM$d zieWv%9ITCnm-;4PublsF?x1-Qfg>W@cnh!`xEr_{xL@IyfvEd&%(ISTtgr@*uK_E8 zPb+)|h>uhJ1keY38Hh=VUjhbzF>IS4kWU!nATR{v9na%beBLs}2-R1&*BC1(7grx^ zvsfb{&@I3ir!VdTqR<`-vz#tfd&6ezI~S-H)C1zZ`+d->pm#tYfF6K&KbL``pdRzZ z*lThse;0~uZ@z=9HFJ|)C#S;JiMyB`q$eg}!8nfxV+>Y|zf$~irHA*_`9+Fr~*+l6s1NE}57@_JOX*nT$Co zr?!x0BBdr%%4Ez=*4k3~(fSms>abEY$4vg(<5JM2TBn5ANe^mwPIkHJXkA>+Bg8m#^H8K0J7#lq4 zjxRlC@!y}3JW;NPGGr=k9FC+7e>cqHp^piCCv6OwvcYvE&q#8+;PP)42L}faj1NJ7 z(ZJvPhCw0F!)M8OjQlRi%n0+spc=`X7M4^8`nx+%DHO`bfmc|Eg)L` zvBt*Q#yVQpTvBKKoZ`&&1yoU^@hy5}aD1%4YV=4nQX^_&p{7t%4d0sRXU%TgdF&-_ zvxvY!;@20bsbxd%GSR8&0x_$0)60;Yg(O29Hw1jW)NQ)nU!Z~3mE>wQr`JS8b#*Wl z3fDw9yWI58Wp@*P23ozDVbR>|Zwv$i&2U4$R=15OkJ}v(=OUo_ht>_bsf#|IR+6FX z3yIKrO;UGTzPvz(+8i2x3(9D?ZH2~lKbLzn-R3gABrrn|OU&d*AyWJ~2 v^pE!E|Mw5(+a2GM|K}H|GsCp%3WB|g=yBkOApW>>zXzV