Пример #1
0
 public void Send(OSCARUdp self, ref FLAPHeader f)
 {
     var tlvs = new TLVChain(2)
     {
         new TLV { TypeID = SvcLayer.TLV_TYPE, Value = new byte[1] { SvcLayer.TYPE_CONNECT_REQST }},
         new TLV{TypeID = SvcLayer.TLV_CONNECT_HASH, Value = Hash }
     };
     self.queuePacket(ref self.m_svcFlap, (byte[])tlvs, Host);
     AttemptsTaken++;
     LastSent = Environment.TickCount;
 }
Пример #2
0
        private void HandlePacket(ref FLAPHeader flap, byte[] data, IPEndPoint from)
        {
            var tlvs = (TLVChain)data;
            var type = tlvs[SvcLayer.TLV_TYPE].Value[0];
            switch(type)
            {
                case SvcLayer.TYPE_USER_DATA:
                    if (Connections.Contains(from))
                        m_events.TriggerPacketReceived(this, new PacketEventArgs(from, ref flap, tlvs[SvcLayer.TLV_USER_DATA].Value));
                    break;

                case SvcLayer.TYPE_CONNECT_ACCEPT:
                    if (IsConnecting
                        && m_connReq.Host.Equals(from)
                        && Misc.CompareByteArrays(m_connReq.Hash, tlvs[SvcLayer.TLV_CONNECT_HASH].Value))
                    {
                        m_connReq = null;
                        Connections.Add(from);
                        m_events.Connected(this, new HostConnectEventArgs(from, true));
                    }
                    break;

                case SvcLayer.TYPE_CONNECT_REQST:
                    if (m_acceptsIncomingConnections
                        && (!this.IsConnecting || m_connReq.Host != from)
                        && m_events.AuthorizeIncomingConnection(this, new HostEventArgs(from))
                        && !this.Connections.Contains(from))
                    {
                        var tosend = new TLVChain(2)
                        {
                            new TLV { TypeID = SvcLayer.TLV_TYPE, Value = new byte[1] { SvcLayer.TYPE_CONNECT_ACCEPT } },
                            new TLV { TypeID = SvcLayer.TLV_CONNECT_HASH, Value = tlvs[SvcLayer.TLV_CONNECT_HASH].Value }
                        };
                        sendPacket(from, ref flap, (byte[])tosend);

                        Connections.Add(from);
                        m_events.Connected(this, new HostConnectEventArgs(from, false));
                    }
                    break;
            }
        }
