Create Domino LTPA token on F5 problem

Hi,

I’m trying to use the code at

to create a Domino LTPA token but I am getting the following error showing on the Domino server:

Token does not lead with 0 [Single Sign-On token is invalid].

The token should begin with the version number 0123 e.g. from the code

set ltpa_version “\x00\x01\x02\x03”

However, after decoding the token and then looking at it in a hex editor the version number shows as:

C0 80 01 02 03 …

Can somebody explain to me why the \x00 is being changed to C0 80 please?

I’ve experimented putting other numbers in thefirst position to see what happens e.g. \x01\x01\x02\x03 and the hex readout looks correct i.e. 01 01 02 03. It only fails when I use a \x00 in the first position.

Thanks for any suggestions.

Jeff

Jeff,

are there any TCL errors in /var/log/ltm (grep TCL /var/log/ltm)?

If there are no errors, could you please add some log statements to the iRule and post the output (see /var/log/ltm) here?

Final Base64 encoded token
 set ltpa_token_final [b64encode $ltpa_token_raw]

  please add these lines.
 binary scan $ltpa_token_raw H* ltpa_token_raw_hex
 log local0. "LTP_TOKEN Hex: $ltpa_token_raw_hex"
 log local0. "LTP_TOKEN Final: $ltpa_token_final"

If I run the code on my test system, the HEX encoded string looks good.

local/tmm info tmm[5104]: Rule rule01 : LTP_TOKEN Hex: 0001020334454237453145363445423745384545e3f09dbbff9248a638a6bfeeb876f66c52df6cb2

local/tmm info tmm[5104]: Rule rule01 : LTP_TOKEN Final: wIABAgM0RUI3RTFFNjRFQjdFOEVFw6PDsMKdwrvDv8KSSMKmOMKmwr/DrsK4dsO2bFLDn2zCsg==

Regards

Kurt Knochner

Hi Kurt,

No errors are showing in the ltm log. I added the debug lines and I get the same result as you. Leading 00 is where it shoud be. So I know that part is working correctly. Thanks.

What we’ve now found is when the token is subsequently b64encoded, then b64decoded, the leading 00 is replaced with the C0 80. This happens on both v9.4.4 and v10.2.0.

Regards,

Jeff Green

What we’ve now found is when the token is subsequently b64encoded, then b64decoded, the leading 00 is replaced with the C0 80. This happens on both v9.4.4 and v10.2.0.

hm.. can you post some sample code? There is no b64decode in the original iRule, at least not for the token.

Regards

Kurt Knochner

Hi,

I’m able to reproduce what you’ve seen.

set text "\x00\x01\x02\x03Hello World"
 set text_enc [b64encode $text]
 set text_dec [b64decode $text_enc]
 binary scan $text H* text_hex
 binary scan $text_enc H* text_enc_hex
 binary scan $text_dec H* text_dec_hex

 log local0. "Text: $text_hex"
 log local0. "Text encoded: $text_enc_hex"
 log local0. "Text decoded: $text_dec_hex"

The result:

Nov 9 03:13:54 local/tmm info tmm[5158]: Rule rule01 : Text: 0001020348656c6c6f20576f726c64

Nov 9 03:13:54 local/tmm info tmm[5158]: Rule rule01 : Text encoded: 7749414241674e495a5778736279425862334a735a413d3d

Nov 9 03:13:54 local/tmm info tmm[5158]: Rule rule01 : Text decoded: c08001020348656c6c6f20576f726c64

So, yes there is a c080 in front of the text and it only happens if the initial string starts with \x00.

This looks like a bug. Maybe something with internal string handling. Please open a case with my example and ask support what’s going wrong. It would be nice if you could update this thread as soon as you get a reply from support.

Thanks!

Regards

Kurt Knochner

why does it seem okay to me?

[root@ve1023:Active] config  b version|grep -iA 1 version
BIG-IP Version 10.2.3 112.0
Final Edition
[root@ve1023:Active] config  b rule myrule list
rule myrule {
   when RULE_INIT {
 set text "\x00\x01\x02\x03Hello World"
 set text_enc [b64encode $text]
 set text_dec [b64decode $text_enc]
 binary scan $text H* text_hex
 binary scan $text_enc H* text_enc_hex
 binary scan $text_dec H* text_dec_hex

 log local0. "Text: $text_hex"
 log local0. "Text encoded: $text_enc_hex"
 log local0. "Text decoded: $text_dec_hex"
}
}

