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); }