Java Serversocket and Bash Connection - java

I was wondering if there was a way to open a pipe between a java serversocket and a bash tcp pipe. If so how would you do this. I know how to setup the java server side but how do you open the socket connection via bash or even a windows cmd prompt. Basically i want to pipe standard input into the tcp connection and receive standard output from it.
Any examples apprechiated!
-TJ

A ServerSocket can't do anything expect accept incoming connections, and create new Sockets which you use as endpoints (you don't use the ServerSocket for any send or recv operations). This is fine, but be aware of what side of the connection needs to accept connections. I'd assume it would be Bash since this seems to 'own' the pipe, so you'd use a Socket instead and connect that.

Use any of the SSH tools (there are a bunch opensources, e.g., ganymade) Ref:
http://java-source.net/open-source/network-clients/ganymed-ssh-2-for-java
I have not used this particular one, but other ssh clients to do what you want.
PS: You really do not need a ServerSocket for this, but use of threads is helpful.

Netcat is usually used to open TCP connections from a Unix shell. Bash (or any other shell I'm aware of) doesn't support it directly. There seem to exist a Windows port of Netcat too, but I haven't used it.
But it's a much better idea to just use SSH, as no special setup is required on the Java side in this case - you'll just get your standard I/O streams redirected to the SSH client automatically, with free encryption and optional compression (ssh -C) as bonuses. The disadvantage is that it would require installing an SSH server on the Java side and an SSH client on the connecting side.

Here is an example - the classes Connection, Session, etc. are defined in the imports.
At the time we were using the trilead SSH, and I dont think it is available publicly any more, but you can find a lot of other libraries on the web, e.g., http://linuxmafia.com/ssh/java.html
The point is, we did not have to open a serversocket to (1) establish an SSH session, (2) do a password authentication, (3) run some command at the user's login shell, and (4) grab its stdout. I believe most SSH libraries will give you this functionality. Hope this help, - M.S.
public void runCommand (String uName, String pWord, String cmd) throws Exception {
Connection conn = new Connection ("localhost");
conn.connect();
boolean authenticated = conn.authenticateWithPassword (uName, pWord);
if (!authenticated)
throw new Exception ("Authentication failure");
Session sess = connection.openSession();
sess.execCommand (cmd);
BufferedReader br = new BufferedReader (new InputStreamReader (
new StreamGobbler (sess.getStdout())));
for (String s = br.readLine() ; s != null ; s = br.readLine()) {
// do stuff with s
}
br.close();
sess.close();
conn.close();
}

Related

How to find out client is connecting to my server through telnet?

I'm writing a ServerSocket in java. I want to send some special content to client connecting to me through telnet. I want to send other content if he/she connects through Browser and etc. Is there any way to find out that user is connecting to me with telnet?
My code :
public void handleConnection(Socket socket) throws IOException {
String author = "Ehsan Akbari";
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
if(checkoutClientType(socket)=="telnet")
out.println("You are connecting through telnet :\)");
else
out.println("You are not connecting through telnet :|");
}
What should be the definition of checkoutClientType(Socket s);?
You cannot tell what program is on the other side of a socket by examining the socket itself. There is no test or operation you can perform on the socket that will distinguish the client program.
The only hope is to examine the data being transmitted to see if it matches an expected pattern, but for that you have to have some data transmitted. It might be possible to tell if the remote is telnet if you were to send a Telnet Protocol command such as AYT (Are You There), but that would probably not sit well with a different client such as a browser.
If you were able to proxy the data between the client and a handling process or thread and examine it you might be able to eventually determine if it was Telnet, but probably not, and probably not immediately.

Telnet session vs TCP session

What's the difference between a TELNET and TCP session?
I have a simple server:
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(5555);
Socket socket = ss.accept();
System.out.println("Waiting for a client...");
InputStream sin = socket.getInputStream();
OutputStream sout = socket.getOutputStream();
DataOutputStream out = new DataOutputStream(sout);
out.writeUTF("\u001B[2J");
out.writeUTF("Hello client\r\n");
while (true) {
int b = sin.read();
sout.write(b);
}
}
I'm connecting via telnet and typing like this:
So I assume that packet sending by telnet client has no specific headers and pass to low level protocol (TCP in my case) completely without changing. Is it correct?
From http://en.wikipedia.org/wiki/Telnet#Telnet_data:
All data octets except 0377 are transmitted over the TCP transport as is. Therefore, a Telnet client application may also be used to establish an interactive raw TCP session, and it is commonly believed that such session which does not use the IAC (0377 character, or 255 in decimal) is functionally identical.[citation needed] This is not the case, however, because there are other network virtual terminal (NVT) rules, such as the requirement for a bare carriage return character (CR, ASCII 13) to be followed by a NULL (ASCII 0) character, that distinguish the telnet protocol from raw TCP sessions.[clarification needed] On the other hand, many systems now possess true raw TCP clients, such as netcat or socat on UNIX and PuTTY on Windows, which also can be used to manually "talk" to other services without specialized client software. Nevertheless, Telnet is still sometimes used in debugging network services such as SMTP, IRC, HTTP, FTP or POP3 servers, to issue commands to a server and examine the responses, but of all these protocols only FTP really uses Telnet data format.
Another difference of Telnet from a raw TCP session is that Telnet is not 8-bit clean by default. 8-bit mode may be negotiated, but high-bit-set octets may be garbled until this mode was requested, and it obviously will not be requested in non-Telnet connection. The 8-bit mode (so named binary option) is intended to transmit binary data, not characters though. The standard suggests the interpretation of codes 0000–0176 as ASCII, but does not offer any meaning for high-bit-set data octets. There was an attempt to introduce a switchable character encoding support like HTTP has,[3] but nothing is known about its actual software support.
I would type some more but really Wikipedia covered it nicely :)
Telnet is a name of services. and TCP is protocol to connect computer together with reliable, ordered, error-checked delivery of a stream.

