Пример #1
0
 public void TestByteStreamReading()
 {
     // Test bytes
     using (ByteStream stream = new ByteStream(testData))
     {
         for (int i = 0; i < testData.Length; i++)
         {
             Assert.AreEqual(testData[i], stream.ReadByte(), "ReadByte returned incorrect value");
         }
     }
     // Test ushorts
     using (ByteStream stream = new ByteStream(testData))
     {
         Assert.AreEqual(0x0841, stream.ReadUshort());
         Assert.AreEqual(0x6472, stream.ReadUshort());
         Assert.AreEqual(0x6965, stream.ReadUshort());
         Assert.AreEqual(0x6e6e, stream.ReadUshort());
     }
     // Test uints
     using (ByteStream stream = new ByteStream(testData))
     {
         Assert.AreEqual(0x08416472, stream.ReadUint());
         Assert.AreEqual(0x69656e6e, stream.ReadUint());
     }
     // Test string
     using (ByteStream stream = new ByteStream(testData))
     {
         Assert.AreEqual("Adrienne", stream.ReadString(stream.ReadByte(), Encoding.ASCII));
     }
 }
Пример #2
0
        /// <summary>
        /// Requests the alias assigned to an ICQ account
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        /// <param name="screenname">The account for which to retrieve information</param>
        public static void GetAlias(ISession sess, string screenname)
        {
            if (!ScreennameVerifier.IsValidICQ(screenname))
            {
                throw new ArgumentException(screenname + " is not a valid ICQ screenname", "screenname");
            }

            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.ICQExtensionsService;
            sh.FamilySubtypeID = (ushort) ICQExtensionsService.MetaInformationRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            stream.WriteUshort(0x0001);
            stream.WriteUshort(0x000A);
            stream.WriteUshort(0x0008);
            stream.WriteUint(uint.Parse(sess.ScreenName));
            stream.WriteUshortLE(0x07D0);
            stream.WriteUshortLE((ushort) sh.RequestID);
            stream.WriteUshort(0x04BA);
            stream.WriteUint(uint.Parse(screenname));

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Пример #3
0
        /// <summary>
        /// Modifies a series of SSI items on the server-side list -- SNAC(13,09)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <param name="items">An array of <see cref="SSIItem"/> objects</param>
        public static void ModifySSIItems(Session sess, SSIItem[] items)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.SSIService;
            sh.FamilySubtypeID = (ushort) SSIService.SSIEditUpdateGroupHeader;

            ByteStream stream = new ByteStream();
            stream.WriteSSIItems(items);
            sess.SSI.OutstandingRequests++;
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Пример #4
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));
        }
Пример #5
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]);
            }
        }
Пример #6
0
        public void TestChatRoomCreation()
        {
            ByteStream dataStream = new ByteStream(Data.SNAC_0D_09);
            using (TlvBlock tlvs = new TlvBlock(dataStream.ReadByteArrayToEnd()))
            {
                Assert.IsTrue(tlvs.HasTlv(0x0004), "TLV 0x0004 missing from data stream");
                ChatRoom chatRoom = new ChatRoom(new ByteStream(tlvs.ReadByteArray(0x0004)));

                Assert.AreEqual(0x0004, chatRoom.Exchange);
                Assert.AreEqual("!aol://2719:10-4-chat9614646934270543373", chatRoom.FullName);
                Assert.AreEqual(0x0000, chatRoom.Instance);
                Assert.AreEqual("Chat 9614646934270543373", chatRoom.DisplayName);
                Assert.AreEqual(new DateTime(2007, 8, 5, 20, 9, 21, DateTimeKind.Utc), chatRoom.CreationTime);
            }
        }
Пример #7
0
        /// <summary>
        /// Sends a request to find accounts by their associated email address -- SNAC(0A,02)
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        /// <param name="email">The email address to query</param>
        public static void FindUsersByEmail(ISession sess, string email)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.UserLookupService;
            sh.FamilySubtypeID = (ushort) UserLookupService.FindUserByEmailRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            stream.WriteString(email, Encoding.ASCII);

            sess.StoreRequestID(sh.RequestID, email);

            DataPacket dp = Marshal.BuildDataPacket(sess, sh, stream);
            SNACFunctions.BuildFLAP(dp);
        }