[root@ve1023:Active] config  grep -i myrule /var/log/ltm
Nov  8 23:54:37 local/ve1023 err mcpd[3752]: 01020066:3: The requested rule (myrule) already exists in partition Common.
Nov  8 23:54:37 local/tmm info tmm[4766]: Rule myrule : Text: 0001020348656c6c6f20576f726c64
Nov  8 23:54:37 local/tmm info tmm[4766]: Rule myrule : Text encoded: 414145434130686c6247787649466476636d786b
Nov  8 23:54:37 local/tmm info tmm[4766]: Rule myrule : Text decoded: 0001020348656c6c6f20576f726c64

why does it seem okay to me?

maybe the TMOS version you’ve used, 10.2.3. I’ve tested with 10.2.2 and Jeff with 9.4.4 and 10.2.0.

EDIT: I ran the test again and this time it gave the correct result. Strange. I’ll try to figure out in which cases it will produce the wrong result.

Regards

Kurt Knochner

Hi,

the append function in the original iRule might cause the problem.

Nov 9 03:49:44 local/tmm info tmm[5158]: Rule irule03 : WITHOUT append

Nov 9 03:49:44 local/tmm info tmm[5158]: Rule irule03 : Text: 0001020348656c6c6f20576f726c64

Nov 9 03:49:44 local/tmm info tmm[5158]: Rule irule03 : Text encoded: 414145434130686c6247787649466476636d786b

Nov 9 03:49:44 local/tmm info tmm[5158]: Rule irule03 : Text decoded: 0001020348656c6c6f20576f726c64

Nov 9 03:49:57 local/tmm info tmm[5158]: Rule irule03 : WITH append

Nov 9 03:49:57 local/tmm info tmm[5158]: Rule irule03 : Text: 0001020348656c6c6f20576f726c64

Nov 9 03:49:57 local/tmm info tmm[5158]: Rule irule03 : Text encoded: 7749414241674e495a5778736279425862334a735a413d3d

Nov 9 03:49:57 local/tmm info tmm[5158]: Rule irule03 : Text decoded: c08001020348656c6c6f20576f726c64

[root@lb01:Active] log  b rule irule03 list
rule irule03 {
   when RULE_INIT {

 log local0. "WITHOUT append"
 set text "\x00\x01\x02\x03Hello World"

 log local0. "WITH append"
 set hello "\x00\x01\x02\x03Hello World"
 set text {}
 append text $hello

 set text_enc [b64encode $text]
 set text_dec [b64decode $text_enc]
 binary scan $text H* text_hex
 binary scan $text_enc H* text_enc_hex
 binary scan $text_dec H* text_dec_hex

 log local0. "Text: $text_hex"
 log local0. "Text encoded: $text_enc_hex"
 log local0. "Text decoded: $text_dec_hex"
}
}

Is this a bug?

EDIT: Something is wrong with the string when it is initialized as an empty string with ‘set text {}’. Anyway, if I change the init to -- set text ‘’ --, the output looks like this, and it’s still wrong (c080 in the string).

Nov 9 03:54:20 local/tmm info tmm[5158]: Rule irule03 : WITH append

Nov 9 03:54:20 local/tmm info tmm[5158]: Rule irule03 : Text: 27270001020348656c6c6f20576f726c64

Nov 9 03:54:20 local/tmm info tmm[5158]: Rule irule03 : Text encoded: 4a796641674145434130686c6247787649466476636d786b

Nov 9 03:54:20 local/tmm info tmm[5158]: Rule irule03 : Text decoded: 2727c08001020348656c6c6f20576f726c64

So, it’s only a problem, if the string is initialized as an empty string and if one uses ‘append’ to add other strings to it. I’m not sure if this is O.K.

EDIT2: Furthermore, the problem only exists, if the appended string starts with \x00.

Nov 9 04:20:36 local/tmm info tmm[5158]: Rule irule03 : WITH append

Nov 9 04:20:36 local/tmm info tmm[5158]: Rule irule03 : Text: 01020348656c6c6f20576f726c64

Nov 9 04:20:36 local/tmm info tmm[5158]: Rule irule03 : Text encoded: 415149445347567362473867563239796247513d

Nov 9 04:20:36 local/tmm info tmm[5158]: Rule irule03 : Text decoded: 01020348656c6c6f20576f726c64

To sum it up.

1.) create a string that starts with \x00

2.) initialize another string with “set string2 {}”

3.) append the first string to the second string. ‘append string2 $string1’

4.) b64encode and then b64decode string2 and the result will contain (or start with) c080.

This really looks like a bug.

Regards

Kurt Knochner

Hi,