Java.net.SocketException: Permission denied: connect

I have two PCs in one network that I want to connect. One of them should send a notification to the other via TCP. One the one PC I have a "server" (Python script) socket which waits for the "client"(Jar file) to send a specific String and then it gives me a notification. This works perfectly fine when I'm trying it out one one PC. But when I want to do the intended action the "client" PC's .jar gives me an error that the connection is refused. Do I have to open a specific port on the other PC or what else could cause trouble? One PC runs Fedora the other Windows 8
"Server Code"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 5005))
s.listen(1)
try:
while True:
komm, addr = s.accept()
while True:
data = komm.recv(1024)
if data == "$":
noty()
if not data:
komm.close()
break
finally:
s.close()
"Client" Code
public static void main(String[] args) throws Exception {
Socket socket = new Socket("192.168.178.25", 5005);
OutputStream out = socket.getOutputStream();
String dat = "$";
out.write(dat.getBytes());
socket.close();
}
Your server is probably binding to the wrong interface,
calling
s.bind(("", 5005))
Without setting an interface will allow the program to pick what ip address / interface it will connect to.
Since your client is trying to connect to ("192.168.178.25", 5005); you may want to put an IP address into the bind call to prevent the server picking the wrong ip interface.
Example:
s.bind(("192.168.178.25", 5005))
if its permission denied then something is blocking your connection with the computer. i would try to open a port and see if that works. if you want an example of java sockets you can take a look at my SUPER Tic-Tac-Toe Multiplayer it uses java sockets to send strings to the clients as a way to represent what actions the clients should take.

Java and SSH: maintaining a connection

