/// <summary> /// Connect to Remote Admin Protocol /// </summary> /// <param name = "sessionname">local alias name for this connection</param> /// <param name = "host">host name</param> /// <param name = "login">authentication data</param> public static ICifsRemoteAdmin ConnectRemoteAdmin(string sessionname, string host, CifsLogin login) { // check if the admname connection is already open ICifsSession session = LookupSession(sessionname); if (session != null) { throw new CifsIoException("SS1", sessionname); } if (login == null) { login = fDefaultLogin; } var share = new Share(login); share.SetInfo(Share.IPC, host, "IPC$"); var nbt = new NbtSession(); SmbMessage smb = CifsSession.AllocateSmbMessage(); int protocol; CifsRemoteAdmin admin = null; try { protocol = CifsSession.Negotiate(nbt, share.HostName, smb); admin = new CifsRemoteAdmin(sessionname, protocol, share, nbt, smb); admin.Connect(); } catch (IOException e) { //nbt.doHangup(); if (admin != null) { admin.Dispose(); } else { nbt.DoHangup(); } throw; } return(admin); }
public void SendAndRecieve(NbtSession nbt, SmbMessage reply) { nbt.DoSend(this); if (Debug.DebugOn) { dumpPacket("Send SMB buffer"); } nbt.DoRecieve(reply); if (Debug.DebugOn) { dumpPacket("Recieve SMB buffer"); } }
internal CifsRemoteAdmin(string sessionname, int prot, Share share, NbtSession nbt, SmbMessage packet) : base(sessionname, prot, share, nbt, packet) { }
/// <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; }
/// <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> /// Disconnect the connection /// </summary> public void Disconnect() { DoTreeDisconnect(); //logoff(); if (fNBTSession != null) fNBTSession.DoHangup(); fNBTSession = null; fMsg = null; RemoveSession(fSessionName); }
/// <summary> /// Allocates SMB message buffer /// </summary> internal static SmbMessage AllocateSmbMessage() { SmbMessage m; lock (typeof (CifsSession)) { //m = new SMBMessage(CIFS_MAX_BUFFER_SIZE); m = new SmbMessage(1024); } return m; }
/// <summary> /// Reconnects server if disconnected /// </summary> public void Reconnect() { lock (this) { if (IsConnected) return; if (Debug.DebugOn) Debug.WriteLine(Debug.Info, "Reconnect session"); if (fMsg == null) fMsg = AllocateSmbMessage(); if (fNBTSession == null) fNBTSession = new NbtSession(); fConnectionLost = false; try { fProtocol = Negotiate(fNBTSession, fShare.HostName, fMsg); SetNegotiatedData(fMsg); Connect(); } catch (IOException e) { fNBTSession.DoHangup(); fNBTSession = null; throw e; } } // lock }
/// <summary> /// Constructor /// </summary> /// <param name = "sessionname">String identfying the session</param> /// <param name = "protocol"></param> /// <param name = "share">Share object</param> /// <param name = "nbt">NetBIOS session</param> /// <param name = "msg">Message containing negotiated data</param> internal CifsSession(string sessionname, int protocol, Share share, NbtSession nbt, SmbMessage msg) { fShare = share; fNBTSession = nbt; fMsg = msg; fProtocol = protocol; SetNegotiatedData(msg); if (sessionname == null) fSessionName = "Session" + fSessionNameCounter++; else fSessionName = sessionname; }
/// <summary> /// Initializes SMB message for SMB_COM_TRANSACTION_SECONDARY /// </summary> /// <param name = "msg">SMB message</param> /// <param name = "cmd">Command</param> internal void SetupSmbMessageSecondary(SmbMessage msg, byte cmd) // should be protected { msg.setCommand(cmd); msg.setUID(fUID); msg.setTID(fTID); msg.setPID(fPID); msg.setMID(fMID); msg.setCanHandleLongNames(); msg.setExtededAttributes(); }
/// <summary> /// Initializes the SMB message /// </summary> /// <param name = "msg">SMB message</param> /// <param name = "cmd">Command</param> internal void SetupSmbMessage(SmbMessage msg, byte cmd) // should be protected { msg.setCommand(cmd); msg.setUID(fUID); msg.setTID(fTID); msg.setPID(fPID); msg.setMID(nextMID()); msg.setCanHandleLongNames(); msg.setExtededAttributes(); if (cmd == SmbMessage.SMB_COM_TREE_CONNECT_ANDX || cmd == SmbMessage.SMB_COM_TREE_DISCONNECT || cmd == SmbMessage.SMB_COM_SESSION_SETUP_ANDX || cmd == SmbMessage.SMB_COM_LOGOFF_ANDX) return; CheckConnection(); }
public void SendAndRecieve(NbtSession nbt, SmbMessage reply) { nbt.DoSend(this); if(Debug.DebugOn) dumpPacket("Send SMB buffer"); nbt.DoRecieve(reply); if(Debug.DebugOn) dumpPacket("Recieve SMB buffer"); }