Example #1
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);
        }
Example #2
0
        /// <summary>
        /// Adds a frame to the delay queue
        /// </summary>
        /// <param name="sh">The SNAC header of the frame to add</param>
        /// <param name="data">A byte array consisting of the delayed frame</param>
        /// <returns><c>true</c> if a queue already existed for this family, or <c>false</c> if <see cref="ServiceManager.RequestNewService"/> should be called
        /// </returns>
        public bool AddFrameToDelayQueue(SNACHeader sh, byte[] data)
        {
            Queue  q      = null;
            bool   retval = true;
            ushort key    = sh.FamilyServiceID;

            DelayedFrame df = new DelayedFrame();

            df.SNAC = sh;
            df.Data = data;

            if (_delayqueues.ContainsKey(key))
            {
                q = (Queue)_delayqueues[key];
                q.Enqueue(df);
                retval = true;
            }
            else
            {
                q = new Queue();
                q.Enqueue(df);
                _delayqueues[key] = q;
                retval            = false;
            }
            return(retval);
        }
Example #3
0
        /// <summary>
        /// Adds a frame to the delay queue
        /// </summary>
        /// <param name="sh">The SNAC header of the frame to add</param>
        /// <param name="data">A byte array consisting of the delayed frame</param>
        /// <returns><c>true</c> if a queue already existed for this family, or <c>false</c> if <see cref="ServiceManager.RequestNewService"/> should be called
        /// </returns>
        public bool AddFrameToDelayQueue(SNACHeader sh, byte[] data)
        {
            Queue q = null;
            bool retval = true;
            ushort key = sh.FamilyServiceID;

            DelayedFrame df = new DelayedFrame();
            df.SNAC = sh;
            df.Data = data;

            if (_delayqueues.ContainsKey(key))
            {
                q = (Queue) _delayqueues[key];
                q.Enqueue(df);
                retval = true;
            }
            else
            {
                q = new Queue();
                q.Enqueue(df);
                _delayqueues[key] = q;
                retval = false;
            }
            return retval;
        }
Example #4
0
        /// <summary>
        /// Sets the user's directory information -- SNAC(02,09)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <param name="allow"><c>true</c> if other users may search this information, <c>false</c> if not</param>
        /// <param name="firstname">A first name</param>
        /// <param name="middlename">A middle name</param>
        /// <param name="lastname">A last name</param>
        /// <param name="maidenname">A maiden name</param>
        /// <param name="nickname">A nickname</param>
        /// <param name="city">A city</param>
        /// <param name="state">A state</param>
        /// <param name="country">A country (two-letter code)</param>
        /// <param name="zip">A ZIP code</param>
        /// <param name="address">An address</param>
        public static void SetDirectoryInformation(
            Session sess, bool allow,
            string firstname, string middlename, string lastname, string maidenname, string nickname,
            string city, string state, string country, string zip, string address)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.LocationService;
            sh.FamilySubtypeID = (ushort)LocationServices.UpdateDirectoryInfoRequest;



            ByteStream stream = new ByteStream();

            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteUshort(0x001A, (ushort)((allow) ? 0x0001 : 0x0000));
                tlvs.WriteString(DIRECTORY_FIRSTNAME, firstname, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_MIDDLENAME, middlename, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_LASTNAME, lastname, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_MAIDENNAME, maidenname, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_COUNTRY, country, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_STATE, state, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_CITY, city, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_NICKNAME, nickname, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_ZIPCODE, zip, Encoding.ASCII);
                tlvs.WriteString(DIRECTORY_ADDRESS, address, Encoding.ASCII);
                stream.WriteByteArray(tlvs.GetBytes());
            }

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Example #5
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));
        }
Example #6
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));
        }
Example #7
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);
        }
Example #8
0
        public static DataPacket BuildDataPacket(Session sess, SNACHeader header, ByteStream data)
        {
            DataPacket dp = new DataPacket(data);

            dp.ParentSession = sess;
            dp.SNAC          = header;
            return(dp);
        }
