| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570 | 
							- // 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 System.Collections.Generic;
 
- using System.IO;
 
- using System.Net;
 
- using SharpCifs.Netbios;
 
- using SharpCifs.Util.Sharpen;
 
- namespace SharpCifs.Smb
 
- {
 
- 	public sealed class SmbSession
 
- 	{
 
- 		private static readonly string LogonShare = Config.GetProperty("jcifs.smb.client.logonShare"
 
- 			, null);
 
- 		private static readonly int LookupRespLimit = Config.GetInt("jcifs.netbios.lookupRespLimit"
 
- 			, 3);
 
- 		private static readonly string Domain = Config.GetProperty("jcifs.smb.client.domain"
 
- 			, null);
 
- 		private static readonly string Username = Config.GetProperty("jcifs.smb.client.username"
 
- 			, null);
 
- 		private static readonly int CachePolicy = Config.GetInt("jcifs.netbios.cachePolicy"
 
- 			, 60 * 10) * 60;
 
- 		internal static NbtAddress[] DcList;
 
- 		internal static long DcListExpiration;
 
- 		internal static int DcListCounter;
 
- 		/// <exception cref="SharpCifs.Smb.SmbException"></exception>
 
- 		private static NtlmChallenge Interrogate(NbtAddress addr)
 
- 		{
 
- 			UniAddress dc = new UniAddress(addr);
 
- 			SmbTransport trans = SmbTransport.GetSmbTransport(dc, 0);
 
- 			if (Username == null)
 
- 			{
 
- 				trans.Connect();
 
-                 if (SmbTransport.LogStatic.Level >= 3)
 
- 				{
 
-                     SmbTransport.LogStatic.WriteLine("Default credentials (jcifs.smb.client.username/password)"
 
- 						 + " not specified. SMB signing may not work propertly." + "  Skipping DC interrogation."
 
- 						);
 
- 				}
 
- 			}
 
- 			else
 
- 			{
 
- 				SmbSession ssn = trans.GetSmbSession(NtlmPasswordAuthentication.Default
 
- 					);
 
- 				ssn.GetSmbTree(LogonShare, null).TreeConnect(null, null);
 
- 			}
 
- 			return new NtlmChallenge(trans.Server.EncryptionKey, dc);
 
- 		}
 
- 		/// <exception cref="SharpCifs.Smb.SmbException"></exception>
 
- 		/// <exception cref="UnknownHostException"></exception>
 
- 		public static NtlmChallenge GetChallengeForDomain()
 
- 		{
 
- 			if (Domain == null)
 
- 			{
 
- 				throw new SmbException("A domain was not specified");
 
- 			}
 
- 			lock (Domain)
 
- 			{
 
- 				long now = Runtime.CurrentTimeMillis();
 
- 				int retry = 1;
 
- 				do
 
- 				{
 
- 					if (DcListExpiration < now)
 
- 					{
 
- 						NbtAddress[] list = NbtAddress.GetAllByName(Domain, 0x1C, null, 
 
- 							null);
 
- 						DcListExpiration = now + CachePolicy * 1000L;
 
- 						if (list != null && list.Length > 0)
 
- 						{
 
- 							DcList = list;
 
- 						}
 
- 						else
 
- 						{
 
- 							DcListExpiration = now + 1000 * 60 * 15;
 
-                             if (SmbTransport.LogStatic.Level >= 2)
 
- 							{
 
-                                 SmbTransport.LogStatic.WriteLine("Failed to retrieve DC list from WINS");
 
- 							}
 
- 						}
 
- 					}
 
- 					int max = Math.Min(DcList.Length, LookupRespLimit);
 
- 					for (int j = 0; j < max; j++)
 
- 					{
 
- 						int i = DcListCounter++ % max;
 
- 						if (DcList[i] != null)
 
- 						{
 
- 							try
 
- 							{
 
- 								return Interrogate(DcList[i]);
 
- 							}
 
- 							catch (SmbException se)
 
- 							{
 
-                                 if (SmbTransport.LogStatic.Level >= 2)
 
- 								{
 
-                                     SmbTransport.LogStatic.WriteLine("Failed validate DC: " + DcList[i]);
 
-                                     if (SmbTransport.LogStatic.Level > 2)
 
- 									{
 
-                                         Runtime.PrintStackTrace(se, SmbTransport.LogStatic);
 
- 									}
 
- 								}
 
- 							}
 
- 							DcList[i] = null;
 
- 						}
 
- 					}
 
- 					DcListExpiration = 0;
 
- 				}
 
- 				while (retry-- > 0);
 
- 				DcListExpiration = now + 1000 * 60 * 15;
 
- 			}
 
- 			throw new UnknownHostException("Failed to negotiate with a suitable domain controller for "
 
- 				 + Domain);
 
- 		}
 
- 		/// <exception cref="SharpCifs.Smb.SmbException"></exception>
 
- 		/// <exception cref="UnknownHostException"></exception>
 
- 		public static byte[] GetChallenge(UniAddress dc)
 
- 		{
 
- 			return GetChallenge(dc, 0);
 
- 		}
 
- 		/// <exception cref="SharpCifs.Smb.SmbException"></exception>
 
- 		/// <exception cref="UnknownHostException"></exception>
 
- 		public static byte[] GetChallenge(UniAddress dc, int port)
 
- 		{
 
- 			SmbTransport trans = SmbTransport.GetSmbTransport(dc, port);
 
- 			trans.Connect();
 
- 			return trans.Server.EncryptionKey;
 
- 		}
 
- 		/// <summary>
 
- 		/// Authenticate arbitrary credentials represented by the
 
- 		/// <tt>NtlmPasswordAuthentication</tt> object against the domain controller
 
- 		/// specified by the <tt>UniAddress</tt> parameter.
 
- 		/// </summary>
 
- 		/// <remarks>
 
- 		/// Authenticate arbitrary credentials represented by the
 
- 		/// <tt>NtlmPasswordAuthentication</tt> object against the domain controller
 
- 		/// specified by the <tt>UniAddress</tt> parameter. If the credentials are
 
- 		/// not accepted, an <tt>SmbAuthException</tt> will be thrown. If an error
 
- 		/// occurs an <tt>SmbException</tt> will be thrown. If the credentials are
 
- 		/// valid, the method will return without throwing an exception. See the
 
- 		/// last <a href="../../../faq.html">FAQ</a> question.
 
- 		/// <p>
 
- 		/// See also the <tt>jcifs.smb.client.logonShare</tt> property.
 
- 		/// </remarks>
 
- 		/// <exception cref="SmbException"></exception>
 
- 		public static void Logon(UniAddress dc, NtlmPasswordAuthentication auth)
 
- 		{
 
- 			Logon(dc, -1, auth);
 
- 		}
 
- 		/// <exception cref="SharpCifs.Smb.SmbException"></exception>
 
- 		public static void Logon(UniAddress dc, int port, NtlmPasswordAuthentication auth
 
- 			)
 
- 		{
 
- 			SmbTree tree = SmbTransport.GetSmbTransport(dc, port).GetSmbSession(auth).GetSmbTree
 
- 				(LogonShare, null);
 
- 			if (LogonShare == null)
 
- 			{
 
- 				tree.TreeConnect(null, null);
 
- 			}
 
- 			else
 
- 			{
 
- 				Trans2FindFirst2 req = new Trans2FindFirst2("\\", "*", SmbFile.AttrDirectory);
 
- 				Trans2FindFirst2Response resp = new Trans2FindFirst2Response();
 
- 				tree.Send(req, resp);
 
- 			}
 
- 		}
 
- 		internal int ConnectionState;
 
- 		internal int Uid;
 
- 		internal List<object> Trees;
 
- 		private UniAddress _address;
 
- 		private int _port;
 
- 		private int _localPort;
 
- 		private IPAddress _localAddr;
 
- 		internal SmbTransport transport;
 
- 		internal NtlmPasswordAuthentication Auth;
 
- 		internal long Expiration;
 
- 		internal string NetbiosName;
 
- 		internal SmbSession(UniAddress address, int port, IPAddress localAddr, int localPort
 
- 			, NtlmPasswordAuthentication auth)
 
- 		{
 
- 			// Transport parameters allows trans to be removed from CONNECTIONS
 
- 			this._address = address;
 
- 			this._port = port;
 
- 			this._localAddr = localAddr;
 
- 			this._localPort = localPort;
 
- 			this.Auth = auth;
 
- 			Trees = new List<object>();
 
- 			ConnectionState = 0;
 
- 		}
 
- 		internal SmbTree GetSmbTree(string share, string service)
 
- 		{
 
- 			lock (this)
 
- 			{
 
- 				SmbTree t;
 
- 				if (share == null)
 
- 				{
 
- 					share = "IPC$";
 
- 				}
 
- 				/*for (IEnumeration e = trees.GetEnumerator(); e.MoveNext(); )
 
- 				{
 
- 					t = (SmbTree)e.Current;
 
- 					if (t.Matches(share, service))
 
- 					{
 
- 						return t;
 
- 					}
 
- 				}*/
 
- 			    foreach (var e in Trees)
 
- 			    {
 
-                     t = (SmbTree)e;
 
-                     if (t.Matches(share, service))
 
-                     {
 
-                         return t;
 
-                     }
 
- 			    }
 
- 				t = new SmbTree(this, share, service);
 
- 				Trees.Add(t);
 
- 				return t;
 
- 			}
 
- 		}
 
- 		internal bool Matches(NtlmPasswordAuthentication auth)
 
- 		{
 
- 			return this.Auth == auth || this.Auth.Equals(auth);
 
- 		}
 
- 		internal SmbTransport Transport()
 
- 		{
 
- 			lock (this)
 
- 			{
 
- 				if (transport == null)
 
- 				{
 
- 					transport = SmbTransport.GetSmbTransport(_address, _port, _localAddr, _localPort, null
 
- 						);
 
- 				}
 
- 				return transport;
 
- 			}
 
- 		}
 
- 		/// <exception cref="SharpCifs.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 se)
 
- 				{
 
- 					if (request is SmbComTreeConnectAndX)
 
- 					{
 
- 						Logoff(true);
 
- 					}
 
- 					request.Digest = null;
 
- 					throw;
 
- 				}
 
- 			}
 
- 		}
 
