Has anyone successfully created a custom Windows Credential Provider in C#? The samples that are in the Windows SDK are all in C++. Some initial searching I have done indicates it may be possible but cannot seem to find anyone who has confirmed it.
+1 for pgina. As Cody says, there is no managed API you can use to make a Credential Provider, and if you want to go the pInvoke route it will probably take more of your time troubleshooting pInvoke issues than figuring out the Credential Provider.
Where pGina can help you is that it has a nice Plugin architecture and the Plugins are written in managed code. See the chart here. pGina handles the communication with LogonUI (native code) but relies on the plugins (managed) to do the actual authentication, which is probably what you want to control (otherwise you probably wouldn't need your own credential provider).
The new CredentialProvider model in Windows Vista and higher is based on COM. This means that it should be possible as long as you implement the correct COM interfaces.
Based on this, it should be easier to build than the older GINA model since the older GINA module used DLL entry points and function pointers instead of COM interfaces.
Given the ability for .Net to inter-operate with COM, it should be as easy as:
Building a C# definition of the ICredentialProvider interface and adding the correct COM attributes with the correct GUIDS
Building a credential provider class that implements the ICredenitalProvider and is marked as COMVisible(True)
Registering the new assembly with Regasm
Adding the correct registry keys to register your new CredentialProvider with Windows (Software\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers)
If you do all of that, you will have a working credential provider, written in C#
Check out pGina. I was playing around with it and it seems to work alright on my Windows 8 install, so it should work well with all Windows versions before that too. It is still in pretty early stages though and I can't see any way of creating a custom UI without having to delve into the native half of the project. Hope this helps!
[EDIT] Just read Cody Gray's comment again. To be clear, pGina is really just the native code written for you. But yeah, you'd probably have more control writing it in C++ to begin with, but if you don't need too much control as to how it is presented then pGina is the way to go.
Related
I have zero experience with COM. I actually never thought, I'll need to do something with COM, thinking it's something that I luckily managed to avoid. Oh, well.
I need to create a wrapper for Web Services, which could be used from COM. I was hoping, that it's a solved problem, but failed to find an easy solution (for example: just generating a wrapper from WSDL).
A sidenote: Apparently, I also can't use .NET Framework (I could solve my problem easily with the help of COMVisible attribute, right?), unless I'll prove, that it's not that hard to install it on hundreds of machines. Proving that seems easier than my other alternatives at the moment. Today is a weird day.
You can call a Web Service from just about anywhere, including VB6 and COM.
If you can create an XMLHTTP60 COM object, here's an SO answer that shows you how to use it: What is the best way to consume a web service from VB6?
Take a look at Python; it's almost trivial to create a COM server from Python (compared to most of the non-MS languages, at least), and it makes as good a COM client as any other language.
If your Web service isn't already written, it's also fairly easy to write them in Python as well.
I have searched quite a lot of places and I only found one GINA replacement called pGINA but it is in C++ which I don't know at all.
Does anybody know one in either C# or VB.NET?
(I'm writing software for use at work to control what employees are doing)
Hosting .NET in Winlogon (where GINA dlls are loaded) is probably not such a hot idea- could cause all sorts of conflicts if something else decides to do the same thing, and if you trash winlogon, you're not getting anywhere with that PC. Also, GINA has been replaced as of Vista with ICredentialProvider (see here)- so your investment would be lost as soon as you move to a newer OS. Even there, the same thing applies: custom credential providers are loaded into Winlogon, so probably not a great idea to use .NET there.
Regardless, both of these are intended to support custom authentication modules, not "controlling what employees are doing". There are other ways to run software on the logon desktops, if that's what you're trying to do.
All that said, if you still want to try it, you'll need an unmanaged shim DLL, C++/CLI or some IL hacking (see here) to export the GINA functions because C# can't directly export DLL functions. A pure managed C# solution isn't possible.
To expand on nitzmahone's eexcellent points:
Completely replacing GINA is really a no-no using managed code. OTOH, it is quite possible to write a replacement GINA in C++ and have it call .Net code to do the grunt work.
Some years ago I used this technique to replace the CTRL+ALT+DEL screen with a fancy news service. My custom GINA was a proxy for the standard GINA. Most of the time it transparently passed calls on to the standard GINA. The exception was that it ran the .exe for the .Net app instead of displaying the ALT+DEL+CTRL screen, then waited for the .exe to terminate before displaying the logon screen.
With regret, I abandoned the project when it was clear that the work could not be directly applied to Vista.
I know how to create a COM DLL (a Class Library) in C#. Is it possible to create a COM Surrogate EXE using C#?
This would be a standalone server capable of launching and hosting COM objects, which would then be accessible to COM clients.
The default surrogate process for COM - the thing that hosts COM DLLs, aka the COM Surrogate - is dllhost.exe. It is possible to create a surrogate process in C++. This article explains how.
But those APIs are not exposed in wrappers as part of the base class library in the .NET Framework. If you want to write to write only managed code, you need something else.
I see a couple options.
The Visual Studio SDK, a free download that is intended for devs who want to extend Visual Studio. Within that SDK, there's a class lib that has such wrappers. In particular, look at the ISurrogate class.
BUT, the VS SDK license says that the SDK is ok to use only for products that extend or add value to Visual Studio. I am no lawyer, but that is my understanding of the license, which is pretty clear. These terms means the VS SDK would not be useful for general app building.
The one remaining question is, exactly how do you use the VS SDK technically to produce a COM Surrogate using only C# code? Again, here I don't know. I looked in the docs briefly for guides on using the ISurrogate wrapper, but found none.
Use the code in this article.
The article explores a bunch of different aspects around COM and .NET interop. Towards the end of the article it offers source code for building your own COM server in C#, complete with all the p/invoke calls to CoRegisterClassObject() and friends.
I wanted to make same thing and found excellent project example CSExeCOMServer on All-In-One Code Framework. It actually reconstructs normal COM server logic by means of .NET and native calls to Windows API. But it looks all still overcomplicated. I suppose there is no simple and fast way to expose .NET objects as COM in out-of-process server and it is not the architecture of choice.
One option, if you want an out-of-process COM component, is to host a dll in COM+ via serviced components. This only supports dll though, but you could write a shell exe (for standalone use) that simply defers to the dll.
Not quite as simple as VB, but it works.
I do remember somebody showing me a more direct way (no COM+), but I can't for the life of me remember what it was...
I know it's not easy to find a master in GINA, but my question is most near to Interprocess Communication(IPC), I wrote my custom GINA in unmanaged c++, I included it a method that checks for validity of a fingerprint for the user try to login, this function will call some method in a running system windows service written in c#, the code follows:
in GINA, unmanaged c++
if(Fingerprint.Validate(userName,finerprintTemplate)
{
//perform login
}
in windows service, C#
public class Fingerprint
{
public static bool Validate(string userName, byte[] finerprintTemplate)
{
//Preform Some code to validate fingerprintTemplate with userName
//and retuen result
}
}
Does anyone know how to do such Communication between GINA and the windows service, or simply between c++ written service and C# written service.
Thanks
The canonical method for communicating with a service (or most IPC that potentially needs to cross a session/desktop boundary) is a named pipe. You can use mailslots as well, but you have to deal with duplication issues because mailslot messages get duped across all installed protocols, so you need some kind of tagging system... gets kinda messy.
See the docs for CreateNamedPipe and work your way out from there. I have talked between C++ and C# using pipes: the interop got a little messy (binary messages), but its do-able. There's some sample code for C# pipes (from both sides) here.
The nice thing about using a pipe for your specific service to service comms problem is you can expand the design later on to support a UI if you need it.
NISGINA is an open-source GINA plugin to authenticate against a NIS directory. If you haven't already seen this, it's the only example of an open-source GINA plugin that I'm aware of. If you haven't already, You might find it worth your while to peruse the source code for this.
Note that as of Windows Vista, GINA has been deprecated and replaced with another API called Credential Provider Architecture.
I'd strongly recommend that you use named pipes. They are fast, easy to use from the C# side, provided you are using .Net 3.5 or higher, and relatively easy from the C++ side (with lots of examples available). And most importantly very easy to secure by applying a simple security descriptor.
I'm curious if you followed the suggested "answers" and attempted the Named Pipe route? According to both this link and my own experience, GINA operates in a pre-authenticated (Session 0) context and any attempt to access a Named Pipe from your unmanaged C++ GINA dll will result in Error #5 "access is denied".
I believe Mailslots may be the only available Windows IPC mechanism that is actually available at that level, but I'm not even certain that will work (haven't tried.)
Problem
Language: C# 2.0 or later
I would like to register context handlers to create menues when the user right clicks certain files (in my case *.eic). What is the procedure to register, unregister (clean up) and handle events (clicks) from these menues?
I have a clue it's something to do with the windows registry, but considering how much stuff there is in .net, I wouldn't be surprised if there are handy methods to do this clean and easy.
Code snippets, website references, comments are all good. Please toss them at me.
Update
Obviously there is a slight problem creating context menues in managed languages, as several users have commented. Is there any other preferred way of achieving the same behaviour, or should I spend time looking into these workarounds? I don't mind doing that at all, I'm glad people have put effort into making this possible - but I still want to know if there is a "proper/clean" way of achieving this.
Resist writing Shell Extensions in managed languages - there are a multitude of things that could go bang if you pursue this route.
Have a browse through this thread for more details. It contains links to do it if really want, and sagely advice of why it can be done, but shouldn't.
http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/1428326d-7950-42b4-ad94-8e962124043e/
You're back to unmanaged C/C++ as your only real tools here.
This is not a good idea because of potential dependency issues between different versions of the .NET Framework. Your shell extension could be expecting one version, while a different version may have already been loaded by the application that's currently running.
This thread contains a good summary of the situation.
While others already mentioned that writing shell extensions in pure .NET is a bad idea due to framework conflicts, you should still note that:
There are 3rd party drivers out there (see Eldos or LogicNP) that do the unmanaged side for you, allowing you to write managed code that talks to the native driver, thus preventing shell-related CLR version conflicts.
A recent MSDN article mentioned that Microsoft has solved this problem for the CoreCLR, as used by Silverlight. They've accomplished this by allowing multiple versions of the CLR to run in the same process, thus fixing the problem. The author further stated that this fix in Silverlight will be rolled into future versions of the full CLR. (Meaning, in the future, it will be quite feasible to write shell extensions in managed code.)
I've done them before in C#. It ends up being a hell of a lot harder than it should be. Once you get the boilerplate code down, though, it is easy to roll out new items. I followed this link:
Link To Info
As the prior comments mention, it isn't the best idea to write shell extensions in managed languages, but I thought I'd share an Open Source project that is doing just that :)
ShellGlue is a managed shell extension that is actually quite helpful. The source also might be helpful to you if you're interested in pursuing writing a shell extension in C/C++.
Aside from the caveats that have been mentioned concerning the implementation of shell extensions in managed code, what you'd basically need to do is the following:
First, create a COM component in C# that implements the IShellExtInit IContextMenu interfaces. How to create COM components in C# is described here. How to implement the necessary interfaces is described in this article. While the description is for a C++ implementation, you can apply that knowledge to you C# version.
Your COM component will have GUID called the Class-ID or CLSID. You need to register that ID with your file type as a context-menu shell extension:
HKEY_CLASSES_ROOT\.eic\ShellEx\ContextMenuHandlers\MyShellExt
(Default) -> {YOUR-COMPONENTS-CLSID}
Also make sure that you registered your component correctly as described in the C# COM tutorial. You should find it in the registry under
HKEY_CLASSES_ROOT\CLSID\{YOUR-COMPONENTS-CLSID}
InprocServer32
(Default) -> C:\WINDOWS\system32\mscoree.dll
Class -> YourImplClass
assembly -> YourAssembly, version=..., Culture=neutral, PublicKey=...
...
Good luck...
As others have pointed out, shell extensions are not practical in windows development currently.
I asked a similar question recently which was answered with a link to a guide to do exactly what I wanted to do