Пример #3
0
        /// <summary>
        /// Выполняет попытку входа в сеть ICQ.
        /// </summary>
        public void SignIn()
        {
            if (m_signInAsync != null)
                throw new InvalidAsynchronousStateException("SignIn/BeginSignIn/SignInAsync was already called and is not finished.");
            else if (string.IsNullOrWhiteSpace(m_icqConfig.UserLogin))
                throw new ArgumentNullException("ICQClientConfiguration.UserLogin", "Value is null, empty, or consisting only from white-space characters.");
            else if (string.IsNullOrWhiteSpace(m_icqConfig.UserPassword))
                throw new ArgumentNullException("ICQClientConfiguration.UserPassword", "Value is null, empty, or consisting only from white-space characters.");
            else if (!m_icqConfig.LoginServer.IsValid)
                throw new ArgumentException("Invalid ICQClientConfiguration.LoginServer value specified.");

            try
            {
                // Set state to Connecting
                this.changeState(ICQClientState.Connecting);
                LogWrite("SignIn starting for Host({0}), UserLogin({1}), UserPassword.Length({2})", m_icqConfig.LoginServer, m_icqConfig.UserLogin, m_icqConfig.UserPassword.Length);

                // Connect to login server
                this.Connection.Connect(m_icqConfig.LoginServer.EndPoint, false);
                LogWrite("OSCAR is connected to host({0})", m_icqConfig.LoginServer.Address);

                // Define our packet read timeout
                const int readTimeout = (int) TimeSpan.TicksPerSecond * 10;

                // Expect: SRV_HELLO
                var flap = FLAPHeader.Empty;
                byte[] packet = null;
                if (!this.Connection.Receive(ref flap, out packet, true, readTimeout))
                    throw new TimeoutException("Server did not reply in proper time, expected: SRV_HELLO");
                ICQ.Packets.SRV_HELLO_VALIDATE(this, ref flap, packet);

                // Reply with: CLI_HELLO
                ICQ.Packets.CLI_HELLO(ref flap, ref packet);
                this.Connection.Send(ref flap, packet);

                // Send: CLI_CHALLENGE_REQUEST
                byte[] userLoginBytes = Encoding.UTF8.GetBytes(m_icqConfig.UserLogin);
                var tlvs = new TLVChain(3)
                {
                    new TLV { TypeID = 0x01, Value = userLoginBytes },
                    new TLV { TypeID = 0x4B, Value = OSCAR.EmptyData },
                    new TLV { TypeID = 0x5A, Value = OSCAR.EmptyData },
                };
                ICQ.Packets.Make(ref flap, ref packet, ICQ.Packets.CLI_CHALLENGE_REQUEST, tlvs);
                this.Connection.Send(ref flap, packet);

                // Set state to Authorizing
                this.changeState(ICQClientState.Authorizing);

                byte[] auth_challenge = null;

                // Expect: SRV_CHALLENGE_REPLY or SRV_AUTH_RESPONSE
                if (!this.Connection.Receive(ref flap, out packet, true, readTimeout))
                    throw new TimeoutException("Server did not reply in proper time, expected: SRV_CHALLENGE_REPLY or SRV_AUTH_RESPONSE");
                else if (!flap.IsSNAC)
                    throw new ProtocolViolationException("Expected SNAC, got packet: " + flap);
                var snac = (SNAC)packet;
                if (snac.Type == ICQ.Packets.SRV_CHALLENGE_RESPONSE)
                {
                    // We have challenge now, read it (TLV without TypeID)
                    var challengeLength = XBitConvert.ToUInt16(snac.Data, 0);
                    auth_challenge = new byte[challengeLength];
                    Array.Copy(snac.Data, 2, auth_challenge, 0, challengeLength);
                }
                else if (snac.Type == ICQ.Packets.SRV_AUTH_RESPONSE)
                {
                    // Most likely login rejected
                    goto handleAuthResponse;
                }
                else
                    throw new ProtocolViolationException("Expected SNAC: SRV_AUTH_RESPONSE or SRV_CHALLENGE_RESPONSE, got: " + snac);

                // Send: CLI_AUTH_REQUEST
                byte[] protectedAuthRequest = ICQ.AimPasswordHashFunction(auth_challenge, m_icqConfig.UserPassword, "AOL Instant Messenger (SM)");
                tlvs = new TLVChain(3)
                {
                    new TLV { TypeID = 0x01, Value = userLoginBytes },
                    new TLV { TypeID = 0x25, Value = protectedAuthRequest },
                    new TLV { TypeID = 0x4C, Value = OSCAR.EmptyData },
                };
                ICQ.Packets.Make(ref flap, ref packet, ICQ.Packets.CLI_AUTH_REQUEST, tlvs);
                this.Connection.Send(ref flap, packet);

            #if IMadering
                        Следующие данные идентификации клиента уже не обязательны (изменение 2011 года).
                        0003 // Метка блока данных со строкой идентификации клиента
                            0024 // Длина строки идентификации клиента
                                TestBuddy AOL Instant Messenger (SM) // Строка идентификации клиента
                        0017 // Метка блока данных с мажорной версией клиента
                            0002 // Длина данных о мажорной версии
                                0001 // Номер мажорной версии: 1
                        0018 // Метка блока данных о минорной версии клиента
                            0002 // Длина данных о минорной версии
                                0000 // Номер минорной версии: 0
                        0019 // Метка блока данных о меньшей версии клиента
                            0002 // Длина данных о меньшей версии
                                0000 // Номер меньшей версии: 0
                        001a // Метка блока данных о номере сборки клиента
                            0002 // Длина данных номера сборки
                                0001 // Номер сборки клиента: 1
                        0016 // Метка блока данных идентификатора клиента
                            0002 // Длина данных идентификатора
                                010e // Идентификатор клиента (значение: 270)
                        000f // Метка блока данных о языке клиента
                            0002 // Длина данных о языке
                                656e // Язык клиента (значение: en)
                        000e // Метка блока данных о стране клиента
                            0002 // Длина данных о стране
                                7573 // Страна клиента (значение: us)

                        Дополнения пакета:
                        0014 // Метка блока данных с "Client distribution number"
                            0004 // Длина данных в блоке
                                00000150 // Client distribution number (значение: 336)
                        004a // Метка блока поддержки мультиподключений к серверу с одним UIN
                            0001 // Длина данных
                                01 // Флаг поддержки мультиподключений
            #endif

                // Expect: SRV_AUTH_RESPONSE
                if (!this.Connection.Receive(ref flap, out packet, true, readTimeout))
                    throw new TimeoutException("Server did not reply in proper time, expected: SRV_AUTH_RESPONSE");
                else if (!flap.IsSNAC)
                    throw new ProtocolViolationException("Expected SNAC, got packet: " + flap);
                snac = (SNAC)packet;
                if (snac.Type != ICQ.Packets.SRV_AUTH_RESPONSE)
                    throw new ProtocolViolationException("Expected SNAC: SRV_AUTH_RESPONSE, got: " + snac);

            handleAuthResponse:

                // Construct TLVChain from SNAC packet data
                tlvs = (TLVChain)snac.Data;

                // Connection is not needed anymore
                this.Connection.Disconnect(0);

                // Did authorization fail?
                if ( tlvs.Contains(0x08) )
                {
                    // Do we have reason/error code TLV?
                    ushort errorCode = 0;
                    if (tlvs.Contains(0x0008))
                    {
                        // Get reason/error code
                        errorCode = XBitConvert.ToUInt16(tlvs[0x0008].Value, 0);
                    }
                    else
                        this.LogWrite("[WARNING] (SRV_AUTH_RESPONSE:AUTH_FAIL) does not contain error code (tlv:0x0008)!");

                    // Is there any
                    string helpUrl = null;
                    if (tlvs.Contains(0x04))
                        helpUrl = Encoding.ASCII.GetString(tlvs[0x04].Value);
                    else
                        this.LogWrite("[WARNING] (SRV_AUTH_RESPONSE:AUTH_FAIL) does not contain Help Url (tlv:0x04).");

                    // Event:
                    throw new ICQException(this, "Authorization failed.", helpUrl, errorCode);
                }
                else
                {
                    // Anything is fine!
                    if (!tlvs.Contains(0x05) || !tlvs.Contains(0x06))
                        throw new ProtocolViolationException("Received invalid/unsupported SRV_AUTH_RESPONSE packet (no required info...).");

                    // Get BOSS info
                    byte[] bossCookie = tlvs[0x06].Value;
                    string bossHost = Encoding.UTF8.GetString(tlvs[0x05].Value);

                    // Continue SignIn
                    this.LogWrite("Authorization complete, received bossCookie(length: {0}) and bossHost({1})", bossCookie.Length, bossHost);
                    this.changeState(ICQClientState.Authorized);
                    this.ConnectInitSession(new NetworkHost(bossHost, 5190), bossCookie);
                }

                throw new NotImplementedException();
            }
            catch (Exception ex)
            {
                LogWrite("SignIn exception: {0}", ex);
                this.changeState(ICQClientState.Idle, ex);
            }
        }