- 		/// <exception cref="SharpCifs.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 sae)
 
- 								{
 
- 									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 se)
 
- 								{
 
- 									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 sae)
 
- 									{
 
- 										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 se)
 
- 				{
 
- 					Logoff(true);
 
- 					ConnectionState = 0;
 
- 					throw;
 
- 				}
 
- 				finally
 
- 				{
 
- 					Runtime.NotifyAll(transport);
 
- 				}
 
- 			}
 
- 		}
 
- 		internal void Logoff(bool inError)
 
- 		{
 
- 			lock (Transport())
 
- 			{
 
- 				if (ConnectionState != 2)
 
- 				{
 
- 					// not-connected
 
- 					return;
 
- 				}
 
- 				ConnectionState = 3;
 
- 				// disconnecting
 
- 				NetbiosName = null;
 
-                 foreach (SmbTree t in Trees)
 
- 			    {
 
- 			        t.TreeDisconnect(inError);
 
- 			    }
 
-                 if (!inError && transport.Server.Security != SmbConstants.SecurityShare)
 
- 				{
 
- 					SmbComLogoffAndX request = new SmbComLogoffAndX(null);
 
- 					request.Uid = Uid;
 
- 					try
 
- 					{
 
- 						transport.Send(request, null);
 
- 					}
 
- 					catch (SmbException)
 
- 					{
 
- 					}
 
- 					Uid = 0;
 
- 				}
 
- 				ConnectionState = 0;
 
- 				Runtime.NotifyAll(transport);
 
- 			}
 
- 		}
 
- 		public override string ToString()
 
- 		{
 
- 			return "SmbSession[accountName=" + Auth.Username + ",primaryDomain=" + Auth.Domain
 
- 				 + ",uid=" + Uid + ",connectionState=" + ConnectionState + "]";
 
- 		}
 
- 	}
 
- }
 
 
  |