Forum Discussion

jsgibbs1's avatar
jsgibbs1
Icon for Nimbostratus rankNimbostratus
Jul 15, 2015

Scan command irule with URI encoding

iRulers,

 

I need to set the SSL Cert and separate the Subject DN attributes to reference later. This works when not URI encoding, though that's what I need. Can SCAN handle this? I have tested this successfully unencoded:

 

when HTTP_REQEUST log local0. "================== ** Begin Log ** ==================" if { [SSL::cert count] > 0 } { set user [X509::subject [SSL::cert 0]] scan $user {CN=%[^,],OU=%[^,],OU=%[^,],OU=%[^,],O=%[^,],C=%[^,]} test1 test2 test3 test4 test5 test6 log local0. test1 log local0. test2 log local0. test3 log local0. test4 log local0. test5 log local0. test6 } log local0. "================== ** End Log ** ==================" }

 

However I need the set user command as: set user [URI::encode [X509::subject [SSL::cert 0]]]

 

Then scan $user would "presumably look like this: scan $user {%3d%[^%20],OU=%[^%20],OU=%[^%20],OU=%[^%20],O=%[^%20],C=%[^%20]} test1 test2 test3 test4 test5 test6

 

Of course, then I'm presented the issue of escaping the percent symbol that's intended to represent encoded characters, as opposed to SCAN's percent parameter.

 

Any ideas/suggestions? I'm also not tied to SCAN. Just looking for the most efficient method of doing this. Thx!

 

6 Replies

  • Curious why you need to do the scan after the URI encoding. That would just make it harder.

    You can also split the values using a list function:

    set val "CN=bob.user,OU=my-ou-1,OU=my-ou-2,OU=my-ou-3,O=my-org,C=my-country"
    
    set cnlist [split $val ","]
    
    foreach x $cnlist {
        log local0. $x
    } 
    

    If your DNs are always formatted the same way, then you can just short circuit the whole thing with explicit [lindex ] commands:

    log local0. [findstr [lindex $cnlist 0] "=" 1]
    
  • You can do another scan, but I usually prefer a list function.

    set tmp "Homer Simpson J"    
    
    set namelist [split $tmp " "]    
    
    log local0. "Middle = [lindex $namelist 2]"    
    
  • How is it failing? Is your CN like the example, with a space between first, last and middle initial?

     

  • Herein lies the beauty of list commands over scan. Once you've created a list, that list has properties like a length value:

    log local0. [llength $namelist]    
    if { [llength $namelist] == 3 } {    
        middle name present
    }           
    

    The llength command returns the number of values in the list (3 if there's a middle name). The lindex command returns the item in a list position. List indexes start at zero, so the third item is the second list item.

  • That's a great job for findstr:

    set var "this is a [test]"    
    
    set found [findstr $var "\[" 1 "\]"]    
    

    The findstr command takes 3 options:

    • the first is the string to find inside another string, and from where to start collecting from. "["

    • the second is a skip count. You don't want to include the "[" in the result, so you'll skip one character.

    • the third is an optional terminator value (number of characters) or character. Without this option it'll collect to the end of the string. "]"

    I don't have a test environment in front of me right now to verify, but I'm pretty sure you need to escape the brackets. "["

  • That's how the findstr command works. The first parameter is the character or string to start collecting from. The second parameter is the number of characters to skip once you've found the character or string in the first parameter. And the third option is where or when to end collecting. So for example, the string

    this is a [test]
    

    would return "test" from the above findstr example. It starts collecting at the first occurrence of a "[", skips that 1 character, and stops collecting at the first occurrence of "]" after that. Here's another example using a distinguishedName value:

    set mycn "CN=bob.user,ou=myou,o=myorg,dc=mydomain,dc=com"
    
    log local0. [findstr $mycn "CN=" 3 ","]
    

    It starts collecting at "CN=", skips these 3 characters, and stops collecting at the next comma, resulting in:

    bob.user
    

    Make sense?