MikeRobinson_64
Dec 01, 2009Nimbostratus
auth_result not called for some client certificates
Hi everyone,
I am trying to resolve an issue with an irule that is utilized to ask for client certificates for certain folders. The irule works great except for certain client certificates. I have noticed from the statistics in the irule editor that when testing with these certificates the session does not appear to pass through the auth_result section. As a result the user gets to see the ever popular "page cannot be displayed" message. I need to get this resolved for a larger test. The irule is pasted below. Thanks in advance for your help!
Mike
when RULE_INIT {
set tmm_auth_subscription "*"
}
when CLIENT_ACCEPTED {
set needcert 0
set gotcert 0
set badcert 0
set tmm_auth_ssl_ocsp_sid 0
set tmm_auth_ssl_ocsp_done 0
}
when CLIENTSSL_HANDSHAKE {
set certcnt [SSL::cert count]
if { $certcnt > 0 } {
set gotcert 1
HTTP::release
}
}
when CLIENTSSL_CLIENTCERT {
set tmm_auth_ssl_ocsp_done 0
if { $needcert == 1 and $tmm_auth_ssl_ocsp_sid == 0} {
set tmm_auth_ssl_ocsp_sid [AUTH::start pam ssl_ocsp_prod]
AUTH::subscribe $tmm_auth_ssl_ocsp_sid
set varcert [SSL::cert 0]
AUTH::cert_credential $tmm_auth_ssl_ocsp_sid $varcert
AUTH::cert_issuer_credential $tmm_auth_ssl_ocsp_sid [SSL::cert issuer 0]
AUTH::authenticate $tmm_auth_ssl_ocsp_sid
set id [SSL::sessionid]
set ssl_array [list blah1 blah2]
lset ssl_array 0 [X509::verify_cert_error_string [SSL::verify_result]]
SSL::handshake hold
}
}
when AUTH_RESULT {
array set auth_response_data [AUTH::response_data]
set auth_status [AUTH::status]
set ocsp_status [lindex [array get auth_response_data ocsp:response:status] 1]
if {$tmm_auth_ssl_ocsp_sid eq [AUTH::last_event_session_id]} {
if {[AUTH::status] == 2} {
reject
}
elseif {[AUTH::status] != 0} {
SSL::handshake resume
lset ssl_array 1 "auth_failure"
session add ssl $id $ssl_array 21600
log local0.debug "ocsp_status = $ocsp_status"
log local0.debug "status = autherror"
log local0.debug "SSLClientCertIssuer [X509::issuer $varcert]"
log local0.debug "SSLClientCertNotValidBefore [X509::not_valid_before $varcert]"
log local0.debug "SSLClientCertNotValidAfter [X509::not_valid_after $varcert]"
log local0.debug "SSLClientCertSubject [X509::subject $varcert]"
}
else {
SSL::handshake resume
lset ssl_array 1 "auth_success"
session add ssl $id $ssl_array 21600
}
}
}
when HTTP_REQUEST {
switch -glob [string tolower [HTTP::uri]] {
"/folder1/*" -
"/folder2/*" {
set id [clientside {SSL::sessionid}]
set ssl_array1 [session lookup ssl $id]
set ssl_data0 [lindex $ssl_array1 0]
set ssl_data1 [lindex $ssl_array1 1]
if {$gotcert == 0} {
if { [SSL::cert count] == 0} {
HTTP::collect
set needcert 1
SSL::authenticate always
SSL::authenticate depth 9
SSL::cert mode require
SSL::session invalidate
SSL::renegotiate
}
}
else {
pool my_pool
}
}
}
}
when LB_SELECTED {
if {$needcert == 1} {
set ssl_array1 [session lookup ssl $id]
set ssl_data0 [lindex $ssl_array1 0]
set ssl_data1 [lindex $ssl_array1 1]
if { $ssl_data0 contains "expired" } {
set cert_status "expired"
}
elseif { $ssl_data1 contains "auth_failure" } {
set cert_status "revoked"
}
elseif { $ssl_data0 contains "ok" } {
set cert_status "success"
}
else {
set cert_status "other"
}
HTTP::header replace "SSLCLientCertStatus" $cert_status
HTTP::header replace "SSLClientCertVersion" [X509::version $varcert]
HTTP::header replace "SSLClientCertSerialNumber" [X509::serial_number $varcert]
HTTP::header replace "SSLClientCertIssuer" [X509::issuer $varcert]
HTTP::header replace "SSLClientCertNotValidBefore" [X509::not_valid_before $varcert]
HTTP::header replace "SSLClientCertNotValidAfter" [X509::not_valid_after $varcert]
HTTP::header replace "SSLClientCertSubject" [X509::subject $varcert]
}
}