Execute a command on kerberos using java and the ticket - java

I can execute a command using my kerberos ticket on the kerberos server by running
ssh hostname ls
it uses the kerberos ticket I got earlier by running kinit on the client.
I want to do the same thing through a java client. I have a client that can SSH to that machine using the privatekey or the username and password.
I want the java client to use the kerberos ticket.
How can I do that?

Well from what i understand your problem statement is:
Use kinit to generate a kerberos ticket
Use Java Client to send the ticket generated for authentication
I am also assuming you are writing the code for the java client:
Well in that case you to use a jaas.conf
Sample Jaas conf:-
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required
isInitiator=true
useTicketCache=true
doNotPrompt=true;
};
Set jaas conf via system property:-
-Djava.security.auth.login.config=jaasconffilepath
This will allow you to pick up whatever is defined in default credential cache(in your case that is populated with kinit)
Once you do this:-
LoginContext lc = new LoginContext();
lc.login()
After this use Subject.doAs to elevate privileges and get your job done:-
Subject.doAs(lc.getSubject(), new YourAction())
Here YourAction is a class you define (which must implement PrivilegedExceptionAction) and in its run method do whatever you want to.
P.S In case you are not "coding" your java client you need to check for jaas documentation of the module in question and see if it is supported or not. Then all you need to do is use your jaas.conf file and you are good to go.
P.S You can avoid kinit all together by putting useTicketCache=false and doNotPrompt=false. Then you can specify password and username in your client and it will get you ticket.
P.S Please ensure you define the system property for krb5.conf for any of this to work: -D java.security.krb5.conf=krb5conffilepath

Related

Does anyone implemented JSch using Kerberos/GASAPI-based authentication

As we are in corporate environment and with basic configuration changes, SSH Kerberos working seamlessly in OpenSSH
SSH -K server#domain.com
Since default Kerberos setup didn't work, we have installed MIT Kerberos and generated ktab files for the application uses.
However we are not aware how to setup Kerberos settings and properties for JSch. Password based authentication is working fine. But not sure how to implement the gssapi-with-mic. Any pointers or suggestion would be grateful.
Jsch connection with Kerberos
How to create these files with valid the values and explanation would
be grateful.
JSch is here for more than a decade, I don't see any single workable
sample with Kerberos/GSSAPI authentication online. If anyone
successfully implemented, kindly let me know.
JSch has Kerberos authentication enabled by default (what is a frequent cause of problems).
So you should not need to do anything special to use it in JSch. Just try to login with username only.

What [else] does this PowerShell Command? How could I reproduce it in Java?

I want to create a web application where employees could manage their email-forwarding settings.
In the past, this happened via some PowerShell scripts. For example, setting email forward with copy:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://[server] -Authentication Kerberos
Import-PSSession $Session
Set-Mailbox -Identity "{USERNAME}" -DeliverToMailboxAndForward $true -ForwardingAddress "{EMAIL}"
I set the redirection and watched the Active Directory for changes. It set the parameter altRecipient of the original recipient to the DN of the new and the parameter altRecipientBL of the new recipient to the DN of the old. I tried to reproduce these parameters with JND functionalities, but it doesn't redirect the mails. So there must be more what this PowerShell Command does, maybe changing the settings of the ExchangeServer.
How could I reproduce following functionality in Java preferably without using the PowerShell?
check forwarding status
remove forwarding
set forwarding with copy
set forwarding without copy
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://[server] -Authentication Kerberos :Creates a new remote session (via WSMAN) to the exchange server.
Import-PSSession $Session: Is used to import the remote Exchange cmdlets to your local machine. If you would not call Import-PSSession, Set-MailBox-cmdlet of the next line would not be available on your local machine:
Set-Mailbox -Identity "{USERNAME}" -DeliverToMailboxAndForward $true -ForwardingAddress "{EMAIL}"
From microsoft:
The Import-PSSession cmdlet imports commands , such as cmdlets, functions, and aliases, from a PSSession on a local or remote computer into the current session. You can import any command that the Get-Command cmdlet can find in the PSSession. ...
Your question:
How could I reproduce following functionality in Java preferably without using the PowerShell?
Well you've to use kind of Java remoting mechanism towards Exchange server. On the Exchange server there needs to be some endpoint that is able to call the PowerShell command.
Hope that helps.

How to connect from java code to remote mongodb which uses kerberos on windows system?

I am new to mongodb and kerberos. I have a remote mongodb setup which uses kerberos authentication. Now I have a windows machine and have to connect to remote mongodb instance through java code. I am using the below code which connects well, but asks for username and password during the execution which I need to avoid. I have searched a lot on google and found that I need to provide keytab file but not sure how to generate it on windows machine? Any help would be appreciated.
Note: I don't have access to mongodb server and kerberos which are running on remote machine.
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
System.setProperty("java.security.krb5.realm", "have a proper value here");
System.setProperty("java.security.krb5.kdc", "have a proper value here");
String server = "have a valid host here";
String user = "valid user name";
String databaseName = "valid database name";
MongoCredential credential = MongoCredential.createGSSAPICredential(user);
MongoClient mongoClient = new MongoClient(new ServerAddress(server, "valid port"), Arrays.asList(credential));
Your question is how to generate a keytab on a Windows machine. The Keytab must be generated on either a member server or a domain controller of the Active Directory domain using the ktpass.exe command. Use the Windows Server built-in utility ktpass.exe to create the keytab. Note that Keytabs must be created on a Windows Server OS as they cannot be created on a workstation operating system, such as Windows 7, 8 or Windows 10. When running ktpass.exe, the Command-line shell (cmd.exe) must be run "As administrator". If User Account Control (UAC) is enabled, that must be disabled. The keytab must be created in such a way that it contains the service principal name, realm name, and the encrypted hash of the password of the AD user or computer account to which the service principal inside of the keytab is related. To do this, an example command is given below.
ktpass -out centos1-dev-local.keytab -mapUser krbCentos#DEV.LOCAL +rndPass -mapOp set +DumpSalt -crypto AES256-SHA1 -ptype KRB5_NT_PRINCIPAL -princ HTTP/centos1.dev.local#DEV.LOCAL
The above command example creates a keytab named centos1-dev-local.keytab for use in an AD domain named DEV.LOCAL. For additional reference, you can read more about my article on Kerberos keytabs on Microsoft Technet: Kerberos Keytabs – Explained. I frequently go back and edit it based on questions I see here in this forum.

