I need help on sending certificate information from one program to another, and logging into Windows with that information through the use of CredMarshalCredential and LogonUser. My program currently passes credentials and logs in successfully with a regular username/password combination. I'm just adding the ability to do it with Smart Card credentials.
I've used this example successfully to login with a Smart Card Certificate.
This works when you run the program as the user, but not when trying to run the program as SYSTEM. This is because SYSTEM cannot access the user's "MY" store. I'm trying to work around this, either by passing the cert or the entire cert store to the program running as SYSTEM from an application running as the user.
I've tried numerous approaches to get something that would login successfully after serialization, but haven't gotten anything to successfully work. The approach that seems to work the best has been to call CertSaveStore and Open the BLOB. I've used the last example at the bottom of this Microsoft Example Page. This restores the cert store from the BLOB correctly, finds certs, and even generates a username. But the generated username is different than the original generated username and fails to login with an error of ERROR_LOGON_FAILURE (The user name or password is incorrect).
My current test applications saves the cert and loads it again in the same program. I've taken the SYSTEM aspect out of the equation for now. I'm guessing the restored cert store is missing some information, but I'm not sure what I'm missing. Any insight would be appreciated.
One last note, I originally tried to just pass the generated username and PIN to SYSTEM and have it step down, but it failed with the same ERROR_LOGON_FAILURE error. I'm assuming the username has to be regenerated since being called by a different user/program, but that assumption could be wrong.
I have gotten my example program working with CertSerializeCertificatesStoreElement and CertAddCertificateContextToStore. I am able to serialize the certificate, and add it to a new store in memory at a later time. I had tried this earlier, but accidentally did not save the size of the serialized item, I just tried to use sizeof() the item which returned an incorrect size.
If anyone is looking to send certificate credentials between programs in the same userspace this approach will work well.
I took this ahead step further and implemented it in my userspace/SYSTEM paradigm. The logic worked correctly, and I was able to generate a username but still failed to LogonUser. After another week or trial and error, I found a solution that works between the userspace and SYSTEM. I ended up having to use LsaLogonUser instead of LogonUser.
If anyone is looking to have a userspace program send credentials to a daemon running in SYSTEM and have that program step down to the user use this example. I initially tried this very similar example, but it continues to fail. In the working example, you do not need to pass in a domain or username, just the PIN. The system will read the Smart Card from the reader and verify with the passed in PIN. This solution will work across computers, ONLY IF the smart card is located at the remote computer. I am looking into a way to accomplish having it work with the smart card in the host computer, but it is outside of this post.
I hope this saves someone the weeks of work I put into getting to this point.
Related
When I execute on solaris 11.0:
pfiles /proc/PROCESSID
The result is process information, a small chunk of output is what interest me:
4: S_IFSOCK mode:0666 dev:543,0 ino:46228 uid:0 gid:0 size:0
O_RDWR|O_NONBLOCK
SOCK_STREAM
SO_REUSEADDR,SO_KEEPALIVE,SO_SNDBUF(49152),SO_RCVBUF(128480)
sockname: AF_INET6 ::ffff:10.10.50.28 port: 22
peername: AF_INET6 ::ffff:10.16.6.150 port: 55504
The process I pfiles /proc/PROCESSID is the sshd session itself.
My question is given a process id, how can i get this (pfiles) information from within a kernel code ?
When looking in struct proc i could not find something that give me this data.
Is there a pointer to struct that hold all open files occupied by the process on the proccess' proc?
I also executed truss pfiles /proc/PROCESSID but could not find the exact call
If you look in /usr/include/sys/user.h you'll see the open file information can be found in the p_user.u_finfo structure of the current process.
Walking that structure is not trivial. Just look at what the proc filesystem code has to do to look up the attributes of just one open file descriptor. There's lots of locking needed - you can't simply walk the data structures while things are running.
And, the following is beyond the scope of the question, but it's important...
For what it's worth, what you're doing can't work. It's fundamentally flawed - technically and legally.
What you're trying to do - track users who share a user account - is worthless anyway. You will never be able to prove that just because a certain login session executed some code that the code was executed because the user logged into that session purposely ran that code. Because any of the users with access to that account can modify the environment of the shared account such that malware is run by someone else. And they can make it look just like a typed-in command.
Shared credentials and accounts violate nonrepudiation. That's your insurmountable legal flaw in using any data your custom kernel tracking may produce - even if you manage to produce a system that's foolproof, which isn't likely.
If I'm logged into a shared account, you can never prove that the code I ran was run intentionally.
Well, that's not entirely true - if you have perfect auditing where you can trace every thing a user does down to the bytes modified on disk, you can. And "perfect" in this case means those users have no access whatsoever to change any part of the auditing system.
But if you already have perfect auditing in place, you don't need to write kernel modules to try and implement it.
Of course, it's impossible to prove you have perfect auditing in place because you can't prove that you don't have holes in it.
See the problem?
We're right back to "You CAN'T prove I did it intentionally."
You'd be much better off just using the OS-provided auditing services. Whatever you come up with isn't going to be useful in proving "who did it" for any intelligent bad actor - like someone who figures out a way to insert malicious code into another user's session. And the OS auditing will be sufficient to catch anyone who has no clue in how to cover their tracks.
But you won't be able to provably catch any bad actor who knows what he's doing when shared accounts are involved. And if you can't prove it, you might not even be able to do anything at all to someone you suspect. Because someone who really knows what they're doing will be able to pin the apparent blame on someone who's innocent - if they can't hide or destroy the evidence of the bad act[s] in the first place.
What are you going to do if you find the shared .profile file has a line in it that after a certain date emails sensitive data to a throwaway email account, but only when the login comes from a certain IP address?
Any one of the users who share that one account could have put it in there.
No auditing system in the world can solve that problem unless it's perfect and tracks every file change.
If the data you're trying to protect is important, whoever is tasking you to solve the problem by writing custom kernel modules needs to grow a brain and solve the real problem - shared user accounts. Get rid of them.
There's a reason why every security guide says not to use shared accounts, and every security audit I've ever seen will fail anyone using shared accounts.
I have 2 file signing cards with the same "sponsor" (obviously, the actual "signer" is different between the 2). Until quite recently, I've only been using the one but today I tried using the other. I built my application and signed it using the same process I always use and I downloaded both the .out and the .p7s files the same way I always do, but when the download finishes, I get an error message about the signature not matching.
I was pretty sure that you could use 2 different signing cards as long as the sponsor was the same between them. Am I wrong? What am I missing?
For the record:
This is for a Vx520
My terminal is on the latest OS
I have verified that the sponsor certificate name on the terminal's boot up screen matches the sponsor cert name in the signing tool's diagnostics menu
My terminal also has VMAC and CommServer, but no other programs on it (besides the one I built and am trying to download and run)
When the file signing tool runs, it generates the .p7s file, which is always required, but it also generates a file Certif.crt. This file is not necessary to download to the terminal if you are only using a single signing card, but if you use a second card, you MUST download it along with the .p7s. From what I can tell, this .crt file is what the terminal uses to determine that the sponsors are the same. Once I downloaded the .crt file along with everything else, it worked.
Side note: The tool also generates a SponsorCertif.crt file. I'm not using that nor do I know what scenarios would require it... If you know, please comment below.
I bought two VeriShield file signing cards. Unfortunately neither of the cards work--they each give a "wrong pin" error.
PIN Entry Try is 3. Do we see any message if the cards are locked? Can we sign the file as default and download the app to terminal? Also will there be any ownership issues if I sign the files as default for development?
Let's start with why you are getting the wrong PIN. There could be a few different reasons:
VERIFY YOU HAVE THE RIGHT PIN
When you first got your cards, each one should have come with a welcome letter telling you what the PIN is for that card. Note that each card will have a unique PIN and that you can't mix the two up (that is--if you try to enter the PIN for card 1 on card 2, it won't work and visa-versa).
NOTE: VeriFone is not infallible--when I was in my VF training class, one student got a pair of cards that didn't work and the teacher decided he must have had the wrong PINs sent to him. The only remedy is to contact the VF rep from whom you purchased the cards.
CHECK FOR PROPER INSTALLATION
Are you using the latest version of the File Signing Tool (FST)? I believe the latest version is 04.01.04. If you have an older version, go to the DevNet page and get the latest.
I have a note saying that the FST installer needs to be run using administrator privileges, though if I remember correctly, it will elevate itself to administrator, so this shouldn't be off too much concern. My note also says that during the setup, you may get a message about not being able to change folder permissions, but not to worry about it.
Once you have the FST installed, set it to always run as administrator. This IS important and it won't work if you don't.
The first time you run FST, you'll need to set up 2 officers and give them temporary passwords (you will be required to change the passwords on the next log-in). Note that for some reason, VF decided to make the USER NAMES case sensitive (not just the passwords).
Once those users are set up, log in as those users and change the password to the "permanent" password ("permanent" as in you don't have to change it again if you don't want to). If I'm not mistaken, you can't use one of the last (3?) passwords, so you can't use the same as the temporary password you set them up with.
Now log in with BOTH users that you set up and choose Change PIN.
If you are still having trouble, contact your VF rep.
PIN Entry Try is 3. Do we see any message if the cards are locked?
I know that you do have a very limited number of retries before the card locks itself, but seeing as mine worked on my first try, I really couldn't tell you what happens as you approach and/or cross that limit.
Can we sign the file as default and download the app to terminal? Also will there be any ownership issues if i sign the files as default for development.
That depends on what type of terminal you are using. If it is a Verix or VerixV (so like 3740, 3750, 3730, 510, 570) then, yes you can use a default signature (that's what I regularly do on these terminals) and no, it won't cause any problems, assuming everything else that is running on that terminal is also default-signed. If you are using some things that ARE secure-signed, then I believe that all items must have the same sponsor to run on that terminal (I know that's true with the eVo platform, but I'm just assuming on the Verix/VerixV platforms).
HOWEVER, if you are running an eVo terminal (like 520) then you MUST use a secure signature--eVo will not accept a default certificate. What's more, once a secure-signed program is loaded into the terminal, then ALL future applications MUST be signed using a certificate with the same sponsor, or that program will not run. (One exception--if you run the certificate removal program, then AFTER it runs, you can load a new sponsor on. However, note that the removal tool will not run unless it has been singed by the same sponsor).
Trying to use a default certificate should not cause any ownership problems, it just won't run. I know that if I try and use the default certificate on my terminal that already has a sponsor, it will compare the file signatures after download and say they don't match. I haven't tried it on a blank (no sponsor cert yet) eVo, but I suspect you would get roughly the same result.
Those file signing cards have gotten expensive recently, so if yours aren't working, then I'd get with the VF rep quickly and try to get it fixed--the longer you wait, the less likely they'll help you.
I have two C binaries which tries to open network connection for communication.
This is for external communication. When i run that for the first time, OS X' firewall pops up the message as given in title. How can I get rid of this?
I suspect this is related to code-signing? How to do code-sign this binary?
Basically I have to build this binary in one Mac machine, and distribute outside app store.
How can I get rid of the firewall pop up if the OS X firewall is enabled in the machine?
You can resolve this by signing the offending application binary yourself.
Disclaimer: Signing an application yourself will make an application appear more
secure to the operating system, when in reality it isn’t. Only sign applications
that you are 100% sure are not spyware or otherwise malicious. If you have any
doubts, just uninstall/reinstall.
Part 1: Create a Signing Identity
The solution I’m going for – signing the app myself – requires that I create a Signing Identity, also known as Signing Certificate. This is very easy to do:
Open Applications > Utilities > Keychain Access.
From the Keychain Access menu, choose Certificate Assistant > Create a Certificate.
Fill in a name for the certificate. This name appears in the Keychain Access utility as the name of the certificate. This is also the name you will use when referencing this certificate. Personally, I used the name, “My Signing Identity.”
Choose Code Signing from the Certificate Type menu.
Choose Self Signed Root from the Type popup menu.
Check the Let me override defaults checkbox.
Click Continue.
Specify a serial number for the certificate. Any number will do as long as you have no other certificate with the same name and serial number.
Click Continue.
Fill in the information for the certificate. You can use real or fake data, I used real data personally.
Click Continue.
Accept the defaults for the rest of the dialogs.
Once completed, you will see your certificate in Keychain Access. Verify the name you picked, and you’re done with this step. Well done!
Step 2: (Re-)Sign your application
Now you have to sign your application. To do this, open up Terminal again and use the following command:
codesign -s "My Signing Identity" -f /path/to/your/binary/app
A dialog will appear, click "Allow".
Now start your application again. You will get the accept incoming connections dialog one last time. Click "Allow".
From now on you should no longer get the warnings anymore! Now it is possible to enjoy the security of your firewall being active without the inconvenience of having to click "allow" constantly.
Credit: The original source which served as a starting place for this updated and annotated solution guide was http://silvanolte.com/blog/2011/01/18/do-you-want-the-application-to-accept-incoming-network-connections/
In my case this alert appeared when i run Python project from PyCharm after updating MacOS to 10.15 Cataline. I fixed it with
codesign -vvv /Applications/PyCharm.app/
I was trying to apply this solution to fix python as used by Arduino OTA, I found another solution describing self-signing the app that stated $(which python) as the file path to sign, but in my case that resolved to /usr/bin/python. Self-signing this not only required I drop to Rootless mode to allow writing to /usr/bin, but when I went back and tested it, python was STILL asking for permission to allow incoming connections!
The correct python file to self-sign is in fact (in my case at least) /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app
Once I self-signed this correct file path, the Arduino OTA process no longer required me clicking allow incoming connections - Hoorah!
Hope that helps someone.
I installed a PostScript printer driver and have setup REDMON (redmonnt.dll) for redirecting postscript output to my program. In my rather simple c program I capture the data from STDIN and I am able to successfully save it into a .ps file. The file looks OK.
However, I want to start gsview.exe for viewing the file. If I call ShellExecute it fails in Windows 7 because of permission issues. It seems that my program is called under a different user account (LOCAL SERVICE). So I am looking for a way to run gsview.exe under a specific username (the user who initiated the print job) which is available to the program in a variable called REDMON_USER along with the SESSIONID as well.
Q: What are the minimum WinAPI calls required to start a program given a username and a sessionid?
Any code examples in C/C++, .NET would be very helpful.
EDIT: What I am trying accomplish is something very similar to redrunee (from redmonee). I don't want to use redrunee because it opens about a console window for a brief moment.
Note:
1) The program is called by the printer service as [LOCAL SERVICE] account.
2) The first parameter Username (REDMON_USER), in effect, points to the user currently looking at the screen
Look at CreateProcessAsUser.
Also look at CreateProcessWithLogonW and CreateProcess.
They are linked from the CreateProcessAsUser
EDIT In reply to comments by OP.
Follow advice from this thread.
I am copying this here verbatim, in case the original link stops working:
The same code works for us on Vista as
on XP, etc. The service is running as
the Local System.
use WTSGetActiveConsoleSessionId to get the ID of the current active
Windows session at the console (i.e.
the machine keyboard and display, as
opposed to WTS sessions).
use WTSQueryUserToken to get the token for that session.
use DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,
&hTokenDup) to duplicate that token.
use CreateEnvironmentBlock to create an environment that you will be
passing to the process.
use CreateProcessAsUser with the duplicated token and the created
environment. Actually, we use
CreateProcessAsUserW, since the A
version had some sort of bug on some
older systems.
Don't forget to CloseHandle on the various tokens, etc, and to
DestroyEnvironmentBlock the
environment.
Thank you efratian.
PS. Oh joy of Windows programming, did not do it for quite a while. Now I remember why. The only thing that is close or even worse documented is OpenSSH programming.
The documentation describes the "Run as User" feature, which seems to be exactly what you want:
Run as User is intended for launching a GUI program such as GSview locally via RedRun.