Giter VIP home page Giter VIP logo

nsspi's People

Contributors

antiduh avatar matt-sullivan avatar mcgov avatar stefanossendorf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nsspi's Issues

Enforcing Kerberos only (using PackageNames.Kerberos)

I am trying to use PackageNames.Kerberos instead of PackageNames.Negotiate in order to only accept Kerberos authentication.

Ideally, I'd like to do this in a client-agnostic way, where I still return WWW-Authenticate: Negotiate and then I parse the Negotiate <token> header and pass it to AcceptToken, but with PackageNames.Kerberos.

I tried exactly that, but I'm getting Failed to call AcceptSecurityContext. Error Code = '0x80090300' - \"Not enough memory.\"."

Could I get a clarification of the exact use-case for PackageNames.Kerberos and whether what I'm trying to do is supposed to fail by design ? Thanks in advance :)

GSSAPI support

Hi antiduh, I'm following this in the github. In kerberos we have some steps like 1. Client requesting the TGT from KDC 2. Client getting the TGT 3.Client requesting SGT from KDC by using TGT, to access specific service 4. Client getting the SGT 5. Send SGT to resource server 6. Access the resource. Can you please tell me how do you handle the 3rd and 4th steps in the github.com/antiduh/nsspi/blob/master/TestClient/ClientForm.cs. Thanks.:)

Strong name

As we use strong-named assemblies in our applications, we cannot reference the Nsspi.dll from the NuGet package. Would it be possible to strong-name future releases?

Authentication with AZURE AD fails

Hello,
nsspi works fine for domain joined user / machines.
Recently our company has switched to AZURE AD. All PCs are now 'AzureAdJoined' and all user are now managed.
With this configuration authentication doesn't work anymore. TestServer always fails with LogonDenied (0x8009030c).
How can this be solved?
Thank you.

Authorization

Hi,

I understand the authentication part of this solution. How the authorization piece works? If the user is authenticated how can I get the group membership back?

Thank you,
-Zoltan

Nuget package

Hello and thank you for implementing this wrapper,

what do you think of deploying it as a nuget package?

Kind regards
Daniel

Issues (reading registry and other stuff) after impersonation (using NTLM)

Hello,

I have tried nsspi, and it's a very nice component.
However I'm having issues after impersonation:

  • with special folders (MyDocuments)
  • trying to read registry.
  • The existing code which writes a file does not work either.

The server is running under a user profile (Someuser2) which:

  • is part of the Users group.
  • has the "Impersonate a Client AfterAuthentication" User Right (SeImpersonatePrivilege).
    I suppose the problem is with Someuser2.
    I hope you can point me to the right direction...

The client is running under another profile.

The tests are performed in the same workgroup (no domain), and the problem occurs when the client and the server run on the same machine (Win 8.1) or on 2 different machines (server=Win8.1,client=Win2016).

