It's not that much different that the stock one, just got rid of the 401 requirement and added more uniqueness to the session cookie. I think the session cookie still should be a little stronger, which I'll add the next time I get a window from the windows folks (they are very risk averse).
when RULE_INIT {
set static::actsync_401_http_body "Authentication FailuredError: Authentication Failure"
set static::actsync_503_http_body "Service is not availableError: Service is not available"
set static::ACCESS_LOG_PREFIX "01490000:7:"
}
when HTTP_REQUEST {
set http_path [string tolower [HTTP::path]]
set f_clientless_mode 0
HTTP::header replace X-Teros-Client-IP [IP::client_addr]
HTTP::header replace Host mobilemail.mastercard.com
if {[SSL::cert count] > 0}{
HTTP::header insert X-Client-Cert [X509::subject [SSL::cert 0]]
}
if { [HTTP::method] equals "OPTIONS" } {
HTTP::respond 200 -version 1.1 noserver Cache-Control "private" Allow "OPTIONS,POST" Server "Microsoft-IIS/8.5" MS-Server-ActiveSync "14.3" MS-ASProtocolVersions "2.0,2.1,2.5,12.0,12.1,14.0,14.1" MS-ASProtocolCommands "Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,Provision,ResolveRecipients,ValidateCert" Public "OPTIONS,POST" X-AspNet-Version "4.0.30319" X-Powered-By: "ASP.NET" X-FEServer "STL3MSXCAS02" Content-Length 0
}
if { $http_path == "/microsoft-server-activesync" } {
}
elseif { $http_path == "/autodiscover/autodiscover.xml" } {
set f_auto_discover 1
}
else return
if { ! [ info exists src_ip ] } {
set src_ip [IP::remote_addr]
}
if { ! [ info exists PROFILE_RESTRICT_SINGLE_IP ] } {
set PROFILE_RESTRICT_SINGLE_IP 1
}
Only allow HTTP Basic Authentication.
set auth_info_b64enc ""
set http_hdr_auth [HTTP::header Authorization]
regexp -nocase {Basic (.*)} $http_hdr_auth match auth_info_b64enc
if { $auth_info_b64enc == "" } {
set http_hdr_auth ""
}
set MRHSession_cookie [HTTP::cookie value MRHSession]
Do we have valid MRHSession cookie.
if { $MRHSession_cookie != "" } {
if { [ACCESS::session exists -state_allow -sid $MRHSession_cookie] } {
log -noname accesscontrol.local1.debug "$static::ACCESS_LOG_PREFIX HTTP *VALID* MRHSession cookie: $MRHSession_cookie"
Default profile access setting is false
if { $PROFILE_RESTRICT_SINGLE_IP == 0 } {
return
}
elseif { [ IP::addr $src_ip equals [ ACCESS::session data get -sid $MRHSession_cookie "session.user.clientip" ] ] } {
log -noname accesscontrol.local1.debug "$static::ACCESS_LOG_PREFIX source IP matched"
return
}
else {
log -noname accesscontrol.local1.debug "$static::ACCESS_LOG_PREFIX source IP does not matched"
}
}
else {
log -noname accesscontrol.local1.debug "$static::ACCESS_LOG_PREFIX HTTP *INVALID* MRHSession cookie: $MRHSession_cookie"
}
set MRHSession_cookie ""
HTTP::cookie remove MRHSession
}
if { [HTTP::header exists X-Client-Cert] } {
set apm_username [ string tolower [HTTP::header X-Client-Cert] ]
} else {
set apm_username [ string tolower [HTTP::header username] ]
}
set apm_password [HTTP::password]
if { $PROFILE_RESTRICT_SINGLE_IP == 0 } {
binary scan [md5 "$apm_password$"] H* user_hash
} else {
binary scan [md5 "$apm_password$src_ip$apm_username"] H* user_hash
}
set user_key {}
append user_key $apm_username "." $user_hash
unset user_hash
set f_insert_clientless_mode 0
set apm_cookie_list [ ACCESS::user getsid $user_key ]
if { [ llength $apm_cookie_list ] != 0 } {
set apm_cookie [ ACCESS::user getkey [ lindex $apm_cookie_list 0 ] ]
if { $apm_cookie != "" } {
HTTP::cookie insert name MRHSession value $apm_cookie
} else {
set f_insert_clientless_mode 1
}
} else {
set f_insert_clientless_mode 1
}
if { $f_insert_clientless_mode == 1 } {
HTTP::header insert "clientless-mode" 1
HTTP::header insert "username" $apm_username
HTTP::header insert "password" $apm_password
if { [HTTP::header exists X-Client-Cert] } {
log local0. "if: HTTP::header X-Client-Cert: [HTTP::header X-Client-Cert] [IP::client_addr]:[TCP::client_port]"
} else {
if {[catch {b64decode [lindex [split [HTTP::header Authorization] " "] 1]} authorization] == 0 and $authorization ne ""}{
set username [lindex [split $authorization ":"] 0]
log local0. "else: HTTP::header username: $username [IP::client_addr]:[TCP::client_port]"
} else {
log local0. "failed to decode [lindex [split [HTTP::header Authorization] " "] 1] [IP::client_addr]:[TCP::client_port]"
}
}
}
unset f_insert_clientless_mode
}
when ACCESS_SESSION_STARTED {
if { [ info exists user_key ] } {
ACCESS::session data set "session.user.uuid" $user_key
ACCESS::session data set "session.user.microsoft-exchange-client" 1
ACCESS::session data set "session.user.activesync" 1
if { [ info exists f_auto_discover ] && $f_auto_discover == 1 } {
set f_auto_discover 0
ACCESS::session data set "session.user.microsoft-autodiscover" 1
}
}
}
when ACCESS_ACL_ALLOWED {
if { [HTTP::header exists X-Client-Cert] } {
foreach field [HTTP::header value X-Client-Cert] {
if {$field contains "CN="} {
set name [string range $field [expr { [string first "=" $field ] + 1} ] end ]
HTTP::header remove username
HTTP::header replace username $name
}
}
}
}
when ACCESS_POLICY_COMPLETED {
if { ! [ info exists user_key ] } {
return
}
set policy_result [ACCESS::policy result]
switch $policy_result {
"allow" {
}
"deny" {
ACCESS::respond 401 content $static::actsync_401_http_body Connection close
ACCESS::session remove
}
default {
ACCESS::respond 503 content $static::actsync_503_http_body Connection close
ACCESS::session remove
}
}
unset user_key
}
}