internal virtual string ReadString(byte[] src, int srcIndex, int maxLen, bool useUnicode ) { int len = 0; string str = null; try { if (useUnicode) { // Unicode requires word alignment if (((srcIndex - HeaderStart) % 2) != 0) { srcIndex++; } while (src[srcIndex + len] != 0x00 || src[srcIndex + len + 1] != 0x00) { len += 2; if (len > maxLen) { if (Log.Level > 0) { Hexdump.ToHexdump(LogStream.GetInstance(), src, srcIndex, maxLen < 128 ? maxLen + 8 : 128); } throw new RuntimeException("zero termination not found"); } } str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.UniEncoding); } else { while (src[srcIndex + len] != 0x00) { len++; if (len > maxLen) { if (Log.Level > 0) { Hexdump.ToHexdump(LogStream.GetInstance(), src, srcIndex, maxLen < 128 ? maxLen + 8 : 128); } throw new RuntimeException("zero termination not found"); } } str = Runtime.GetStringForBytes(src, srcIndex, len, SmbConstants.OemEncoding); } } catch (UnsupportedEncodingException uee) { if (Log.Level > 1) { Runtime.PrintStackTrace(uee, Log); } } return(str); }
public virtual void Run() { int nameTrnId; NameServicePacket response; try { while (_thread == Thread.CurrentThread()) { _socket.SoTimeOut = _closeTimeout; int len = _socket.Receive(_rcvBuf, 0, RcvBufSize); if (_log.Level > 3) { _log.WriteLine("NetBIOS: new data read from socket"); } nameTrnId = NameServicePacket.ReadNameTrnId(_rcvBuf, 0); response = (NameServicePacket)_responseTable.Get(nameTrnId); if (response == null || response.Received) { continue; } lock (response) { response.ReadWireFormat(_rcvBuf, 0); if (_log.Level > 3) { _log.WriteLine(response); Hexdump.ToHexdump(_log, _rcvBuf, 0, len); } if (response.IsResponse) { response.Received = true; Runtime.Notify(response); } } } } catch (TimeoutException) { } catch (Exception ex) { if (_log.Level > 2) { Runtime.PrintStackTrace(ex, _log); } } finally { TryClose(); } }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> public SigningDigest(SmbTransport transport, NtlmPasswordAuthentication auth) { try { _digest = MessageDigest.GetInstance("MD5"); } catch (NoSuchAlgorithmException ex) { if (Log.Level > 0) { Runtime.PrintStackTrace(ex, Log); } throw new SmbException("MD5", ex); } try { switch (SmbConstants.LmCompatibility) { case 0: case 1: case 2: { _macSigningKey = new byte[40]; auth.GetUserSessionKey(transport.Server.EncryptionKey, _macSigningKey, 0); Array.Copy(auth.GetUnicodeHash(transport.Server.EncryptionKey), 0, _macSigningKey , 16, 24); break; } case 3: case 4: case 5: { _macSigningKey = new byte[16]; auth.GetUserSessionKey(transport.Server.EncryptionKey, _macSigningKey, 0); break; } default: { _macSigningKey = new byte[40]; auth.GetUserSessionKey(transport.Server.EncryptionKey, _macSigningKey, 0); Array.Copy(auth.GetUnicodeHash(transport.Server.EncryptionKey), 0, _macSigningKey , 16, 24); break; } } } catch (Exception ex) { throw new SmbException(string.Empty, ex); } if (Log.Level >= 5) { Log.WriteLine("LM_COMPATIBILITY=" + SmbConstants.LmCompatibility); Hexdump.ToHexdump(Log, _macSigningKey, 0, _macSigningKey.Length); } }
/// <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); } } } }
public virtual byte[] Digest() { byte[] b; b = _digest.Digest(); if (Log.Level >= 5) { Log.WriteLine("digest: "); Hexdump.ToHexdump(Log, b, 0, b.Length); } _updates = 0; return(b); }
public virtual void Update(byte[] input, int offset, int len) { if (Log.Level >= 5) { Log.WriteLine("update: " + _updates + " " + offset + ":" + len); Hexdump.ToHexdump(Log, input, offset, Math.Min(len, 256)); } if (len == 0) { return; } _digest.Update(input, offset, len); _updates++; }
/// <exception cref="System.IO.IOException"></exception> protected internal override ServerMessageBlock PeekKey() { int n; do { if ((n = Readn(In, Sbuf, 0, 4)) < 4) { return(null); } }while (Sbuf[0] == 0x85); if ((n = Readn(In, Sbuf, 4, 32)) < 32) { return(null); } if (Log.Level >= 4) { Log.WriteLine("New data read: " + this); Hexdump.ToHexdump(Log, Sbuf, 4, 32); } for (;;) { if (Sbuf[0] == 0x00 && Sbuf[1] == 0x00 && Sbuf[4] == 0xFF && Sbuf[5] == 'S' && Sbuf[6] == 'M' && Sbuf[7] == 'B') { break; } for (int i = 0; i < 35; i++) { Sbuf[i] = Sbuf[i + 1]; } int b; if ((b = In.Read()) == -1) { return(null); } Sbuf[35] = unchecked ((byte)b); } Key.Mid = Encdec.Dec_uint16le(Sbuf, 34) & 0xFFFF; return(Key); }
/// <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); } }
/// <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="SharpCifs.Smb.SmbException"></exception> public SigningDigest(byte[] macSigningKey, bool bypass) { try { _digest = MessageDigest.GetInstance("MD5"); } catch (NoSuchAlgorithmException ex) { if (Log.Level > 0) { Runtime.PrintStackTrace(ex, Log); } throw new SmbException("MD5", ex); } this._macSigningKey = macSigningKey; this._bypass = bypass; _updates = 0; _signSequence = 0; if (Log.Level >= 5) { Log.WriteLine("macSigningKey:"); Hexdump.ToHexdump(Log, macSigningKey, 0, macSigningKey.Length); } }
/// <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); //TCPローカルポートは、毎回空いているものを使う。 //https://blogs.msdn.microsoft.com/dgorti/2005/09/18/only-one-usage-of-each-socket-address-protocolnetwork-addressport-is-normally-permitted/ Socket.Bind(new IPEndPoint(LocalAddr, 0)); Socket.Connect(new IPEndPoint(IPAddress.Parse(Address.GetHostAddress()), port), // <- 445 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); } } } }
/// <exception cref="SharpCifs.Smb.SmbException"></exception> public virtual byte[] InitSecContext(byte[] token, int offset, int len) { switch (State) { case 1: { Type1Message msg1 = new Type1Message(NtlmsspFlags, Auth.GetDomain(), Workstation); token = msg1.ToByteArray(); if (Log.Level >= 4) { Log.WriteLine(msg1); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, token, 0, token.Length); } } State++; break; } case 2: { try { Type2Message msg2 = new Type2Message(token); if (Log.Level >= 4) { Log.WriteLine(msg2); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, token, 0, token.Length); } } ServerChallenge = msg2.GetChallenge(); NtlmsspFlags &= msg2.GetFlags(); //netbiosName = getNtlmsspListItem(token, 0x0001); Type3Message msg3 = new Type3Message(msg2, Auth.GetPassword(), Auth.GetDomain(), Auth.GetUsername(), Workstation, NtlmsspFlags); token = msg3.ToByteArray(); if (Log.Level >= 4) { Log.WriteLine(msg3); if (Log.Level >= 6) { Hexdump.ToHexdump(Log, token, 0, token.Length); } } if ((NtlmsspFlags & NtlmFlags.NtlmsspNegotiateSign) != 0) { SigningKey = msg3.GetMasterKey(); } isEstablished = true; State++; break; } catch (Exception e) { throw new SmbException(e.Message, e); } } default: { throw new SmbException("Invalid state"); } } return token; }
/// <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); } } } }
/// <exception cref="System.IO.IOException"></exception> internal virtual void Send(NameServicePacket request, NameServicePacket response, int timeout) { int nid = 0; int max = NbtAddress.Nbns.Length; if (max == 0) { max = 1; } lock (response) { while (max-- > 0) { try { lock (_lock) { request.NameTrnId = GetNextNameTrnId(); nid = request.NameTrnId; response.Received = false; _responseTable.Put(nid, response); EnsureOpen(timeout + 1000); int requestLenght = request.WriteWireFormat(_sndBuf, 0); _socket.Send(_sndBuf, 0, requestLenght, new IPEndPoint(request.Addr, _lport)); if (_log.Level > 3) { _log.WriteLine(request); Hexdump.ToHexdump(_log, _sndBuf, 0, requestLenght); } } if (_waitResponse) { long start = Runtime.CurrentTimeMillis(); while (timeout > 0) { Runtime.Wait(response, timeout); if (response.Received && request.QuestionType == response.RecordType) { return; } response.Received = false; timeout -= (int)(Runtime.CurrentTimeMillis() - start); } } } catch (Exception ie) { throw new IOException(ie.Message); } finally { //Sharpen.Collections.Remove(responseTable, nid); if (_waitResponse) { _responseTable.Remove(nid); } } if (_waitResponse) { lock (_lock) { if (NbtAddress.IsWins(request.Addr) == false) { break; } if (request.Addr == NbtAddress.GetWinsAddress()) { NbtAddress.SwitchWins(); } request.Addr = NbtAddress.GetWinsAddress(); } } } } }
/// <exception cref="System.IO.IOException"></exception> internal virtual void Send(NameServicePacket request, NameServicePacket response, int timeout) { //Log.Out("NameSerciceClient.Send - Start"); int nid = 0; int max = NbtAddress.Nbns.Length; if (max == 0) { max = 1; } lock (response) { this._isActive = true; while (max-- > 0) { try { lock (_lock) { request.NameTrnId = GetNextNameTrnId(); nid = request.NameTrnId; response.Received = false; _responseTable.Put(nid, response); //Log.Out($"NameSerciceClient.Send - timeout = {timeout}"); EnsureOpen(timeout + 1000); int requestLenght = request.WriteWireFormat(_sndBuf, 0); byte[] msg = new byte[requestLenght]; Array.Copy(_sndBuf, msg, requestLenght); _socketSender.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, request.IsBroadcast ? 1 : 0); _socketSender.SendTo(msg, new IPEndPoint(request.Addr, _lport)); //Log.Out("NameSerciceClient.Send - Sended"); if (_log.Level > 3) { _log.WriteLine(request); Hexdump.ToHexdump(_log, _sndBuf, 0, requestLenght); } } if (_waitResponse) { long start = Runtime.CurrentTimeMillis(); var isRecieved = false; var startTime = DateTime.Now; while (timeout > 0) { Runtime.Wait(response, timeout); if (response.Received && request.QuestionType == response.RecordType) { //return; isRecieved = true; break; } response.Received = false; timeout -= (int)(Runtime.CurrentTimeMillis() - start); //if (timeout <= 0) //{ // Log.Out($"NameSerciceClient.Send Timeout! - {(DateTime.Now - startTime).TotalMilliseconds} msec"); //} } if (isRecieved) { break; } } } catch (Exception ie) { if (_waitResponse) { _responseTable.Remove(nid); } //Log.Out("NameSerciceClient.Send - IOException"); throw new IOException(ie.Message); } finally { if (_waitResponse) { _responseTable.Remove(nid); } } if (_waitResponse) { lock (_lock) { if (NbtAddress.IsWins(request.Addr) == false) { break; } if (request.Addr == NbtAddress.GetWinsAddress()) { NbtAddress.SwitchWins(); } request.Addr = NbtAddress.GetWinsAddress(); } } } this._isActive = false; //Log.Out("NameSerciceClient.Send - Normaly Ended."); } }
public virtual void Run() { int nameTrnId; NameServicePacket response; try { while (Thread.CurrentThread().Equals(_thread)) { if (_thread.IsCanceled) { break; } var localPort = (SmbConstants.Lport == 0) ? _lport : SmbConstants.Lport; var sockEvArg = new SocketAsyncEventArgs(); sockEvArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, localPort); sockEvArg.SetBuffer(_rcvBuf, 0, RcvBufSize); sockEvArg.Completed += this.OnReceiveCompleted; _socketSender.SoTimeOut = _closeTimeout; this._recievedLength = -1; //Log.Out($"NameServiceClient.Run - Wait Recieve: {IPAddress.Any}: {localPort}"); _socketSender.ReceiveFromAsync(sockEvArg); while (this._recievedLength == -1) { if (_thread.IsCanceled) { break; } Task.Delay(300).GetAwaiter().GetResult(); } sockEvArg?.Dispose(); if (_thread.IsCanceled) { break; } if (_log.Level > 3) { _log.WriteLine("NetBIOS: new data read from socket"); } nameTrnId = NameServicePacket.ReadNameTrnId(_rcvBuf, 0); response = (NameServicePacket)_responseTable.Get(nameTrnId); if (response == null || response.Received) { continue; } lock (response) { if (_thread.IsCanceled) { break; } response.ReadWireFormat(_rcvBuf, 0); if (_log.Level > 3) { _log.WriteLine(response); Hexdump.ToHexdump(_log, _rcvBuf, 0, this._recievedLength); } if (response.IsResponse) { response.Received = true; Runtime.Notify(response); } } } } catch (TimeoutException) { } catch (Exception ex) { if (_log.Level > 2) { Runtime.PrintStackTrace(ex, _log); } } finally { TryClose(); } }