Пример #1
0
        public void TestByteStreamNumberWriting()
        {
            ByteStream stream = new ByteStream();
            stream.WriteByte(0x08);
            stream.WriteUshort(0x4164);
            stream.WriteUint(0x7269656e);
            stream.WriteByteArray(new byte[] {0x6e, 0x65});

            Assert.AreEqual(testData.Length, stream.GetByteCount());
            ByteStream testStream = new ByteStream(stream.GetBytes());
            Assert.AreEqual("Adrienne", testStream.ReadString(testStream.ReadByte(), Encoding.ASCII));
        }
Пример #2
0
        public void TestByteStreamStringWriting()
        {
            ByteStream stream = new ByteStream();
            stream.WriteByte((byte) Encoding.ASCII.GetByteCount("Adrienne"));
            stream.WriteString("Adrienne", Encoding.ASCII);

            Assert.AreEqual(testData.Length, stream.GetByteCount());
            byte[] data = stream.GetBytes();
            for (int i = 0; i < testData.Length; i++)
            {
                Assert.AreEqual(testData[i], data[i]);
            }
        }
Пример #3
0
        /// <summary>
        /// Parses a byte buffer into an <see cref="BartID"/> object
        /// </summary>
        private void ReadIconInfo(byte[] buffer, UserInfo userinfo)
        {
            using (ByteStream iconStream = new ByteStream(buffer))
            {
                int iconStreamSize = iconStream.GetByteCount();

                while (iconStream.CurrentPosition + 4 <= iconStreamSize)
                {
                    BartID item = new BartID(iconStream);

                    // Find the end of the current data item in the stream
                    int endDataPosition = iconStream.CurrentPosition + item.Data.Length;

                    switch (item.Type)
                    {
                        case BartTypeId.BuddyIcon:
                            if (!GraphicsManager.IsBlankIcon(item.Data))
                            {
                                userinfo.Icon = item;
                            }
                            break;

                        case BartTypeId.StatusString: // Available message
                            using (ByteStream messageStream = new ByteStream(item.Data))
                            {
                                Encoding encoding = Encoding.UTF8;
                                byte[] amessage = new byte[0];

                                if (messageStream.HasMoreData)
                                {
                                    // Pull the message to a byte array, assume at first that the encoding
                                    // is UTF-8.  If existing encoding information exists, use that instead
                                    amessage = messageStream.ReadByteArray(messageStream.ReadByte());

                                    // Check if there's encoding information available
                                    if (messageStream.HasMoreData)
                                    {
                                        // Check to see if the encoding's been specified
                                        if (messageStream.ReadUshort() == 0x0001)
                                        {
                                            messageStream.AdvanceOffset(2);
                                            string encodingStr = messageStream.ReadString(messageStream.ReadUshort(), Encoding.ASCII);

                                            // Try to use the encoding from the byte stream
                                            try
                                            {
                                                encoding = Encoding.GetEncoding(encodingStr);
                                            }
                                            catch (ArgumentException)
                                            {
                                                Logging.WriteString(
                                                    "ReadIconInfo: Got unknown encoding for available message ("
                                                    + encodingStr + "), falling back to UTF-8");
                                                encoding = Encoding.UTF8;
                                            }
                                        }
                                    }
                                }

                                userinfo.AvailableMessage = Encoding.Unicode.GetString(
                                    Encoding.Convert(encoding, Encoding.Unicode, amessage));

                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Processes the asynchronous receipt of a FLAP
        /// </summary>
        /// <param name="res">The <see cref="IAsyncResult"/> of a BeginReceive call</param>
        private void ProcessFLAP(IAsyncResult res)
        {
            int bytesreceived = 0;
            int receiveindex  = 0;

            byte[] flapbuffer = null;

            try
            {
                lock (socket)
                {
                    bytesreceived = socket.EndRead(res);
                    if (bytesreceived == 0)
                    {
                        throw new Exception("Socket receive returned 0 bytes read");
                    }

                    flapbuffer = (byte[])res.AsyncState;

                    receiveindex = bytesreceived;
                    while (receiveindex < flapbuffer.Length)
                    {
                        bytesreceived = socket.Read(flapbuffer, receiveindex, flapbuffer.Length - receiveindex);
                        if (bytesreceived == 0)
                        {
                            throw new Exception("Socket receive returned 0 bytes read");
                        }
                        receiveindex += bytesreceived;
                    }
                }
            }
            catch (Exception ex)
            {
                if (!isDisconnecting)
                {
                    Logging.WriteString("Receive error in ProcessFLAP: {0}, connection {1}", ex.Message, ID);
                    DisconnectFromServer(true);
                }
                return;
            }

            if (flapbuffer[0] == 0xFF)
            {
                int badcount = 0;
                for (badcount = 0; badcount < flapbuffer.Length && flapbuffer[badcount] == 0xFF; badcount++)
                {
                    ;
                }

                // SOMEHOW there are two bytes of 0xFF occuring when requesting
                // SNAC family 0x10 and receiving SNAC(01,03).  So that has to stop
                for (int i = badcount; i < flapbuffer.Length; i++)
                {
                    flapbuffer[i - badcount] = flapbuffer[i];
                }

                socket.Read(flapbuffer, flapbuffer.Length - badcount, badcount);
            }

            // Get the FLAP header out of the async result
            FLAPHeader flap   = GetFLAPHeader(flapbuffer);
            ByteStream stream = ReadPacket(flap.DataSize);

            if (stream == null)
            {
                return;
            }

            // The full packet is here, so we can chuck it out for processing
            DataPacket dp;

            switch (flap.Channel)
            {
            case 0x01:     // New connection negotiation
                // This will not occur, FLAP 0x01 is handled in ConnectToServer
                break;

            case 0x02:     //  SNAC data
                if (stream.GetByteCount() < 10)
                {
                    break;     // Don't return, don't disconnect, just keep on keeping on
                }

                dp                  = stream.CreateDataPacket();
                dp.FLAP             = flap;
                dp.ParentConnection = this;
                dp.ParentSession    = parent;
                Processor.Enqueue(dp);
                break;

            case 0x03:     // FLAP error
                // Session error:  FLAP error, bailing out
                Logging.WriteString("Received error FLAP");
                DisconnectFromServer(true);
                return;

            case 0x04:     // Close connection negotiation
                //KSD-SYSTEMS - added at 27.11.2009
                if (stream.GetByteCount() > 10)
                {
                    dp = stream.CreateDataPacket();
                    if (((SNACFamily)dp.SNAC.FamilyServiceID) == SNACFamily.PrivacyManagementService)
                    {
                        PrivacyManagementService sub = (PrivacyManagementService)dp.SNAC.FamilySubtypeID;
                        if (sub == PrivacyManagementService.ServiceParametersRequest)
                        {
                            parent.OnError(ServerErrorCode.ExternalClientRequest, dp);
                        }
                    }
                }

                Logging.WriteString("Received close connection FLAP");
                DisconnectFromServer(false);
                return;

            case 0x05:     // Keepalive packet
                Logging.WriteString("Received keepalive FLAP");
                SendKeepalive(null);
                break;

            default:
                break;
            }

            // Shine on, you crazy connection
            keepAliveTimer.Change(60000, Timeout.Infinite);
            ReadHeader();
        }
Пример #5
0
        /// <summary>
        /// Cancel a direct connection attempt
        /// </summary>
        public void SendDirectConnectionCancellation(DirectConnection conn, string reason)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_OUTGOING_MESSAGE;

            ByteStream stream = new ByteStream();
            InsertIcbmHeader(stream, conn.Cookie, 0x0002, conn.Other.ScreenName);
            using (ByteStream tlv05 = new ByteStream())
            {
                tlv05.WriteUshort(RendezvousData.UshortFromType(RendezvousType.Cancel));
                tlv05.WriteByteArray(conn.Cookie.ToByteArray());
                tlv05.WriteByteArray(CapabilityProcessor.GetCapabilityArray(conn.Capability));

                using (TlvBlock tlvs = new TlvBlock())
                {
                    tlvs.WriteUshort(0x000B, 0x0001);
                    tlvs.WriteString(0x000C, reason, Encoding.ASCII);
                    tlvs.WriteEmpty(0x0003);
                    //KSD-SYSTEMS - commented at 02.12.2009 -> Canceling = Send Message only with Cookie
                    //tlv05.WriteByteArray(tlvs.GetBytes());
                }

                stream.WriteUshort(0x0005);
                stream.WriteUshort((ushort)tlv05.GetByteCount());
                stream.WriteByteArray(tlv05.GetBytes());
            }

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Пример #6
0
        /// <summary>
        /// Accept a direct connection attempt
        /// </summary>
        public void SendDirectConnectionAccept(DirectConnection conn)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_OUTGOING_MESSAGE;

            ByteStream stream = new ByteStream();
            InsertIcbmHeader(stream, conn.Cookie, 0x0002, conn.Other.ScreenName);
            using (ByteStream tlv05 = new ByteStream())
            {
                tlv05.WriteUshort(RendezvousData.UshortFromType(RendezvousType.Accept));
                tlv05.WriteByteArray(conn.Cookie.ToByteArray());
                tlv05.WriteByteArray(CapabilityProcessor.GetCapabilityArray(conn.Capability));
                tlv05.WriteUint(0x00030000);

                stream.WriteUshort(0x0005);
                stream.WriteUshort((ushort)tlv05.GetByteCount());
                stream.WriteByteArray(tlv05.GetBytes());
            }

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Пример #7
0
        /// <summary>
        /// Sends a direct connection request
        /// </summary>
        /// <param name="conn">A <see cref="DirectConnection"/> object that will handle the request</param>
        public void RequestDirectConnectionInvite(DirectConnection conn)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_OUTGOING_MESSAGE;

            ByteStream stream = new ByteStream();
            InsertIcbmHeader(stream, conn.Cookie, 0x0002, conn.Other.ScreenName);
            using (ByteStream tlv05 = new ByteStream())
            {
                tlv05.WriteUshort(RendezvousData.UshortFromType(RendezvousType.Invite));
                tlv05.WriteByteArray(conn.Cookie.ToByteArray());
                tlv05.WriteByteArray(CapabilityProcessor.GetCapabilityArray(conn.Capability));

                using (TlvBlock tlvs = new TlvBlock())
                {
                    tlvs.WriteUshort(DC_SEQUENCE_NUMBER, RendezvousData.UshortFromSequence(conn.Sequence));
                    if (conn.Sequence == RendezvousSequence.DirectOrStage1)
                    {
                        tlvs.WriteEmpty(0x000F);
                    }
                    if (!String.IsNullOrEmpty(conn.Message))
                    {
                        tlvs.WriteString(DC_MESSAGE, conn.Message, Encoding.ASCII);
                    }

                    uint ipaddress = 0;
                    if (conn.Method == DirectConnectionMethod.Proxied)
                    {
                        ipaddress = ConvertIPAddress(conn.AOLProxyIP);
                    }
                    else
                    {
                        ipaddress = ConvertIPAddress(conn.ClientIP);
                    }

                    tlvs.WriteUint(DC_PROXY_IP_ADDRESS, ipaddress);
                    tlvs.WriteUint(DC_PROXY_IP_ADDRESS_COMPLIMENT, ~ipaddress);

                    if (conn.Sequence == RendezvousSequence.DirectOrStage1)
                    {
                        tlvs.WriteUint(DC_CLIENT_IP_ADDRESS, ConvertIPAddress(conn.ClientIP));
                    }

                    if (conn.Sequence != RendezvousSequence.Stage3)
                    {
                        tlvs.WriteUshort(DC_PORT, (ushort)conn.Port);
                        tlvs.WriteUshort(DC_PORT_COMPLIMENT, (ushort)(~conn.Port));
                    }

                    if (conn.Method == DirectConnectionMethod.Proxied)
                    {
                        tlvs.WriteEmpty(DC_USE_PROXY_FLAG);
                    }

                    if (conn is FileTransferConnection && conn.Sequence == RendezvousSequence.DirectOrStage1)
                    {
                        FileTransferConnection ftc = conn as FileTransferConnection;
                        using (ByteStream tlv2711 = new ByteStream())
                        {
                            tlv2711.WriteUshort((ushort)((ftc.TotalFiles > 1) ? 0x0002 : 0x0001));
                            tlv2711.WriteUshort((ushort)ftc.TotalFiles);
                            tlv2711.WriteUint(ftc.TotalFileSize);
                            tlv2711.WriteString(ftc.FileHeader.Name, Encoding.ASCII);
                            tlv2711.WriteByte(0x00);
                            tlvs.WriteByteArray(0x2711, tlv2711.GetBytes());
                        }
                        tlvs.WriteString(0x2712, ftc.LocalFileNameEncoding.WebName, Encoding.ASCII);
                    }

                    tlv05.WriteByteArray(tlvs.GetBytes());
                }

                stream.WriteUshort(0x0005);
                stream.WriteUshort((ushort)tlv05.GetByteCount());
                stream.WriteByteArray(tlv05.GetBytes());
            }

            // Acknowledgement request
            stream.WriteUint(0x00030000);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Пример #8
0
        /// <summary>
        /// Invites an AIM user to an AOL chatroom
        /// </summary>
        /// <param name="chatroom">The <see cref="ChatRoom"/> describing the chatroom</param>
        /// <param name="screenName">The screenname of the user to invite</param>
        /// <param name="message">A message to send along with the invitation</param>
        public Cookie InviteToChatRoom(ChatRoom chatroom, string screenName, string message)
        {
            if (!parent.LoggedIn)
            {
                throw new NotLoggedInException();
            }

            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_OUTGOING_MESSAGE;

            Cookie cookie = Cookie.CreateCookieForSending();

            Encoding enc = Encoding.ASCII;
            byte destlength = (byte) enc.GetByteCount(screenName);
            ushort messagelength = (ushort) enc.GetByteCount(message);
            byte roomnamelength = (byte) enc.GetByteCount(chatroom.FullName);

            ByteStream stream = new ByteStream();
            InsertIcbmHeader(stream, cookie, 0x0002, screenName);

            ByteStream header = new ByteStream();
            header.WriteUshort(0x0000);
            header.WriteByteArray(cookie.ToByteArray());
            header.WriteUint(0x748F2420);
            header.WriteUint(0x628711D1);
            header.WriteUint(0x82224445);
            header.WriteUint(0x53540000);

            using (TlvBlock tlv05 = new TlvBlock())
            {
                tlv05.WriteUshort(0x000A, 0x0001);
                tlv05.WriteEmpty(0x000F);
                tlv05.WriteString(0x000C, message, enc);

                ByteStream tlv2711 = new ByteStream();
                tlv2711.WriteUshort(chatroom.Exchange);
                tlv2711.WriteByte(roomnamelength);
                tlv2711.WriteString(chatroom.FullName, enc);
                tlv2711.WriteUshort(chatroom.Instance);

                tlv05.WriteByteArray(0x2711, tlv2711.GetBytes());

                header.WriteByteArray(tlv05.GetBytes());
            }

            stream.WriteUshort(0x0005);
            stream.WriteUshort((ushort) header.GetByteCount());
            stream.WriteByteArray(header.GetBytes());

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));

            return cookie;
        }
Пример #9
0
        /// <summary>
        /// Parses a byte buffer into an <see cref="BartID"/> object
        /// </summary>
        private void ReadIconInfo(byte[] buffer, UserInfo userinfo)
        {
            using (ByteStream iconStream = new ByteStream(buffer))
            {
                int iconStreamSize = iconStream.GetByteCount();

                while (iconStream.CurrentPosition + 4 <= iconStreamSize)
                {
                    BartID item = new BartID(iconStream);

                    // Find the end of the current data item in the stream
                    int endDataPosition = iconStream.CurrentPosition + item.Data.Length;

                    switch (item.Type)
                    {
                    case BartTypeId.BuddyIcon:
                        if (!GraphicsManager.IsBlankIcon(item.Data))
                        {
                            userinfo.Icon = item;
                        }
                        break;

                    case BartTypeId.StatusString:     // Available message
                        using (ByteStream messageStream = new ByteStream(item.Data))
                        {
                            Encoding encoding = Encoding.UTF8;
                            byte[]   amessage = new byte[0];

                            if (messageStream.HasMoreData)
                            {
                                // Pull the message to a byte array, assume at first that the encoding
                                // is UTF-8.  If existing encoding information exists, use that instead
                                amessage = messageStream.ReadByteArray(messageStream.ReadByte());

                                // Check if there's encoding information available
                                if (messageStream.HasMoreData)
                                {
                                    // Check to see if the encoding's been specified
                                    if (messageStream.ReadUshort() == 0x0001)
                                    {
                                        messageStream.AdvanceOffset(2);
                                        string encodingStr = messageStream.ReadString(messageStream.ReadUshort(), Encoding.ASCII);

                                        // Try to use the encoding from the byte stream
                                        try
                                        {
                                            encoding = Encoding.GetEncoding(encodingStr);
                                        }
                                        catch (ArgumentException)
                                        {
                                            Logging.WriteString(
                                                "ReadIconInfo: Got unknown encoding for available message ("
                                                + encodingStr + "), falling back to UTF-8");
                                            encoding = Encoding.UTF8;
                                        }
                                    }
                                }
                            }

                            userinfo.AvailableMessage = Encoding.Unicode.GetString(
                                Encoding.Convert(encoding, Encoding.Unicode, amessage));
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
        }