/// <summary> /// Sets negotiated data /// </summary> /// <param name = "msg">SMB message returned by negotiation</param> private void SetNegotiatedData(SmbMessage msg) { // Security mode at position 2 fSecurityMode = msg.getByteParameterAt(2); fExtendedSecurity = ((fCapabilities & CAP_EXTENDED_SECURITY) != 0); fMaxPendingMPRequests = msg.getShortParameterAt(3); fMaxVCs = msg.getShortParameterAt(5); fMaxBufferSize = msg.getIntParameterAt(7); fMaxRawSize = msg.getIntParameterAt(11); fSessionKey = msg.getIntParameterAt(15); fCapabilities = msg.getIntParameterAt(19); // System time from 1601 in 100ns (ticks) long lo_time = msg.getIntParameterAt(23) & 0xffffffff; long hi_time = msg.getIntParameterAt(27) & 0xffffffff; // System time from 1601 in 100ns -> convert it to base 1/1/0001 fSystemTime = DateTime.FromFileTime((hi_time << 32) + lo_time).Ticks; fTimeZone = msg.getSignedShortParameterAt(31); fEncryptionKeyLen = msg.getByteParameterAt(33) & 0xff; int off = msg.getContentOffset(); byte[] msgbuf = msg.getMessageBuffer(); int content_size = msg.getContentSize(); if (!fExtendedSecurity) { // Encryption key fEncryptionKey = new byte[fEncryptionKeyLen]; for (int i = 0; i < fEncryptionKeyLen; i++) fEncryptionKey[i] = msgbuf[off + i]; } }
/// <summary> /// Negotiates protocol (we only support NT_LM_0_12). Calls NetBIOS /// </summary> /// <param name = "nbt">NetBIOS session</param> /// <param name = "nbtname">NetBIOS name</param> /// <param name = "msg">SMB Message</param> /// <returns>Negotiated protocol</returns> internal static int Negotiate(NbtSession nbt, string nbtname, SmbMessage msg) { if (Debug.DebugOn) Debug.WriteLine(Debug.Info, "SMB_COM_NEGOTIATE"); nbt.DoCall(nbtname); msg.setCommand(SmbMessage.SMB_COM_NEGOTIATE); msg.setPID(fPID); /** * struct { * UCHAR BufferFormat; // DT_DIALECT * UCHAR DialectName[]; // Null-terminated * } Dialects[]; */ var buf = new StringBuilder(); for (int i = 0; i < SUPPORTED_DIALECTS.Length; i++) { buf.Append((char) SmbMessage.DT_DIALECT); buf.Append(SUPPORTED_DIALECTS[i]); buf.Append('\0'); } msg.setContent(Encoding.UTF8.GetBytes(buf.ToString())); if (Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer) { Debug.WriteLine(Debug.Buffer, "Supported Dialects:"); Debug.WriteLine(Debug.Buffer, msg.getMessageBuffer(), 0, msg.getMessageSize()); } msg.SendAndRecieve(nbt, msg); if (Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer) { Debug.WriteLine(Debug.Buffer, "Dialects Response:"); Debug.WriteLine(Debug.Buffer, msg.getMessageBuffer(), 0, msg.getMessageSize()); } int protocol = msg.getParameter(0); if (protocol == -1) throw new CifsIoException("PE1"); if (protocol != NT_LM_0_12) throw new CifsIoException("PE2", SUPPORTED_DIALECTS[protocol]); if (msg.getWordCount() != 17) throw new CifsIoException("PE2", SUPPORTED_DIALECTS[protocol]); if (Debug.DebugOn && Debug.DebugLevel >= Debug.Info) Debug.WriteLine(Debug.Info, "Negotiated protocol: " + SUPPORTED_DIALECTS[protocol]); return protocol; }