/// <exception cref="SharpCifs.Smb.SmbException"></exception>
internal void SessionSetup(ServerMessageBlock andx, ServerMessageBlock andxResponse
)
{
lock (Transport())
{
INtlmContext 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 = Config.getNtlmContextFactory().create(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);
}
}
}