/* Copyright © 2002, The KPD-Team All rights reserved. http://www.mentalis.org/ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Neither the name of the KPD-Team, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Text; using System.Security.Cryptography; using System.Collections; using System.Collections.Specialized; namespace Org.Mentalis.Proxy.Socks.Authentication { ///Stores a dictionary with username/password combinations. ///This class can be used by a SOCKS5 listener. ///This class uses an MD5 has to store the passwords in a secure manner. ///The username is treated in a case-insensitive manner, the password is treated case-sensitive. public class AuthenticationList { ///Initializes a new instance of the AuthenticationList class. public AuthenticationList() {} ///Adds an item to the list. ///The username to add. ///The corresponding password to add. ///Either Username or Password is null. public void AddItem(string Username, string Password) { if (Password == null) throw new ArgumentNullException(); AddHash(Username, Convert.ToBase64String(new MD5CryptoServiceProvider().ComputeHash(Encoding.ASCII.GetBytes(Password)))); } ///Adds an item to the list. ///The username to add. ///The hashed password to add. ///Either Username or Password is null. public void AddHash(string Username, string PassHash) { if (Username == null || PassHash == null) throw new ArgumentNullException(); if (Listing.ContainsKey(Username)) { Listing[Username] = PassHash; } else { Listing.Add(Username, PassHash); } } ///Removes an item from the list. ///The username to remove. ///Username is null. public void RemoveItem(string Username) { if (Username == null) throw new ArgumentNullException(); Listing.Remove(Username); } ///Checks whether a user/pass combination is present in the collection or not. ///The username to search for. ///The corresponding password to search for. ///True when the user/pass combination is present in the collection, false otherwise. public bool IsItemPresent(string Username, string Password) { return IsHashPresent(Username, Convert.ToBase64String(new MD5CryptoServiceProvider().ComputeHash(Encoding.ASCII.GetBytes(Password)))); } ///Checks whether a username is present in the collection or not. ///The username to search for. ///True when the username is present in the collection, false otherwise. public bool IsUserPresent(string Username) { return Listing.ContainsKey(Username); } ///Checks whether a user/passhash combination is present in the collection or not. ///The username to search for. ///The corresponding password hash to search for. ///True when the user/passhash combination is present in the collection, false otherwise. public bool IsHashPresent(string Username, string PassHash) { return Listing.ContainsKey(Username) && Listing[Username].Equals(PassHash); } ///Gets the StringDictionary that's used to store the user/pass combinations. ///A StringDictionary object that's used to store the user/pass combinations. protected StringDictionary Listing { get { return m_Listing; } } ///Gets an array with all the keys in the authentication list. ///An array of strings containing all the keys in the authentication list. public string[] Keys { get { ICollection keys = Listing.Keys; string [] ret = new string[keys.Count]; keys.CopyTo(ret, 0); return ret; } } ///Gets an array with all the hashes in the authentication list. ///An array of strings containing all the hashes in the authentication list. public string[] Hashes { get { ICollection values = Listing.Values; string [] ret = new string[values.Count]; values.CopyTo(ret, 0); return ret; } } ///Clears the authentication list. public void Clear() { Listing.Clear(); } // private variables /// Holds the value of the Listing property. private StringDictionary m_Listing = new StringDictionary(); } }