예제 #1
0
        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);
        }
예제 #2
0
        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));
        }
예제 #3
0
        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);
        }
예제 #4
0
        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}");
            }
        }
예제 #5
0
        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);
        }