Esempio n. 1
0
        /// <summary>
        /// Sends a request for a new chat room connection -- SNAC(01,04)
        /// </summary>
        /// <param name="chatRoom">A <see cref="ChatRoom"/> object</param>
        internal void RequestChatRoomConnection(ChatRoom chatRoom)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = 0x0001;
            sh.FamilySubtypeID = 0x0004;



            ByteStream chatStream = new ByteStream();

            chatStream.WriteUshort(chatRoom.Exchange);
            chatStream.WriteByte((byte)Encoding.ASCII.GetByteCount(chatRoom.FullName));
            chatStream.WriteString(chatRoom.FullName, Encoding.ASCII);
            chatStream.WriteUshort(chatRoom.Instance);

            TlvBlock tlv = new TlvBlock();

            tlv.WriteByteArray(0x0001, chatStream.GetBytes());

            ByteStream mainStream = new ByteStream();

            mainStream.WriteUshort(0x000E);
            mainStream.WriteTlvBlock(tlv);

            parent.StoreRequestID(sh.RequestID, chatRoom);

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, mainStream);

            // This one is always sent on BOS
            dp.ParentConnection = parent.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Esempio n. 2
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);
        }
Esempio n. 3
0
        /// <summary>
        /// Sets the away message and/or profile of the client
        /// </summary>
        /// <param name="awayMessage">The away message to set</param>
        /// <param name="profile">The profile to set</param>
        private void SetAwayMessageProfileInternal(string awayMessage, string profile)
        {
            // Build the SNAC header
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = SNAC_LOCATION_FAMILY;
            sh.FamilySubtypeID = LOCATION_PARAMETER_USERINFO;

            ByteStream stream = new ByteStream();

            using (TlvBlock tlvs = new TlvBlock())
            {
                if (profile != null)
                {
                    Encoding profileEncoding = UtilityMethods.FindBestOscarEncoding(profile);
                    tlvs.WriteString(LOCATION_PROFILE_ENCODING, Marshal.EncodingToAolMime(profileEncoding), Encoding.ASCII);
                    tlvs.WriteString(LOCATION_PROFILE, profile, profileEncoding);
                }
                if (awayMessage != null)
                {
                    Encoding awayMessageEncoding = UtilityMethods.FindBestOscarEncoding(awayMessage);
                    tlvs.WriteString(LOCATION_AWAYMESSAGE_ENCODING, Marshal.EncodingToAolMime(awayMessageEncoding),
                                     Encoding.ASCII);
                    tlvs.WriteString(LOCATION_AWAYMESSAGE, awayMessage, awayMessageEncoding);
                }
                stream.WriteByteArray(tlvs.GetBytes());
            }

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Esempio n. 4
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);
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
        /// <summary>
        /// Sends a request for parameter information -- SNAC(09,02)
        /// </summary>
        /// <param name="sess">A <see cref="Session"/> object</param>
        public static void RequestParametersList(Session sess)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = (ushort)SNACFamily.PrivacyManagementService;
            sh.FamilySubtypeID = (ushort)PrivacyManagementService.ServiceParametersRequest;


            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, new ByteStream()));
        }
Esempio n. 7
0
        /// <summary>
        /// Requests parameter settings for the ChatNav SNAC family
        /// </summary>
        internal void RequestParameters()
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = SNAC_CHATNAV_FAMILY;
            sh.FamilySubtypeID = CHATNAV_PARAMETER_LIMITREQUEST;


            chatParameterRequests[sh.RequestID] = "parameters";

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, new ByteStream()));
        }
Esempio n. 8
0
        /// <summary>
        /// Requests parameter settings for the Location and Buddy Management SNAC families
        /// </summary>
        /// <remarks>This method sends both SNAC(0x02,0x02) and SNAC(0x03,0x02)</remarks>
        internal void RequestParameters()
        {
            SNACHeader header1 = new SNACHeader();

            header1.FamilyServiceID = SNAC_LOCATION_FAMILY;
            header1.FamilySubtypeID = LOCATION_PARAMETER_REQUEST;
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, header1, new ByteStream()));

            SNACHeader header2 = new SNACHeader();

            header2.FamilyServiceID = SNAC_BUDDY_FAMILY;
            header2.FamilySubtypeID = BUDDY_PARAMETER_REQUEST;
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, header2, new ByteStream()));
        }
