public static byte[] GetAuthenticationData(TacacsAuthenticationService service, string user, SecureString password) { var userBuf = user.GetUserBuffer(); var authenticationHeader = new TacacsAuthenticationRequestHeader() { Action = TacacsAction.Login, PrivilegeLevel = 0x01, AuthenticationType = TacacsAuthenticationType.MsChap, Service = service, UserLength = ((byte)userBuf.Length), PortLength = ((byte)ClientPortName.Length), RemoteLength = 0x00, // optional -- excluded DataLength = 0x42 // 66 bytes }; var challenge = new byte[8]; Rng.GetBytes(challenge, 0, 8); var lmChallengeResponse = GetLmChallengeResponse(challenge, password); var ntChallengeResponse = GetNtChallengeResponse(challenge, password); // MS-CHAPv1 response (49 bytes) -- see RFC 2433 var challengeResponse = new byte[49]; Buffer.BlockCopy(lmChallengeResponse, 0, challengeResponse, 0, 24); Buffer.BlockCopy(ntChallengeResponse, 0, challengeResponse, 24, 24); Buffer.BlockCopy(new byte[] { 0x01 }, 0, challengeResponse, 48, 1); // ppp id var identifier = new byte[1]; Rng.GetBytes(identifier, 0, 1); // draft 18 -- 5.4.2.4 var data = new byte[66]; Buffer.BlockCopy(identifier, 0, data, 0, 1); Buffer.BlockCopy(challenge, 0, data, 1, 16); Buffer.BlockCopy(challengeResponse, 0, data, 17, 49); // tacacs data var authenticationDataLength = 8 /* header */ + userBuf.Length + ClientPortName.Length + 0 /* remote */ + 66 /* MsChapV2 length */; var authenticationData = new byte[authenticationDataLength]; var headerBuf = StructConverter.StructToBytes(authenticationHeader); Buffer.BlockCopy(headerBuf, 0, authenticationData, 0, 8); Buffer.BlockCopy(userBuf, 0, authenticationData, 8, userBuf.Length); Buffer.BlockCopy(ClientPortName, 0, authenticationData, 8 + userBuf.Length, ClientPortName.Length); Buffer.BlockCopy(data, 0, authenticationData, 8 + userBuf.Length + ClientPortName.Length, data.Length); return(authenticationData); }
public static byte[] GetAuthenticationPacket(TacacsAuthenticationType type, TacacsAuthenticationService service, string user, SecureString password, SecureString sharedSecret) { byte[] intBuf = { 0x00, 0x00, 0x00, 0x00 }; Rng.GetBytes(intBuf, 0, 4); var sessionId = BitConverter.ToInt32(intBuf, 0); var header = new TacacsHeader { Version = TacacsHeaderExtensions.VersionOne, Type = TacacsType.Authentication, SequenceNumber = 0x01, Flags = TacacsFlags.Encrypted, SessionId = sessionId, Length = 0 }; byte[] authenticationData; switch (type) { case TacacsAuthenticationType.Ascii: throw new NotSupportedException("ASCII authentication method not supported"); case TacacsAuthenticationType.Pap: throw new NotSupportedException("PAP authentication method not supported"); case TacacsAuthenticationType.Arap: throw new NotSupportedException("ARAP authentication method not supported"); case TacacsAuthenticationType.MsChap: throw new NotSupportedException("MS-CHAP authentication method not supported"); case TacacsAuthenticationType.Chap: authenticationData = Chap.GetAuthenticationData(service, user, password); break; case TacacsAuthenticationType.MsChapV2: authenticationData = MsChapV2.GetAuthenticationData(service, user, password); break; default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } return(CreatePacket(header, authenticationData, sharedSecret)); }
public static byte[] GetAuthenticationData(TacacsAuthenticationService service, string user, SecureString password) { var userBuf = user.GetUserBuffer(); var authenticationHeader = new TacacsAuthenticationRequestHeader() { Action = TacacsAction.Login, PrivilegeLevel = 0x01, AuthenticationType = TacacsAuthenticationType.Chap, Service = service, UserLength = ((byte)userBuf.Length), PortLength = ((byte)ClientPortName.Length), RemoteLength = 0x00, // optional -- excluded DataLength = 0x42 // 66 bytes -- big challenge }; var identifier = new byte[1]; Rng.GetBytes(identifier, 0, 1); //var challenge = new byte[49]; //Rng.GetBytes(challenge, 0, 32); var challenge = Encoding.ASCII.GetBytes("1234567890123456789012345678901234567890123456789"); var response = GetResponse(identifier, challenge, password); var data = new byte[1 /* identifier */ + 49 /* challenge */ + 16 /* response */]; Buffer.BlockCopy(identifier, 0, data, 0, 1); Buffer.BlockCopy(challenge, 0, data, 1, 49); Buffer.BlockCopy(response, 0, data, 50, 16); var authenticationDataLength = 8 /* header */ + userBuf.Length + ClientPortName.Length + 0 /* remote */ + 66 /* CHAP length */; var authenticationData = new byte[authenticationDataLength]; var headerBuf = StructConverter.StructToBytes(authenticationHeader); Buffer.BlockCopy(headerBuf, 0, authenticationData, 0, 8); Buffer.BlockCopy(userBuf, 0, authenticationData, 8, userBuf.Length); Buffer.BlockCopy(ClientPortName, 0, authenticationData, 8 + userBuf.Length, ClientPortName.Length); Buffer.BlockCopy(data, 0, authenticationData, 8 + userBuf.Length + ClientPortName.Length, data.Length); return(authenticationData); }
public bool Authenticate(TacacsAuthenticationType type, TacacsAuthenticationService service, string user, SecureString password) { if (string.IsNullOrEmpty(user)) { throw new ArgumentException("Must specify a valid user name", nameof(user)); } if (password == null) { throw new ArgumentException("Must specify a valid password", nameof(password)); } var requestPacket = TacacsPlusProtocol.GetAuthenticationPacket(type, service, user, password, _sharedSecret); var responsePacket = SendReceive(requestPacket); var responsePayload = ValidateResponseAndGetPayload(responsePacket); var authenticationReplyHeader = StructConverter.BytesToStruct <TacacsAuthenticationReplyHeader>(responsePayload); switch (authenticationReplyHeader.Status) { case TacacsAuthenticationStatus.Pass: return(true); case TacacsAuthenticationStatus.Fail: return(false); case TacacsAuthenticationStatus.Error: var serverMessage = Encoding.UTF8.GetString(responsePacket.Skip(6 /* Authentication Reply Header Size */) .Take(authenticationReplyHeader.ServerMessageLength).ToArray()); throw new Exception($"Server responded with an error: {serverMessage}"); default: throw new Exception($"Unexpected authentication status: {authenticationReplyHeader.Status}"); } }
public static byte[] GetAuthenticationData(TacacsAuthenticationService service, string user, SecureString password) { var userBuf = user.GetUserBuffer(); var authenticationHeader = new TacacsAuthenticationRequestHeader() { Action = TacacsAction.Login, PrivilegeLevel = 0x01, AuthenticationType = TacacsAuthenticationType.MsChapV2, Service = service, UserLength = ((byte)userBuf.Length), PortLength = ((byte)ClientPortName.Length), RemoteLength = 0x00, // optional -- excluded DataLength = 0x42 // 66 bytes }; var authenticatorChallenge = new byte[16]; var peerChallenge = new byte[16]; Rng.GetBytes(authenticatorChallenge, 0, 16); Rng.GetBytes(peerChallenge, 0, 16); // see RFC 2433 var challengeResponse = new byte[49]; // challenge -- 16 bytes Buffer.BlockCopy(peerChallenge, 0, challengeResponse, 0, 16); // reserved -- 8 bytes (zeroes) for (var i = 16; i < 24; i++) { Buffer.SetByte(challengeResponse, i, 0x00); } // NT-response -- 24 bytes var ntResponse = GetNtResponse(authenticatorChallenge, peerChallenge, userBuf, password); Buffer.BlockCopy(ntResponse, 0, challengeResponse, 24, 24); // flags -- 1 byte (zero) Buffer.SetByte(challengeResponse, 48, 0); var identifier = new byte[1]; Rng.GetBytes(identifier, 0, 1); // draft 18 -- 5.4.2.5 var data = new byte[66]; Buffer.BlockCopy(identifier, 0, data, 0, 1); Buffer.BlockCopy(authenticatorChallenge, 0, data, 1, 16); Buffer.BlockCopy(challengeResponse, 0, data, 17, 49); // tacacs data var authenticationDataLength = 8 /* header */ + userBuf.Length + ClientPortName.Length + 0 /* remote */ + 66 /* MsChapV2 length */; var authenticationData = new byte[authenticationDataLength]; var headerBuf = StructConverter.StructToBytes(authenticationHeader); Buffer.BlockCopy(headerBuf, 0, authenticationData, 0, 8); Buffer.BlockCopy(userBuf, 0, authenticationData, 8, userBuf.Length); Buffer.BlockCopy(ClientPortName, 0, authenticationData, 8 + userBuf.Length, ClientPortName.Length); Buffer.BlockCopy(data, 0, authenticationData, 8 + userBuf.Length + ClientPortName.Length, data.Length); return(authenticationData); }