Exemple #1
0
        /// <summary>
        /// Sends service versions request -- SNAC(01,17)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        public static void RequestServiceVersions(DataPacket dp)
        {
            Session sess = dp.ParentSession;
            // Construct SNAC (01,17)
            SNACHeader sh = new SNACHeader();

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

            // Pack the family IDs and version numbers into a stream
            ushort[] families = sess.Connections.GetFamilies(dp.ParentConnection);

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

            ByteStream stream = new ByteStream();

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

            DataPacket dp2 = Marshal.BuildDataPacket(sess, sh, stream);

            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
Exemple #2
0
        /// <summary>
        /// Requests a full set of information about 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 GetAllICQInfo(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(0x04B2);
            stream.WriteUint(uint.Parse(screenname));

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Exemple #3
0
        /// <summary>
        /// Sets the client's extended status -- SNAC(01,1E)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <param name="availablemessage">The available message to set</param>
        /// <param name="flags">The ICQ flags to set</param>
        /// <param name="status">The ICQ status to set</param>
        /// <remarks>Either the available message or the flags/status can be set in one call to SetExtendedStatus</remarks>
        private static void SetExtendedStatus(Session sess, string availablemessage, ICQFlags flags, ICQStatus status)
        {
            SNACHeader sh = new SNACHeader();

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

            ByteStream stream = new ByteStream();

            if (availablemessage != null)
            {
                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);
            }
            else
            {
                uint stat = (uint)((ushort)flags << 16);
                stat |= (ushort)status;
                stream.WriteUint(0x00060004);
                stream.WriteUint(stat);
            }

            DataPacket dp = Marshal.BuildDataPacket(sess, sh, stream);

            dp.ParentConnection = sess.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Exemple #4
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));
        }
Exemple #5
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());
     }
 }
Exemple #6
0
        /// <summary>
        /// Allows the authorization to another client in the future
        /// </summary>
        /// <param name="sess">the session object</param>
        /// <param name="screenname">the destination screenname</param>
        /// <param name="reason">the reason for the future authorization</param>
        public static void SendFutureAuthorizationGrant(Session sess, string screenname, string reason)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.SSIService;
            sh.FamilySubtypeID = (ushort)SSIService.SendFutureAuthorizationGrant;


            ByteStream stream = new ByteStream();

            stream.WriteByte((byte)Encoding.ASCII.GetByteCount(screenname));
            stream.WriteString(screenname, Encoding.ASCII);

            stream.WriteUshort((ushort)sess.Encoding.GetByteCount(reason));
            stream.WriteString(reason, sess.Encoding);

            stream.WriteUshort(0x0000);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Exemple #7
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));
        }
Exemple #8
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));
        }
Exemple #9
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));
        }
Exemple #10
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));
        }
Exemple #11
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));
        }
Exemple #12
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);
            }
        }
Exemple #13
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);
            }
        }
Exemple #14
0
        /// <summary>
        /// Requests for the server side contact list.
        /// </summary>
        /// <param name="sess">the session object</param>
        /// <param name="modificationDate">the last client side modification date</param>
        /// <param name="isLocalTime">Determines if the given modification time is in the local or universal time format</param>
        /// <param name="itemCount">the total item count at the client side</param>
        public static void SendContactListCheckout(Session sess, DateTime modificationDate, bool isLocalTime,
                                                   ushort itemCount)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.SSIService;
            sh.FamilySubtypeID = (ushort)SSIService.ContactListCheckout;


            ByteStream stream       = new ByteStream();
            uint       modDateValue = ByteStream.ConvertDateTimeToUint(modificationDate, isLocalTime);

            stream.WriteUint(modDateValue);

            stream.WriteUshort(itemCount);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Exemple #15