it’s a more general “problem” and related to the concatenation of strings, where the first string starts with \x00. 0x00 would be the terminator for a string in C. I’m not sure how TCL handles that. The strange thing is, that binary scan shows the correct value, while b64encode followed by a b64decode leads to the additional c080.

rule irule03a {
   when RULE_INIT {

 set hello "Hello World"

 log local0. "WITH leading \\x00"
 set prefix "\x00\x01\x02\x03"

 log local0. "WITHOUT leading \\x00"
 set prefix "\x01\x02\x03"

 set text "${prefix}${hello}"

 log local0. "WITHOUT concatenation"
 set text "\x00\x01\x02\x03HelloWorld"

 set text_enc [b64encode $text]
 set text_dec [b64decode $text_enc]
 binary scan $text H* text_hex
 binary scan $text_enc H* text_enc_hex
 binary scan $text_dec H* text_dec_hex

 log local0. "Text: $text"
 log local0. "Text hex: $text_hex"
 log local0. "Text encoded: $text_enc_hex"
 log local0. "Text decoded: $text_dec_hex"

}
}

Nov 9 04:45:36 local/tmm info tmm[5158]: Rule irule03a : WITHOUT concatenation

Nov 9 04:45:36 local/tmm info tmm[5158]: Rule irule03a : Text: ÀHelloWorld

Nov 9 04:45:36 local/tmm info tmm[5158]: Rule irule03a : Text hex: 0001020348656c6c6f576f726c64

Nov 9 04:45:36 local/tmm info tmm[5158]: Rule irule03a : Text encoded: 414145434130686c62477876563239796247513d

Nov 9 04:45:36 local/tmm info tmm[5158]: Rule irule03a : Text decoded: 0001020348656c6c6f576f726c64

Nov 9 04:46:01 local/tmm info tmm[5158]: Rule irule03a : WITH leading \x00

Nov 9 04:46:01 local/tmm info tmm[5158]: Rule irule03a : Text: ÀHello World

Nov 9 04:46:01 local/tmm info tmm[5158]: Rule irule03a : Text hex: 0001020348656c6c6f20576f726c64

Nov 9 04:46:01 local/tmm info tmm[5158]: Rule irule03a : Text encoded: 7749414241674e495a5778736279425862334a735a413d3d

Nov 9 04:46:01 local/tmm info tmm[5158]: Rule irule03a : Text decoded: c08001020348656c6c6f20576f726c64

Nov 9 04:46:13 local/tmm info tmm[5158]: Rule irule03a : WITHOUT leading \x00

Nov 9 04:46:13 local/tmm info tmm[5158]: Rule irule03a : Text: Hello World

Nov 9 04:46:13 local/tmm info tmm[5158]: Rule irule03a : Text hex: 01020348656c6c6f20576f726c64

Nov 9 04:46:13 local/tmm info tmm[5158]: Rule irule03a : Text encoded: 415149445347567362473867563239796247513d

Nov 9 04:46:13 local/tmm info tmm[5158]: Rule irule03a : Text decoded: 01020348656c6c6f20576f726c64

Regards

Kurt Knochner

From http://wiki.tcl.tk/1211

“In orthodox UTF-8, a NUL byte(\x00) is represented by a NUL byte. Plain enough. But in Tcl we sometimes want NUL bytes inside “binary” strings (e.g. image data), without them terminating it as a real NUL byte does. To represent a NUL byte without any physical NUL bytes, we treat it like a character above ASCII, which must be a minimum two bytes long:”

(110)00000 (10)000000 => C0 80

I guess the function fails to convert it back.

I guess the function fails to convert it back.

sounds reasonable. Thanks for the link!

@Jeff: With all that information you should be able to open a support case.

Regards

Kurt Knochner

Hi everyone,

Thanks for the input. I have opened a support case and will report back once they figure it out.

regards,

Jeff

F5 have asupplied a workaround that seems to be doing everything correctly. We’re going to test more thoroughly before declaring victory. The relevant line in the code is:

Create binary formatted token.
 set ltpa_token_raw_bin [binary a* $ltpa_token_raw]

Here’s the entire code that seems to be working:

when RULE_INIT {
 set ::DEBUG 0
 set cookie_name "LtpaToken"
 set ltpa_version "\x00\x01\x02\x03"
 set ltpa_secret "b64encodedsecretkey"
 set ltpa_timeout "1800"
}

