/// <exception cref="WinrtCifs.Smb.SmbException"></exception> internal virtual void CheckStatus(ServerMessageBlock req, ServerMessageBlock resp ) { resp.ErrorCode = SmbException.GetStatusByCode(resp.ErrorCode); switch (resp.ErrorCode) { case NtStatus.NtStatusOk: { break; } case NtStatus.NtStatusAccessDenied: case NtStatus.NtStatusWrongPassword: case NtStatus.NtStatusLogonFailure: case NtStatus.NtStatusAccountRestriction: case NtStatus.NtStatusInvalidLogonHours: case NtStatus.NtStatusInvalidWorkstation: case NtStatus.NtStatusPasswordExpired: case NtStatus.NtStatusAccountDisabled: case NtStatus.NtStatusAccountLockedOut: case NtStatus.NtStatusTrustedDomainFailure: { throw new SmbAuthException(resp.ErrorCode); } case NtStatus.NtStatusPathNotCovered: { if (req.Auth == null) { throw new SmbException(resp.ErrorCode, null); } DfsReferral dr = GetDfsReferrals(req.Auth, req.Path, 1); if (dr == null) { throw new SmbException(resp.ErrorCode, null); } SmbFile.Dfs.Insert(req.Path, dr); throw dr; } case unchecked ((int)(0x80000005)): { break; } case NtStatus.NtStatusMoreProcessingRequired: { break; } default: { throw new SmbException(resp.ErrorCode, null); } } if (resp.VerifyFailed) { throw new SmbException("Signature verification failed."); } }
internal AndXServerMessageBlock(ServerMessageBlock andx) { if (andx != null) { this.Andx = andx; _andxCommand = andx.Command; } }
/// <exception cref="System.IO.IOException"></exception> protected internal override void MakeKey(ServerMessageBlock request) { if (++Mid == 32000) { Mid = 1; } request.Mid = Mid; }
internal SmbComOpenAndX(string fileName, int access, int flags, ServerMessageBlock andx) : base(andx) { // flags (not the same as flags constructor argument) // Access Mode Encoding for desiredAccess // bit 12 // bit 14 // flags is NOT the same as flags member Path = fileName; Command = SmbComOpenAndx; DesiredAccess = access & 0x3; if (DesiredAccess == 0x3) { DesiredAccess = 0x2; } DesiredAccess |= SharingDenyNone; DesiredAccess &= ~0x1; // Win98 doesn't like GENERIC_READ ?! -- get Access Denied. // searchAttributes SearchAttributes = SmbConstants.AttrDirectory | SmbConstants.AttrHidden | SmbConstants.AttrSystem; // fileAttributes FileAttributes = 0; // openFunction if ((flags & SmbFile.OTrunc) == SmbFile.OTrunc) { // truncate the file if ((flags & SmbFile.OCreat) == SmbFile.OCreat) { // create it if necessary OpenFunction = OpenFnTrunc | OpenFnCreate; } else { OpenFunction = OpenFnTrunc; } } else { // don't truncate the file if ((flags & SmbFile.OCreat) == SmbFile.OCreat) { // create it if necessary if ((flags & SmbFile.OExcl) == SmbFile.OExcl) { // fail if already exists OpenFunction = OpenFnCreate | OpenFnFailIfExists; } else { OpenFunction = OpenFnCreate | OpenFnOpen; } } else { OpenFunction = OpenFnOpen; } } }
/// <exception cref="System.IO.IOException"></exception> protected internal override void DoRecv(Response response) { ServerMessageBlock resp = (ServerMessageBlock)response; resp.UseUnicode = UseUnicode; resp.ExtendedSecurity = (Capabilities & SmbConstants.CapExtendedSecurity) == SmbConstants.CapExtendedSecurity; lock (Buf) { Array.Copy(Sbuf, 0, Buf, 0, 4 + SmbConstants.HeaderLength); int size = Encdec.Dec_uint16be(Buf, 2) & 0xFFFF; if (size < (SmbConstants.HeaderLength + 1) || (4 + size) > RcvBufSize) { throw new IOException("Invalid payload size: " + size); } int errorCode = Encdec.Dec_uint32le(Buf, 9) & unchecked ((int)(0xFFFFFFFF)); if (resp.Command == ServerMessageBlock.SmbComReadAndx && (errorCode == 0 || errorCode == unchecked ((int)(0x80000005)))) { // overflow indicator normal for pipe SmbComReadAndXResponse r = (SmbComReadAndXResponse)resp; int off = SmbConstants.HeaderLength; Readn(In, Buf, 4 + off, 27); off += 27; resp.Decode(Buf, 4); int pad = r.DataOffset - off; if (r.ByteCount > 0 && pad > 0 && pad < 4) { Readn(In, Buf, 4 + off, pad); } if (r.DataLength > 0) { Readn(In, r.B, r.Off, r.DataLength); } } else { Readn(In, Buf, 4 + 32, size - 32); resp.Decode(Buf, 4); if (resp is SmbComTransactionResponse) { ((SmbComTransactionResponse)resp).Current(); } } if (Digest != null && resp.ErrorCode == 0) { Digest.Verify(Buf, 4, resp); } if (Log.Level >= 4) { Log.WriteLine(response); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, Buf, 4, size); } } } }
internal virtual int WriteAndXWireFormat(byte[] dst, int dstIndex) { int start = dstIndex; WordCount = WriteParameterWordsWireFormat(dst, start + AndxOffsetOffset + 2); WordCount += 4; // for command, reserved, and offset dstIndex += WordCount + 1; WordCount /= 2; dst[start] = unchecked ((byte)(WordCount & unchecked (0xFF))); ByteCount = WriteBytesWireFormat(dst, dstIndex + 2); dst[dstIndex++] = unchecked ((byte)(ByteCount & unchecked (0xFF))); dst[dstIndex++] = unchecked ((byte)((ByteCount >> 8) & unchecked (0xFF))); dstIndex += ByteCount; if (Andx == null || SmbConstants.UseBatching == false || BatchLevel >= GetBatchLimit(Andx.Command )) { _andxCommand = unchecked (unchecked (0xFF)); Andx = null; dst[start + AndxCommandOffset] = unchecked (unchecked (0xFF)); dst[start + AndxReservedOffset] = unchecked (unchecked (0x00)); // dst[start + ANDX_OFFSET_OFFSET] = (byte)0x00; // dst[start + ANDX_OFFSET_OFFSET + 1] = (byte)0x00; dst[start + AndxOffsetOffset] = unchecked (unchecked (0xde)); dst[start + AndxOffsetOffset + 1] = unchecked (unchecked (0xde)); // andx not used; return return(dstIndex - start); } Andx.BatchLevel = BatchLevel + 1; dst[start + AndxCommandOffset] = _andxCommand; dst[start + AndxReservedOffset] = unchecked (unchecked (0x00)); _andxOffset = dstIndex - HeaderStart; WriteInt2(_andxOffset, dst, start + AndxOffsetOffset); Andx.UseUnicode = UseUnicode; if (Andx is AndXServerMessageBlock) { Andx.Uid = Uid; dstIndex += ((AndXServerMessageBlock)Andx).WriteAndXWireFormat(dst, dstIndex ); } else { // the andx smb is not of type andx so lets just write it here and // were done. int andxStart = dstIndex; Andx.WordCount = Andx.WriteParameterWordsWireFormat(dst, dstIndex); dstIndex += Andx.WordCount + 1; Andx.WordCount /= 2; dst[andxStart] = unchecked ((byte)(Andx.WordCount & unchecked (0xFF))); Andx.ByteCount = Andx.WriteBytesWireFormat(dst, dstIndex + 2); dst[dstIndex++] = unchecked ((byte)(Andx.ByteCount & unchecked (0xFF))); dst[dstIndex++] = unchecked ((byte)((Andx.ByteCount >> 8) & unchecked (0xFF) )); dstIndex += Andx.ByteCount; } return(dstIndex - start); }
/// <exception cref="WinrtCifs.Smb.SmbException"></exception> internal virtual void TreeConnect(ServerMessageBlock andx, ServerMessageBlock andxResponse ) { lock (Session.Transport()) { string unc; while (ConnectionState != 0) { if (ConnectionState == 2 || ConnectionState == 3) { // connected or disconnecting return; } try { Runtime.Wait(Session.transport); } catch (Exception ie) { throw new SmbException(ie.Message, ie); } } ConnectionState = 1; // trying ... try { Session.transport.Connect(); unc = "\\\\" + Session.transport.TconHostName + '\\' + Share; Service = Service0; if (Session.transport.Log.Level >= 4) { Session.transport.Log.WriteLine("treeConnect: unc=" + unc + ",service=" + Service ); } SmbComTreeConnectAndXResponse response = new SmbComTreeConnectAndXResponse(andxResponse ); SmbComTreeConnectAndX request = new SmbComTreeConnectAndX(Session, unc, Service, andx); Session.Send(request, response); Tid = response.Tid; Service = response.Service; InDfs = response.ShareIsInDfs; TreeNum = _treeConnCounter++; ConnectionState = 2; } catch (SmbException e) { // connected TreeDisconnect(true); ConnectionState = 0; throw e; } } }
internal SmbComWriteAndX(int fid, long offset, int remaining, byte[] b, int off, int len, ServerMessageBlock andx) : base(andx) { this._fid = fid; this._offset = offset; this._remaining = remaining; this._b = b; this._off = off; _dataLength = len; Command = SmbComWriteAndx; }
internal virtual int Decode(byte[] buf, int bi) { Allow = buf[bi++] == unchecked (unchecked (0x00)); Flags = buf[bi++] & unchecked (0xFF); int size = ServerMessageBlock.ReadInt2(buf, bi); bi += 2; Access = ServerMessageBlock.ReadInt4(buf, bi); bi += 4; Sid = new Sid(buf, bi); return(size); }
/// <exception cref="System.IO.IOException"></exception> public virtual int Decode(byte[] buffer, int bufferIndex, int len) { int start = bufferIndex; bufferIndex++; // revision bufferIndex++; Type = ServerMessageBlock.ReadInt2(buffer, bufferIndex); bufferIndex += 2; ServerMessageBlock.ReadInt4(buffer, bufferIndex); // offset to owner sid bufferIndex += 4; ServerMessageBlock.ReadInt4(buffer, bufferIndex); // offset to group sid bufferIndex += 4; ServerMessageBlock.ReadInt4(buffer, bufferIndex); // offset to sacl bufferIndex += 4; int daclOffset = ServerMessageBlock.ReadInt4(buffer, bufferIndex); bufferIndex = start + daclOffset; bufferIndex++; // revision bufferIndex++; int size = ServerMessageBlock.ReadInt2(buffer, bufferIndex); bufferIndex += 2; int numAces = ServerMessageBlock.ReadInt4(buffer, bufferIndex); bufferIndex += 4; if (numAces > 4096) { throw new IOException("Invalid SecurityDescriptor"); } if (daclOffset != 0) { Aces = new Ace[numAces]; for (int i = 0; i < numAces; i++) { Aces[i] = new Ace(); bufferIndex += Aces[i].Decode(buffer, bufferIndex); } } else { Aces = null; } return(bufferIndex - start); }
public Sid(byte[] src, int si) { Revision = src[si++]; SubAuthorityCount = src[si++]; IdentifierAuthority = new byte[6]; Array.Copy(src, si, IdentifierAuthority, 0, 6); si += 6; if (SubAuthorityCount > 100) { throw new RuntimeException("Invalid SID sub_authority_count"); } SubAuthority = new int[SubAuthorityCount]; for (int i = 0; i < SubAuthorityCount; i++) { SubAuthority[i] = ServerMessageBlock.ReadInt4(src, si); si += 4; } }
/// <summary>Performs MAC signing of the SMB.</summary> /// <remarks> /// Performs MAC signing of the SMB. This is done as follows. /// The signature field of the SMB is overwritted with the sequence number; /// The MD5 digest of the MAC signing key + the entire SMB is taken; /// The first 8 bytes of this are placed in the signature field. /// </remarks> /// <param name="data">The data.</param> /// <param name="offset">The starting offset at which the SMB header begins.</param> /// <param name="length">The length of the SMB data starting at offset.</param> internal virtual void Sign(byte[] data, int offset, int length, ServerMessageBlock request, ServerMessageBlock response) { request.SignSeq = _signSequence; if (response != null) { response.SignSeq = _signSequence + 1; response.VerifyFailed = false; } try { Update(_macSigningKey, 0, _macSigningKey.Length); int index = offset + SmbConstants.SignatureOffset; for (int i = 0; i < 8; i++) { data[index + i] = 0; } ServerMessageBlock.WriteInt4(_signSequence, data, index); Update(data, offset, length); Array.Copy(Digest(), 0, data, index, 8); if (_bypass) { _bypass = false; Array.Copy(Runtime.GetBytesForString("BSRSPYL "), 0, data, index, 8); } } catch (Exception ex) { if (Log.Level > 0) { Runtime.PrintStackTrace(ex, Log); } } finally { _signSequence += 2; } }
/// <exception cref="WinrtCifs.Smb.SmbException"></exception> internal void Send(ServerMessageBlock request, ServerMessageBlock response) { lock (Transport()) { if (response != null) { response.Received = false; } Expiration = Runtime.CurrentTimeMillis() + SmbConstants.SoTimeout; SessionSetup(request, response); if (response != null && response.Received) { return; } if (request is SmbComTreeConnectAndX) { SmbComTreeConnectAndX tcax = (SmbComTreeConnectAndX)request; if (NetbiosName != null && tcax.path.EndsWith("\\IPC$")) { tcax.path = "\\\\" + NetbiosName + "\\IPC$"; } } request.Uid = Uid; request.Auth = Auth; try { transport.Send(request, response); } catch (SmbException) { if (request is SmbComTreeConnectAndX) { Logoff(true); } request.Digest = null; throw; } } }
/// <summary>Performs MAC signature verification.</summary> /// <remarks> /// Performs MAC signature verification. This calculates the signature /// of the SMB and compares it to the signature field on the SMB itself. /// </remarks> /// <param name="data">The data.</param> /// <param name="offset">The starting offset at which the SMB header begins.</param> /// <param name="length">The length of the SMB data starting at offset.</param> internal virtual bool Verify(byte[] data, int offset, ServerMessageBlock response ) { Update(_macSigningKey, 0, _macSigningKey.Length); int index = offset; Update(data, index, SmbConstants.SignatureOffset); index += SmbConstants.SignatureOffset; byte[] sequence = new byte[8]; ServerMessageBlock.WriteInt4(response.SignSeq, sequence, 0); Update(sequence, 0, sequence.Length); index += 8; if (response.Command == ServerMessageBlock.SmbComReadAndx) { SmbComReadAndXResponse raxr = (SmbComReadAndXResponse)response; int length = response.Length - raxr.DataLength; Update(data, index, length - SmbConstants.SignatureOffset - 8); Update(raxr.B, raxr.Off, raxr.DataLength); } else { Update(data, index, response.Length - SmbConstants.SignatureOffset - 8); } byte[] signature = Digest(); for (int i = 0; i < 8; i++) { if (signature[i] != data[offset + SmbConstants.SignatureOffset + i]) { if (Log.Level >= 2) { Log.WriteLine("signature verification failure"); Hexdump.ToHexdump(Log, signature, 0, 8); Hexdump.ToHexdump(Log, data, offset + SmbConstants.SignatureOffset, 8); } return(response.VerifyFailed = true); } } return(response.VerifyFailed = false); }
/// <exception cref="System.IO.IOException"></exception> protected internal override void DoSend(ServerMessageBlock request) { lock (Buf) { ServerMessageBlock smb = request; int n = smb.Encode(Buf, 4); Encdec.Enc_uint32be(n & 0xFFFF, Buf, 0); if (Log.Level >= 4) { do { Log.WriteLine(smb); }while (smb is AndXServerMessageBlock && (smb = ((AndXServerMessageBlock)smb).Andx ) != null); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, Buf, 4, n); } } Out.Write(Buf, 0, 4 + n); } }
/// <exception cref="System.IO.IOException"></exception> protected internal virtual void DoSend0(ServerMessageBlock request) { try { DoSend(request); } catch (IOException ioe) { if (Log.Level > 2) { Runtime.PrintStackTrace(ioe, Log); } try { Disconnect(true); } catch (IOException ioe2) { Runtime.PrintStackTrace(ioe2, Log); } throw; } }
/// <exception cref="WinrtCifs.Smb.SmbException"></exception> internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response ) { lock (Session.Transport()) { if (response != null) { response.Received = false; } TreeConnect(request, response); if (request == null || (response != null && response.Received)) { return; } if (Service.Equals("A:") == false) { switch (request.Command) { case ServerMessageBlock.SmbComOpenAndx: case ServerMessageBlock.SmbComNtCreateAndx: case ServerMessageBlock.SmbComReadAndx: case ServerMessageBlock.SmbComWriteAndx: case ServerMessageBlock.SmbComClose: case ServerMessageBlock.SmbComTreeDisconnect: { break; } case ServerMessageBlock.SmbComTransaction: case ServerMessageBlock.SmbComTransaction2: { switch (((SmbComTransaction)request).SubCommand & unchecked (0xFF)) { case SmbComTransaction.NetShareEnum: case SmbComTransaction.NetServerEnum2: case SmbComTransaction.NetServerEnum3: case SmbComTransaction.TransPeekNamedPipe: case SmbComTransaction.TransWaitNamedPipe: case SmbComTransaction.TransCallNamedPipe: case SmbComTransaction.TransTransactNamedPipe: case SmbComTransaction.Trans2GetDfsReferral: { break; } default: { throw new SmbException("Invalid operation for " + Service + " service"); } } break; } default: { throw new SmbException("Invalid operation for " + Service + " service" + request); } } } request.Tid = Tid; if (InDfs && !Service.Equals("IPC") && !string.IsNullOrEmpty(request.Path)) { request.Flags2 = SmbConstants.Flags2ResolvePathsInDfs; request.Path = '\\' + Session.Transport().TconHostName + '\\' + Share + request.Path; } try { Session.Send(request, response); } catch (SmbException se) { if (se.GetNtStatus() == NtStatus.NtStatusNetworkNameDeleted) { TreeDisconnect(true); } throw; } } }
internal SmbComTreeConnectAndXResponse(ServerMessageBlock andx) : base(andx) { }
internal virtual int ReadAndXWireFormat(byte[] buffer, int bufferIndex) { int start = bufferIndex; WordCount = buffer[bufferIndex++]; if (WordCount != 0) { _andxCommand = buffer[bufferIndex]; _andxOffset = ReadInt2(buffer, bufferIndex + 2); if (_andxOffset == 0) { _andxCommand = unchecked (unchecked (0xFF)); } if (WordCount > 2) { ReadParameterWordsWireFormat(buffer, bufferIndex + 4); if (Command == SmbComNtCreateAndx && ((SmbComNtCreateAndXResponse)this).IsExtended) { WordCount += 8; } } bufferIndex = start + 1 + (WordCount * 2); } ByteCount = ReadInt2(buffer, bufferIndex); bufferIndex += 2; if (ByteCount != 0) { int n; n = ReadBytesWireFormat(buffer, bufferIndex); bufferIndex += ByteCount; } if (ErrorCode != 0 || _andxCommand == unchecked (unchecked (0xFF))) { _andxCommand = unchecked (unchecked (0xFF)); Andx = null; } else { if (Andx == null) { _andxCommand = unchecked (unchecked (0xFF)); throw new RuntimeException("no andx command supplied with response"); } bufferIndex = HeaderStart + _andxOffset; Andx.HeaderStart = HeaderStart; Andx.Command = _andxCommand; Andx.ErrorCode = ErrorCode; Andx.Flags = Flags; Andx.Flags2 = Flags2; Andx.Tid = Tid; Andx.Pid = Pid; Andx.Uid = Uid; Andx.Mid = Mid; Andx.UseUnicode = UseUnicode; if (Andx is AndXServerMessageBlock) { bufferIndex += ((AndXServerMessageBlock)Andx).ReadAndXWireFormat(buffer , bufferIndex); } else { buffer[bufferIndex++] = unchecked ((byte)(Andx.WordCount & unchecked (0xFF)) ); if (Andx.WordCount != 0) { if (Andx.WordCount > 2) { bufferIndex += Andx.ReadParameterWordsWireFormat(buffer, bufferIndex); } } Andx.ByteCount = ReadInt2(buffer, bufferIndex); bufferIndex += 2; if (Andx.ByteCount != 0) { Andx.ReadBytesWireFormat(buffer, bufferIndex); bufferIndex += Andx.ByteCount; } } Andx.Received = true; } return(bufferIndex - start); }
/// <exception cref="WinrtCifs.Smb.SmbException"></exception> internal SmbComSessionSetupAndX(SmbSession session, ServerMessageBlock andx, object cred) : base(andx) { Command = SmbComSessionSetupAndx; this.Session = session; this.Cred = cred; _sessionKey = session.transport.SessionKey; _capabilities = session.transport.Capabilities; if (session.transport.Server.Security == SmbConstants.SecurityUser) { if (cred is NtlmPasswordAuthentication) { NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)cred; if (auth == NtlmPasswordAuthentication.Anonymous) { _lmHash = new byte[0]; _ntHash = new byte[0]; _capabilities &= ~SmbConstants.CapExtendedSecurity; } else { if (session.transport.Server.EncryptedPasswords) { _lmHash = auth.GetAnsiHash(session.transport.Server.EncryptionKey); _ntHash = auth.GetUnicodeHash(session.transport.Server.EncryptionKey); // prohibit HTTP auth attempts for the null session if (_lmHash.Length == 0 && _ntHash.Length == 0) { throw new RuntimeException("Null setup prohibited."); } } else { if (DisablePlainTextPasswords) { throw new RuntimeException("Plain text passwords are disabled"); } if (UseUnicode) { // plain text string password = auth.GetPassword(); _lmHash = new byte[0]; _ntHash = new byte[(password.Length + 1) * 2]; WriteString(password, _ntHash, 0); } else { // plain text string password = auth.GetPassword(); _lmHash = new byte[(password.Length + 1) * 2]; _ntHash = new byte[0]; WriteString(password, _lmHash, 0); } } } _accountName = auth.Username; if (UseUnicode) { _accountName = _accountName.ToUpper(); } _primaryDomain = auth.Domain.ToUpper(); } else { if (cred is byte[]) { _blob = (byte[])cred; } else { throw new SmbException("Unsupported credential type"); } } } else { if (session.transport.Server.Security == SmbConstants.SecurityShare) { if (cred is NtlmPasswordAuthentication) { NtlmPasswordAuthentication auth = (NtlmPasswordAuthentication)cred; _lmHash = new byte[0]; _ntHash = new byte[0]; _accountName = auth.Username; if (UseUnicode) { _accountName = _accountName.ToUpper(); } _primaryDomain = auth.Domain.ToUpper(); } else { throw new SmbException("Unsupported credential type"); } } else { throw new SmbException("Unsupported"); } } }
internal SmbComNtCreateAndX(string name, int flags, int access, int shareAccess, int extFileAttributes, int createOptions, ServerMessageBlock andx) : base(andx) { // share access specified in SmbFile // create disposition // create options // security flags Path = name; Command = SmbComNtCreateAndx; DesiredAccess = access; DesiredAccess |= SmbConstants.FileReadData | SmbConstants.FileReadEa | SmbConstants.FileReadAttributes; // extFileAttributes this._extFileAttributes = extFileAttributes; // shareAccess this._shareAccess = shareAccess; // createDisposition if ((flags & SmbFile.OTrunc) == SmbFile.OTrunc) { // truncate the file if ((flags & SmbFile.OCreat) == SmbFile.OCreat) { // create it if necessary _createDisposition = FileOverwriteIf; } else { _createDisposition = FileOverwrite; } } else { // don't truncate the file if ((flags & SmbFile.OCreat) == SmbFile.OCreat) { // create it if necessary if ((flags & SmbFile.OExcl) == SmbFile.OExcl) { // fail if already exists _createDisposition = FileCreate; } else { _createDisposition = FileOpenIf; } } else { _createDisposition = FileOpen; } } if ((createOptions & unchecked (0x0001)) == 0) { this._createOptions = createOptions | unchecked (0x0040); } else { this._createOptions = createOptions; } _impersonationLevel = unchecked (0x02); // As seen on NT :~) _securityFlags = unchecked (unchecked (0x03)); }
/// <exception cref="WinrtCifs.Smb.SmbException"></exception> internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response ) { Connect(); request.Flags2 |= Flags2; request.UseUnicode = UseUnicode; request.Response = response; if (request.Digest == null) { request.Digest = Digest; } try { if (response == null) { DoSend0(request); return; } if (request is SmbComTransaction) { response.Command = request.Command; SmbComTransaction req = (SmbComTransaction)request; SmbComTransactionResponse resp = (SmbComTransactionResponse)response; req.MaxBufferSize = SndBufSize; resp.Reset(); try { BufferCache.GetBuffers(req, resp); req.Current(); if (req.MoveNext()) { SmbComBlankResponse interim = new SmbComBlankResponse(); Sendrecv(req, interim, SmbConstants.ResponseTimeout); if (interim.ErrorCode != 0) { CheckStatus(req, interim); } req.Current(); } else { MakeKey(req); } lock (this) { response.Received = false; resp.IsReceived = false; try { ResponseMap.Put(req, resp); do { DoSend0(req); }while (req.MoveNext() && req.Current() != null); long timeout = SmbConstants.ResponseTimeout; resp.Expiration = Runtime.CurrentTimeMillis() + timeout; while (resp.MoveNext()) { Runtime.Wait(this, timeout); timeout = resp.Expiration - Runtime.CurrentTimeMillis(); if (timeout <= 0) { throw new TransportException(this + " timedout waiting for response to " + req); } } if (response.ErrorCode != 0) { CheckStatus(req, resp); } } catch (Exception ie) { if (ie is SmbException) { throw; } else { throw new TransportException(ie); } } finally { //Sharpen.Collections.Remove<Hashtable, SmbComTransaction>(response_map, req); ResponseMap.Remove(req); } } } finally { BufferCache.ReleaseBuffer(req.TxnBuf); BufferCache.ReleaseBuffer(resp.TxnBuf); } } else { response.Command = request.Command; Sendrecv(request, response, SmbConstants.ResponseTimeout); } } catch (SmbException) { throw; } catch (IOException ioe) { throw new SmbException(ioe.Message, ioe); } CheckStatus(request, response); }
internal SmbComSessionSetupAndXResponse(ServerMessageBlock andx) : base(andx) { }
/// <exception cref="WinrtCifs.Smb.SmbException"></exception> internal void SessionSetup(ServerMessageBlock andx, ServerMessageBlock andxResponse ) { lock (Transport()) { NtlmContext nctx = null; SmbException ex = null; SmbComSessionSetupAndX request; SmbComSessionSetupAndXResponse response; byte[] token = new byte[0]; int state = 10; while (ConnectionState != 0) { if (ConnectionState == 2 || ConnectionState == 3) { // connected or disconnecting return; } try { Runtime.Wait(transport); } catch (Exception ie) { throw new SmbException(ie.Message, ie); } } ConnectionState = 1; // trying ... try { transport.Connect(); if (transport.Log.Level >= 4) { transport.Log.WriteLine("sessionSetup: accountName=" + Auth.Username + ",primaryDomain=" + Auth.Domain); } Uid = 0; do { switch (state) { case 10: { if (Auth != NtlmPasswordAuthentication.Anonymous && transport.HasCapability(SmbConstants .CapExtendedSecurity)) { state = 20; break; } request = new SmbComSessionSetupAndX(this, andx, Auth); response = new SmbComSessionSetupAndXResponse(andxResponse); if (transport.IsSignatureSetupRequired(Auth)) { if (Auth.HashesExternal && NtlmPasswordAuthentication.DefaultPassword != NtlmPasswordAuthentication .Blank) { transport.GetSmbSession(NtlmPasswordAuthentication.Default).GetSmbTree(LogonShare , null).TreeConnect(null, null); } else { byte[] signingKey = Auth.GetSigningKey(transport.Server.EncryptionKey); request.Digest = new SigningDigest(signingKey, false); } } request.Auth = Auth; try { transport.Send(request, response); } catch (SmbAuthException) { throw; } catch (SmbException se) { ex = se; } if (response.IsLoggedInAsGuest && Runtime.EqualsIgnoreCase("GUEST", Auth. Username) == false && transport.Server.Security != SmbConstants.SecurityShare && Auth != NtlmPasswordAuthentication.Anonymous) { throw new SmbAuthException(NtStatus.NtStatusLogonFailure); } if (ex != null) { throw ex; } Uid = response.Uid; if (request.Digest != null) { transport.Digest = request.Digest; } ConnectionState = 2; state = 0; break; } case 20: { if (nctx == null) { bool doSigning = (transport.Flags2 & SmbConstants.Flags2SecuritySignatures ) != 0; nctx = new NtlmContext(Auth, doSigning); } if (SmbTransport.LogStatic.Level >= 4) { SmbTransport.LogStatic.WriteLine(nctx); } if (nctx.IsEstablished()) { NetbiosName = nctx.GetNetbiosName(); ConnectionState = 2; state = 0; break; } try { token = nctx.InitSecContext(token, 0, token.Length); } catch (SmbException) { try { transport.Disconnect(true); } catch (IOException) { } Uid = 0; throw; } if (token != null) { request = new SmbComSessionSetupAndX(this, null, token); response = new SmbComSessionSetupAndXResponse(null); if (transport.IsSignatureSetupRequired(Auth)) { byte[] signingKey = nctx.GetSigningKey(); if (signingKey != null) { request.Digest = new SigningDigest(signingKey, true); } } request.Uid = Uid; Uid = 0; try { transport.Send(request, response); } catch (SmbAuthException) { throw; } catch (SmbException se) { ex = se; try { transport.Disconnect(true); } catch (Exception) { } } if (response.IsLoggedInAsGuest && Runtime.EqualsIgnoreCase("GUEST", Auth. Username) == false) { throw new SmbAuthException(NtStatus.NtStatusLogonFailure); } if (ex != null) { throw ex; } Uid = response.Uid; if (request.Digest != null) { transport.Digest = request.Digest; } token = response.Blob; } break; } default: { throw new SmbException("Unexpected session setup state: " + state); } } }while (state != 0); } catch (SmbException) { Logoff(true); ConnectionState = 0; throw; } finally { Runtime.NotifyAll(transport); } } }
/// <exception cref="System.IO.IOException"></exception> private void Negotiate(int port, ServerMessageBlock resp) { lock (Sbuf) { if (port == 139) { Ssn139(); } else { if (port == -1) { port = SmbConstants.DefaultPort; } // 445 Socket = new SocketEx(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (LocalAddr != null) { Socket.Bind2(new IPEndPoint(LocalAddr, LocalPort)); } Socket.Connect(Address.GetHostAddress(), port); //Socket.Connect(new IPEndPoint(IPAddress.Parse(Address.GetHostAddress()), port), SmbConstants.ConnTimeout); Socket.SoTimeOut = SmbConstants.SoTimeout; Out = Socket.GetOutputStream(); In = Socket.GetInputStream(); } if (++Mid == 32000) { Mid = 1; } NegotiateRequest.Mid = Mid; int n = NegotiateRequest.Encode(Sbuf, 4); Encdec.Enc_uint32be(n & 0xFFFF, Sbuf, 0); if (Log.Level >= 4) { Log.WriteLine(NegotiateRequest); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, Sbuf, 4, n); } } Out.Write(Sbuf, 0, 4 + n); Out.Flush(); if (PeekKey() == null) { throw new IOException("transport closed in negotiate"); } int size = Encdec.Dec_uint16be(Sbuf, 2) & 0xFFFF; if (size < 33 || (4 + size) > Sbuf.Length) { throw new IOException("Invalid payload size: " + size); } Readn(In, Sbuf, 4 + 32, size - 32); resp.Decode(Sbuf, 4); if (Log.Level >= 4) { Log.WriteLine(resp); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, Sbuf, 4, n); } } } }
internal SmbComTreeConnectAndX(SmbSession session, string path, string service, ServerMessageBlock andx) : base(andx) { this._session = session; this.path = path; this._service = service; Command = SmbComTreeConnectAndx; }