Esempio n. 9
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);
        }
Esempio n. 10
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);
        }
Esempio n. 11
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);
        }
Esempio n. 12
0
        public void SendNewPassword(string password)
        {
            ByteStream stream = new ByteStream();

            stream.WriteUshortLE((ushort)password.Length);
            stream.WriteString(password, Encoding.ASCII);

            /* * * * * Header * * * * */
            SNACHeader sh = CreateIcqMetaHeader();

            stream = CreateMetaInfoHeader(parent, sh, MetaInfoRequestType.SetPassword, stream);

            //parent.StoreRequestID(sh.RequestID, screenname);
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Esempio n. 13
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);
        }
Esempio n. 14
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));
        }
Esempio n. 15
0
        /// <summary>
        /// Send a message to this chatroom using a specific character set and language
        /// </summary>
        /// <param name="message">The message to send</param>
        /// <param name="charset">The character set in which to encode the message</param>
        /// <param name="language">The two-letter code of the language of the message</param>
        private void SendMessage(string message, Encoding charset, string language)
        {
            if (!Connection.Connected)
            {
                // TODO:  The semantics here aren't right
                throw new NotLoggedInException();
            }

            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = 0x000E;
            sh.FamilySubtypeID = (ushort)ChatService.MessageFromClient;

            byte[] cookie = new byte[8];
            Random r      = new Random();

            r.NextBytes(cookie);

            ByteStream stream = new ByteStream();

            stream.WriteByteArray(cookie);
            stream.WriteUshort(0x0003);

            TlvBlock tlvs = new TlvBlock();

            using (TlvBlock messageBlock = new TlvBlock())
            {
                Encoding messageEncoding = UtilityMethods.FindBestOscarEncoding(message);

                messageBlock.WriteString(CHATMESSAGE_MESSAGE, message, messageEncoding);
                messageBlock.WriteString(CHATMESSAGE_CHARSET,
                                         UtilityMethods.OscarEncodingToString(messageEncoding), Encoding.ASCII);
                messageBlock.WriteString(CHATMESSAGE_LANGUAGE, language, Encoding.ASCII);
                messageBlock.WriteString(CHATMESSAGE_CONTENTTYPE, "text/x-aolrtf", Encoding.ASCII);
                messageBlock.WriteString(CHATMESSAGE_ENCODING, "binary", Encoding.ASCII);

                tlvs.WriteByteArray(0x0005, messageBlock.GetBytes());
            }
            tlvs.WriteEmpty(0x0001);

            stream.WriteTlvBlock(tlvs);

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

            dp.ParentConnection = Connection;
            SNACFunctions.BuildFLAP(dp);
        }
Esempio n. 16
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));
        }
