Пример #1
0
        /// <summary>
        ///Verifies a CHAP password against the given plaintext password.
        ///@return plain-text password
        /// </summary>
        private bool VerifyChapPassword(String plaintext)
        {
            if (string.IsNullOrEmpty(plaintext))
            {
                throw new ArgumentException("plaintext must not be empty");
            }
            if (chapChallenge == null || chapChallenge.Length != 16)
            {
                throw new RadiusException("CHAP challenge must be 16 bytes");
            }
            if (chapPassword == null || chapPassword.Length != 17)
            {
                throw new RadiusException("CHAP password must be 17 bytes");
            }

            byte chapIdentifier = chapPassword[0];

            var byteAry = new List <byte> {
                chapIdentifier
            };

            byteAry.AddRange(RadiusUtil.GetUtf8Bytes(plaintext));
            byte[] chapHash = MD5.Create().ComputeHash(chapChallenge);

            // compar
            for (var i = 0; i < 16; i++)
            {
                if (chapHash[i] != chapPassword[i + 1])
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #2
0
        /// <summary>
        ///Sets and encrypts the User-Password attribute.
        ///@see TinyRadius.packet.RadiusPacket#encodeRequestAttributes(java.lang.String)
        /// </summary>
        protected override void EncodeRequestAttributes(String sharedSecret)
        {
            if (string.IsNullOrEmpty(password))
            {
                return;
            }
            // ok for proxied packets whose CHAP password is already encrypted
            //throw new NotImplementedException("no password set");

            if (AuthProtocol.Equals(AuthenticationType.pap))
            {
                byte[] pass = EncodePapPassword(RadiusUtil.GetUtf8Bytes(password), RadiusUtil.GetUtf8Bytes(sharedSecret));
                RemoveAttributes(USER_PASSWORD);
                AddAttribute(new RadiusAttribute(USER_PASSWORD, pass));
            }
            else if (AuthProtocol.Equals(AuthenticationType.chap))
            {
                byte[] challenge = CreateChapChallenge();
                byte[] pass      = EncodeChapPassword(password, challenge);
                RemoveAttributes(CHAP_PASSWORD);
                RemoveAttributes(CHAP_CHALLENGE);
                AddAttribute(new RadiusAttribute(CHAP_PASSWORD, pass));
                AddAttribute(new RadiusAttribute(CHAP_CHALLENGE, challenge));
            }
        }
Пример #3
0
        /// <summary>
        ///Decrypts the User-Password attribute.
        /// </summary>
        protected override void DecodeRequestAttributes(String sharedSecret)
        {
            // detect auth protocol
            RadiusAttribute userPassword  = GetAttribute(USER_PASSWORD);
            RadiusAttribute chapPassword  = GetAttribute(CHAP_PASSWORD);
            RadiusAttribute chapChallenge = GetAttribute(CHAP_CHALLENGE);

            if (userPassword != null)
            {
                AuthProtocol = AuthenticationType.pap;
                password     = DecodePapPassword(userPassword.Data, RadiusUtil.GetUtf8Bytes(sharedSecret));
                // copy truncated data
                userPassword.Data = RadiusUtil.GetUtf8Bytes(password);
            }
            else if (chapPassword != null && chapChallenge != null)
            {
                AuthProtocol       = AuthenticationType.chap;
                this.chapPassword  = chapPassword.Data;
                this.chapChallenge = chapChallenge.Data;
            }
            else
            {
                throw new RadiusException("Access-Request: User-Password or CHAP-Password/CHAP-Challenge missing");
            }
        }
Пример #4
0
        /**
         * @see AccountingRequest#updateRequestAuthenticator(String, int, byte[])
         */

        protected override byte[] UpdateRequestAuthenticator(String sharedSecret,
                                                             int packetLength, byte[] attributes)
        {
            var authenticator = new byte[16];

            /*for (int i = 0; i < 16; i++)
             *  authenticator[i] = 0;*/


            var ms = new List <byte>
            {
                Convert.ToByte(Type),
                Convert.ToByte(Identifier),
                Convert.ToByte(packetLength >> 8),
                Convert.ToByte(packetLength & 0xff)
            };

            ms.AddRange(authenticator);
            ms.AddRange(attributes);
            ms.AddRange(RadiusUtil.GetUtf8Bytes(sharedSecret));

            return(MD5.Create().ComputeHash(ms.ToArray()));

            /*MessageDigest md5 = getMd5Digest();
             * md5.reset();
             * md5.update((byte)getPacketType());
             * md5.update((byte)getPacketIdentifier());
             * md5.update((byte)(packetLength >> 8));
             * md5.update((byte)(packetLength & 0xff));
             * md5.update(authenticator, 0, authenticator.Length);
             * md5.update(attributes, 0, attributes.Length);
             * md5.update(RadiusUtil.getUtf8Bytes(sharedSecret));
             * return md5.digest();*/
        }
Пример #5
0
        /// <summary>
        ///  Creates a request authenticator for this packet. This request authenticator
        ///  is constructed as described in RFC 2865.
        ///  @param sharedSecret shared secret that secures the communication
        ///  with the other Radius server/client
        ///  @return request authenticator, 16 bytes
        /// </summary>
        protected virtual byte[] CreateRequestAuthenticator(String sharedSecret)
        {
            byte[] secretBytes = RadiusUtil.GetUtf8Bytes(sharedSecret);

            var randomBytes = new byte[16];

            Random.NextBytes(randomBytes);

            var md5Bytes = new byte[secretBytes.Length + 16];

            Array.Copy(secretBytes, 0, md5Bytes, 0, secretBytes.Length);
            Array.Copy(randomBytes, 0, md5Bytes, secretBytes.Length, 16);
            return(MD5.Create().ComputeHash(md5Bytes));
        }
Пример #6
0
        /// <summary>
        ///  Creates an authenticator for a Radius response packet.
        ///  @param sharedSecret shared secret
        ///  @param packetLength Length of response packet
        ///  @param attributes encoded attributes of response packet
        ///  @param requestAuthenticator request packet authenticator
        ///  @return new 16 byte response authenticator
        /// </summary>
        protected virtual byte[] CreateResponseAuthenticator(String sharedSecret, int packetLength, byte[] attributes,
                                                             byte[] requestAuthenticator)
        {
            var bytes = new List <byte>
            {
                Convert.ToByte(Type),
                Convert.ToByte(Identifier),
                Convert.ToByte(packetLength >> 8),
                Convert.ToByte(packetLength & 0x0ff)
            };

            bytes.AddRange(requestAuthenticator);
            bytes.AddRange(attributes); //bug fix from [email protected]
            bytes.AddRange(RadiusUtil.GetUtf8Bytes(sharedSecret));

            return(MD5.Create().ComputeHash(bytes.ToArray()));
        }
Пример #7
0
        /// <summary>
        ///Decodes the passed encrypted password and returns the clear-text form.
        ///@param encryptedPass encrypted password
        ///@param sharedSecret shared secret
        ///@return decrypted password
        /// </summary>
        private String DecodePapPassword(byte[] encryptedPass, byte[] sharedSecret)
        {
            if (encryptedPass == null || encryptedPass.Length < 16)
            {
                // PAP passwords require at least 16 bytes
                logger.Warn("invalid Radius packet: User-Password attribute with malformed PAP password, Length = " +
                            (encryptedPass != null ? encryptedPass.Length : 0) + ", but Length must be greater than 15");
                throw new RadiusException("malformed User-Password attribute");
            }

            var byteAry   = new List <byte>();
            var lastBlock = new byte[16];
            MD5 md5       = MD5.Create();

            for (int i = 0; i < encryptedPass.Length; i += 16)
            {
                byteAry.Clear();
                byteAry.AddRange(sharedSecret);
                byteAry.AddRange(i == 0 ? Authenticator : lastBlock);
                byte[] bn = md5.ComputeHash(byteAry.ToArray());

                Array.Copy(encryptedPass, i, lastBlock, 0, 16);

                // perform the XOR as specified by RFC 2865.
                for (int j = 0; j < 16; j++)
                {
                    encryptedPass[i + j] = (byte)(bn[j] ^ encryptedPass[i + j]);
                }
            }

            // remove trailing zeros
            int len = encryptedPass.Length;

            while (len > 0 && encryptedPass[len - 1] == 0)
            {
                len--;
            }
            var passtrunc = new byte[len];

            Array.Copy(encryptedPass, 0, passtrunc, 0, len);

            // convert to string
            return(RadiusUtil.GetStringFromUtf8(passtrunc));
        }
Пример #8
0
        /// <summary>
        ///Encodes a plain-text password using the given CHAP challenge.
        ///@param plaintext plain-text password
        ///@param chapChallenge CHAP challenge
        ///@return CHAP-encoded password
        /// </summary>
        private byte[] EncodeChapPassword(String plaintext, byte[] chapChallenge)
        {
            // see RFC 2865 section 2.2
            var chapIdentifier = (byte)random.Next(256);
            var chapPassword   = new byte[17];

            chapPassword[0] = chapIdentifier;

            MD5 md5     = MD5.Create();
            var aryList = new List <byte>();

            aryList.Add(chapIdentifier);
            aryList.AddRange(RadiusUtil.GetUtf8Bytes(plaintext));
            aryList.AddRange(chapChallenge);
            byte[] chapHash = md5.ComputeHash(aryList.ToArray());

            Array.Copy(chapHash, 0, chapPassword, 1, 16);
            return(chapPassword);
        }
Пример #9
0
        /// <summary>
        /// Calculates the request authenticator as specified by RFC 2866.
        /// @see TinyRadius.packet.RadiusPacket#updateRequestAuthenticator(java.lang.String, int, byte[])
        /// </summary>
        protected override byte[] UpdateRequestAuthenticator(String sharedSecret, int packetLength, byte[] attributes)
        {
            var authenticator = new byte[16];

            for (int i = 0; i < 16; i++)
            {
                authenticator[i] = 0;
            }

            var bytes = new List <byte>
            {
                (byte)Type,
                (byte)Identifier,
                (byte)(packetLength >> 8),
                (byte)(packetLength & 0xff)
            };

            bytes.AddRange(authenticator);
            bytes.AddRange(attributes);
            bytes.AddRange(RadiusUtil.GetUtf8Bytes(sharedSecret));
            return(MD5.Create().ComputeHash(bytes.ToArray()));
        }