Some stuff works, but:

  • I have added serveral lines of code in ServerForm.impersonateButton_Click() to read the registry and it does not work (exceptions thrown).

  • The code which is is originally in ServerForm.impersonateButton_Click() to write a file does not work anymore either.

  • Of course I did not change anything else in the code.

      private void impersonateButton_Click(object sender, EventArgs e)
      {
      	ImpersonationHandle handle;
    
      	// Get the MyDocuments folder before impersonation: WORKS.
      	Console.WriteLine("MyDoc BEFORE impersonation=" + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
    
      	using (handle = this.serverContext.ImpersonateClient())
      	{
      		// Get the current UserName AFTER impersonation: WORKS.
      		Console.WriteLine("Starting impersonation: " + Environment.UserName + Environment.NewLine);
    
      		// Get the MyDocuments folder AFTER impersonation: *** DOES NOT WORK ***.
      		// (an empty string is returned)
      		string s = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
      		Console.WriteLine("MyDoc AFTER impersonation=" + s);
    
      		MessageBox.Show("Starting impersonation: " + Environment.UserName);
      		MessageBox.Show("MyDoc AFTER impersonation=" + Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)); // EMPTY
    
      		try
      		{
      			Console.WriteLine("GetVal");
    
      			// *** DOES NOT WORK (Exceptions) ***
      			// (Details about the exceptions below)
      			var data = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion",
      				"CommonFilesDir", "Not found");
    
      			Console.WriteLine(data.ToString());
      			int a = 123;
      		}
      		catch (Exception ex)
      		{
      			Console.WriteLine("EX: " + ex.ToString());
      			Console.WriteLine(ex.StackTrace);
      			ex = ex;
      			int a = 123;
      		}
    
      		try
      		{
      			// *** DOES NOT WORK (Exception) ***
      			// (Detail about the exceptions below)
      			FileStream stream = File.Create(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\test.txt");
      			StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
    
      			writer.WriteLine("Hello world.");
    
      			writer.Close();
      			stream.Close();
      		}
      		catch (Exception ex)
      		{
      			Console.WriteLine("EX2: " + ex.ToString());
      			Console.WriteLine(ex.StackTrace);
      			ex = ex;
      			int a = 123;
      		}
      	}
    

`
Here are the details I could get with the Visual Studio debugger:

System.ArgumentException occurred
HResult=-2147024809
Message=Unknown error "1346".
Source=mscorlib
StackTrace:
at System.Diagnostics.Tracing.EventProvider.Register(Guid providerGuid)
InnerException:

(1346 is Either a required impersonation level was not provided, or the provided impersonation level is invalid.)

System.Security.SecurityException occurred
HResult=-2146233078
Message=Requested registry access is not allowed.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
InnerException:

(-2146233078 = 0x8013150A = COR_E_SECURITY)

Here are the details in the console:

TestServer
Server: Received ClientToken
Server: Sent ServerToken
Server: Received ClientToken
Server: Sent ServerToken
MyDoc BEFORE impersonation=C:\Users\Someuser2\Documents
Starting impersonation: ggo

MyDoc AFTER impersonation=
GetVal
*** REGISTRY access ***
EX: System.Security.SecurityException: Requested registry access is not allowed.
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at Microsoft.Win32.Registry.GetValue(String keyName, String valueName, Object
defaultValue)
at TestServer.ServerForm.impersonateButton_Click(Object sender, EventArgs e)
The Zone of the assembly that failed was:
MyComputer
System.Security.SecurityException
at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
at Microsoft.Win32.Registry.GetValue(String keyName, String valueName, Object
defaultValue)
at TestServer.ServerForm.impersonateButton_Click(Object sender, EventArgs e)

*** File creation access ***
EX2: System.IO.IOException: Unknown error "1346".
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I
nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o
ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolea
n useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access,
FileShare share, Int32 bufferSize)
at System.IO.File.Create(String path)
at TestServer.ServerForm.impersonateButton_Click(Object sender, EventArgs e)
System.IO.IOException
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I
nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o
ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolea
n useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access,
FileShare share, Int32 bufferSize)
at System.IO.File.Create(String path)
at TestServer.ServerForm.impersonateButton_Click(Object sender, EventArgs e)

Thank you very much,
best regards,
Olivier gg.

Alternative credentials; NuGet Package; versioning

Hi Kevin,

Thank you for your project. Great effort

I change some code to be able to logon with another credential (for client and server).
I was planning to do a pull request. But saw you did an implementation yourself.

I want to adapt your implementation to able to use nuget and future releases, but these change are not in a nuget package yet. Also the TestClient (and TestServer) lacks an implementation.

Will you be able to do this in near future?

Regards!

v0.3.1 pre-release or release?

Hi,

is version 0.3.1 a Pre-Release (as I can see here: Release-List) or a "full" release? I'm aksing because the nuget-package is a full release and not a pre-release.

Thanks in advance

Delegation after impersonation

Hello,

I have been using the NSSPI lib succesfully to exchange keys invoking server's AcceptToken() until SspiCommon.Status.Ok state reached.

Upon that, I invoke ImpersonateClient() and try to delgate this security context further via WCF (httpTransport.AuthenticationScheme = AuthenticationSchemes.Negotiate;)
DC/Kerberos are all set up, all users have been granted domain Admin priviledges, all users have SPNs so that delegation can be enabled, all computers have delegations enabled.

However, when I invoke WindowsIdentity.GetCurrent().ImpersonationLevel from within Impersonation block I get "Identification" only.

Both server and client context required:
ContextAttrib.MutualAuth |
ContextAttrib.AcceptIdentify |
ContextAttrib.Confidentiality |
ContextAttrib.ReplayDetect |
ContextAttrib.SequenceDetect |
ContextAttrib.Delegate,

Any ideas? Can this work at all? Do I have to dive into SPN management to get this running?

Thanks
Vladimir

NTLM authentication to a proxy/web server using Nsspi Client ??

Hi,

To continue our discussion from the post at

http://stackoverflow.com/questions/17241365/client-server-authentication-using-sspi/24312883?noredirect=1#

As I said I want to achieve the NTLM authentication from my client program to the web server (IIS/Proxy server). I am wondering if it is possible via the nssp library. At the moment the nsspi has both client side and server side code which uses the SSPI to achieve the authentication.

How can I proceed to may be just use the client side api to somehow replicate what browser does in case of NTLM authentication, which would be to just replicate and fill in the required request response headers for the initial and 2 way handshakes?

I was planning to do it on my own, but not sure if I could utilize a standard mechanism to hash the password and achieve the same without using SSPI ? OR it would be better to use the SSPI api.

I have to write this solution in c#.

Update:

As you suggested I decided to use the client side of NSSPI and try to generate tokens and stuff into the request headers. However, the Server sends back the response as WWW-Authenticate again as NTLM. If i do not Base 64 encode the token before putting in authoraization header then i get back
400 (bad request) error.

I am expecting IIS server to return me the challenge based on the token that i send to it in type 2 message.

Thank you
Kuldeep

ServerContext does not contain a definition for GetRemoteIdentity

With latest PR changes, I tried to start the TestServer project in visual studio and I got the build error for TestServer project. The error is saying:

"'ServerContext' does not contain a definition for 'GetRemoteIdentity' and no accessible extension method 'GetRemoteIdentity' accepting a first argument of type 'ServerContext' could be found (are you missing a using directive or an assembly reference?)"

Seems like code is not retrieving remoteId as expected on this line: https://github.com/antiduh/nsspi/blob/master/TestServer/ServerForm.cs#L180

"Context not yet fully formed" exceptions

From time to time, I can see The context is not yet fully formed. exceptions being thrown when trying to access ServerContext.ContextUserName property.

The property is being accessed (for logging purposes) immediately after AcceptToken is called and successful.

Interestingly, the next thing after that logging call is an ImpersonateClient() call which always works.

Is there any hidden race condition/concurrency I'm perhaps not aware of here?

Here's an illustration of what my code is doing:

var status= ctx.AcceptToken(negotiateToken), out var serverToken);
LogTokenAccepted(ctx) // ctx.ContextUserName is being accessed here
using (ctx.ImpersonateClient()) { ... } // This never fails

Support channel binding tokens

The call to InitializeSecurityContext and AcceptSecurityContext can have multiple input token buffers specified. One of these buffer types is the SECBUFFER_CHANNEL_BINDINGS which is a value of SEC_CHANNEL_BINDINGS which is a binding that the caller to SSPI would provide.

Currently the context Init method does not have a way to pass in a bindings value to be used with authentication which means it cannot be used with services that mandate channel binding support. It would be great if this could be added to this library.

Initializing ClientContext while impersonating

Hi,

I am trying to use NSSPI to manually facilitate double-hop with Kerberos inside a custom OWIN and IIS based reverse-proxy/API Gateway.

My code looks something like this:

var identity = (WindowsIdentity) context.Request.User.Identity;
using (var impersonation = identity.Impersonate())
{
    var clientCredentials = new ClientCurrentCredential(PackageNames.Kerberos);
    var client = new ClientContext(
        clientCredentials,
        "HTTP/" + backendHostname, // e.g. HTTP/myapi.mydomain.com
        ContextAttrib.MutualAuth |
        ContextAttrib.InitIdentify |
        ContextAttrib.Confidentiality |
        ContextAttrib.ReplayDetect |
        ContextAttrib.SequenceDetect |
        ContextAttrib.Connection |
        ContextAttrib.Delegate
    );
    var clientStatus = client.Init(null, out var tokenBytes);
    var token = Convert.ToBase64String(tokenBytes);
    context.Request.Headers.Append("Negotiate", token);
}

However the client.Init() call fails saying No credentials are available in the security package. Without the impersonation context, I'm able to get a token just fine. The SPNs should be set up correctly, and the app that's doing the impersonation is trusted in AD for Kerberos delegation. The ImpersonationLevel of the impersonated identity is Impersonation not Delegation.

I was hoping someone here might have a better insight into this and maybe see what I might be doing wrong, thanks.

Trouble with NTLM Proxy Authentication

I've been trying to implement this library to perform NTLM Proxy Authentication, and am running into a peculiar issue.

The environment setup is:

  1. Both the client machine and the proxy are on the same domain.
  2. The proxy supports Kerberos, NTLM, and Negotiate.

If negotiate is used and selects Kerberos, everything works fine.

However, if I try to force NTLM as the package, the final token gets rejected by the proxy. When testing the code at other sites where NTLM is the only supported option, the handshake also fails in the same way.

My gut instinct is something is wrong with the credential handle or the crypto functions for generating the 3rd token. When I loaded up a token analysis tool, all of the flags and target information looks identical to other apps' tokens which do seem to work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.