Esempio n. 17
0
        /// <summary>
        /// <para>Request full user informations from Server. Strings are ASCII and UTF8.</para>
        /// <para>Works only with ICQ-Contacts not e.g. AOL-Contacts.</para>
        /// </summary>
        /// <param name="screenname">The screenname to get information about, see <see cref="Utility.ScreennameVerifier.IsValidICQ"/></param>
        /// <remarks>Results are returned by the <see cref="FullUserInfoReceived"/> event.</remarks>
        public void RequestFullUserInfo(string screenname)
        {
            if (!ScreennameVerifier.IsValidICQ(screenname))
            {
                return;
            }

            ByteStream stream = new ByteStream();

            // Metatoken
            SSIBuddy buddy = parent.SSI.GetBuddyByName(screenname);

            byte[] metatoken = (buddy != null ? buddy.MetaInfoToken : null);

            // Length
            ushort len_token = (ushort)(metatoken != null ? metatoken.Length + 4 : 0);
            ushort len_name  = (ushort)(Encoding.ASCII.GetByteCount(screenname) + 4);

            /* * * * * User * * * * */
            stream.WriteUshort(0x0003);
            stream.WriteUint((uint)1);
            stream.WriteUshort((ushort)(len_name + len_token));         // size to end

            // MetaToken for extendet userinfo
            if (metatoken != null)
            {
                stream.WriteUshort(0x003c);
                stream.WriteUshort((ushort)metatoken.Length);
                stream.WriteByteArray(metatoken);
            }

            // TLV Block
            stream.WriteUshort(0x0032);
            stream.WriteUshort((ushort)Encoding.ASCII.GetByteCount(screenname));
            stream.WriteString(screenname, Encoding.ASCII);

            /* * * * * Header * * * * */
            SNACHeader sh = CreateIcqMetaHeader();

            stream = CreateDirectoryHeader(DirectoryRequestType.QueryInfoRequest, stream);
            stream = CreateMetaInfoHeader(parent, sh, MetaInfoRequestType.DirectoryQueryRequest, stream);

            parent.StoreRequestID(sh.RequestID, DirecotyQueryType.InfoUser);
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Esempio n. 18
0
        /// <summary>
        /// Creates a new AIM chat room
        /// </summary>
        /// <param name="chatRoom">A <see cref="ChatRoom"/> object describing the room to create</param>
        /// <remarks>TODO:  I think this doesn't work, the fullname should be "create" maybe?</remarks>
        private void CreateChatRoom(ChatRoom chatRoom)
        {
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = SNAC_CHATNAV_FAMILY;
            sh.FamilySubtypeID = CHATNAV_CREATE_ROOM;



            ByteStream stream = new ByteStream();

            chatRoom.WriteToByteStream(stream);

            chatRoomCreationRequests[sh.RequestID] = chatRoom;
            chatParameterRequests[sh.RequestID]    = "create";

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Esempio n. 19
0
        /// <summary>
        /// <para>Request short user informations from Server. Strings are ASCII.</para>
        /// <para>Works only with ICQ-Contacts not e.g. AOL-Contacts.</para>
        /// </summary>
        /// <param name="screenname">The screenname to get information about, see <see cref="Utility.ScreennameVerifier.IsValidICQ"/></param>
        /// <remarks>Results are returned by the <see cref="ShortUserInfoReceived"/> event</remarks>
        public void RequestShortUserInfo(string screenname)
        {
            if (!ScreennameVerifier.IsValidICQ(screenname))
            {
                return;
            }

            ByteStream stream = new ByteStream();

            stream.WriteUintLE(uint.Parse(screenname));

            /* * * * * Header * * * * */
            SNACHeader sh = CreateIcqMetaHeader();

            stream = CreateMetaInfoHeader(parent, sh, MetaInfoRequestType.ShortUserInfoRequest, stream);

            parent.StoreRequestID(sh.RequestID, screenname);
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Esempio n. 20
0
        /// <summary>
        /// Downloads a buddy icon from the AIM servers
        /// </summary>
        /// <param name="screenName">The screenname to which the icon belongs</param>
        /// <param name="iconId">The ID of the icon stored on the server</param>
        public void DownloadBuddyIcon(string screenName, BartID iconId)
        {
            // Check to make sure the icon ID is valid and actually a buddy icon
            if (iconId == null || iconId.Data == null ||
                !(iconId.Type == BartTypeId.BuddyIcon || iconId.Type == BartTypeId.BigBuddyIcon))
            {
                return;
            }

            // Check to see if the icon's cached, if the cache location is set
            if (!String.IsNullOrEmpty(AutoSaveLocation))
            {
                string saveLocation = Path.Combine(AutoSaveLocation, iconId.ToString());
                if (File.Exists(saveLocation))
                {
                    OnBuddyIconDownloaded(screenName, iconId, saveLocation);
                    return;
                }
            }

            // Check to see if there's already a request in progress for this icon ID
            if (currentlyDownloading.Contains(iconId))
            {
                return;
            }
            currentlyDownloading.Add(iconId);

            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = SNAC_BART_FAMILY;
            sh.FamilySubtypeID = BART_DOWNLOAD;
            sh.Flags           = 0;


            ByteStream stream = new ByteStream();

            stream.WriteByte((byte)Encoding.ASCII.GetByteCount(screenName));
            stream.WriteString(screenName, Encoding.ASCII);
            stream.WriteByte(0x01);
            stream.WriteBartID(iconId);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Esempio n. 21
0
        /// <summary>
        /// Requests a list of accounts associated with an email address
        /// </summary>
        /// <param name="email">The email address to search for</param>
        /// <remarks>Results are returned by the <see cref="FindByEmailResults"/> event</remarks>
        /// <exception cref="NotLoggedInException">Thrown when the <see cref="Session"/> is not logged in</exception>
        public void FindUsersByEmail(string email)
        {
            if (!parent.LoggedIn)
            {
                throw new NotLoggedInException();
            }

            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = SNAC_USERLOOKUP_FAMILY;
            sh.FamilySubtypeID = USERLOOKUP_EMAIL_SEARCH;

            ByteStream stream = new ByteStream();

            stream.WriteString(email, Encoding.ASCII);

            parent.StoreRequestID(sh.RequestID, email);

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Esempio n. 22
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));
            }
        }
Esempio n. 23
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);
        }
