Java psexec interactive remote command line - java

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

Related

Java authentication against local SASL

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.

how To Execute Hadoop Command from Java app remotely

Hi I'm triying execute any hadoop command like "hadoop fs -ls" throught a Java app remotely. I have my Java app in my local machine and Hadoop in a VM.
First I make a ssh connection and work. Also I can execute a linux command throught the java code it was working ,but hadoop commands are not working,it throws the following Error .Any idea to Execute hadoop commands?
this is my jsch program
package com.jsch.test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class Jschtest {
public static void main(String[] args){
String command="hadoop fs -ls /";
try{
String host = "192.168.3.197"; //IP address of the remote server
String user = "user"; // Username of the remote server
String password = "HDP123!"; // Password of the remote server
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);;
session.setPassword(password);
session.connect();
Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream input = channel.getInputStream();
channel.connect();
System.out.println("Channel Connected to machine " + host + " server
with command: " + command );
try{
InputStreamReader inputReader = new InputStreamReader(input);
BufferedReader bufferedReader = new BufferedReader(inputReader);
String line = null;
while((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
bufferedReader.close();
inputReader.close();
}catch(IOException ex){
ex.printStackTrace();
}
channel.disconnect();
session.disconnect();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
This is my Error Message
Channel Connected to machine 192.168.3.197 server with command: hadoop fs -ls /
bash: hadoop: command not found
Open your bashsrc and add the Hadoop BIN folder path to the PATH variable in the file.
Run source ~/.bashrc command.
Alternatively, you can make the following change to the command variable :
command = usr/local/hadoop/bin/hadoop fs -ls
If you are getting this error "bash: hadoop: command not found" means. Hadoop is not recognized by the OS
You need to update ".bashrc" file with hadoop home directory

what is the correct com.skype.* usage with Linux?

On Linux (Ubuntu 14.04), this code hangs after "got contact list" is printed:
package skype;
import com.skype.ContactList;
import com.skype.Friend;
import com.skype.Skype;
import com.skype.SkypeException;
public class ContactLister {
public void getAllFriend() throws SkypeException, InterruptedException {
System.out.println("starting...");
ContactList contactList = Skype.getContactList();
System.out.println("got contact list " + contactList.toString());
Friend friends[] = contactList.getAllFriends();
System.out.println("got friends");
System.out.println(friends.length);
for (Friend friend : friends) {
System.out.println("Friend ID :" + friend.getId());
Thread.sleep(100);
}
}
public static void main(String[] args) throws SkypeException, InterruptedException, SkypeException {
new ContactLister().getAllFriend();
}
}
Examining the library, com.skype.connector would seem to use JNI to connect with Skype. At least for me, the connection never seems to occur.
Is it even possible to use this to connect to skype? How do I know why why it's not (apparently) connecting?
thufir#dur:~$
thufir#dur:~$ java -jar NetBeansProjects/Skype/dist/Skype.jar
starting...
got contact list com.skype.ContactList#1d7ad1c
^Cthufir#dur:~$
thufir#dur:~$ skype --version
Skype 4.2.0.11
Copyright (c) 2004-2013, Skype
thufir#dur:~$
While this works:
package net.bounceme.dur.skype;
import java.io.*;
public class SkypeEchoTest {
public static void main(String args[]) throws IOException {
String s = null;
Process p = Runtime.getRuntime().exec("skype --callto echo123");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
}
It doesn't quite have the "wow" factor. Also, it just works on Linux, not sure how it would work in Windows. (You have to have Skype running first, then execute the bytecode.)

Executing Hive Query from Java

I tried to execute a small hive query from Java, but it is failing with below error, bur when I copy the same query and run on terminal it is giving me the result.
Can someone help me on this.
Java Code:
Runtime.getRuntime().exec("hive -e 'show databases;'");
Error thrown:
FAILED: ParseException line 1:5 cannot recognize input near '<EOF>' '<EOF>' '<EOF>' in ddl statement
Regards,
GHK.
I have been working with this Java problem for a while, and I believe I have solved this problem. Basically the reason you are failing is because the environment variables are not ser up properly. put the following in your /home/<username>/.bash_profile file and restart your machine to fix this.
HIVE_HOME=/usr/lib/hive
export HIVE_HOME
PATH=$PATH:$HIVE_HOME/bin/hive
export PATH
This will ensure that they get set up properly.
However while this will get rid of the error it still won't show you a list of databases because the process that runs the hive command will run in the background, not on the console the main program is running from. The following code will let you redirect the outputs of the program to the console that the main program is running from.
package testing.console;
import java.io.IOException;
import java.lang.ProcessBuilder;
import java.util.Map;
import testing.console.OutputRedirector;
//This Works
public class ConsoleTester {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
ProcessBuilder hiveProcessBuilder = new ProcessBuilder("hive", "-e",
"show databases");
String path = processEnv.get("PATH");
Process hiveProcess = hiveProcessBuilder.start();
OutputRedirector outRedirect = new OutputRedirector(
hiveProcess.getInputStream(), "HIVE_OUTPUT");
OutputRedirector outToConsole = new OutputRedirector(
hiveProcess.getErrorStream(), "HIVE_LOG");
outRedirect.start();
outToConsole.start();
}
}
And the OutputRedirector class used to get the output to console.
package testing.console;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class OutputRedirector extends Thread {
InputStream is;
String type;
public OutputRedirector(InputStream is, String type){
this.is = is;
this.type = type;
}
#Override
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(type + "> " + line);
}
} catch (IOException ioE) {
}
}
}

Get default gateway in java

I want to fetch default gateway for local machine using java. I know how to get it by executing dos or shell commands, but is there any another way to fetch?
Also need to fetch primary and secondary dns ip.
My way is:
try(DatagramSocket s=new DatagramSocket())
{
s.connect(InetAddress.getByAddress(new byte[]{1,1,1,1}), 0);
return NetworkInterface.getByInetAddress(s.getLocalAddress()).getHardwareAddress();
}
Because of using datagram (UDP), it isn't connecting anywhere, so port number may be meaningless and remote address (1.1.1.1) needn't be reachable, just routable.
In Windows with the help of ipconfig:
import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
public final class Router {
private static final String DEFAULT_GATEWAY = "Default Gateway";
private Router() {
}
public static void main(String[] args) {
if (Desktop.isDesktopSupported()) {
try {
Process process = Runtime.getRuntime().exec("ipconfig");
try (BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
if (line.trim().startsWith(DEFAULT_GATEWAY)) {
String ipAddress = line.substring(line.indexOf(":") + 1).trim(),
routerURL = String.format("http://%s", ipAddress);
// opening router setup in browser
Desktop.getDesktop().browse(new URI(routerURL));
}
System.out.println(line);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Here I'm getting the default gateway IP address of my router, and opening it in a browser to see my router's setup page.
There is not an easy way to do this. You'll have to call local system commands and parse the output, or read configuration files or the registry. There is no platform independent way that I'm aware of to make this work - you'll have to code for linux, mac and windows if you want to run on all of them.
See How can I determine the IP of my router/gateway in Java?
That covers the gateway, and you could use ifconfig or ipconfig as well to get this. For DNS info, you'll have to call a different system command such as ipconfig on Windows or parse /etc/resolv.conf on Linux or mac.
There is currently no standard interface in Java to obtain the default gateway or the DNS server addresses. You will need a shell command.
I'm not sure if it works on every system but at least here I found this:
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Main
{
public static void main(String[] args)
{
try
{
//Variables to find out the Default Gateway IP(s)
String canonicalHostName = InetAddress.getLocalHost().getCanonicalHostName();
String hostName = InetAddress.getLocalHost().getHostName();
//"subtract" the hostName from the canonicalHostName, +1 due to the "." in there
String defaultGatewayLeftover = canonicalHostName.substring(hostName.length() + 1);
//Info printouts
System.out.println("Info:\nCanonical Host Name: " + canonicalHostName + "\nHost Name: " + hostName + "\nDefault Gateway Leftover: " + defaultGatewayLeftover + "\n");
System.out.println("Default Gateway Addresses:\n" + printAddresses(InetAddress.getAllByName(defaultGatewayLeftover)));
} catch (UnknownHostException e)
{
e.printStackTrace();
}
}
//simple combined string out the address array
private static String printAddresses(InetAddress[] allByName)
{
if (allByName.length == 0)
{
return "";
} else
{
String str = "";
int i = 0;
while (i < allByName.length - 1)
{
str += allByName[i] + "\n";
i++;
}
return str + allByName[i];
}
}
}
For me this produces:
Info:
Canonical Host Name: PCK4D-PC.speedport.ip
Host Name: PCK4D-PC
Default Gateway Leftover: speedport.ip
Default Gateway Addresses:
speedport.ip/192.168.2.1
speedport.ip/fe80:0:0:0:0:0:0:1%12

Categories

Resources