Example #9
0
        /// <summary>
        /// Requests that the server activate the client's SSI information -- SNAC(13,07)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <remarks>
        /// Sending this SNAC will cause the server to begin broadcasting online notifications
        /// to the contacts on the client's buddy list.
        /// </remarks>
        public static void ActivateSSI(Session sess)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort) SNACFamily.SSIService;
            sh.FamilySubtypeID = (ushort) SSIService.LoadContactList;

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, new ByteStream()));
        }
Example #10
0
        /// <summary>
        /// Finishes an SSI modification transaction -- SNAC(13,12)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        public static void SendEditComplete(Session sess)
        {
            SNACHeader sh = new SNACHeader();

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

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, new ByteStream()));
        }
Example #11
0
        /// <summary>
        /// Sends a request for the original SSI contact list -- SNAC(13,04)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        public static void RequestInitialContactList(Session sess)
        {
            SNACHeader sh = new SNACHeader();

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


            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, new ByteStream()));
        }
Example #12
0
        /// <summary>
        /// Requests a list of known interests -- SNAC(0F,04)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        public static void RequestInterestList(Session sess)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.DirectoryUserSearch;
            sh.FamilySubtypeID = (ushort)DirectorySearch.InterestsListRequest;


            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, new ByteStream()));
        }
Example #13
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));
        }
Example #14
0
        /// <summary>
        /// Reads an <see cref="SNACHeader"/> from the stream
        /// </summary>
        /// <returns>A populated <see cref="SNACHeader"/></returns>
        public SNACHeader ReadSnacHeader()
        {
            if (dataIndex + 10 > dataBuffer.Length)
            {
                throw new ByteStreamReadException(dataBuffer.Length, dataIndex, 10);
            }

            SNACHeader sh = new SNACHeader(ReadUshort(), ReadUshort(), ReadUshort(), ReadUint());

            return(sh);
        }
Example #15
0
 /// <summary>
 /// Writes a <see cref="SNACHeader"/> into the stream
 /// </summary>
 public void WriteSnacHeader(SNACHeader value)
 {
     lock (this)
     {
         dataSegments.Add(new UshortSegment(value.FamilyServiceID));
         dataSegments.Add(new UshortSegment(value.FamilySubtypeID));
         dataSegments.Add(new UshortSegment(value.Flags));
         dataSegments.Add(new UintSegment(value.RequestID));
         byteCount += 10;
     }
 }
Example #16
0
        /// <summary>
        /// (Obsolete) Sends a keepalive no-op -- SNAC(01,16)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <remarks>
        /// This SNAC is not used anymore. Channel 5 FLAPs should be used
        /// for keepalive, and are sent automatically by the <see cref="Connection"/>
        /// objects.
        /// </remarks>
        public static void SendNoOp(Session sess)
        {
            SNACHeader sh = new SNACHeader();

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

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, new ByteStream()));
        }
Example #17
0
 /// <summary>
 /// Prepends a <see cref="FLAPHeader"/> and a <see cref="SNACHeader"/> into the byte stream
 /// </summary>
 public void PrependOscarHeaders(FLAPHeader flap, SNACHeader snac)
 {
     lock (this)
     {
         dataSegments.Insert(0, new FlapSegment(flap));
         byteCount += 6;
         if (snac != null)
         {
             dataSegments.Insert(1, new SnacSegment(snac));
             byteCount += 10;
         }
     }
 }
Example #18
0
        /// <summary>
        /// Removes a series of SSI items from the server-side list -- SNAC(13,0A)
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="items">An array of <see cref="SSIItem"/> objects</param>
        public static void RemoveSSIItems(Session sess, SSIItem[] items)
        {
            SNACHeader sh = new SNACHeader();

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


            ByteStream stream = new ByteStream();

            stream.WriteSSIItems(items);
            sess.SSI.OutstandingRequests++;
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Example #19
0
        /// <summary>
        /// Delete yourself from another client server-side contact list.
        /// </summary>
        /// <param name="sess"></param>
        /// <param name="screenname">The contacts icq-number.</param>
        public static void RemoveMySSIItem(Session sess, string screenname)
        {
            SNACHeader sh = new SNACHeader();

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


            ByteStream stream = new ByteStream();

            stream.WriteByte((byte)screenname.Length);
            stream.WriteString(screenname, Encoding.ASCII);
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Example #20
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));
        }
