public ErrorCodes Authorize(SipMessageReader reader, ArraySegment <byte> content, AuthenticationKind kind) { //if (state.Message.Reader.Count.AuthorizationCount > 0) // return ErrorCodes.NoResponse; // User-Agent: X-Lite release 1104o stamp 56125 // It use old Authorization header from INVITE request to ACK request: // 1. Do NOT increment nc // 2. Uses INVITE method for response calculation // User-Agent: 3CXPhone 5.0.14900.0 // Look like X-Lite clone -> disable auth for all ACK if (reader.CSeq.Method == Methods.Ackm) // && reader.UserAgent.IsXLite) { return(ErrorCodes.Ok); } IAccount account; var credentials = FindCredentials(reader, out account); // User-Agent: NCH Software Express Talk 4.15 // Quotes message-qop value, qop="auth" //if (credentials.MessageQop.IsInvalid && reader.UserAgent.IsNch) // credentials.MessageQop = ResponseCalculator.Auth; if (credentials.AuthScheme != AuthSchemes.Digest) { return(ErrorCodes.NoResponse); } if (credentials.AuthAlgorithm == AuthAlgorithms.Other) { return(ErrorCodes.NotSupportedAuthAlgorithm); } if (credentials.Username.IsInvalid) { return(ErrorCodes.UsernmaeNotFound); } if (credentials.Username.Equals(reader.From.AddrSpec.User) == false) { return(ErrorCodes.UsernamesNotMatch); } if (credentials.Realm.IsInvalid) { return(ErrorCodes.RealmNotFound); } if (credentials.Nonce.IsInvalid) { return(ErrorCodes.NonceNotFound); } if (credentials.MessageQop.IsValid) { if (credentials.Cnonce.IsInvalid) { return(ErrorCodes.CnonceNotFound); } } if (credentials.DigestUri.IsInvalid) { return(ErrorCodes.DigestUriNotFound); } if (credentials.Response.IsInvalid) { return(ErrorCodes.ResponseNotFound); } //if (credentials.Realm.Equals(realm1) == false) // return ErrorCodes.InvalidRealm; if (credentials.Nonce.Length != 32) { return(ErrorCodes.NonceInvalid); } Nonce nonce; if (Nonce.TryParse(credentials.Nonce.Bytes, credentials.Nonce.Begin, out nonce) == false) { return(ErrorCodes.FailedToParseNonce); } int opaque = nonce.DecodeOpaque(); AuthState state; if (authStates.TryGetValue(opaque, out state) == false) { return(ErrorCodes.AuthStateNotFound); } if (state.Nonce.IsEqualValue(nonce) == false) { return(ErrorCodes.NonceStale); } if (state.NonceCount >= credentials.NonceCount && state.IsNonceCountExpected) { return(ErrorCodes.NonceCountExpected); } var password = GetPassword(account.Id, credentials.Username); if (password == null) { return(ErrorCodes.FailedToRetriveUserPassword); } if (responseCalculator == null) { responseCalculator = new ResponseCalculator(); } //var responseCalculator = base.GetResponseCalculator(); if (reader.Method == Methods.Extension || reader.Method == Methods.None) // нужно исправить!!!!!!!!!!!!!!!!!!! { return(ErrorCodes.NotSupportedAuthAlgorithm); } //if (responseCalculator.IsResponseValid(credentials, reader.Method.ToByteArrayPart(), content, password.ToByteArrayPart()) == false) // return ErrorCodes.WrongResponse; var response = responseCalculator.GetResponseHexChars( credentials.Username, credentials.Realm, credentials.AuthAlgorithm == AuthAlgorithms.Md5Sess, credentials.Nonce, credentials.Cnonce, credentials.MessageQop, credentials.DigestUri, credentials.NonceCountBytes, reader.Method.ToByteArrayPart(), content, password.ToByteArrayPart()); if (credentials.Response.Equals(response) == false) { return(ErrorCodes.WrongResponse); } state.NonceCount = credentials.NonceCount; state.LastAccess = unchecked (Environment.TickCount - 10000); authStates.Replace(state.Opaque, state); return(ErrorCodes.Ok); }
public ErrorCodes IsAuthorizedInternal(ISheduler sheduler, ShedulerState shedulerState, AuthenticationKind kind) { var reader = shedulerState.Reader; var content = shedulerState.Content; IAccount account; var credentials = FindCredentials(reader, out account); if (credentials.AuthScheme != AuthSchemes.Digest) { return(ErrorCodes.NoResponse); } if (credentials.AuthAlgorithm == AuthAlgorithms.Other) { return(ErrorCodes.NotSupportedAuthAlgorithm); } if (credentials.Realm.IsInvalid) { return(ErrorCodes.RealmNotFound); } if (credentials.Realm.Equals(shedulerState.Realm) == false) { return(ErrorCodes.InvalidRealm); } if (credentials.Nonce.IsInvalid) { return(ErrorCodes.NonceNotFound); } if (credentials.MessageQop.IsValid) { if (credentials.Cnonce.IsInvalid) { return(ErrorCodes.CnonceNotFound); } } if (credentials.DigestUri.IsInvalid) { return(ErrorCodes.DigestUriNotFound); } if (credentials.Response.IsInvalid) { return(ErrorCodes.ResponseNotFound); } if (credentials.Nonce.Length != 32) { return(ErrorCodes.NonceInvalid); } if (credentials.Username.IsInvalid) { return(ErrorCodes.UsernmaeNotFound); } if (sheduler.ValidateAuthorization(reader, credentials.Username, shedulerState.Param) == false) { return(ErrorCodes.NotAuthorized); } Nonce nonce; if (Nonce.TryParse(credentials.Nonce.Bytes, credentials.Nonce.Begin, out nonce) == false) { return(ErrorCodes.FailedToParseNonce); } int opaque = nonce.DecodeOpaque(); AuthState state; if (authStates.TryGetValue(opaque, out state) == false) { return(ErrorCodes.AuthStateNotFound); } if (state.Nonce.IsEqualValue(nonce) == false) { return(ErrorCodes.NonceStale); } if (state.NonceCount >= credentials.NonceCount && state.IsNonceCountExpected) { return(ErrorCodes.NonceCountExpected); } var password = GetPassword(account.Id, credentials.Username); if (password == null) { return(ErrorCodes.FailedToRetriveUserPassword); } if (responseCalculator == null) { responseCalculator = new ResponseCalculator(); } var response = responseCalculator.GetResponseHexChars( credentials.Username, credentials.Realm, credentials.AuthAlgorithm == AuthAlgorithms.Md5Sess, credentials.Nonce, credentials.Cnonce, credentials.MessageQop, credentials.DigestUri, credentials.NonceCountBytes, reader.MethodBytes, content, new ByteArrayPart(password)); if (credentials.Response.Equals(response) == false) { return(ErrorCodes.WrongResponse); } state.NonceCount = credentials.NonceCount; state.LastAccess = unchecked (Environment.TickCount - 10000); authStates.Replace(state.Opaque, state); return(ErrorCodes.Ok); }