Пример #4
0
        /// <summary>
        /// Отправляет данные на подключенный хост. Он должен быть подключен к текущему пиру.
        /// </summary>
        /// <param name="to">Адресат доставки</param>
        /// <param name="data">Данные для отправки</param>
        public void Send(EndPoint to, byte[] data)
        {
            #if DEBUG
            if (!Connections.Contains(to))
                throw new ArgumentException('\"' + to.ToString() + "' is not connected peer.");
            #endif

            var tlvs = new TLVChain(2)
            {
                new TLV { TypeID = SvcLayer.TLV_TYPE, Value = new byte[1] { SvcLayer.TYPE_USER_DATA } },
                new TLV { TypeID = SvcLayer.TLV_USER_DATA, Value = data},
            };
            m_sendBuffer.Enqueue(new OSCARQueueEntity { Host = to, FLAP = m_svcFlap, Data = (byte[])tlvs });
        }
Пример #5
0
 public static void Make(ref FLAPHeader flap, ref byte[] packet, sSNACType type, TLVChain tlvs, uint requestID = 0, eSNACFlags snacFlags = eSNACFlags.None)
 {
     flap.Channel = (byte)eFLAPChannel.SNACPacket;
     var snac = new SNAC(type, requestID, snacFlags);
     snac.Data = (byte[])tlvs;
     packet = (byte[])snac;
 }