Example #21
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);
            }
        }
Example #22
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);
        }
Example #23
0
        /// <summary>
        /// Sends a request for rate information -- SNAC(01,06)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        public static void RequestRateInformation(DataPacket dp)
        {
            Session sess = dp.ParentSession;

            // Construct SNAC (01,06)
            SNACHeader sh = new SNACHeader();

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

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

            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
Example #24
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);
            }
        }
Example #25
0
        /// <summary>
        /// Requests the client's own online information -- SNAC(01,0E)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        public static void RequestOwnInformation(Session sess)
        {
            SNACHeader sh = new SNACHeader();

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

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

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

            // Always gets sent on BOS
            dp.ParentConnection = sess.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Example #26
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));
        }
Example #27
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));
        }
Example #28
0
        /// <summary>
        /// Registers the user's screenname with the Location service -- SNAC(02,0B)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <remarks>
        /// The function of this SNAC is unknown, but the official AIM client (5.9.3861) sends it sometime
        /// after SNAC(01,02) is sent.
        /// </remarks>
        public static void SetSelfLocation(Session sess)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.LocationService;
            sh.FamilySubtypeID = (ushort)0x000B;



            ByteStream stream = new ByteStream();

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

            // This SNAC expects a response in SNAC(02,0C)
            sess.StoreRequestID(sh.RequestID, null);
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Example #29
0
        /// <summary>
        /// Performs a directory search by interest -- SNAC(0F,02)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <param name="interest">The interest to search for</param>
        public static void SearchByInterest(Session sess, string interest)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.DirectoryUserSearch;
            sh.FamilySubtypeID = (ushort)DirectorySearch.SearchUserRequest;


            ByteStream stream = new ByteStream();

            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteString(0x001C, "us-ascii", Encoding.ASCII);
                tlvs.WriteUshort(0x000A, 0x0001);
                tlvs.WriteString(0x0001, interest, Encoding.ASCII);
                stream.WriteTlvBlock(tlvs);
            }
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, stream));
        }
Example #30
0
        /// <summary>
        /// Creates a <see cref="DataPacket"/> from the beginning of the stream
        /// </summary>
        /// <returns>A new <see cref="DataPacket"/></returns>
        public DataPacket CreateDataPacket()
        {
            if (dataIndex != 0)
            {
                throw new Exception("A DataPacket can only be created from an unused ByteStream");
            }

            SNACHeader header = new SNACHeader(this);

            if ((header.Flags & 0x8000) != 0)
            {
                dataIndex += 2 + ReadUshort(); // Read past family version information
            }

            DataPacket retval = new DataPacket(this);

            retval.SNAC = header;
            return(retval);
        }
Example #31
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);
        }
Example #32
0
        /// <summary>
        /// Sets the client's privacy settings -- SNAC(01,14)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <param name="settings">The privacy flags to send to the server</param>
        public static void SetPrivacySettings(Session sess, uint settings)
        {
            SNACHeader sh = new SNACHeader();

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

            ByteStream stream = new ByteStream();

            stream.WriteUint(settings);

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

            // Always gets sent on BOS
            dp.ParentConnection = sess.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Example #33
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));
        }
Example #34
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));
        }
Example #35
0
        /// <summary>
        /// Sends a response to a client verification request -- SNAC(01,20)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        /// <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. This SNAC pair not been
        /// reported as being used in years.
        /// </remarks>
        public static void SendVerificationResponse(Session sess)
        {
            SNACHeader sh = new SNACHeader();

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

            ByteStream stream = new ByteStream();

            stream.WriteUint(0x44a95d26);
            stream.WriteUint(0xd2490423);
            stream.WriteUint(0x93b8821f);
            stream.WriteUint(0x51c54b01);

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

            dp.ParentConnection = sess.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Example #36
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);
        }
