コード例 #1
0
ファイル: Connection.cs プロジェクト: saroj82/OscarLib
        /// <summary>
        /// Sends a keepalive packet (FLAP channel 5)
        /// </summary>
        /// <param name="threadstate">Always <c>null</c></param>
        private void SendKeepalive(object threadstate)
        {
            using (ByteStream stream = new ByteStream())
            {
                FLAPHeader fh;
                fh.Channel = 0x05;
                fh.DatagramSequenceNumber = 0;
                fh.DataSize = 0;

                stream.PrependOscarHeaders(fh, null);

                try
                {
                    byte[] keepalive = stream.GetBytes();
                    Marshal.InsertUshort(keepalive, (ushort)FLAPSequence, 2);
                    lock (socket)
                    {
                        socket.Write(keepalive);
                    }
                    Logging.WriteString("Sent keepalive over connection {0}", ID);
                }
                catch (Exception ex)
                {
                    if (!isDisconnecting)
                    {
                        Logging.WriteString("Couldn't send keepalive: {0}, connection {1}", ex.Message, ID);
                        DisconnectFromServer(true);
                    }
                }

                keepAliveTimer.Change(60000, Timeout.Infinite);
            }
        }
コード例 #2
0
 byte[] ISegment.GetBytes()
 {
     using (ByteStream buffer = new ByteStream())
     {
         buffer.WriteUshort((ushort)item.Type);
         buffer.WriteByte((byte)item.Flags);
         buffer.WriteByte((byte)item.Data.Length);
         buffer.WriteByteArray(item.Data);
         return(buffer.GetBytes());
     }
 }
コード例 #3
0
ファイル: ByteStreamTests.cs プロジェクト: pkt30/OscarLib
        public void TestByteStreamNumberWriting()
        {
            ByteStream stream = new ByteStream();
            stream.WriteByte(0x08);
            stream.WriteUshort(0x4164);
            stream.WriteUint(0x7269656e);
            stream.WriteByteArray(new byte[] {0x6e, 0x65});

            Assert.AreEqual(testData.Length, stream.GetByteCount());
            ByteStream testStream = new ByteStream(stream.GetBytes());
            Assert.AreEqual("Adrienne", testStream.ReadString(testStream.ReadByte(), Encoding.ASCII));
        }
コード例 #4
0
ファイル: ByteStreamTests.cs プロジェクト: pkt30/OscarLib
        public void TestByteStreamStringWriting()
        {
            ByteStream stream = new ByteStream();
            stream.WriteByte((byte) Encoding.ASCII.GetByteCount("Adrienne"));
            stream.WriteString("Adrienne", Encoding.ASCII);

            Assert.AreEqual(testData.Length, stream.GetByteCount());
            byte[] data = stream.GetBytes();
            for (int i = 0; i < testData.Length; i++)
            {
                Assert.AreEqual(testData[i], data[i]);
            }
        }
コード例 #5
0
            public byte[] GetBytes()
            {
                ByteStream buffer = new ByteStream();

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

                return(buffer.GetBytes());
            }
コード例 #6
0
ファイル: ByteStream.cs プロジェクト: pkt30/OscarLib
 byte[] ISegment.GetBytes()
 {
     using (ByteStream buffer = new ByteStream())
     {
         buffer.WriteUshort((ushort)item.Type);
         buffer.WriteByte((byte)item.Flags);
         buffer.WriteByte((byte)item.Data.Length);
         buffer.WriteByteArray(item.Data);
         return buffer.GetBytes();
     }
 }
コード例 #7
0
ファイル: ByteStream.cs プロジェクト: pkt30/OscarLib
            public byte[] GetBytes()
            {
                ByteStream buffer = new ByteStream();

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

                return buffer.GetBytes();
            }
コード例 #8
0
ファイル: Session.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Returns an MD5 hash of the client's password, an authorization key, and a constant string
        /// </summary>
        /// <param name="authkey">The authorization key sent by the server</param>
        /// <returns>A 16-byte MD5 hash</returns>
        /// <remarks>
        /// <para>
        /// The hashing process is fairly simple:
        /// <list>
        /// <item>The authorization key is put into a buffer</item>
        /// <item>The password itself is hashed via MD5 and appended to the buffer</item>
        /// <item>The constant string, "AOL Instant Messenger (SM)", is appended to the buffer in plaintext</item>
        /// <item>The entire buffer is MD5 hashed and returned to the caller</item>
        /// </list>
        /// </para>
        /// <para>
        /// This method exists to prevent the password from having to be passed around in a data structure
        /// </para>
        /// </remarks>
        protected internal byte[] HashPassword(byte[] authkey)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

            ByteStream stream = new ByteStream();
            stream.WriteByteArray(authkey);
            stream.WriteByteArray(md5.ComputeHash(Encoding.ASCII.GetBytes(_password)));
            stream.WriteString(Constants.AIM_MD5_STRING, Encoding.ASCII);

            return md5.ComputeHash(stream.GetBytes());
        }