Пример #8
0
        /// <summary>
        /// Sends an acknowledgement of the server's rate limitations -- SNAC(01,08)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        /// <param name="classes">The known rate classes to acknowledge</param>
        public static void AcknowledgeRateLimitations(DataPacket dp, ushort[] classes)
        {
            Session sess = dp.ParentSession;

            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort)SNACFamily.BasicOscarService;
            sh.FamilySubtypeID = (ushort)GenericServiceControls.AcknowledgeRateLimits;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            for (int i = 0; i < classes.Length; i++)
            {
                stream.WriteUshort(classes[i]);
            }

            DataPacket dp2 = Marshal.BuildDataPacket(sess, sh, stream);
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);

            sess.OnLoginStatusUpdate("Protocol negotiation complete", 0.66);

            /*
             * If this is the initial services connection, we call the remaining SNACs
             * in the login sequence.
             * Otherwise, this is the last step in setting up a new service connection,
             * and we send SNAC(01,02) here.
             */
            if (!sess.LoggedIn)
            {
                // Start stage 3, services setup
                RequestOwnInformation(sess);
                SNAC13.RequestParametersList(sess);
                SNAC13.RequestInitialContactList(sess);
                sess.Statuses.RequestParameters();
                sess.Messages.RequestParametersList();
                SNAC09.RequestParametersList(sess);
                sess.Statuses.ReportClientCapabilities();
                sess.Statuses.SetProfile(sess.Statuses.Profile);
            }
            else
            {
                SendReadyNotification(dp);
            }
        }
Пример #9
0
        /// <summary>
        /// Sends an AIM invitation to a receipient -- SNAC(06,02)
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        /// <param name="email">The email address of the person to invite</param>
        /// <param name="text">The text of the invitation</param>
        public static void SendInvitiationRequest(ISession sess, string email, string text)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.PrivacyManagementService;
            sh.FamilySubtypeID = (ushort) PrivacyManagementService.ServiceParametersRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteString(0x0011, email, Encoding.ASCII);
                tlvs.WriteString(0x0015, text, Encoding.ASCII);
                stream.WriteTlvBlock(tlvs);
            }

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Пример #10
0
        /// <summary>
        /// Changes the password on an ICQ account
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        /// <param name="newpassword">The new password</param>
        /// <remarks>If the new password is longer than 8 characters, it is automatically
        /// truncated to 8 characters by the server.</remarks>
        public static void ChangeICQPassword(ISession sess, string newpassword)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.ICQExtensionsService;
            sh.FamilySubtypeID = (ushort) ICQExtensionsService.MetaInformationRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            stream.WriteUshort(0x0001);
            stream.WriteUshort(0x000A);
            stream.WriteUshort(0x0008);
            stream.WriteUint(uint.Parse(sess.ScreenName));
            stream.WriteUshortLE(0x07D0);
            stream.WriteUshortLE((ushort) sh.RequestID);
            stream.WriteUshort(0x042E);
            stream.WriteUshort((ushort) (newpassword.Length + 1));
            stream.WriteString(newpassword, Encoding.ASCII);
            stream.WriteByte(0x00);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Пример #11
