123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- // This code is derived from jcifs smb client library <jcifs at samba dot org>
- // Ported by J. Arturo <webmaster at komodosoft dot net>
- //
- // This library is free software; you can redistribute it and/or
- // modify it under the terms of the GNU Lesser General Public
- // License as published by the Free Software Foundation; either
- // version 2.1 of the License, or (at your option) any later version.
- //
- // This library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- // Lesser General Public License for more details.
- //
- // You should have received a copy of the GNU Lesser General Public
- // License along with this library; if not, write to the Free Software
- // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- using System;
- using SharpCifs.Util;
- using SharpCifs.Util.Sharpen;
- namespace SharpCifs.Smb
- {
- /// <summary>To filter 0 len updates and for debugging</summary>
- public class SigningDigest
- {
- internal static LogStream Log = LogStream.GetInstance();
- private MessageDigest _digest;
- private byte[] _macSigningKey;
- private bool _bypass;
- private int _updates;
- private int _signSequence;
- /// <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="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);
- }
- }
- 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));
- Log.Flush();
- }
- if (len == 0)
- {
- return;
- }
- _digest.Update(input, offset, len);
- _updates++;
- }
- public virtual byte[] Digest()
- {
- byte[] b;
- b = _digest.Digest();
- if (Log.Level >= 5)
- {
- Log.WriteLine("digest: ");
- Hexdump.ToHexdump(Log, b, 0, b.Length);
- Log.Flush();
- }
- _updates = 0;
- return b;
- }
- /// <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;
- }
- }
- /// <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;
- }
- public override string ToString()
- {
- return "LM_COMPATIBILITY=" + SmbConstants.LmCompatibility + " MacSigningKey=" + Hexdump.ToHexString
- (_macSigningKey, 0, _macSigningKey.Length);
- }
- }
- }
|