Java authentication against local SASL - java

I'm trying to make a java class in order to authenticate users against local SASL. My saslauthd configuration is like this:
$ cat /etc/sysconfig/saslauthd
# Directory in which to place saslauthd's listening socket, pid file, and so
# on. This directory must already exist.
SOCKETDIR=/run/saslauthd
# Mechanism to use when checking passwords. Run "saslauthd -v" to get a list
# of which mechanism your installation was compiled with the ablity to use.
MECH=pam
# Additional flags to pass to saslauthd on the command line. See saslauthd(8)
# for the list of accepted flags.
FLAGS="-t 1"
Basically it redirects an authentication against PAM. So, if I'm doing for example a test like this.
testsaslauthd -s login -u <user> -p <password>
0: OK "Success."
It is all working correctly.
I now want to manage this mechanism through Java so I compiled something like this:
import java.util.Arrays;
import java.util.List;
import java.io.*;
public class PamAuthenticator {
public static void main(String args[]) {
String s = null;
try {
Process p = Runtime.getRuntime().exec("testsaslauthd -s "+args[2]+" -u "+args[0]+" -p "+args[1]);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("Exception: ");
e.printStackTrace();
System.exit(-1);
}
}
}
This is correctly working:
$ java -cp .:* PamAuthenticator <user> <password> login
0: OK "Success."
My problem is that I don't want to execute the testsaslauthd command, since this is just a test command. Is there something better and smart I can do in order to try the authentication agains SASL with java?

You are on the right track, not to use the code above. Besides being a test solution it would introduce a serious security problem: command injection.
From Java 1.6 there is an interface called SaslClient. This does exactly what you need. An example on the JDK8 version of it:
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import java.util.HashMap;
public class Test {
public static void main(String[] args) throws SaslException {
String userName = "username";
String password = "password";
SaslClient saslClient = Sasl.createSaslClient(new String[]{"PLAIN"},
null, null, null, new HashMap<>(), callbacks -> {
for (final Callback callback : callbacks) {
if (callback instanceof NameCallback) {
NameCallback.class.cast(callback).setName(userName);
continue;
}
if (callback instanceof PasswordCallback) {
PasswordCallback.class.cast(callback).setPassword(password.toCharArray());
continue;
}
throw new UnsupportedCallbackException(callback);
}
});
}
}
Of course you should alter the source of the username and password.

Related

I can't run a python script from java and I think it's because the script does not have execute permissions