0
        /// <summary>
        /// Sends authorization request -- SNAC(17,02)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,07)</param>
        public static void SendAuthorizationRequest(DataPacket dp)
        {
            // Pull apart SNAC(17,07)
            byte[] key = dp.Data.ReadByteArray(dp.Data.ReadUshort());

            // Construct SNAC(17,02)
            SNACHeader header = new SNACHeader();
            header.FamilyServiceID = (ushort) SNACFamily.AuthorizationRegistrationService;
            header.FamilySubtypeID = (ushort) AuthorizationRegistrationService.LoginRequest;
            header.Flags = 0;
            header.RequestID = Session.GetNextRequestID();

            OSCARIdentification id = dp.ParentSession.ClientIdentification;

            ByteStream stream = new ByteStream();
            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteString(0x0001, dp.ParentSession.ScreenName, Encoding.ASCII);
                tlvs.WriteString(0x0003, id.ClientName, Encoding.ASCII);
                tlvs.WriteString(0x000F, "en", Encoding.ASCII);
                tlvs.WriteString(0x000E, "us", Encoding.ASCII);
                tlvs.WriteUint(0x0014, id.ClientDistribution);
                tlvs.WriteUshort(0x0016, id.ClientId);
                tlvs.WriteUshort(0x0017, id.ClientMajor);
                tlvs.WriteUshort(0x0018, id.ClientMinor);
                tlvs.WriteUshort(0x0019, id.ClientLesser);
                tlvs.WriteUshort(0x001A, id.ClientBuild);
                tlvs.WriteByteArray(0x0025, dp.ParentSession.HashPassword(key));
                tlvs.WriteByte(0x004A, 0x01);
                tlvs.WriteEmpty(0x004C);
                stream.WriteTlvBlock(tlvs);
            }

            DataPacket newPacket = Marshal.BuildDataPacket(dp.ParentSession, header, stream);
            newPacket.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(newPacket);
        }
Пример #12
0
        /// <summary>
        /// Kicks off the authorization hash request when the initial connection is complete
        /// </summary>
        void loginConnection_ServerConnectionCompleted(Connection conn)
        {
            conn.ReadyForData = true;

            /*** Send SNAC(17,06) to get the auth key ***/
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_AUTH_FAMILY;
            sh.FamilySubtypeID = AUTH_KEY_REQUEST;

            ByteStream stream = new ByteStream();
            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteString(0x0001, parent.ScreenName, Encoding.ASCII);
                tlvs.WriteEmpty(0x004B);
                tlvs.WriteEmpty(0x005A);
                stream.WriteTlvBlock(tlvs);
            }

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

            conn.ReadHeader();
        }
Пример #13
0
        /// <summary>
        /// Processes the list of rate limitations -- SNAC(01,07)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(01,07)</param>
        /// <remarks>This is the last step in setting up a secondary service connection,
        /// and the trigger to initialize basic services for the primary connection.</remarks>
        private void ProcessRateLimitations(DataPacket dp)
        {
            ushort num_classes = dp.Data.ReadUshort();
            ushort[] classes = new ushort[num_classes];

            RateClassManager rcm = parent.RateClasses;

            // Get the rate class attributes out of the SNAC
            for (int i = 0; i < num_classes; i++)
            {
                ushort id = dp.Data.ReadUshort();
                RateClass rc = rcm.GetByID(id);
                rc.WindowSize = dp.Data.ReadUint();
                rc.ClearLevel = dp.Data.ReadUint();
                rc.AlertLevel = dp.Data.ReadUint();
                rc.LimitLevel = dp.Data.ReadUint();
                rc.DisconnectLevel = dp.Data.ReadUint();
                rc.CurrentLevel = dp.Data.ReadUint();
                rc.MaxLevel = dp.Data.ReadUint();
                if (parent.Families.GetFamilyVersion(0x0001) >= 3)
                {
                    rc.LastTime = dp.Data.ReadUint();
                    rc.IsDroppingSNACs = dp.Data.ReadByte() != 0;
                }
                rcm.SetByID(id, rc);
                rc.StartLimitedTransmission();

                classes[i] = id;
            }

            // Register rates with the session's ConnectionList
            for (int i = 0; i < num_classes; i++)
            {
                ushort id = dp.Data.ReadUshort();
                ushort num_pairs = dp.Data.ReadUshort();

                for (int j = 0; j < num_pairs; j++)
                {
                    ushort family = dp.Data.ReadUshort();
                    ushort subtype = dp.Data.ReadUshort();
                    if (family == 0x04)
                    {
                        if (id == 1)
                        {
                            Console.WriteLine("** SNAC 4 handled by RC " + id);
                        }
                        else
                        {
                            Console.WriteLine("SNAC 4-{0} handled by RC " + id, subtype);
                        }
                    }
                    else if (family == 0x02 && subtype == 0x05)
                    {
                        Console.WriteLine("** 02,05 handled by RC " + id);
                    }
                    rcm.SetRateClassKey(family, subtype, id);
                }
            }

            // Construct SNAC(01,08)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_ACKNOWLEDGE_RATE_LIMITS;

            ByteStream stream = new ByteStream();
            for (int i = 0; i < classes.Length; i++)
            {
                stream.WriteUshort(classes[i]);
            }

            DataPacket dp2 = Marshal.BuildDataPacket(parent, sh, stream);
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);

            parent.OnLoginStatusUpdate("Protocol negotiation complete", 0.66);

            /*
             * If this is the initial services connection, we call the remaining SNACs
             * in the login sequence.
             * Otherwise, this is the last step in setting up a new service connection,
             * and we send SNAC(01,02) here.
             */
            if (!parent.LoggedIn)
            {
                // Start stage 3, services setup
                RequestOnlineInformation();
                SNAC13.RequestParametersList(parent);
                SNAC13.RequestInitialContactList(parent);
                parent.Statuses.RequestParameters();
                parent.Messages.RequestParametersList();
                SNAC09.RequestParametersList(parent);
                parent.Statuses.ReportClientCapabilities();
                parent.Statuses.SetProfile(parent.Statuses.Profile);
            }
            else
            {
                SendReadyNotification(dp.ParentConnection);
            }
        }
