Rick_Nyman
May 23, 2009Nimbostratus
XMPP with STARTTLS
I love the simplicity of SSL offload using standard SSL/TLS. Unfortunately, I've recently been given a requirement to do XMPP (an Instant Messaging protocol) using STARTTLS.
I found the excellent examples of IMAP and SMTP using STARTTLS, but it appears that XMPP is a different animal. To start, it's XML based. In addition, it appears to keep track of client requests and will not respond to what it thinks are repeat requests.
Here's what I have so far (Caveat - I do a little bit of PERL coding, but don't know much about TCL, so there may be fundamental issues with this script). At a basic level, this script starts by watching the server output and when it sees a stream:features XML tag, it inserts the STARTTLS capability. At that point, it starts watching client traffic - and expects to see the client requesting encryption. At that point, it starts encryption locally.
Anyone here familiar with XMPP?
Thanks all,
Rick
Last week's code
when CLIENT_ACCEPTED {
SSL::disable
}
when SERVER_CONNECTED {
TCP::collect
}
when CLIENT_DATA {
set lcpayload [string tolower [TCP::payload]]
if { $lcpayload starts_with " TCP::respond "\r\n"
TCP::payload replace 0 [TCP::payload length] ""
TCP::release
SSL::enable
} else {
TCP::respond "TLS is required on this stream - you sent $lcpayload\r\n"
TCP::payload replace 0 [TCP::payload length] ""
TCP::release
TCP::collect
}
}
when SERVER_DATA {
if {[string first "" [TCP::payload]] == -1 } {
TCP::release
TCP::collect
}
else {
regsub {\} [TCP::payload] {} changed
TCP::payload replace 0 [TCP::payload length] $changed
TCP::release
clientside { TCP::collect }
}
}
I received the following feedback from our XMPP expert
as I described in mail from last week, there are subsequent requests generated by the client as each feature is negotiated. What is happening is the server responds back w/ a list of (which the F5 rewrites as it is being sent to the client); the client negotiates TLS; then the client sends another request. The server receives this, but will *not* respond back... from the server's perspective, the client has simply made two requests and hasn't negotiated a feature yet.
Last night's rule - I'm still waiting for feedback
when CLIENT_ACCEPTED {
SSL::disable
}
when SERVER_CONNECTED {
TCP::collect
}
when CLIENT_DATA {
set clientdata [string tolower [TCP::payload]]
if { $clientdata starts_with " TCP::respond ""
TCP::payload replace 0 [TCP::payload length] ""
TCP::release
SSL::enable
TCP::collect
} elseif { $clientdata contains " TCP::respond $serverdata
} else {
TCP::respond "TLS is required on this stream - you sent $clientdata"
TCP::payload replace 0 [TCP::payload length] ""
TCP::release
TCP::collect
}
}
when SERVER_DATA {
if {[string first "" [TCP::payload]] == -1 } {
TCP::release
TCP::collect
}
else {
set serverdata [TCP::payload]
regsub {\} $serverdata {} changed
TCP::payload replace 0 [TCP::payload length] $changed
TCP::release
clientside { TCP::collect }
}
}