Example #1
0
        internal Session(TcpClient client)
        {
            // Get a stream object for reading and writing
            stream = client.GetStream();

            readPacket = new ReadPacket(stream);
            writePacket = new WritePacket(stream);
            callback = new ReadPacket.CallbackDelegate(HandlePacket);
        }
        /// <summary>
        /// Read a negotiation packet from the client.
        /// </summary>
        /// <param name="packet">the reading packet</param>
        internal NegotiationHandler(ReadPacket packet)
        {
            int offset = 0;
            int recordType;
            while ((recordType = packet.ReadUnsignedByte()) != 0xFF)
            {
                records.Add(new Record(recordType, packet.ReadBeShort(), packet.ReadBeShort()));
                offset += 5;
            }
            offset++; // the ending mark 0xFF

            for (int i = 0; i < records.Count; i++)
            {
                offset = records[i].ReadData(offset, packet);
            }
        }
        internal LoginHandler(ReadPacket packet)
        {
            int currentPacketSize = packet.ReadInt();
            if (currentPacketSize != packet.DataAvailable + 4)
            {
                throw new IOException("Wrong Login Packet size:" + currentPacketSize);
            }
            int protocolVersion = packet.ReadInt();
            networkChunkSize = packet.ReadInt();
            if (networkChunkSize > 0xFFFF)
            {
                throw new IOException("Network Chunk Size to large:" + networkChunkSize);
            }

            packet.ReadInt(); // Unknown
            processID = packet.ReadInt();
            connectionID = packet.ReadInt();

            // 0x20: enable warning messages if USE <database> issued
            // 0x40: change to initial database must succeed
            // 0x80: enable warning messages if SET LANGUAGE issued
            packet.ReadByte();

            int loginFlags = packet.ReadByte();
            bool isNtlmLogin = (loginFlags & 0x80) > 0;
            if (isNtlmLogin)
            {
                //TODO add support for NTLM
                throw new IOException("NTLM login currently not implemented.");
            }

            packet.ReadByte(); // SQL Type
            packet.ReadByte();
            packet.ReadInt(); // Timezone
            packet.ReadInt(); // Collation

            int wsidOffset = packet.ReadUnsignedShort();
            int wsidLength = packet.ReadUnsignedShort();

            int userOffset = packet.ReadUnsignedShort();
            int userLength = packet.ReadUnsignedShort();

            int passOffset = packet.ReadUnsignedShort();
            int passLength = packet.ReadUnsignedShort();

            int applOffset = packet.ReadUnsignedShort();
            int applLength = packet.ReadUnsignedShort();

            int servOffset = packet.ReadUnsignedShort();
            int servLength = packet.ReadUnsignedShort();

            int unknOffset = packet.ReadUnsignedShort();
            int unknLength = packet.ReadUnsignedShort();

            int progOffset = packet.ReadUnsignedShort();
            int progLength = packet.ReadUnsignedShort();

            int langOffset = packet.ReadUnsignedShort();
            int langLength = packet.ReadUnsignedShort();

            int dbOffset = packet.ReadUnsignedShort();
            int dbLength = packet.ReadUnsignedShort();

            packet.Skip(6);

            int ntlmOffset = packet.ReadUnsignedShort();
            int ntlmLength = packet.ReadUnsignedShort();

            int packetSize2 = packet.ReadInt();
            if (currentPacketSize != packetSize2)
            {
                throw new IOException("Invalid login packet.");
            }

            int offset = 86;
            wsid = ReadString(ref offset, packet, wsidOffset, wsidLength);
            user = ReadString(ref offset, packet, userOffset, userLength);
            password = EncryptPassword(ReadString(ref offset, packet, passOffset, passLength));
            application = ReadString(ref offset, packet, applOffset, applLength);
            server = ReadString(ref offset, packet, servOffset, servLength);
            ReadString(ref offset, packet, unknOffset, unknLength);
            program = ReadString(ref offset, packet, progOffset, progLength);
            language = ReadString(ref offset, packet, langOffset, langLength);
            database = ReadString(ref offset, packet, dbOffset, dbLength);
        }
 /// <summary>
 /// Read the data and check if the offset is correct.
 /// </summary>
 /// <param name="offset">the desired offset</param>
 /// <param name="packet">the reading packet</param>
 /// <returns>The new offset after the data</returns>
 internal int ReadData(int offset, ReadPacket packet)
 {
     if (offset != this.offset)
     {
         throw new IOException("Invalid Record Offset");
     }
     data = packet.ReadBytes(size);
     return offset + size;
 }
 private static String ReadString(ref int offset, ReadPacket packet, int strOffset, int strLength)
 {
     if (strLength == 0)
     {
         return "";
     }
     if (offset < strOffset)
     {
         packet.Skip(strOffset - offset);
         offset = strOffset;
     }
     if (offset != strOffset)
     {
         throw new IOException("Invalid login packet");
     }
     offset += 2 * strLength;
     return packet.ReadString(strLength);
 }