Пример #14
0
        /// <summary>
        /// Sets the client's ICQ status -- SNAC(01,1E)
        /// </summary>
        /// <param name="flags">The ICQ flags to set</param>
        /// <param name="status">The ICQ status flags to set</param>
        internal void SetExtendedICQStatus(ICQFlags flags, ICQStatus status)
        {
            SNACHeader sh = new SNACHeader(SNAC_BOS_FAMILY, BOS_SET_EXTENDED_STATUS);

            ByteStream stream = new ByteStream();
            uint stat = (uint)((ushort)flags << 16);
            stat |= (ushort)status;
            stream.WriteUint(0x00060004);
            stream.WriteUint(stat);

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);
            dp.ParentConnection = parent.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Пример #15
0
        /// <summary>
        /// Sets the client's DC info -- SNAC(01,1E)
        /// </summary>
        /// <remarks>see <see cref="UserDCInfo"/> for contact info</remarks>
        internal void SetDCInfo()
        {
            SNACHeader sh = new SNACHeader(SNAC_BOS_FAMILY, BOS_SET_EXTENDED_STATUS);
            ByteStream stream = new ByteStream();

            // Header
            stream.WriteUshort(0x000c);
            stream.WriteUshort(0x0025);

            // Values from Icq 6.5 & 7 dumping
            // Miranda use other Values (see CIcqProto::handleServUINSettings)
            stream.WriteUint(0);                                // IP
            stream.WriteUint(0);                                // Port
            stream.WriteByte((byte)DCType.Disabled);            // DC type
            stream.WriteUshort((ushort)DCProtocol.IcqLite);     // DC protocol version

            stream.WriteInt(AuthCookie);                        // DC auth cookie

            stream.WriteUint(0);                                // Web front port
            stream.WriteUint(0);                                // Client futures
            stream.WriteUint(0);                                // last info update time
            stream.WriteUint(0);                                // last ext info update time (i.e. icqphone status)
            stream.WriteUint(0);                                // last ext status update time (i.e. phonebook)
            stream.WriteUshort(0);                              // unknown

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);
            dp.ParentConnection = parent.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Пример #16