Esempio n. 24
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);
        }
Esempio n. 25
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);
        }
Esempio n. 26
0
        /// <summary>
        /// Requests all user information from the server
        /// </summary>
        /// <param name="screenname">The screenname to get information about</param>
        /// <remarks>Results are returned by the <see cref="UserInfoReceived"/> event</remarks>
        public void RequestAllUserInfo(string screenname)
        {
            //KSD-SYSTEMS - commented at 24.02.2010 -> I want AllUserInfo, no Redirect
            // If the requested information is an ICQ name, redirect this
            //if (ScreennameVerifier.IsValidICQ(screenname))
            //{
            //    RequestBasicUserInfo(screenname, BasicUserInfoRequest.AwayMessage);
            //    return;
            //}

            // Build SNAC(02,15)
            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = SNAC_LOCATION_FAMILY;
            sh.FamilySubtypeID = LOCATION_REQUEST_ALL_INFO;

            ByteStream stream = new ByteStream();

            stream.WriteUint((uint)(UserInfoRequest.AwayMessage | UserInfoRequest.Capabilities | UserInfoRequest.UserProfile));
            stream.WriteByte((byte)Encoding.ASCII.GetByteCount(screenname));
            stream.WriteString(screenname, Encoding.ASCII);
            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
Esempio n. 27
0
        /// <summary>
        /// Sets the client's idle time.
        /// </summary>
        /// <param name="seconds">The client's idle time, in seconds</param>
        /// <remarks>
        /// <para>
        /// To remove idle status, set <paramref name="seconds"/> to zero.
        /// </para>
        /// <para>
        /// This method should be used only once to set the client as idle,
        /// or to remove idle status. The server updates the client's idle time
        /// automatically.  So, for example, if the client application wants the
        /// user to appear idle after ten minutes, the application should call
        /// this method after 10 minutes of being idle:
        /// <code>Session s;
        /// ...
        /// s.SetIdleTime(600);</code>
        /// The next time this method is called, it should be to remove idle status:
        /// <code>s.SetIdleTime(0);</code>
        /// </para>
        /// </remarks>
        /// <exception cref="NotLoggedInException">Thrown when the <see cref="Session"/> is not logged in</exception>
        public void SetIdleTime(uint seconds)
        {
            if (!parent.LoggedIn)
            {
                throw new NotLoggedInException();
            }

            SNACHeader sh = new SNACHeader();

            sh.FamilyServiceID = 0x0001;
            sh.FamilySubtypeID = 0x0011;



            ByteStream stream = new ByteStream();

            stream.WriteUint(seconds);

            // Always gets sent on BOS
            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);

            dp.ParentConnection = parent.Connections.BOSConnection;
            SNACFunctions.BuildFLAP(dp);
        }
Esempio n. 28
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();
        }
Esempio n. 29
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);
            }
        }
Esempio n. 30
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);
                }
            }
        }