コード例 #9
0
ファイル: Connection.cs プロジェクト: saroj82/OscarLib
        /// <summary>
        /// This method is invoked when the connection is complete
        /// </summary>
        protected virtual void OnConnectionFinished()
        {
            Connecting = true;

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

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

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

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

            StopTimeoutPeriod();
            Connecting = true;

            // And the handshaking is done. Auth connection will send
            // SNAC(17,06) and any other connection will receive SNAC(01,03)
            OnServerConnectionCompleted();
        }
コード例 #10
0
        /// <summary>
        /// Sends a status report to the OSCAR server -- SNAC(0B,03)
        /// </summary>
        /// <param name="sess">A <see cref="ISession"/> object</param>
        /// <remarks>libfaim does not send this report</remarks>
        public static void SendStatusReport(ISession sess)
        {
            SNACHeader sh = new SNACHeader();

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

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

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

            ByteStream mainStream = new ByteStream();

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

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

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(sess, sh, mainStream));
        }
コード例 #11
0
ファイル: MessageManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Cancel a direct connection attempt
        /// </summary>
        public void SendDirectConnectionCancellation(DirectConnection conn, string reason)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_OUTGOING_MESSAGE;

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

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

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

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
コード例 #12
0
ファイル: MessageManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Accept a direct connection attempt
        /// </summary>
        public void SendDirectConnectionAccept(DirectConnection conn)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_OUTGOING_MESSAGE;

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

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

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
コード例 #13
0
ファイル: MessageManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Sends a direct connection request
        /// </summary>
        /// <param name="conn">A <see cref="DirectConnection"/> object that will handle the request</param>
        public void RequestDirectConnectionInvite(DirectConnection conn)
        {
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_ICBM_FAMILY;
            sh.FamilySubtypeID = ICBM_OUTGOING_MESSAGE;

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

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

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

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

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

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

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

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

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

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

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

            SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
        }
コード例 #14
0
ファイル: MessageManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Invites an AIM user to an AOL chatroom
        /// </summary>
        /// <param name="chatroom">The <see cref="ChatRoom"/> describing the chatroom</param>
        /// <param name="screenName">The screenname of the user to invite</param>
        /// <param name="message">A message to send along with the invitation</param>
        public Cookie InviteToChatRoom(ChatRoom chatroom, string screenName, string message)
        {
            if (!parent.LoggedIn)
            {
                throw new NotLoggedInException();
            }

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

            Cookie cookie = Cookie.CreateCookieForSending();

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

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

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

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

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

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

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

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

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

            return cookie;
        }
コード例 #15
0
ファイル: MessageManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Sends an ICBM on channel 1 -- SNAC(04,06)
        /// </summary>
        /// <param name="destination">The screenname to receive the IM</param>
        /// <param name="message">The message to send</param>
        /// <param name="flags">A <see cref="OutgoingMessageFlags"/> enumeration specifying what
        /// additional information should be sent with the message</param>
        private Cookie SendMessageThroughServer(string destination, string message, OutgoingMessageFlags flags)
        {
            SNACHeader sh = new SNACHeader();
                    sh.FamilyServiceID = SNAC_ICBM_FAMILY;
                    sh.FamilySubtypeID = ICBM_OUTGOING_MESSAGE;

                    byte[] default_features = new byte[] { 0x01, 0x01, 0x01, 0x02 };
                    Cookie cookie = Cookie.CreateCookieForSending();
                    Encoding encoding = UtilityMethods.FindBestOscarEncoding(message);

                    ByteStream stream = new ByteStream();

                    InsertIcbmHeader(stream, cookie, 0x0001, destination);
                    using (TlvBlock tlvs = new TlvBlock())
                    {
                        // Write in TLV 0x0002: a text message
                        using (TlvBlock tlv02 = new TlvBlock())
                        {
                            tlv02.WriteByteArray(0x0501, default_features);
                            ByteStream feature0101 = new ByteStream();
                            feature0101.WriteUshort(Marshal.EncodingToCharset(encoding));
                            feature0101.WriteUshort(0x0000);
                            feature0101.WriteString(message, encoding);
                            tlv02.WriteByteArray(0x0101, feature0101.GetBytes());
                            tlvs.WriteByteArray(0x0002, tlv02.GetBytes());
                        }

                        // Pack in optional TLVs
                        if ((flags & OutgoingMessageFlags.AutoResponse) != 0)
                        {
                            tlvs.WriteEmpty(0x0004);
                        }
                        else
                        {
                            // Request a notification of delivery - note that this can't happen
                            // with an AutoResponse flag set, otherwise the message is bounced
                            tlvs.WriteEmpty(0x0003);
                        }

                        if ((flags & OutgoingMessageFlags.DeliverOffline) != 0
                            && (flags & OutgoingMessageFlags.AutoResponse) == 0)
                        {
                            // Try to store if the user is offline
                            tlvs.WriteEmpty(0x0006);
                        }

                        // Add the TLVs to the byte stream
                        stream.WriteByteArray(tlvs.GetBytes());
                    }

                    // Cache the message for delivery updates
                    messageStatuses.Add(sh.RequestID, new MessageStatusEventArgs(cookie, destination));

                    // Send that sucker off
                    SNACFunctions.BuildFLAP(Marshal.BuildDataPacket(parent, sh, stream));
                    return cookie;
        }