when HTTP_REQUEST {
 
  Do your usual F5 HTTP authentication here
 

  Initial values
 set now [clock seconds]
 set creation_time_temp [expr { $now }]
 set creation_time [format %X $creation_time_temp]
 set expr_time_temp [expr { $creation_time_temp + $::ltpa_timeout}]
 set expr_time [format %X $expr_time_temp]
 set username [HTTP::header "username"]
 set ltpa_secret_decode [b64decode $::ltpa_secret]

  First part of token
 set cookie_data_raw {}
 append cookie_data_raw $::ltpa_version
 append cookie_data_raw $creation_time
 append cookie_data_raw $expr_time
 append cookie_data_raw $username
 append cookie_data_raw $ltpa_secret_decode

  SHA1 of first part of token
 set sha_cookie_raw [sha1 $cookie_data_raw]

  Final not yet encoded token
 set ltpa_token_raw {}
 append ltpa_token_raw $::ltpa_version
 append ltpa_token_raw $creation_time
 append ltpa_token_raw $expr_time
 append ltpa_token_raw $username
 append ltpa_token_raw $sha_cookie_raw

  Create binary formatted token.
 set ltpa_token_raw_bin [binary a* $ltpa_token_raw]

  Final Base64 encoded token
 set ltpa_token_final [b64encode $ltpa_token_raw_bin]

  Insert the cookie
 HTTP::cookie insert name $::cookie_name value $ltpa_token_final


  Loop through the list of Cookie headers to remove
  superfluous trailing semi-colons (known F5 issue)
  if they exist.
  
  Save the Cookie headers to a TCL list
 set cookie_headers [HTTP::header values "Cookie"]

 foreach cookie_header $cookie_headers {
    Check if the last character is a semi-colon
   if {[string range $cookie_header end end] eq ";"}{
     HTTP::cookie remove LtpaToken
      Insert the header without the semi-colon
     HTTP::header insert Cookie [string range $cookie_header 0 end-1]
     } else {
      Insert the original header
     HTTP::header insert Cookie $cookie_header
     }
   }
   
  Remove Authorization HTTP header to avoid using basic authentication
 if { [HTTP::header exists "Authorization"] } {
 HTTP::header remove "Authorization"
 }

 if {$::DEBUG} {
   binary scan $ltpa_token_raw H* ltpa_token_raw_hex
   log local0.debug "LTP_TOKEN raw Hex: $ltpa_token_raw_hex"
   binary scan $ltpa_token_raw H* ltpa_token_raw_hex_bin
   log local0.debug "LTP_TOKEN raw_bin Hex: $ltpa_token_raw_hex_bin"   
   set ltpa_final_decoded [b64decode $ltpa_token_final]
   binary scan $ltpa_final_decoded H* ltpa_final_decoded_hex
   log local0.debug "LTP_TOKEN decoded Hex: $ltpa_final_decoded_hex"
 }
}

That alomst came out correct. The relevant line was:

Final Base64 encoded token

set ltpa_token_final [b64encode $ltpa_token_raw_bin]

Hi Jeff,

Thanks for posting the solution.

If you’re on 10+ you can replace the global variables in RULE_INIT with static variables. This will function the same, but be CMP compatible. Using the global variables will prevent the iRule (and VS) from being processed on more than one TMM:

http://devcentral.f5.com/wiki/iRules.CMPCompatibility.ashx

There’s a bug with the DC forums code when you use more than one code block in the quick reply box. You can click Edit on your corrupted post and then submit it as is to have it rendered correctly. Or you can click the reply button instead and use the full reply function instead of the quick reply option.

Aaron

Hi,

i stay in front of the same challenge like jeff and try to implement LTPA token creation incl. Reverse Proxy with SSO. This is all new for me. We use 10.2.2 @ LTM incl. ASM.

So, if i try to create an irule with Jeff’s code from above i get an syntax validation error in Irule editor:

Create binary formatted token.

set ltpa_token_raw_bin [binary a* $ltpa_token_raw]

--> [invalid option “a*” must be: format scan] [a*]

so for me, it looks like the line should be replaced by this:

set ltpa_token_raw_bin [binary fromat a* $ltpa_token_raw]

can someone confirm that behaviour?

Thx

Hi Team. Anyone have this working still? We are running BIG-IP 11.3.0, Domino 8.5.2, and I am struggling to get the code to produce a valid encoded token. Can anyone share an example of the set ltpa_secret “b64encodedsecretkey” field, to give me a clue to what this should look like? Is this a direct copy out of the LTPA document in Domino LTPA_DominoSecret field, or do I need to change that value prior to insert into the iRule? Thanks in advance!

Hi all,

have you got any news about this bug? I’d like to implement an iRule to generate LtpaToken in order to integrate new apps with legacy applications that are running on a mainframe, if there is a new version of this iRule could you please share it with the community?

We’re running 16.1.4.2

Thank you all

Cristian