mirror of
				https://github.com/esiur/esiur-dotnet.git
				synced 2025-11-04 01:11:35 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			383 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			383 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
 using Esiur.Data;
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Linq;
 | 
						|
using System.Security.Cryptography;
 | 
						|
using System.Text;
 | 
						|
using System.Threading.Tasks;
 | 
						|
 | 
						|
namespace Esiur.Net.Packets
 | 
						|
{
 | 
						|
    class IIPAuthPacket : Packet
 | 
						|
    {
 | 
						|
        public enum IIPAuthPacketCommand: byte
 | 
						|
        {
 | 
						|
            Action = 0,
 | 
						|
            Declare,
 | 
						|
            Acknowledge,
 | 
						|
            Error,
 | 
						|
        }
 | 
						|
 | 
						|
        public enum IIPAuthPacketAction: byte
 | 
						|
        {
 | 
						|
            // Authenticate
 | 
						|
            AuthenticateHash,
 | 
						|
 | 
						|
 | 
						|
            //Challenge,
 | 
						|
            //CertificateRequest,
 | 
						|
            //CertificateReply,
 | 
						|
            //EstablishRequest,
 | 
						|
            //EstablishReply
 | 
						|
 | 
						|
            NewConnection = 0x20,
 | 
						|
            ResumeConnection,
 | 
						|
 | 
						|
            ConnectionEstablished = 0x28
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        public enum IIPAuthPacketMethod: byte
 | 
						|
        {
 | 
						|
            None,
 | 
						|
            Certificate,
 | 
						|
            Credentials,
 | 
						|
            Token
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        public IIPAuthPacketCommand Command
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
        public IIPAuthPacketAction Action
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte ErrorCode { get; set; }
 | 
						|
        public string ErrorMessage { get; set; }
 | 
						|
 | 
						|
        public IIPAuthPacketMethod LocalMethod
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] SourceInfo
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] Hash
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] SessionId
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public IIPAuthPacketMethod RemoteMethod
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public string Domain
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public long CertificateId
 | 
						|
        {
 | 
						|
            get;set;
 | 
						|
        }
 | 
						|
 | 
						|
        public string LocalUsername
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public string RemoteUsername
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] LocalPassword
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
        public byte[] RemotePassword
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] LocalToken
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] RemoteToken
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] AsymetricEncryptionKey
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] LocalNonce
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        public byte[] RemoteNonce
 | 
						|
        {
 | 
						|
            get;
 | 
						|
            set;
 | 
						|
        }
 | 
						|
 | 
						|
        private uint dataLengthNeeded;
 | 
						|
 | 
						|
        bool NotEnough(uint offset, uint ends, uint needed)
 | 
						|
        {
 | 
						|
            if (offset + needed > ends)
 | 
						|
            {
 | 
						|
                dataLengthNeeded = needed - (ends - offset);
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
            else
 | 
						|
                return false;
 | 
						|
        }
 | 
						|
 | 
						|
        public override string ToString()
 | 
						|
        {
 | 
						|
            return Command.ToString() + " " + Action.ToString(); 
 | 
						|
        }
 | 
						|
 | 
						|
        public override long Parse(byte[] data, uint offset, uint ends)
 | 
						|
        {
 | 
						|
            var oOffset = offset;
 | 
						|
 | 
						|
            if (NotEnough(offset, ends, 1))
 | 
						|
                return -dataLengthNeeded;
 | 
						|
 | 
						|
            Command = (IIPAuthPacketCommand)(data[offset] >> 6);
 | 
						|
 | 
						|
            if (Command == IIPAuthPacketCommand.Action)
 | 
						|
            {
 | 
						|
                Action = (IIPAuthPacketAction)(data[offset++] & 0x3f);
 | 
						|
 | 
						|
                if (Action == IIPAuthPacketAction.AuthenticateHash)
 | 
						|
                {
 | 
						|
                    if (NotEnough(offset, ends, 32))
 | 
						|
                        return -dataLengthNeeded;
 | 
						|
 | 
						|
                    Hash = data.Clip(offset, 32);
 | 
						|
 | 
						|
                    //var hash = new byte[32];
 | 
						|
                    //Buffer.BlockCopy(data, (int)offset, hash, 0, 32);
 | 
						|
                    //Hash = hash;
 | 
						|
 | 
						|
                    offset += 32;
 | 
						|
                }
 | 
						|
                else if (Action == IIPAuthPacketAction.NewConnection)
 | 
						|
                {
 | 
						|
                    if (NotEnough(offset, ends, 2))
 | 
						|
                        return -dataLengthNeeded;
 | 
						|
 | 
						|
                    var length = data.GetUInt16(offset);
 | 
						|
 | 
						|
                    offset += 2;
 | 
						|
 | 
						|
                    if (NotEnough(offset, ends, length))
 | 
						|
                        return -dataLengthNeeded;
 | 
						|
 | 
						|
                    SourceInfo = data.Clip(offset, length);
 | 
						|
 | 
						|
                    //var sourceInfo = new byte[length];
 | 
						|
                    //Buffer.BlockCopy(data, (int)offset, sourceInfo, 0, length);
 | 
						|
                    //SourceInfo = sourceInfo;
 | 
						|
 | 
						|
                    offset += 32;
 | 
						|
                }
 | 
						|
                else if (Action == IIPAuthPacketAction.ResumeConnection
 | 
						|
                     || Action == IIPAuthPacketAction.ConnectionEstablished)
 | 
						|
                {
 | 
						|
                    //var sessionId = new byte[32];
 | 
						|
 | 
						|
                    if (NotEnough(offset, ends, 32))
 | 
						|
                        return -dataLengthNeeded;
 | 
						|
 | 
						|
                    SessionId = data.Clip(offset, 32);
 | 
						|
 | 
						|
                    //Buffer.BlockCopy(data, (int)offset, sessionId, 0, 32);
 | 
						|
                    //SessionId = sessionId;
 | 
						|
 | 
						|
                    offset += 32;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else if (Command == IIPAuthPacketCommand.Declare)
 | 
						|
            {
 | 
						|
                RemoteMethod = (IIPAuthPacketMethod)((data[offset] >> 4) & 0x3);
 | 
						|
                LocalMethod = (IIPAuthPacketMethod)((data[offset] >> 2) & 0x3);
 | 
						|
                var encrypt = ((data[offset++] & 0x2) == 0x2);
 | 
						|
 | 
						|
 | 
						|
                if (NotEnough(offset, ends, 1))
 | 
						|
                    return -dataLengthNeeded;
 | 
						|
 | 
						|
                var domainLength = data[offset++];
 | 
						|
                if (NotEnough(offset, ends, domainLength))
 | 
						|
                    return -dataLengthNeeded;
 | 
						|
 | 
						|
                var domain = data.GetString(offset, domainLength);
 | 
						|
 | 
						|
                Domain = domain;
 | 
						|
 | 
						|
                offset += domainLength;
 | 
						|
           
 | 
						|
 | 
						|
                if (RemoteMethod == IIPAuthPacketMethod.Credentials)
 | 
						|
                {
 | 
						|
                    if (LocalMethod == IIPAuthPacketMethod.None)
 | 
						|
                    {
 | 
						|
                        if (NotEnough(offset, ends, 33))
 | 
						|
                            return -dataLengthNeeded;
 | 
						|
 | 
						|
                        //var remoteNonce = new byte[32];
 | 
						|
                        //Buffer.BlockCopy(data, (int)offset, remoteNonce, 0, 32);
 | 
						|
                        //RemoteNonce = remoteNonce;
 | 
						|
 | 
						|
                        RemoteNonce = data.Clip(offset, 32);
 | 
						|
 | 
						|
                        offset += 32;
 | 
						|
                        
 | 
						|
                        var length = data[offset++];
 | 
						|
 | 
						|
                        if (NotEnough(offset, ends, length))
 | 
						|
                            return -dataLengthNeeded;
 | 
						|
 | 
						|
                         RemoteUsername = data.GetString(offset, length);
 | 
						|
 | 
						|
                         
 | 
						|
                        offset += length;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (encrypt)
 | 
						|
                {
 | 
						|
                    if (NotEnough(offset, ends, 2))
 | 
						|
                        return -dataLengthNeeded;
 | 
						|
 | 
						|
                    var keyLength = data.GetUInt16(offset);
 | 
						|
 | 
						|
                    offset += 2;
 | 
						|
 | 
						|
                    if (NotEnough(offset, ends, keyLength))
 | 
						|
                        return -dataLengthNeeded;
 | 
						|
 | 
						|
                    //var key = new byte[keyLength];
 | 
						|
                    //Buffer.BlockCopy(data, (int)offset, key, 0, keyLength);
 | 
						|
                    //AsymetricEncryptionKey = key;
 | 
						|
 | 
						|
                    AsymetricEncryptionKey = data.Clip(offset, keyLength);
 | 
						|
 | 
						|
                    offset += keyLength;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else if (Command == IIPAuthPacketCommand.Acknowledge)
 | 
						|
            {
 | 
						|
                RemoteMethod  = (IIPAuthPacketMethod)((data[offset] >> 4) & 0x3);
 | 
						|
                LocalMethod = (IIPAuthPacketMethod)((data[offset] >> 2) & 0x3);
 | 
						|
                var encrypt = ((data[offset++] & 0x2) == 0x2);
 | 
						|
 | 
						|
                if (NotEnough(offset, ends, 1))
 | 
						|
                    return -dataLengthNeeded;
 | 
						|
 
 | 
						|
    
 | 
						|
                if (RemoteMethod == IIPAuthPacketMethod.Credentials)
 | 
						|
                {
 | 
						|
                    if (LocalMethod == IIPAuthPacketMethod.None)
 | 
						|
                    {
 | 
						|
                        if (NotEnough(offset, ends, 32))
 | 
						|
                            return -dataLengthNeeded;
 | 
						|
 | 
						|
                        /*
 | 
						|
                        var remoteNonce = new byte[32];
 | 
						|
                        Buffer.BlockCopy(data, (int)offset, remoteNonce, 0, 32);
 | 
						|
                        RemoteNonce = remoteNonce;
 | 
						|
                        */
 | 
						|
 | 
						|
                        RemoteNonce = data.Clip(offset, 32);
 | 
						|
                        offset += 32;
 | 
						|
 | 
						|
                     }
 | 
						|
                }
 | 
						|
 | 
						|
                if (encrypt)
 | 
						|
                {
 | 
						|
                    if (NotEnough(offset, ends, 2))
 | 
						|
                        return -dataLengthNeeded;
 | 
						|
 | 
						|
                    var keyLength = data.GetUInt16(offset);
 | 
						|
 | 
						|
                    offset += 2;
 | 
						|
 | 
						|
                    if (NotEnough(offset, ends, keyLength))
 | 
						|
                        return -dataLengthNeeded;
 | 
						|
 | 
						|
                    //var key = new byte[keyLength];
 | 
						|
                    //Buffer.BlockCopy(data, (int)offset, key, 0, keyLength);
 | 
						|
                    //AsymetricEncryptionKey = key;
 | 
						|
 | 
						|
                    AsymetricEncryptionKey = data.Clip(offset, keyLength);
 | 
						|
 | 
						|
                    offset += keyLength;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else if (Command == IIPAuthPacketCommand.Error)
 | 
						|
            {
 | 
						|
                if (NotEnough(offset, ends, 4))
 | 
						|
                    return -dataLengthNeeded;
 | 
						|
 | 
						|
                offset++;
 | 
						|
                ErrorCode = data[offset++];
 | 
						|
 | 
						|
 
 | 
						|
                var cl = data.GetUInt16(offset);
 | 
						|
                offset += 2;
 | 
						|
 | 
						|
                if (NotEnough(offset, ends, cl))
 | 
						|
                    return -dataLengthNeeded;
 | 
						|
 | 
						|
                ErrorMessage = data.GetString(offset, cl);
 | 
						|
                offset += cl;
 | 
						|
 | 
						|
            }
 | 
						|
 | 
						|
 | 
						|
            return offset - oOffset;
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
 }
 |