I'm trying to run a python script whenever a button on my gui (swing) is pressed. However, the script never runs and I'm not sure how to fix this. I know the script works fine independently, it should be py not python because windows, and my file system ntfs.
So far I've been trying to use code that can be summarized as below:
myBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Process p = Runtime.getRuntime().exec("py myScript.py");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
I don't think I can chmod ntfs stuff but I tried setting permissions via right clicking the python file and trying to mess with the security settings. Full control for the script to users does nothing.
The python script has the following permissions, my guess is my code isn't working because it does not have execute permissions.
-rw-r--r--
Use complete python executable path instead of "py". It executes the file with just read permissions.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Sample {
public static void main(String[] args) throws Exception {
try {
Process p = Runtime.getRuntime().exec("C:/Windows/py myScript.py");
String cmdOutput = null;
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
// read the output from the command
while ((cmdOutput = stdInput.readLine()) != null) {
System.out.println(cmdOutput);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
myScript.py
print("This line will be printed.")
Output:
C:\Users\Administrator\Documents\demo>javac Sample.java
C:\Users\Administrator\Documents\demo>java Sample
This line will be printed.

Java psexec interactive remote command line

I'm having an issue with psexec where it's not interactive. It returns as soon as it has run the command to open command prompt
Here is my Connection class:
package testProject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
public class ConTest {
private ProcessBuilder process;
private Process connection;
private String main_connection;;
public ConTest(String host, String user, String password) {
process = new ProcessBuilder("cmd.exe");
process.redirectErrorStream(true);
main_connection="<path to psexec>\psexec.exe \\\\" + host +
" -accepteula -nobanner -u " + user + " -p " + password +" cmd";
}
public void runCommand(String command) throws Exception{
/* Variable Declaration */
String readline;
PrintStream output;
BufferedReader input;
/* Variable Initialization */
connection = process.start();
output = new PrintStream(connection.getOutputStream());
input = new BufferedReader(new InputStreamReader(connection.getInputStream()));
/* Running the commands on the Host */
output.println(main_connection);
output.println(command);
output.println("exit");
output.close();
/*print the output from the command*/
while ((readline = input.readLine()) != null) {
System.out.println(readline);
}
input.close();
connection.waitFor();
}
}
And then I'm calling it using the following
package testProject;
public class mainClass {
public mainClass() {
}
public static void main(String[] args) throws Exception {
ConTest con = new ConTest(<IP>, <Admin>, <Password>);
con.runCommand("ping localhost");
}
}
The output shows that it connects to the host but then it just disconnects before writing the ping localhost command
Here is the output
C:><path to psexec>\psexec.exe \\<IP> -accepteula -nobanner -u <Admin> -p <Password> cmd
Microsoft Windows [Version 6.1.7601]Connecting to <IP>...
Starting PSEXESVC service on <IP>...
Connecting with PsExec service on <IP>...
Starting cmd on <IP>...
cmd exited on <IP> with error code 0.
C:\>ping localhost
followed by the ping stats
How can I keep the command prompt the focus of the output stream so when I send more commands down the pipe they are executed on the remote machine not my local machine?
I used paexec instead of psexec and it managed to give me an interactive session, hope this helps someone in the future

How to Execute FreeSWITCH (fs_cli) from a java application

I am new to freeswitch, I have tried originate command in freeswitch from fs_cli console and it was working properly. now my requirement is to execute the same from a java application.
I have tried following code
package org.freeswitch.esl.client.outbound.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class Call {
Call() throws IOException {
Process pr = Runtime.getRuntime().exec("./fs_cli -x \"originate loopback/1234/default &bridge(sofia/internal/1789#192.168.0.198)\"");
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
System.out.print("success");
}
public static void main(String[] args) throws IOException {
Call call;
call = new Call();
}
}
Output
-ERR "originate Command not found!
success
please help me,
fs_cli is at "/usr/local/freeswitch/bin/" location
I have created a symbolic link in my workspace directory.
why don't you use the ESL client? It should provide much more options, and originating a call would be no problem.
Regarding your particular problem, it looks like your program tried to execute "originate" command in the shell, not the ./fs_cli. Probably it needs more Java documentation reading :)

How to get the current umask value from Java?

I am running java 7 applications on unix machines. Is there a way to get the current umask value in pure java ?
In C I would use a combination of umask system calls, but I don't think I can call that in Java without resorting to JNI. Is there another approach ?
Edit: Here is a C example (from GUN libc docs):
mode_t
read_umask (void)
{
mode_t mask = umask (0);
umask (mask);
return mask;
}
A simple solution, if there is no Class/Method to get the umask, why don't you get it before call java and pass as a property?
Can you clarify? Do you want to read the umask of the application(the current java process)? Or do you want to read the umask value of some files on the file system?
You can use NIO (the used code is from the javadocs) to get some file attributes, or you can execute a shell command, since the process created with Runtime.execute inherits the umask of it's creator process.
So you should be able to solve your problem without the use of JNI.
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermissions;
public class Test {
private static final String COMMAND = "/bin/bash -c umask -S";
public static String getUmask() {
final Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
process = runtime.exec(COMMAND);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String umask = reader.readLine();
if (process.waitFor() == 0)
return umask;
} catch (final IOException e) {
e.printStackTrace();
} catch (final InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
return "";
}
public static void main(String[] args) throws IOException {
/*
* NIO
*/
PosixFileAttributes attrs = Files.getFileAttributeView(Paths.get("testFile"), PosixFileAttributeView.class)
.readAttributes();
System.out.format("%s %s%n", attrs.owner().getName(), PosixFilePermissions.toString(attrs.permissions()));
/*
* execute shell command to get umask of current process
*/
System.out.println(getUmask());
}
}

Ganymed ssh2 : how to solve (y/n) prompt in command line

I'm using Ganymede ssh2 to connect to server from my Java app and do some work there.
It works perfectly but problems are ssh commands that request approval, eg.
a command
stop someService
returns
Are you sure (y/n)?
and after appropriate key stroke (y/n) it moves on.
Currently I'm using implementation given by ssh2 ganymed example, smth like this:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
public class ConnectUtil(String hostname, String username, String password, String command)
{
try
{
Connection conn = new Connection(hostname);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
Session sess = conn.openSession();
sess.execCommand(command);
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true)
{
String line = br.readLine();
if (line == null)
break;
System.out.println(line);
}
sess.close();
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
After calling this util class with above mentioned command('stop someService'), it gets stucked at
String line = br.readLine();
and everything breaks after server timeout.
Any ideas on how to solve this issue are more than welcome.
Thanks a lot,
Milos.
Assuming Session has a getStdin() method, you should write the response to the question to that.
Either that or find out if the command that's demanding input has a 'non-interactive' mode that won't prompt.
If you're going to use stdin instead of exec then you have to do session.startShell() first. Read the FAQs.
I use this code...
sess.executeCommand("ena"+'\n' +"pass"+'\n' +"exit"+'\n');

Categories

Resources