0
        /// <summary>
        /// Sets the client's available message -- SNAC(01,1E)
        /// </summary>
        /// <param name="availablemessage">The available message to set</param>
        internal void SetAvailableMessage(string availablemessage)
        {
            SNACHeader sh = new SNACHeader(SNAC_BOS_FAMILY, BOS_SET_EXTENDED_STATUS);

            ByteStream stream = new ByteStream();
            if (String.IsNullOrEmpty(availablemessage))
            {
                availablemessage = String.Empty;
            }

            stream.WriteUshort(0x001D);
            stream.WriteUshort((ushort)(availablemessage.Length + 8));
            stream.WriteUshort(0x0002);
            stream.WriteByte(0x04);
            stream.WriteByte((byte)(Encoding.ASCII.GetByteCount(availablemessage) + 4));
            stream.WriteUshort((ushort)Encoding.ASCII.GetByteCount(availablemessage));
            stream.WriteString(availablemessage, Encoding.ASCII);
            stream.WriteUshort(0x0000);

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);
            dp.ParentConnection = parent.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Пример #17
0
        /// <summary>
        /// Sends a response to a client verification request -- SNAC(01,20)
        /// </summary>
        /// <remarks>
        /// SNAC(01,1F) and SNAC(01,20) are used to verify that the client connecting
        /// to the network was the official AOL Instant Messenger.  The server sends
        /// two integers, an offset and a length, in SNAC(01,1F).  These parameters are then used to
        /// get 16 bytes of data in the offical client's static memory region. However, after
        /// AOL begain using this authentication method, the servers never changed the requested
        /// offset and length. The expected response was the same 16 bytes every time, which made
        /// it a fairly ineffective deterrent to "unauthorized" clients.
        /// </remarks>
        public void SendVerificationResponse()
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_CLIENT_VERIFICATION_RESPONSE;

            ByteStream stream = new ByteStream();
            stream.WriteUint(0x44a95d26);
            stream.WriteUint(0xd2490423);
            stream.WriteUint(0x93b8821f);
            stream.WriteUint(0x51c54b01);

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);
            dp.ParentConnection = parent.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Пример #18
0
        /// <summary>
        /// Notifies the OSCAR server that the new connection is ready to receive service-specific data
        /// </summary>
        /// <remarks>
        /// This SNAC must be sent within 30ish seconds of connection, or the connection will drop.
        /// This should not ever be a problem, barring a lost connection well below the level of this library.
        /// </remarks>
        public void SendReadyNotification(Connection conn)
        {
            // Build SNAC(01,02)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_CONNECTION_READY;

            ushort[] families = parent.Connections.GetFamilies(conn);
            FamilyManager fm = parent.Families;

            Array.Sort(families);
            Array.Reverse(families);

            bool isChatRoomConnection = false;
            bool isChatNavService = false;

            ByteStream stream = new ByteStream();
            DataPacket[][] delayedframes = new DataPacket[families.Length][];

            for (int i = 0; i < families.Length; i++)
            {
                ushort family = families[i];
                delayedframes[i] = parent.Connections.GetDelayedPackets(family);

                stream.WriteUshort(family);
                stream.WriteUshort(fm.GetFamilyVersion(family));
                stream.WriteUshort(fm.GetFamilyToolID(family));
                stream.WriteUshort(fm.GetFamilyToolVersion(family));

                if (family == 0x000D)
                {
                    isChatNavService = true;
                }
                else if (family == 0x000E)
                {
                    isChatRoomConnection = true;
                }
            }

            /*
             * The initial service connection has to send SNAC(01,1E) before it actually
             * sends SNAC(01,02), thus the check for the initial connection here
             * and after it gets sent.
            */
            if (!parent.LoggedIn)
            {
                SetAvailableMessage(parent.Statuses.AvailableMessage);
                SetDCInfo();
                SetExtendedICQStatus(parent.Statuses.ICQFlags, parent.Statuses.ICQStatus);
            }

            // The connection is done, so start sending keepalives
            conn.Connecting = false;
            conn.ReadyForData = true;

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);
            dp.ParentConnection = conn;
            SNACFunctions.BuildFLAP(dp);

            /*
             * If this is a new service connection, there is probably at least one
             * delayed packet. Process those packets. Additionally, if the new connection is
             * a chatroom connection, query the Rendezvous manager to see if it is the result
             * of an explict room creation (or implict, as in accepting a chat invitation).
             * If it was explict, notify the user that it's done
             */
            if (parent.LoggedIn)
            {
                foreach (DataPacket[] list in delayedframes)
                {
                    if (list == null) continue;
                    foreach (DataPacket dp_delay in list)
                    {
                        dp_delay.ParentConnection = conn;
                        SNACFunctions.DispatchToRateClass(dp_delay);
                    }
                }

                if (isChatNavService)
                {
                    parent.ChatRooms.OnChatNavServiceAvailable();
                }
                else if (isChatRoomConnection)
                {
                    ChatRoom chatRoom = parent.Connections.GetChatByConnection((ChatConnection)conn);
                    parent.ChatRooms.OnChatRoomConnectionAvailable(chatRoom);
                }
            }
        }
Пример #19
0
        /// <summary>
        /// Requests the version of SNAC services provided to this connection
        /// </summary>
        /// <param name="connection">The <see cref="Connection"/> for which to retrieve service information</param>
        public void RequestServiceVersions(Connection connection)
        {
            // Pack the family IDs and version numbers into a stream
            ushort[] families = parent.Connections.GetFamilies(connection);

            Array.Sort(families);
            Array.Reverse(families);

            ByteStream stream = new ByteStream();
            foreach (ushort id in families)
            {
                ushort version = parent.Families.GetFamilyVersion(id);
                stream.WriteUshort(id);
                stream.WriteUshort(version);
            }

            // Construct SNAC (01,17)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_FAMILY_VERSION_REQUEST;

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);
            dp.ParentConnection = connection; // Always send this on the same connection it was received
            SNACFunctions.BuildFLAP(dp);
        }
Пример #20
0
        /// <summary>
        /// Sends a request for a new service family
        /// </summary>
        /// <param name="newfamily">The new family to request</param>
        public void RequestNewService(ushort newfamily)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_REQUEST_NEW_SERVICE;

            ByteStream stream = new ByteStream();
            stream.WriteUshort(newfamily);

            // This SNAC expects a response in SNAC(01,05)
            parent.StoreRequestID(sh.RequestID, null);

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);
            // This one is always sent on BOS
            dp.ParentConnection = parent.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Пример #21
0
        /// <summary>
        /// Send MD5 key request -- SNAC(17,06)
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        public static void SendMD5Request(ISession sess)
        {
            /*** Send SNAC(17,06) to get the auth key ***/
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.AuthorizationRegistrationService;
            sh.FamilySubtypeID = (ushort) AuthorizationRegistrationService.MD5AuthkeyRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteString(0x0001, sess.ScreenName, Encoding.ASCII);
                tlvs.WriteEmpty(0x004B);
                tlvs.WriteEmpty(0x005A);
                stream.WriteTlvBlock(tlvs);
            }

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Пример #22
0
        /// <summary>
        /// Sends an XML string
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        /// <param name="xml">The contents of an XML document</param>
        /// <remarks>I have no idea how to use this.</remarks>
        public static void SendXmlRequest(ISession sess, string xml)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.ICQExtensionsService;
            sh.FamilySubtypeID = (ushort) ICQExtensionsService.MetaInformationRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            stream.WriteUshort(0x0001);
            stream.WriteUshort(0x000A);
            stream.WriteUshort(0x0008);
            stream.WriteUint(uint.Parse(sess.ScreenName));
            stream.WriteUshortLE(0x07D0);
            stream.WriteUshortLE((ushort) sh.RequestID);
            stream.WriteUshort(0x0998);
            stream.WriteUshort((ushort) Encoding.ASCII.GetByteCount(xml));
            stream.WriteString(xml, Encoding.ASCII);
            stream.WriteByte(0x00);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Пример #23