Goal: Remote control ssh server with one connection and multiple sessions or one persistent session.
Issue 1: I currently use sshj to do some remote control through SSH and it works well but I cant seem to get it to handle prompts correctly. (the host doesnt provide true root, just sudo -i so I need to log in first).
Issue 2: I downloaded ExpectJ to handle the prompt but I can't for the life of me figure out how to maintain a session once I have logged in and authenticated as root.
The current Hack solution requires that I re-log in every time:
public class Expect {
Spawn shell;
ExpectJ exp;
String host;
int port;
String username;
String passwd;
boolean sudo = false;
public Expect(String host,int port,String username,String passwd) throws IOException, TimeoutException, ExpectJException{
exp = new ExpectJ(5);
this.host = host;
this.port = port;
this.username = username;
this.passwd = passwd;
shell = exp.spawn(host, port, username, passwd);
shell.send("sudo netstat -natvp | grep Xtightvnc\n");
System.out.println(shell.getCurrentStandardOutContents());
try{
shell.expect("[sudo] password for #######:");
shell.send(passwd+"\n");
}
catch (IOException ex){
String err = ex.toString();
if(!err.equals("java.io.IOException: End of stream reached, no match found")){
throw new IOException(ex);
}
}
}
Question 1: can sshj be used to "expect" password prompts? I couldnt find any documentation alluding to that type of control.
Quetsion 2: How can I modify the above Expect code to maintain a persistent connection that I can make multiple calls to? I want to be able to continue to interact once I have reached the state of authenticating as root but the Spawn always closes once the initial command has been sent.
Question 1: can sshj be used to "expect" password prompts? I couldnt find any documentation alluding to that type of control.
Mainly what sshj provides is a handle on the shell or command's I/O streams, and methods to get stuff like the exit status.
Quetsion 2: How can I modify the above Expect code to maintain a persistent connection that I can make multiple calls to? I want to be able to continue to interact once I have reached the state of authenticating as root but the Spawn always closes once the initial command has been sent.
Multiplexing sessions, even concurrent session over a single SSH connection is supported. But note that you can only have one session for one shell/command/subsystem.
Which kind of Session are you using, i.e. Session.Shell (via session.startShell) or Session.Command (via session.exec)? In the latter case, once you're done executing a command, the session is meant to close and this is the expected behavior.
Normally wouldn't recommend Shell over Command but since you are equipped with ExpectJ which I guess can deal with prompts and such, you might want to go that route. If there are problems with echoing of characters or such, play with the PTY options (instead of session.allocateDefaultPTY call session.allocatePTY which takes a whole bunch of args, have a look at the source for allocateDefaultPTY).
Code examples: Shell, Command
Also, if you narrow the problem down to a bug with sshj, do report it on the issue tracker :)

Can anyone recommend a java FOSS server that does all the typical protocols (ssh etc)

I would like to add the ability for users to telnet into my app where by they can type in commands etc. I would like a simple Java Telnet server whereby i can provide the authentication strategy.
By "telnet" i am not referring what lib provides telnet connectivity but something a little more. I want the boring protocol stuff done along with a shell that has hooks that i can use to process and execute command lines. Where or what these commands are, is of course my implementation.
This q is not about how to start a socket server or other protocol plumbing type.
In my experience, telnet is telnet, ssh is ssh... if you want the latter then you might look at something like: http://mina.apache.org/sshd/
I've never used it, though.
You could also use the native operating system SSH (if it has it) to tunnel and then run regular telnet on the server. Creating your own telnet access isn't at all complicated if it's just a custom command shell. And as the other poster mentions, there are libraries that make it easy.
...but ssh would be more secure and more straight-forward.
Telnet servers only do telnet.
You might find http://telnetd.sourceforge.net/ suitable.
"Target Audience:
Developers that want to integrate reasonable telnet access into their application."
What exactly do you mean by "telnet into my app where by they can type in commands etc."?
Since both telnet and ssh requires some application to run on the remote machine (most often an instance of a command shell), they really only provide the transport mechanism for the commands. Telnet in particular can be (and has been) abused to send general text-commands over a tcp connection. You can browse the web by using the command telnet www.target-domain.com 80 and manually enter all the http protocol stuff, but i wouldn't recommend it. ssh is just the same, although it adds ssl/tls security to the channel.
Therefore, what I guess you want is something like this:
import java.io.*;
import java.net.*;
public class telnettest {
public static void main(String[] args) throws IOException {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
//Open a listening socket on port 8022 and wait for a connection
echoSocket = new ServerSocket(8022).accept();
System.out.println("connection established");
//Get input and output streams
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection");
System.exit(1);
}
//Read lines from the input stream (corresponding to user commands)
String userInput;
while ((userInput = in.readLine()) != null) {
//For each line entered, just output it to both remote and local terminal
out.println("echo: " + userInput);
System.out.println("echo: " + userInput);
}
//Clean up connections.
out.close();
in.close();
echoSocket.close();
}
}
which is a shameless edit of this tutorial example.
I'm not sure about ssh login, but I suspect you could get there using javax.net.ssl.SSLServerSocket instead of ServerSocket.
What remains is to do something sensible with the user input, instead of just throwing it back in their faces.
Depeding on the amount of commands and their parameters, you can either do the command parsing yourself, or find a library that handles it for you.

Categories

Resources