Example #37
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));
        }
Example #38
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);
        }
Example #39
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);
        }
Example #40
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);
            }
        }
Example #41
0
        /// <summary>
        /// Processes a pause request from the server -- SNAC(01,0B)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,0B)</param>
        private void ProcessPauseRequest(DataPacket dp)
        {
            // TODO:  Actually tell the connection to stop sending in preparation for the migration
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_PAUSE_CONNECTION_RESPONSE;

            DataPacket dp2 = Marshal.BuildDataPacket(parent, sh, new ByteStream());
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
Example #42
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);
        }
Example #43
0
        /// <summary>
        /// Creates a <see cref="DataPacket"/> from the beginning of the stream
        /// </summary>
        /// <returns>A new <see cref="DataPacket"/></returns>
        public DataPacket CreateDataPacket()
        {
            if (dataIndex != 0)
            {
                throw new Exception("A DataPacket can only be created from an unused ByteStream");
            }

            SNACHeader header = new SNACHeader(this);

            if ((header.Flags & 0x8000) != 0)
            {
                dataIndex += 2 + ReadUshort(); // Read past family version information
            }

            DataPacket retval = new DataPacket(this);
            retval.SNAC = header;
            return retval;
        }
Example #44
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));
        }
Example #45
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);
        }
Example #46
0
        /// <summary>
        /// Requests the client's own online information
        /// </summary>
        public void RequestOnlineInformation()
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_REQUEST_OWN_INFORMATION;

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, new ByteStream());
            // Always gets sent on BOS
            dp.ParentConnection = parent.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Example #47
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);
        }
Example #48
0
 /// <summary>
 /// Writes a <see cref="SNACHeader"/> into the stream
 /// </summary>
 public void WriteSnacHeader(SNACHeader value)
 {
     lock (this)
     {
         dataSegments.Add(new UshortSegment(value.FamilyServiceID));
         dataSegments.Add(new UshortSegment(value.FamilySubtypeID));
         dataSegments.Add(new UshortSegment(value.Flags));
         dataSegments.Add(new UintSegment(value.RequestID));
         byteCount += 10;
     }
 }
Example #49
0
        /// <summary>
        /// Reads an <see cref="SNACHeader"/> from the stream
        /// </summary>
        /// <returns>A populated <see cref="SNACHeader"/></returns>
        public SNACHeader ReadSnacHeader()
        {
            if (dataIndex + 10 > dataBuffer.Length)
            {
                throw new ByteStreamReadException(dataBuffer.Length, dataIndex, 10);
            }

            SNACHeader sh = new SNACHeader(ReadUshort(), ReadUshort(), ReadUshort(), ReadUint());
            return sh;
        }
Example #50
0
        /// <summary>
        /// Sends SNAC(01,06) in response to SNAC(01,18)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,18)</param>
        /// <remarks>OscarLib doesn't store the version list, so this method just sends SNAC(01,06) for rate limit info</remarks>
        private void ProcessVersionsListAndGetRateLimits(DataPacket dp)
        {
            // Construct SNAC (01,06)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_RATE_LIMIT_REQUST;

            DataPacket dp2 = Marshal.BuildDataPacket(parent, sh, new ByteStream());
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
Example #51
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();
        }
Example #52
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);
        }
Example #53
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));
        }
Example #54
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);
        }
Example #55
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));
        }
Example #56
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);
        }
Example #57
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);
        }
Example #58
0
 public SnacSegment(SNACHeader value)
 {
     header = value;
 }
Example #59
0
 /// <summary>
 /// Prepends a <see cref="FLAPHeader"/> and a <see cref="SNACHeader"/> into the byte stream
 /// </summary>
 public void PrependOscarHeaders(FLAPHeader flap, SNACHeader snac)
 {
     lock (this)
     {
         dataSegments.Insert(0, new FlapSegment(flap));
         byteCount += 6;
         if (snac != null)
         {
             dataSegments.Insert(1, new SnacSegment(snac));
             byteCount += 10;
         }
     }
 }
Example #60
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);
                }
            }
        }