0
        /// <summary>
        /// Sends a request for a new service family -- SNAC(01,04)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <param name="newfamily">The new family to request</param>
        public static void RequestNewService(Session sess, ushort newfamily)
        {
            SNACHeader sh = new SNACHeader();

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

            ByteStream stream = new ByteStream();

            stream.WriteUshort(newfamily);

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

            DataPacket dp = Marshal.BuildDataPacket(sess, sh, stream);

            // This one is always sent on BOS
            dp.ParentConnection = sess.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Exemple #16
0
        /// <summary>
        /// Sends an acknowledgement to the pause command -- SNAC(01,0C)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object to be paused</param>
        public static void SendPauseAcknowledgement(DataPacket dp)
        {
            Session sess = dp.ParentSession;

            SNACHeader sh = new SNACHeader();

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

            ByteStream stream = new ByteStream();

            ushort[] families = sess.Connections.GetFamilies(dp.ParentConnection);
            for (int i = 0; i < families.Length; i++)
            {
                stream.WriteUshort(families[i]);
            }

            DataPacket dp2 = Marshal.BuildDataPacket(sess, sh, stream);

            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
Exemple #17
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());
            }
Exemple #18
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));
        }
Exemple #19
0
        /// <summary>
        /// Notifies the BOS server that the client is ready to go online -- SNAC(01,02)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        /// <remarks>
        /// The client sends this SNAC to notify the server that it is ready to receive messages
        /// and online notifications.
        /// <para>
        /// This SNAC must be sent within 30 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.
        /// </para>
        /// </remarks>
        public static void SendReadyNotification(DataPacket dp)
        {
            // Build SNAC(01,02)
            SNACHeader sh = new SNACHeader();

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

            ConnectionManager cm = dp.ParentSession.Connections;

            ushort[]      families = cm.GetFamilies(dp.ParentConnection);
            FamilyManager fm       = dp.ParentSession.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] = dp.ParentSession.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.
             */
            Session sess = dp.ParentSession;

            if (!sess.LoggedIn)
            {
                SetExtendedStatus(sess, sess.AvailableMessage, ICQFlags.Normal, ICQStatus.Online);
                SetExtendedStatus(sess, null, ICQFlags.Normal, ICQStatus.Online);
            }

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

            // Build and send a new DataPacket instead of re-using the originator;
            // SNAC(01,02) was getting sent twice on child connections with the reuse
            DataPacket dp2 = Marshal.BuildDataPacket(dp.ParentSession, sh, stream);

            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);

            /*
             * 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 (sess.LoggedIn)
            {
                foreach (DataPacket[] list in delayedframes)
                {
                    if (list == null)
                    {
                        continue;
                    }
                    foreach (DataPacket dp_delay in list)
                    {
                        dp_delay.ParentConnection = dp.ParentConnection;
                        SNACFunctions.DispatchToRateClass(dp_delay);
                    }
                }

                if (isChatNavService)
                {
                    sess.ChatRooms.OnChatNavServiceAvailable();
                }
                else if (isChatRoomConnection)
                {
                    ChatRoom chatRoom = sess.Connections.GetChatByConnection((ChatConnection)dp.ParentConnection);
                    sess.ChatRooms.OnChatRoomConnectionAvailable(chatRoom);
                }
            }
        }
Exemple #20
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));
        }
Exemple #21
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));
        }
Exemple #22
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);
            }
        }
Exemple #23
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);
        }
Exemple #24
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);
        }
Exemple #25
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();
     }
 }
Exemple #26
0
        /// <summary>
        /// Uploads a buddy icon to the AIM servers
        /// </summary>
        /// <param name="filename">The filename of the icon to upload</param>
        public void UploadBuddyIcon(string filename)
        {
            // Check to make sure the local file exists
            if (!File.Exists(filename))
            {
                OnBuddyIconUploadFailed(BartReplyCode.NotFound);
                return;
            }

            byte[] data = null;
            using (StreamReader reader = new StreamReader(filename))
            {
                if (reader.BaseStream.Length > 7168) // 7KB
                {
                    OnBuddyIconUploadFailed(BartReplyCode.TooBig);
                    return;
                }

                if (!VerifyIcon(filename))
                {
                    OnBuddyIconUploadFailed(BartReplyCode.DimensionsTooBig);
                    return;
                }

                data = new byte[reader.BaseStream.Length];
                int index = 0;
                while (index < data.Length)
                {
                    index += reader.BaseStream.Read(data, index, data.Length - index);
                }
            }

            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BART_FAMILY;
            sh.FamilySubtypeID = BART_UPLOAD;
            sh.Flags = 0;

            ByteStream stream = new ByteStream();
            stream.WriteUshort((ushort)BartTypeId.BuddyIcon);
            stream.WriteUshort((ushort)data.Length);
            stream.WriteByteArray(data);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Exemple #27
0
        /// <summary>
        /// Requests a single type of user information from the server
        /// </summary>
        /// <param name="screenname">The screenname to get information about</param>
        /// <param name="requesttype">The type of information to retrieve</param>
        /// <remarks>Results are returned by the <see cref="UserInfoReceived"/> event</remarks>
        public void RequestBasicUserInfo(string screenname, BasicUserInfoRequest requesttype)
        {
            // Build SNAC(02,05)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_LOCATION_FAMILY;
            sh.FamilySubtypeID = LOCATION_REQUEST_BASIC_INFO;

            ByteStream stream = new ByteStream();
            stream.WriteUshort((ushort)requesttype);
            stream.WriteByte((byte)Encoding.ASCII.GetByteCount(screenname));
            stream.WriteString(screenname, Encoding.ASCII);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Exemple #28
0
        /// <summary>
        /// This method is invoked when the connection is complete
        /// </summary>
        protected virtual void OnConnectionFinished()
        {
            Connecting = true;

            // Read in the first ten bytes (6 byte FLAP channel 0x01 + 0x00000001)
            // of the connection handshake
            byte[] serverhandshake = new byte[10];
            try
            {
                int bytesreceived = 0;
                int receiveindex  = 0;
                lock (socket)
                {
                    while (bytesreceived < 10)
                    {
                        bytesreceived = socket.Read(serverhandshake, receiveindex, 10 - receiveindex);
                        receiveindex += bytesreceived;
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.WriteString("Can't read handshake from server: {0}, connection {1}", ex.Message, ID);
                DisconnectFromServer(true);
                return;
            }
            finally
            {
                serverhandshake = null;
            }

            // Construct our reply to the connection handshake
            using (ByteStream clientHandshake = new ByteStream())
            {
                FLAPHeader fh;
                fh.Channel = 0x01;
                fh.DatagramSequenceNumber = FLAPSequence;
                fh.DataSize = (ushort)(4 + ((cookie == null) ? 0 : 4 + cookie.GetByteCount()));

                clientHandshake.PrependOscarHeaders(fh, null);
                clientHandshake.WriteUint(Constants.PROTOCOL_VERSION);
                if (cookie != null)
                {
                    clientHandshake.WriteUshort(0x0006);
                    clientHandshake.WriteUshort((ushort)cookie.GetByteCount());
                    clientHandshake.WriteByteArray(cookie.ToByteArray());
                }

                try
                {
                    lock (socket)
                    {
                        socket.Write(clientHandshake.GetBytes());
                    }
                }
                catch (Exception ex)
                {
                    Logging.WriteString("Couldn't send handshake to server: {0}, connection {1}", ex.Message, ID);
                    DisconnectFromServer(true);
                    return;
                }
            }

            StopTimeoutPeriod();
            Connecting = true;

            // And the handshaking is done. Auth connection will send
            // SNAC(17,06) and any other connection will receive SNAC(01,03)
            OnServerConnectionCompleted();
        }
Exemple #29
0
        /// <summary>
        /// Sets the client's extended status -- SNAC(01,1E)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <param name="availablemessage">The available message to set</param>
        /// <param name="flags">The ICQ flags to set</param>
        /// <param name="status">The ICQ status to set</param>
        /// <remarks>Either the available message or the flags/status can be set in one call to SetExtendedStatus</remarks>
        private static void SetExtendedStatus(Session sess, string availablemessage, ICQFlags flags, ICQStatus status)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort)SNACFamily.BasicOscarService;
            sh.FamilySubtypeID = (ushort)GenericServiceControls.SetExtendedStatus;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            if (availablemessage != null)
            {
                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);
            }
            else
            {
                uint stat = (uint)((ushort)flags << 16);
                stat |= (ushort)status;
                stream.WriteUint(0x00060004);
                stream.WriteUint(stat);
            }

            DataPacket dp = Marshal.BuildDataPacket(sess, sh, stream);
            dp.ParentConnection = sess.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Exemple #30
0
        /// <summary>
        /// Notifies the BOS server that the client is ready to go online -- SNAC(01,02)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        /// <remarks>
        /// The client sends this SNAC to notify the server that it is ready to receive messages
        /// and online notifications.
        /// <para>
        /// This SNAC must be sent within 30 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.
        /// </para>
        /// </remarks>
        public static void SendReadyNotification(DataPacket dp)
        {
            // Build SNAC(01,02)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort)SNACFamily.BasicOscarService;
            sh.FamilySubtypeID = (ushort)GenericServiceControls.ClientOnline;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ConnectionManager cm = dp.ParentSession.Connections;
            ushort[] families = cm.GetFamilies(dp.ParentConnection);
            FamilyManager fm = dp.ParentSession.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] = dp.ParentSession.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.
               */
            Session sess = dp.ParentSession;
            if (!sess.LoggedIn)
            {
                SetExtendedStatus(sess, sess.AvailableMessage, ICQFlags.Normal, ICQStatus.Online);
                SetExtendedStatus(sess, null, ICQFlags.Normal, ICQStatus.Online);
            }

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

            // Build and send a new DataPacket instead of re-using the originator;
            // SNAC(01,02) was getting sent twice on child connections with the reuse
            DataPacket dp2 = Marshal.BuildDataPacket(dp.ParentSession, sh, stream);
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);

            /*
             * 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 (sess.LoggedIn)
            {
                foreach (DataPacket[] list in delayedframes)
                {
                    if (list == null) continue;
                    foreach (DataPacket dp_delay in list)
                    {
                        dp_delay.ParentConnection = dp.ParentConnection;
                        SNACFunctions.DispatchToRateClass(dp_delay);
                    }
                }

                if (isChatNavService)
                {
                    sess.ChatRooms.OnChatNavServiceAvailable();
                }
                else if (isChatRoomConnection)
                {
                    ChatRoom chatRoom = sess.Connections.GetChatByConnection((ChatConnection)dp.ParentConnection);
                    sess.ChatRooms.OnChatRoomConnectionAvailable(chatRoom);
                }
            }
        }
Exemple #31
0
        /// <summary>
        /// Sends an acknowledgement to the pause command -- SNAC(01,0C)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object to be paused</param>
        public static void SendPauseAcknowledgement(DataPacket dp)
        {
            Session sess = dp.ParentSession;

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

            ByteStream stream = new ByteStream();
            ushort[] families = sess.Connections.GetFamilies(dp.ParentConnection);
            for (int i = 0; i < families.Length; i++)
            {
                stream.WriteUshort(families[i]);
            }

            DataPacket dp2 = Marshal.BuildDataPacket(sess, sh, stream);
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
Exemple #32
0
        /// <summary>
        /// Sends service versions request -- SNAC(01,17)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        public static void RequestServiceVersions(DataPacket dp)
        {
            Session sess = dp.ParentSession;
            // Construct SNAC (01,17)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort)SNACFamily.BasicOscarService;
            sh.FamilySubtypeID = (ushort)GenericServiceControls.ServerServicesVersionRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            // Pack the family IDs and version numbers into a stream
            ushort[] families = sess.Connections.GetFamilies(dp.ParentConnection);

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

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

            DataPacket dp2 = Marshal.BuildDataPacket(sess, sh, stream);
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
Exemple #33
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));
        }
Exemple #34
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();
            }
Exemple #35
0
        /// <summary>
        /// Sends a status report to the OSCAR server -- SNAC(0B,03)
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        /// <remarks>libfaim does not send this report</remarks>
        public static void SendStatusReport(ISession sess)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.UsageStatsService;
            sh.FamilySubtypeID = (ushort)UsageStatsService.UsageReport;
            sh.Flags           = 0;
            sh.RequestID       = Session.GetNextRequestID();

            // Get the necessary strings together
            string sn = sess.ScreenName;
            // Here we start lying until I can figure out how to get *all* the values in .NET
            string osversion   = Environment.OSVersion.ToString();
            string osname      = "Windows 98";    //osversion.Substring(0, osversion.LastIndexOf(" ") - 1);
            string osver       = "4.10.67766446"; //osversion.Substring(osversion.LastIndexOf(" ") + 1);
            string procname    = "Intel Pentium";
            string winsockname = "Microsoft Corporation BSD Socket API for Windows";
            string winsockver  = "4.1.1998";

            Encoding enc               = Encoding.ASCII;
            byte     snlength          = (byte)enc.GetByteCount(sn);
            ushort   osversionlength   = (ushort)enc.GetByteCount(osversion);
            ushort   osnamelength      = (ushort)enc.GetByteCount(osname);
            ushort   osverlength       = (ushort)enc.GetByteCount(osver);
            ushort   procnamelength    = (ushort)enc.GetByteCount(procname);
            ushort   winsocknamelength = (ushort)enc.GetByteCount(winsockname);
            ushort   winsockverlength  = (ushort)enc.GetByteCount(winsockver);

            ByteStream mainStream = new ByteStream();

            using (ByteStream stream = new ByteStream())
            {
                TimeSpan t = (DateTime.Now - new DateTime(1970, 1, 1));
                stream.WriteUint((uint)t.Seconds);
                t = (DateTime.UtcNow - new DateTime(1970, 1, 1).ToUniversalTime());
                stream.WriteUint((uint)t.Seconds);
                stream.WriteUint(0x00000000);
                stream.WriteUint(0x00000000);
                stream.WriteUint(0x00000000);
                stream.WriteUint(0x00000000);
                stream.WriteByte(snlength);
                stream.WriteString(sn, Encoding.ASCII);
                stream.WriteUshort(osnamelength);
                stream.WriteString(osname, Encoding.ASCII);
                stream.WriteUshort(osverlength);
                stream.WriteString(osver, Encoding.ASCII);
                stream.WriteUshort(procnamelength);
                stream.WriteString(procname, Encoding.ASCII);
                stream.WriteUshort(winsocknamelength);
                stream.WriteString(winsockname, Encoding.ASCII);
                stream.WriteUshort(winsockverlength);
                stream.WriteString(winsockver, Encoding.ASCII);
                stream.WriteUint(0x00000002);
                stream.WriteUint(0x00010001);
                stream.WriteUint(0x00020002);

                using (TlvBlock tlv = new TlvBlock())
                {
                    tlv.WriteByteArray(0x0009, stream.GetBytes());
                    mainStream.WriteTlvBlock(tlv);
                }
            }

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, mainStream));
        }
Exemple #36
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);
        }
Exemple #37
0
        /// <summary>
        /// Allows the authorization to another client in the future
        /// </summary>
        /// <param name="sess">the session object</param>
        /// <param name="screenname">the destination screenname</param>
        /// <param name="reason">the reason for the future authorization</param>
        public static void SendFutureAuthorizationGrant(Session sess, string screenname, string reason)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.SSIService;
            sh.FamilySubtypeID = (ushort) SSIService.SendFutureAuthorizationGrant;

            ByteStream stream = new ByteStream();

            stream.WriteByte((byte) Encoding.ASCII.GetByteCount(screenname));
            stream.WriteString(screenname, Encoding.ASCII);

            stream.WriteUshort((ushort) sess.Encoding.GetByteCount(reason));
            stream.WriteString(reason, sess.Encoding);

            stream.WriteUshort(0x0000);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Exemple #38
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);
                }
            }
        }
Exemple #39
0
        /// <summary>
        /// Requests for the server side contact list.
        /// </summary>
        /// <param name="sess">the session object</param>
        /// <param name="modificationDate">the last client side modification date</param>
        /// <param name="isLocalTime">Determines if the given modification time is in the local or universal time format</param>
        /// <param name="itemCount">the total item count at the client side</param>
        public static void SendContactListCheckout(Session sess, DateTime modificationDate, bool isLocalTime,
                                                   ushort itemCount)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.SSIService;
            sh.FamilySubtypeID = (ushort) SSIService.ContactListCheckout;

            ByteStream stream = new ByteStream();
            uint modDateValue = ByteStream.ConvertDateTimeToUint(modificationDate, isLocalTime);
            stream.WriteUint(modDateValue);

            stream.WriteUshort(itemCount);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Exemple #40
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);
        }
Exemple #41
0
 /// <summary>
 /// Inserts an ICBM header
 /// </summary>
 private static void InsertIcbmHeader(ByteStream stream, Cookie cookie, ushort channel, string screenName)
 {
     stream.WriteByteArray(cookie.ToByteArray());
             stream.WriteUshort(channel);
             stream.WriteByte((byte)Encoding.ASCII.GetByteCount(screenName));
             stream.WriteString(screenName, Encoding.ASCII);
 }
Exemple #42
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));
        }
Exemple #43
0
        /// <summary>
        /// Sends a warning to a remote client -- SNAC(04,08)
        /// </summary>
        /// <param name="screenname">The screenname of the client to warn</param>
        /// <param name="anonymous">Send the warning as anonymous or as yourself</param>
        public void SendWarning(string screenname, bool anonymous)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_SEND_WARNING;

            ByteStream stream = new ByteStream();
            stream.WriteUshort((ushort)((anonymous) ? 1 : 0));
            stream.WriteByte((byte)Encoding.ASCII.GetByteCount(screenname));
            stream.WriteString(screenname, Encoding.ASCII);

            // Save the screenname so the handler for the reply SNAC can retrieve it
            parent.StoreRequestID(sh.RequestID, screenname);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Exemple #44
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));
        }
Exemple #45
0
        /// <summary>
        /// Sends a typing notification
        /// </summary>
        /// <param name="screenName">The screenname to receive the typing notification</param>
        /// <param name="tn">A <see cref="TypingNotification"/> enumeration specifying what
        /// notification to send</param>
        /// <exception cref="NotLoggedInException">Thrown when the <see cref="Session"/> is not logged in</exception>
        public void SendTypingNotification(string screenName, TypingNotification tn)
        {
            if (!parent.LoggedIn)
            {
                throw new NotLoggedInException();
            }

            DirectIMConnection conn = parent.Connections.GetDirectIMByScreenname(screenName);
            if (conn != null)
            {
                if (conn.Connected)
                {
                    // TODO:  send DIM typing notifications
                }
            }

            // Construct SNAC(04,14)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_TYPING_NOTIFICATION;

            ByteStream stream = new ByteStream();
            stream.WriteByteArray(new byte[] {0, 0, 0, 0, 0, 0, 0, 0});
            stream.WriteUshort(0x0001);
            stream.WriteByte((byte) Encoding.ASCII.GetByteCount(screenName));
            stream.WriteString(screenName, Encoding.ASCII);
            stream.WriteUshort((ushort) tn);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Exemple #46
0
        /// <summary>
        /// Sends a list of the client's capabilities to the server
        /// </summary>
        /// <remarks>This method sends SNAC(0x02,0x04)</remarks>
        public void ReportClientCapabilities()
        {
            if (parent.ClientCapabilities != Capabilities.None)
            {
                SNACHeader sh = new SNACHeader();
                sh.FamilyServiceID = SNAC_LOCATION_FAMILY;
                sh.FamilySubtypeID = LOCATION_PARAMETER_USERINFO;

                // Build the capabilities list, TLV type 0x0005
                byte[] caps = CapabilityProcessor.GetCapabilityArray(parent.ClientCapabilities);
                ByteStream stream = new ByteStream();
                stream.WriteUshort(LOCATION_CAPABILITIES);
                stream.WriteUshort((ushort)caps.Length);
                stream.WriteByteArray(caps);

                SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
            }
        }
Exemple #47
0
        /// <summary>
        /// Sends a request for a new service family -- SNAC(01,04)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <param name="newfamily">The new family to request</param>
        public static void RequestNewService(Session sess, ushort newfamily)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort)SNACFamily.BasicOscarService;
            sh.FamilySubtypeID = (ushort)GenericServiceControls.NewServiceRequest;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

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

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

            DataPacket dp = Marshal.BuildDataPacket(sess, sh, stream);
            // This one is always sent on BOS
            dp.ParentConnection = sess.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }