procedures
4 TopicsTCL procedures for Base32 encoding/decoding
Problem this snippet solves: Hi Folks, the iRule below contains two TCL procedures to support Base32 encoding and decoding (see RFC 4648 as well as RFC 3548) within iRules. The procedures are based on a rather simple but extensive [string map] syntax to translate or untranslate the Base32 alphabet on a given input data stream via its binary string representation. Compared to other Base32 libraries, which may convert the input on a per-charater/quantum basis, the single step [string map] translation will require significant less CPU cycles to handle the base32 encodings / decodings. Note: The provided Base32 decoder uses a liberal input validation (see RFC 4648 Section 3.3), by ignoring incorrect "=" paddings, accepting upper as well as lower case base32 alphabet characters, automatically translating "0" (zero) to "O", "1" (one) to "I", "8" (eight) to "B" and silently removing any WHITESPACE, TAB and "CRLF" sequences from the input. If the input string contains any other non-Base32 alphabet characters, an internal error will be raised and the output will become an empty string. Cheers, Kai How to use this snippet: The iRule below contains a RULE_INIT event which outlines the procedure usage. Enjoy! Code : when RULE_INIT { set string "Hello World!" set output [call b32encode $string] log local0.debug "Base32 encoded the input \"$string\" to \"$output\"" set string "JBSWY3DPEBLW64TMMQQQ====" set output [call b32decode $string] log local0.debug "Base32 decoded the input \"$string\" to \"$output\"" } proc b32decode { input } { set bin [string map -nocase [list A 00000 B 00001 C 00010 D 00011 \ E 00100 F 00101 G 00110 H 00111 \ I 01000 J 01001 K 01010 L 01011 \ M 01100 N 01101 O 01110 P 01111 \ Q 10000 R 10001 S 10010 T 10011 \ U 10100 V 10101 W 10110 X 10111 \ Y 11000 Z 11001 2 11010 3 11011 \ 4 11100 5 11101 6 11110 7 11111 \ = "" 0 01110 1 01000 8 00001 \ " " "" "" "" "\n" ""] $input] if { [catch { set output [binary format B[expr { int( [string length $bin] / 8 ) * 8 }] $bin] }] } then { set output "" } return $output } proc b32encode { input } { binary scan $input B* bin return [string map [list 00000 A 00001 B 00010 C 00011 D \ 00100 E 00101 F 00110 G 00111 H \ 01000 I 01001 J 01010 K 01011 L \ 01100 M 01101 N 01110 O 01111 P \ 10000 Q 10001 R 10010 S 10011 T \ 10100 U 10101 V 10110 W 10111 X \ 11000 Y 11001 Z 11010 2 11011 3 \ 11100 4 11101 5 11110 6 11111 7 \ 0000 A=== 0001 C=== 0010 E=== 0011 G=== \ 0100 I=== 0101 K=== 0110 M=== 0111 O=== \ 1000 Q=== 1001 S=== 1010 U=== 1011 W=== \ 1100 Y=== 1101 2=== 1110 4=== 1111 6=== \ 000 A====== 001 E====== 010 I====== 011 M====== \ 100 Q====== 101 U====== 110 Y====== 111 4====== \ 00 A= 01 I= 10 Q= 11 Y= \ 0 A==== 1 Q==== ] $bin] } Tested this on version: 12.0706Views0likes0CommentsRandom String Generators
Problem this snippet solves: These procs generate a random string of letters, numbers, or both. Code Source ############################################################ # Note: the RNG used by TCL rand() is not in any way cryptographically secure # ############################################################ How to use this snippet: Code : # iRule proc Source - Define the proc named html_encode in a separate iRule named library: rule library { proc randomNumberGenerator {length {chars "0123456789"}} { set range [expr {[string length $chars]-1}] set txt "" for {set i 0} {$i < $length} {incr i} { set pos [expr {int(rand()*$range)}] append txt [string range $chars $pos $pos] } return $txt } proc randomLetterGenerator {length {chars "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"}} { set range [expr {[string length $chars]-1}] set txt "" for {set i 0} {$i < $length} {incr i} { set pos [expr {int(rand()*$range)}] append txt [string range $chars $pos $pos] } return $txt } proc randomNumberLetterGenerator {length {chars "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}} { set range [expr {[string length $chars]-1}] set txt "" for {set i 0} {$i < $length} {incr i} { set pos [expr {int(rand()*$range)}] append txt [string range $chars $pos $pos] } return $txt } } # Call the procedure from another iRule using the name of the iRule where the proc is defined as the namespace and then the name of the procedure (library::html_encode): # iRule that calls the string generating proc: when CLIENT_ACCEPTED { set x [call library::randomNumberGenerator 10] set y [call library::randomLetterGenerator 10] set z [call library::randomNumberLetterGenerator 10] log local0. "Random Strings: $x / $y / $z" } # log output: Random Strings: 8648734163 / vmQSXmqgxB / Xx7mKZ7733883Views0likes1CommentHTML encoding proc
Problem this snippet solves: This proc HTML encodes an input string. See the OWASP discussion page for details on when/how to use this approach: XSS (Cross Site Scripting) Prevention Cheat Sheet How to use this snippet: iRule proc Source Define the proc named html_encode in a separate iRule named library: Code : rule library { proc html_encode { str } { set encoded "" foreach char [split $str ""] { switch $char { "<" { append encoded "<" } ">" { append encoded "<" } "'" { append encoded "'" } {"} { append encoded """ } "&" { append encoded "&" } default { append encoded $char } } } return $encoded } } # Call the procedure from another iRule using the name of the iRule where the proc is defined as the namespace and then the name of the procedure (library::html_encode): when RULE_INIT { # iRule that calls the html_encode proc: set raw {some xss: < script >alert(document.cookie) and sqli: ' or 1==1# "} log local0. "HTML encoded: [call library::html_encode $raw]" # Log output #HTML encoded: <script<alert(document.cookie)</script< and sqli: ' or 1==1# " }261Views0likes1CommentTcl lmap emulator
Problem this snippet solves: The version of Tcl used as the basis for iRules, TMSH and iApps through version 11.5 (and probably later) does not have the tremendously useful lmap function. This procedure emulates much of that functionality with the same call signature. Code : # ############### # # $rlist = _lmap varname $varlist $body # # Foreach member of $varlist, assign the value to the variable identified # at 'varname', and execute $body in that context. Return a list of # the evaluations. # iRule proc Source # Define the proc named _lmap (the underscore is used in the event that, in the future, lmap becomes a supported method) in a separate iRule or tmsh library: ############### proc _lmap { varname varlist body } { set _bbr {} foreach [subst $varname] $varlist { lappend _bbr [subst $body] } return $_bbr } # As the included procedure comment explains, _lmap takes a Tcl list, $varlist, and a code body, $body. For each element in $varlist, $body is executed, substituting the current element of $varlist for the value of the named variable varname. So far, this is exactly the same as foreach. However, on each iteration, it builds a list of the result from the execution of $body and returns that list. # Example - In a TMSH script assume one wishes to create a firewall address-list that contains all self-IPs. This is one way to do so: cli script self_addr_list { proc script::init {} { proc _lmap { varname varlist body } { set _bbr {} foreach [subst $varname] $varlist { lappend _bbr [subst $body] } return $_bbr } } proc script::run {} { set selfs [_lmap awm [_lmap so [tmsh::get_config /net self] { [tmsh::get_field_value $so "address"] }] { [lindex [split $awm /] 0] }] tmsh::create / security firewall address-list myself addresses replace-all-with \{ [join [_lmap ip $selfs { [format "$ip"] }] " "] \} } proc script::help {} { } proc script::tabc {} { } total-signing-status not-all-signed }300Views0likes0Comments