0
        /// <summary>
        /// Sends authorization request -- SNAC(17,02)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,07)</param>
        void SendAuthorizationRequest(DataPacket dp)
        {
            // Pull apart SNAC(17,07)
            byte[] key = dp.Data.ReadByteArray(dp.Data.ReadUshort());

            // Construct SNAC(17,02)
            SNACHeader header = new SNACHeader();
            header.FamilyServiceID = SNAC_AUTH_FAMILY;
            header.FamilySubtypeID = AUTH_LOGIN_REQUEST;

            OSCARIdentification id = parent.ClientIdentification;

            ByteStream stream = new ByteStream();
            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteString(0x0001, parent.ScreenName, Encoding.ASCII);
                tlvs.WriteString(0x0003, id.ClientName, Encoding.ASCII);
                tlvs.WriteString(0x000F, "en", Encoding.ASCII);
                tlvs.WriteString(0x000E, "us", Encoding.ASCII);
                tlvs.WriteUint(0x0014, id.ClientDistribution);
                tlvs.WriteUshort(0x0016, id.ClientId);
                tlvs.WriteUshort(0x0017, id.ClientMajor);
                tlvs.WriteUshort(0x0018, id.ClientMinor);
                tlvs.WriteUshort(0x0019, id.ClientLesser);
                tlvs.WriteUshort(0x001A, id.ClientBuild);
                tlvs.WriteByteArray(0x0025, parent.HashPassword(key));
                tlvs.WriteByte(0x004A, 0x01);
                tlvs.WriteEmpty(0x004C);
                stream.WriteTlvBlock(tlvs);
            }

            DataPacket newPacket = Marshal.BuildDataPacket(parent, header, stream);
            newPacket.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(newPacket);
        }
Пример #24
0
        /// <summary>
        /// Completes the initial connection to the AOL proxy server
        /// </summary>
        /// <remarks>This method is used to complete the proxy server transaction for both
        /// Stage 1 sending and Stage 2 receiver-redirect proxy scenarios</remarks>
        private void InitAolProxyConnectFinished()
        {
            try
            {
                ProxyInitializeSend();
                RendezvousProxyPacket rpp = ReadProxyPacket();
                if (rpp.Command == RendezvousProxyCommand.Acknowledge)
                {
                    using (ByteStream bstream = new ByteStream(rpp.Data))
                    {
                        Port = bstream.ReadUshort();
                        aolProxyIP = (new IPAddress(bstream.ReadByteArray(4))).ToString();
                    }

                    // Send the "send file" request on SNAC(04,06):02
                    parent.Messages.RequestDirectConnectionInvite(this);

                    // Wait for the proxy to send its 12 byte READY sequence
                    lock (socket)
                    {
                        socket.BeginRead(new byte[12], 0, 12, new AsyncCallback(ProxyReceivedReady), null);
                        //socket.BeginReceive(new byte[12], 0, 12, SocketFlags.None, new AsyncCallback(ProxyReceivedReady), null);
                    }
                }
                else
                {
                    ushort error = (ushort)((rpp.Data[0] << 8) | rpp.Data[1]);
                    if (error == 0x0004)
                    {
                        throw new Exception("Recipient not logged in");
                    }
                    else if (error == 0x000D)
                    {
                        throw new Exception("Client sent bad request");
                    }
                    throw new Exception("AOL proxy sent unknown error");
                }
            }
            catch (Exception ex)
            {
                if (DirectConnectionFailed != null)
                {
                    DirectConnectionFailed(ex.Message);
                }
            }
        }
Пример #25
0
        /// <summary>
        /// Synchronously reads a packet from a Rendezvous proxy connection
        /// </summary>
        private RendezvousProxyPacket ReadProxyPacket()
        {
            int bytesreceived = 0;

            byte[] header = new byte[12];
            while (bytesreceived < header.Length)
            {
                bytesreceived += socket.Read(header, bytesreceived, header.Length - bytesreceived);
            }
            Logging.DumpFLAP(header, "Rendezvous proxy read packet header");

            RendezvousProxyPacket retval = new RendezvousProxyPacket();
            using (ByteStream bstream = new ByteStream(header))
            {
                retval.Data = new byte[bstream.ReadUshort() - 10];
                bstream.AdvanceToPosition(4);
                retval.Command = (RendezvousProxyCommand)bstream.ReadUshort();
            }

            bytesreceived = 0;
            while (bytesreceived < retval.Data.Length)
            {
                bytesreceived +=
                    socket.Read(retval.Data, bytesreceived, retval.Data.Length - bytesreceived);
            }
            Logging.DumpFLAP(retval.Data, "Rendezvous proxy read packet data");
            return retval;
        }