What parameters for an NTLM authentication can be automatized , and how to do it with java?

I want to know what parameters can be automatized out of the 6 used during an NTLM authentication, which are:
"Username" - The one used to login on the Operating System's profile currently in use. -Already automatized, using System.getProperty("user.name")
"Password" - Same as the above. -Probably can't be automated, but i'm never sure till i try and ask...
"ProxyAddress" - Address of the proxy, to which the authentication is "handshaked to" in order to pass. -I already pseudo-automatized, but its fixed code, thus bad.
"ProxyPort" - The listening port on the proxy previously explained. -I already pseudo-automatized, but its fixed code, thus bad.
"Workstation" - My PC's ID in the local network or something...I'm currently using my machine's property ID, and its working, but i have no idea if its the correct value, or if there is a need for a value in the first place. -No idea how to automatize, but i know it's possible. NEED HELP
"Domain" - No idea which domain it refers to, thus no idea what value it should have...leaving it blank seems to be working... -No idea how to automatize, but i know it's possible. NEED HELP
EXTRA INFO: I'm using the HtmlClient library for the process, including authentication.
DefaultCredentialsProvider credentialProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
credentialProvider.addNTLMCredentials(username, password, proxyAddress, proxyPort, workstation, domain);
webClient.setUseInsecureSSL(true);
I'm sort of assuming that you're talking about Apache HTTPClient and HTLMUnit, but I'm basing that assumption off the method signatures in the code you provided, so I apologize if I'm mistaken.
For NTLM, this is the remote username, not necessarily the currently logged in user on the local host. I suspect that these are the same user in your scenario, but I did want to point that out. In that case, yes, using the user.name system property will provide the name of the currently logged in user:
System.getProperty("user.name");
on Windows, you can also use the USERNAME environment variable:
System.getEnv("USERNAME");
or you could use the com.sun.security.auth.module.NTSystem class:
new NTSystem.getName();
You cannot get the user's password. However, you may still be able to perform single signon where the user does not need to provide a password (more on that below.)
The Java mechanism for specifying HTTP proxies is using the http.proxyHost system property:
String proxyHost = System.getProperty("http.proxyHost");
Note that you should also check the http.nonProxyHosts system property.
Some JREs (Mac OS comes to mind immediately) will set these system properties based on the system proxy settings. If this is not set by your JRE, you will probably want to try to determine the proxy from another source. On Unix systems, you may wish to use the HTTP_PROXY environment variable. On Windows systems, you're likely best off using the ProxySelector class, as explained in this stackoverflow post.
Similar to the http.proxyHost system property, the Java mechanism is with the http.proxyPort system property:
int proxyPort = Integer.parseInt(System.getProperty("http.proxyPort"));
To reliably get your hostname on Unix, you should really call gethostname(2) via JNI or exec /usr/bin/hostname, unfortunately. On Windows, you may use the COMPUTERNAME environment variable:
System.getEnv("COMPUTERNAME");
You can get the domain name that the local machine is joined to, however (short of prompting the user), there's no way to automatically get the domain name of the machine you're authenticating to. Of course this is moot if your local workstation and the authentication target are on the same domain. Thus, on Windows, you can either use the USERDOMAIN environment variable:
System.getEnv("USERDOMAIN");
or you can use the NTSystem class:
new NTSystem().getDomain();
Whew.
As for implementing "single signon" (such that the user need not provide a password):
You may be able to perform single signon (without needing a password) by using the Java Kerberos functionality, however I was unsuccessful in this because Java requires explicit Kerberos configuration (and does not use the host's configuration) and it does not implement some ciphers required by Active Directory. (Or that's my understanding.)
You could also perform single signon with NTLM or SPNEGO (Kerberos) by using JNI to call InitializeSecurityContext and pass the resulting tokens in the WWW-Authenticate header.

Java - Access file with user authentication

I have a server where I work with a database and files using a java app.
When I start my app I give a report regarding file access to the server using:
public static boolean folderExists(String folderPath) {
File folderToCheck = new File(folderPath);
return folderToCheck.exists();
}
Every time I start my app (after a fresh restart of my computer)
I get a false response, even though the server is on.
The reason is because I must give an authentication as another user.
What I do is access the server through Windows
where I am being asked for username/password,
and after that I get a true response regarding file access to the server.
Is there a way to give the authentication username/password through Java,
and not through Windows?
Thank you
On Windows 'native' Java IO (e.g. java.io.File) always inherits the security context of the user running the JVM process. For example, you could run the Java app as a Windows service with the correct credentials.
The JCIFS project implements CIFS (the Windows SMB file server protocol) and allows you to directly specify the username/password.
See the API for examples.
I am pretty sure, that there is no way to grant fileaccess by java, without a Windows-Call.
You can call cacls file.log /e /t /p Everyone:f but this will be language-dependent.
I had a similar problem: How to change the file ACL in windows, if I only know the SID?
With Java7 there may be a way to do this.

Categories

Resources