Symptom: a Lync user who is registered in a Lync Survivable Branch Appliance (SBA) or Survivable Branch Server (SBS) dials an UCMA application endpoint which is behind a standalone Lync Front-End Server or a Front-End Server pool. The call is established successfully but subsequent transfer request initiated by the UCMA application fails with error code “403 Forbidden”.
The following sections describe what is happening in the background and how to solve this issue.
What is happening in the background?
It is assumed that an audio call is already established between an SBA/SBS registered Lync user (Lync User A in the picture below) and a UCMA application endpoint registered in a Lync Front End pool or standalone Front-End server. This initial stage is indicated by Step 1 in the picture below. It does not matter who initiated the call originally. The only important thing is that the call is in Established state and the UCMA application tries to transfer the call to a target which can be another Lync user or a PSTN number it does not matter. The picture below indicates the transfer target as Lync User B.
As the picture indicates, the following happens on the signaling level when UCMA application performs an attended transfer (tries to transfer Lync User A to Lync User B):
Step 2: The UCMA stack constructs a SIP REFER message when the UCMA application invokes the Call.BeginTransfer() method. This REFER message looks like this:
REFER sip:email@example.com;opaque=user:epid:Gnzkenucf1uGNpNe_DWJRQAA;gruu SIP/2.0
CSEQ: 1 REFER
REFERRED-BY: <sip:firstname.lastname@example.org>;ms-identity="MIIBrwYJKoZIhvcNAQcCoIIBoDCCAZwCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAXswggF3AgEBMFQwRjETMBEGCgmSJomT8ixkARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB3NiYXRlc3QxFjAUBgNVBAMTDXNiYXRlc3QtREMtQ0ECChpO+i8AAAAAAAYwCQYFKw4DAhoFADANBgkqhkiG9w0BAQEFAASCAQB/1kkxLRiBRzti6LfacdXtLq/xSiaubuxH7hQmR/eiOfDTzwk8viphTs8Hfk3B6HRKsBptRbcTTZH4y2x+NvKTjk83YFVSUqeexawk4EE0X5o+2wUA1lPgORsTZzJgJq5vG8CNFdv1fL4/4QnGFBoZF86l6ARXqr32xAsuRzWTTwkZGcv+vx5qD0LwPmapFvgEFMQbcctfUkfY33dArZnB7VCCmJhattT8ETE5ZKMuTuxGm90dSg7c7kEMXyX87j04xb00kBMsANhVqYTS//F1UdJ2QMsZa5E1jG523ztP96bVzD7mp9eVpMk4zLLaS5eORRBeR/nNu8X4M6pSv2I3:Sat, 18 May 2013 22:27:41 GMT";ms-identity-info="sip:appsrv.sbatest.com:9000;transport=Tls";ms-identity-alg=rsa-sha1
Among others, this REFER message includes REFERRED-TO and REFERRED-BY headers. The REFERRED-TO header includes the transfer target URI, the REFERRED-BY header includes the UCMA application endpoint URI plus the following additional tags:
- ms-identity: this tag includes the digital signature calculated over the TO, REFERRED-TO and REFERRED-BY headers (this signature is to defend against subsequent malicious actions, see Step 6 later)
- ms-identity-info: this tag specifies the peer (server FQDN + port) who created the digital signature. Which is the UCMA application in our case.
- ms-identity-alg: this tag specifies the algorithm used to calculate the digital signature
The UCMA application sends this REFER message to the Front-End server the application endpoint is connected to. Moreover, it subscribes (SUBSRIBE) to transfer related events in order to be notified (NOTIFY) about the transfer outcome.
Step 3: The Front-End Server sends the REFER message to the SBA/SBS the transferee is registered in.
Step 4: SBA/SBS sends the REFER message to the transferee.
Step 5: As part of the attended transfer, the transferee initiates a call (INVITE) to the transfer target. The INVITE message is constructed in a way that it includes transfer target URI in the TO header (it comes from the REFERRED-TO header of the original REFER message) and it includes the same REFERRED-BY header received in the original REFER message. This INVITE message is sent by the transferee to the SBA/SBS.
Step 6: Now things become interesting …. Before the SBA/SBS performs the call (forwards the INVITE) it tries to validate the digital signature found in the REFERRED-BY header. To do that it takes the ms-identity-info tag and sets up an MTLS connection to the FQDN and port included. Which is the UCMA application server FQDN and UCMA application port in our case. Based on the host certificate it receives from the UCMA application server during MTLS negotiation it verifies the digital signature included in the ms-identity tags and checks that the TO and REFERRED-BY headers in the INVITE message are set correctly.
Moreover, it tries to negotiate some parameters with the UCMA application by exchanging SIP NEGOTIATE messages.
Step 7: If the previous step fails then the SBA/SBS sends a SIP “403 Forbidden” error response back to the transferee and the entire transfer process fails. The transferee notifies the UCMA application about the failed transfer through the event subscription the UCMA application initiated at the time the transfer was initiated.
As the outcome of the failed attended transfer request you can find the following error messages in the SBA/SBS server log:
“The identity of the referrer could not be verified with the ms-identity information”
reason="Failed to establish a connection to the signing server";signer="[UCMA application server FQDN]"
and you can find a subsequent SIP “403 Forbidden” error message. This 403 error message also appears in the Lync User A’s Lync log file. UCMA stack raises FailureRequestException exception when application invokes Call.EndTransfer().
Now the only question is why Step 6 fails …
Reason and Solution
Step 6 fails most probably because your application did not specify the SBA/SBS as a trusted domain when CollaborationPlatform has been set up. You need to do the followings:
- Specify the SBA/SBS FQDN as trusted domain
CollaborationPlatform.AddTrustedDomain(new TrustedDomain(“[SBA/SBS FQDN]”, TrustedDomainMode.CommunicationsServer));
Please note that you can specify entire AD domains as trusted domains. See the API documentation for more details.
- If you want to know which devices initiate MTLS connection to your UCMA application port then you can subscribe to the platform’s ConnectionAuthorizationRequested event and accept MTLS connection requests as you want.
platform.ConnectionAuthorizationRequested += OnConnectionAuthorizationRequested;
private static void OnConnectionAuthorizationRequested(object sender, ConnectionAuthorizationRequestedEventArgs e)
logger.Info("Accepting MTLS connection from a peer presenting certificate with subject: " + e.Connection.RemoteCertificate.Subject);
Please note that you always need to perform the first step (add trusted domains) since ConnectionAuthorizationRequested event is raised only if the peer who initiates the MTLS connection belongs to a trusted domain.
I think this MTLS connection authorization procedure and the fact that Lync SBA/SBS devices are not trusted by default is one of the worst design decisions I have met during my multi-years UCMA journey. This forces application developers to deal with the underlying Lync topology. Even just to perform a transfer successfully … In my personal opinion, no application developer wants to deal with the underlying topology and whether SBA/SBS is involved in the signalling path. They just want a transfer request to be performed if they issue one. They expect this regardless the actual Lync topology. If a server is already added by Lync administrators to the Lync topology then that server should be trusted.
The current MTLS connection authorization procedure just results in the following: developers will specify entire AD domains as TrustedDomain because they do not want to face with failed transfer requests and dropped calls just because somebody added/removed SBA or changed SBA FQDN. And this behavior actually kills the original purpose why the authorization procedure and the ConnectionAuthorizationRequested event was introduced.