Пример #26
0
        /// <summary>
        /// Hides the client's IP address from view
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        public static void HidePublicIP(ISession sess)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.ICQExtensionsService;
            sh.FamilySubtypeID = (ushort) ICQExtensionsService.MetaInformationRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            stream.WriteUshort(0x0001);
            stream.WriteUshort(0x000A);
            stream.WriteUshort(0x0008);
            stream.WriteUint(uint.Parse(sess.ScreenName));
            stream.WriteUshortLE(0x07D0);
            stream.WriteUshortLE((ushort) sh.RequestID);
            stream.WriteUshort(0x0424);
            stream.WriteUshort(0x0001);
            stream.WriteUshort(0x0001);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Пример #27
0
            public byte[] GetBytes()
            {
                ByteStream buffer = new ByteStream();

                buffer.WriteUshort((ushort)Encoding.UTF8.GetByteCount(item.Name));
                buffer.WriteString(item.Name, Encoding.UTF8);
                buffer.WriteUshort(item.GroupID);
                buffer.WriteUshort(item.ItemID);
                buffer.WriteUshort(item.ItemType);
                if (item.Tlvs == null)
                    buffer.WriteUshort(0x000);
                else
                {
                    buffer.WriteUshort((ushort)item.Tlvs.GetByteCount());
                    buffer.WriteTlvBlock(item.Tlvs);
                }

                return buffer.GetBytes();
            }
Пример #28
0
        /// <summary>
        /// Sends an out-of-the-country text message
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        /// <param name="number">The number to which to send the message</param>
        /// <param name="message">The message to send</param>
        /// <param name="alias">The sender's alias</param>
        /// <remarks><paramref name="message"/> must be in codepage 1252. A delivery receipt
        /// is automatically requested by this method.</remarks>
        public static void SendSMSMessage(ISession sess, string number, string message, string alias)
        {
            string xmlformat = "<icq_sms_message>\n" +
                               "\t<destination>{0}</destination>\n" +
                               "\t<text>{1}</text>\n" +
                               "\t<codepage>1252</codepage>\n" +
                               "\t<senders_UIN>{2}</senders_UIN>\n" +
                               "\t<senders_name>{3}</senders_name>\n" +
                               "\t<delivery_receipt>Yes</delivery_receipt>\n" +
                               "\t<time>{4}</time>\n" +
                               "</icq_sms_message>\n";

            string xml = String.Format(xmlformat,
                                       number,
                                       message,
                                       sess.ScreenName,
                                       alias,
                                       DateTime.Now.ToString("r"));

            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.ICQExtensionsService;
            sh.FamilySubtypeID = (ushort) ICQExtensionsService.MetaInformationRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            stream.WriteUshort(0x0001);
            stream.WriteUshort(0x000A);
            stream.WriteUshort(0x0008);
            stream.WriteUint(uint.Parse(sess.ScreenName));
            stream.WriteUshortLE(0x07D0);
            stream.WriteUshortLE((ushort) sh.RequestID);
            stream.WriteUshort(0x8214);
            stream.WriteUshort(0x0001);
            stream.WriteUshort(0x0016);
            stream.WriteUint(0x00000000);
            stream.WriteUint(0x00000000);
            stream.WriteUint(0x00000000);
            stream.WriteUint(0x00000000);
            stream.WriteUshort(0x0000);
            stream.WriteUshort((ushort) Encoding.ASCII.GetByteCount(xml));
            stream.WriteString(xml, Encoding.ASCII);
            stream.WriteByte(0x00);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Пример #29
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;
                    }
                }
            }
        }
Пример #30
0
 byte[] ISegment.GetBytes()
 {
     using (ByteStream buffer = new ByteStream())
     {
         buffer.WriteUshort((ushort)item.Type);
         buffer.WriteByte((byte)item.Flags);
         buffer.WriteByte((byte)item.Data.Length);
         buffer.WriteByteArray(item.Data);
         return buffer.GetBytes();
     }
 }
Пример #31
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;
                    }
                }
            }
        }