/// <summary> /// MagicJack apply a custom algorithm when calculating their nonce seemingly in order to /// prevent other SIP UAs from being able to authenticate. This method attempts to apply the same /// algorithm to allow the authenticated requests from this stack. /// </summary> /// <remarks> /// MJ is modifying the nonce dynamically. They append an underscore, then 8 characters to the nonce before computing the MD5. The 8 characters come from the call id. /// Use the first 8 bytes of the nonce as an index into your call id. /// Assume your callid is: /// callid: 9876ABC56738DD43... /// index: 0123456789ABCDEF /// and your nonce is: 8765abc4_32190 /// Take the first digit of your nonce (which in our example is 8 ), and find the value in the callid at index 8, which is 6. /// So, append that to the nonce. 8765abc4_32190_6 /// Then move on to the second digit of the nonce, which is 7 in our example. Find the value at index 7 in the callid, which is 5, and append that: /// 8765abc4_32190_65 continue until you have done 8 digits. Your new nonce would be: /// 8765abc4_32190_65CB38DA Use this value when computing the MD5, but pass the original nonce to magicJack. /// </remarks> /// <param name="authReqdResponse"></param> /// <returns></returns> public static SIPAuthenticationHeader GetAuthenticationHeader(SIPResponse authReqdResponse) { try { SIPAuthenticationHeader mjAuthHeader = new SIPAuthenticationHeader(authReqdResponse.Header.AuthenticationHeader.SIPDigest); string origNonce = mjAuthHeader.SIPDigest.Nonce; string mjNonce = GetNonce(origNonce, authReqdResponse.Header.CallId); mjAuthHeader.SIPDigest.Nonce = mjNonce; mjAuthHeader.SIPDigest.Response = mjAuthHeader.SIPDigest.Digest; mjAuthHeader.SIPDigest.Nonce = origNonce; return mjAuthHeader; } catch (Exception excp) { logger.Error("Exception SIPProviderMagicJack GetAuthenticationHeader. " + excp.Message); throw; } }
public static SIPAuthenticationHeader ParseSIPAuthenticationHeader(SIPAuthorisationHeadersEnum authorizationType, string headerValue) { try { SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(); authHeader.SIPDigest = SIPAuthorisationDigest.ParseAuthorisationDigest(authorizationType, headerValue); return authHeader; } catch { throw new ApplicationException("Error parsing SIP authentication header request, " + headerValue); } }
private SIPResponse GetAuthReqdResponse(SIPRequest sipRequest, string nonce, string realm) { try { SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Unauthorised, null); SIPAuthenticationHeader authHeader = new SIPAuthenticationHeader(SIPAuthorisationHeadersEnum.WWWAuthenticate, realm, nonce); SIPHeader requestHeader = sipRequest.Header; SIPHeader unauthHeader = new SIPHeader(requestHeader.Contact, requestHeader.From, requestHeader.To, requestHeader.CSeq, requestHeader.CallId); if (unauthHeader.To.ToTag == null || unauthHeader.To.ToTag.Trim().Length == 0) { unauthHeader.To.ToTag = CallProperties.CreateNewTag(); } unauthHeader.CSeqMethod = requestHeader.CSeqMethod; unauthHeader.Vias = requestHeader.Vias; unauthHeader.AuthenticationHeader = authHeader; unauthHeader.Server = m_serverAgent; unauthHeader.MaxForwards = Int32.MinValue; authReqdResponse.Header = unauthHeader; return authReqdResponse; } catch (Exception excp) { logger.Error("Exception GetAuthReqdResponse. " + excp.Message); throw excp; } }
public SIPRequestAuthenticationResult(SIPResponseStatusCodesEnum errorResponse, SIPAuthenticationHeader authenticationRequiredHeader) { Authenticated = false; ErrorResponse = errorResponse; AuthenticationRequiredHeader = authenticationRequiredHeader; }