Simple SSH connect open source code with JSch - android

I am trying to make something from this simple example :
SSH, execute remote commands with Android
i am trying to control my raspberry pi through ssh with simple command execution, everything ok except , it doesn't work! the command i am trying is to make empty text.txt, but when i check on the raspberry, there is no such file created. also tried a sudo reboot command , still doesn't work
Here is my main code:
package com.example.thesacredhaven.samplessh;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
executeRemoteCommand("pi","root","192.168.219.178",22);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void executeRemoteCommand(
String username,
String password,
String hostname,
int port) throws Exception {
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, 22);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.setTimeout(10000);
session.connect();
// SSH Channel
ChannelExec channel = (ChannelExec) session.openChannel("exec");
channel.setCommand("lsusb > /home/pi/test.txt");
channel.connect();
channel.disconnect();
}
}
What did I do wrong ? I have no error messages and I don't see any SSH connection on my Linux. is there any library ? or some missing step?

Related

Unable to connect to Oracle 11g database using JDBC on Android

I'm trying to connect my Android app to Oracle Database Express Edition 11g hosted on my laptop. I'm testing the app on my phone with its hotspot ON to which the laptop is connected via WiFi.
I've added ojdbc14.jar to app/libs directory and selected Add as Library option on it through Android Studio.
I'm getting the following errors:
Rejecting re-init on previously-failed class java.lang.Class<oracle.jdbc.pool.OracleDataSource>: java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/naming/Referenceable;
Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.naming.Referenceable" on path: DexPathList
W/System.err: java.sql.SQLException: Io exception: The Network Adapter could not establish the connection
P.s. I know using a server is a better approach. Doing this for a client who wants to use it in a secure private network and they don't want to host a separate server for the database connection.
I read elsewhere that I need to use Async task for connecting JDBC but I'm not sure how; consider me a beginner. All other answers I found related to this keep going off topic. I just want to know how to make JDBC work on Android, considering the risks.
Here's my MainActivity.java:
package com.absingh.apptest;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MainActivity extends AppCompatActivity {
private static final String DEFAULT_DRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DEFAULT_URL = "jdbc:oracle:thin:#192.168.42.49:1521:XE";
private static final String DEFAULT_USERNAME = "myusername";
private static final String DEFAULT_PASSWORD = "mypassword";
private Connection connection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
TextView tv = (TextView) findViewById(R.id.hello);
try {
this.connection = createConnection();
Toast.makeText(MainActivity.this, "Connected",
Toast.LENGTH_SHORT).show();
Statement stmt=connection.createStatement();
StringBuffer stringBuffer = new StringBuffer();
ResultSet rs=stmt.executeQuery("select * from testtable");
while(rs.next()) {
stringBuffer.append( rs.getString(1)+"\n");
}
tv.setText(stringBuffer.toString());
connection.close();
}
catch (Exception e) {
Toast.makeText(MainActivity.this, ""+e,
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException {
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
}
public static Connection createConnection() throws ClassNotFoundException, SQLException {
return createConnection(DEFAULT_DRIVER, DEFAULT_URL, DEFAULT_USERNAME, DEFAULT_PASSWORD);
}
}
Nevermind, I figured it out.
The code in the question works fine if you add this above the application tag in AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
I'll leave the question be, in case someone else gets the same problem.

MySQL connection using jdbc, android studio

I'm new to Android Studio and I hope you don't consider my question silly.I am trying to write a small program in the terminal of the android studio.When I try to run the same program in my terminal(not android studio) it's working fine.I added the MySQL-connector.jar file in android studio lib by going through this mysql JDBC driver to the android studio.But it didn't work.Please help me.Thanks in advance.
//MySQConnectionExample.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class MySQLConnectionExample {
public static void main(String[] args) {
Connection conn1 = null;
String result = " ";
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://127.0.0.1:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
if (conn1 != null) {
System.out.println("Connected to the database test1");
}
String sql = " select address from pharmacy";
PreparedStatement prest = conn1.prepareStatement(sql);
ResultSet rs = prest.executeQuery();
while(rs.next()) {
result = rs.getString(1);
System.out.println(result);
}
} catch (SQLException ex) {
System.out.println("An error occurred. Maybe user/password is invalid");
ex.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//Error after execution
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at MySQLConnectionExample.main(MySQLConnectionExample.java:16)
When I remove "Class.forName("com.mysql.jdbc.Driver")" from the program this is the error i get
An error occurred. Maybe user/password is invalid
java.sql.SQLException: No suitable driver found for
jdbc:mysql://127.0.0.1:3306/demo
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at MySQLConnectionExample.main(MySQLConnectionExample.java:22)
You can't connect directly to databases from android devices. Build APIs that connects to your database. then connect your Android Application to these APIs.
Check this answer for a the same question https://stackoverflow.com/a/12233178/4442067
I assume you're trying to directly connect to a MySQL database from your Android device. But first, you have a ClassNotFound exception, which means you haven't imported the library.
And when you get the driver to work, there's more problem in this part:
....
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://127.0.0.1:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
....
By specifying 127.0.0.1 on your Android device, you're trying to connect to a MySQL server on your device. Now I don't know if you can install MySQL on Android, but you may want to install a MySQL server on your computer. This goes without saying that you must use the IP of that computer and have the MySQL port (3306) open on your computer.
So, what you may want to see is something like
....
try {
Class.forName("com.mysql.jdbc.Driver");
String url1 = "jdbc:mysql://192.168.1.10:3306/demo";
String user = "root";
String password = "mypassword";
conn1 = DriverManager.getConnection(url1, user, password);
....
This assumes your MySQL server is installed and configured on your computer with IP address 192.168.1.10
Good luck.
EDIT: I can't really recommend this approach for a production application though, because I'm afraid what a hacker who can decompile your code can do with it.

"Null" Connection jtds.jdbc1.3.1 connection to SQL server

Here is all of my code. I am trying to connect to my SQL server. These contents in sentences are actually exist. Real username and passwords. But I am getting Null on error catch (not connected). Please let me know where the error could be.
And I also added Internet permission in manifest.
I came across from this article - link
package com.eample.databasetester;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class MainActivity extends Activity {
TextView txv1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txv1=(TextView)findViewById(R.id.text_view);
query2();
}
public void query2()
{
txv1.setText("connected");
Log.i("Android"," MySQL Connect Example.");
Connection conn = null;
try {
String driver = "net.sourceforge.jtds.jdbc.Driver";
Class.forName(driver).newInstance();
String connString = "jdbc:jtds:sqlserver://50.62.209.49:3306/test;encrypt=fasle;user=XXXX;password=YYYY;instance=SQLEXPRESS;";
String username = "XXXX";
String password = "YYYY";
conn = DriverManager.getConnection(connString,username,password);
Log.w("Connection","open");
Statement stmt = conn.createStatement();
ResultSet reset = stmt.executeQuery("select * from test");
while(reset.next()){
txv1.setText("Data:"+reset.getString(3));
}
conn.close();
} catch (Exception e)
{
txv1.setText("Error connection" + e.getMessage());
}
}
}
THis is a really bad idea. You should not connect to a database over the network from a phone. First off, it requires your DB to be publically addressable which is a security risk. Secondly, it means your password for the db is on the clients, and you don't physically control them. Your app will be reverse engineered, they'll get your password, and then your data is fucked. You should always abstract access to the database from any hardware you don't control by use of a webservice. Then the password never leaves your machines and the damage an attacker can do is limited.
Third, this code wont work anyway, you cant do network IO on the UI thread. That's likely why conn returned null. But take this as a sign of the universe telling you to fix things the right way rather than just changing threads.

Simple SSH connect with JSch

I am trying to make something from this simple example :
SSH, execute remote commands with Android
I just want to see if I can connect from my android phone to a linux server using SSH but it doesn't work...
Here is my main code :
package com.example.ssh;
import java.util.Properties;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import android.os.Bundle;
import android.app.Activity;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try
{
JSch jsch = new JSch();
Session session = jsch.getSession("root","192.168.0.26", 22);
session.setPassword("xxxxx");
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
What did I do wrong ? I have no error messages and I don't see any SSH connection on my Linux. I added the libraries jsch and jzlib. I have no problem to get connect with a putty session.
EDIT1 : In fact, I found an error which explain why it doesn't work even if I don't know how to resolve the problem. The error is :
android.os.NetworkOnMainThreadException
so it seems to mean that the app can't perform a networking operation on its main thread...
You have to execute that code in another thread so you don't hang the UI thread is what that exception means. If the UI thread is executing a network call it can't repaint the UI so your users sees a frozen UI that doesn't respond to them while the app is waiting on the network call to finish. Android wants to avoid bad user experiences like this so it prevents you from doing things like this by throwing this exception.
Your onCreate() method should invoke another thread (I'd suggest using an AsyncTask over a raw thread) to perform the SSH connection. Then when it's done it can post the results back to the UI thread and safely update your application's UI from the UI thread.
http://developer.android.com/reference/android/os/AsyncTask.html
chubbsondubs's solution is perfect. I just want to share the code that I made for this problem too for people who want a quick solution:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AsyncTask<Integer, Void, Void>(){
#Override
protected Void doInBackground(Integer... params) {
try {
executeRemoteCommand("root", "myPW","192.168.0.26", 22);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}.execute(1);
}
public static String executeRemoteCommand(String username,String password,String hostname,int port)
throws Exception {
JSch jsch = new JSch();
Session session = jsch.getSession(username, hostname, port);
session.setPassword(password);
// Avoid asking for key confirmation
Properties prop = new Properties();
prop.put("StrictHostKeyChecking", "no");
session.setConfig(prop);
session.connect();
// SSH Channel
ChannelExec channelssh = (ChannelExec)
session.openChannel("exec");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
channelssh.setOutputStream(baos);
// Execute command
channelssh.setCommand("lsusb > /home/pi/test.txt");
channelssh.connect();
channelssh.disconnect();
return baos.toString();
}
A Kotlin solution:
import android.os.AsyncTask
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.jcraft.jsch.ChannelExec
import com.jcraft.jsch.JSch
import java.io.ByteArrayOutputStream
import java.util.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
SshTask().execute()
}
class SshTask : AsyncTask<Void, Void, String>() {
override fun doInBackground(vararg p0: Void?): String {
val output = executeRemoteCommand("demo", "password", "test.rebex.net")
print(output)
return output
}
}
}
fun executeRemoteCommand(username: String,
password: String,
hostname: String,
port: Int = 22): String {
val jsch = JSch()
val session = jsch.getSession(username, hostname, port)
session.setPassword(password)
// Avoid asking for key confirmation.
val properties = Properties()
properties.put("StrictHostKeyChecking", "no")
session.setConfig(properties)
session.connect()
// Create SSH Channel.
val sshChannel = session.openChannel("exec") as ChannelExec
val outputStream = ByteArrayOutputStream()
sshChannel.outputStream = outputStream
// Execute command.
sshChannel.setCommand("ls")
sshChannel.connect()
// Sleep needed in order to wait long enough to get result back.
Thread.sleep(1_000)
sshChannel.disconnect()
session.disconnect()
return outputStream.toString()
}
In build.gradle add:
dependencies {
...
compile group: 'com.jcraft', name: 'jsch', version: '0.1.54'
}

FTPS connection in android

I am new to android, i want to download the files from FTPs server, On emulater i am able to download files but when i try on target board it is giving error at ftp.auth(SSLFTPClient.AUTH_TLS);
Below is the my code, please suggest me where i am wrong.
package com.android.ftp;
import java.io.File;
import android.app.Activity;
import android.os.Bundle;
import com.enterprisedt.net.ftp.FTPClientInterface;
import com.enterprisedt.net.ftp.FTPConnectMode;
import com.enterprisedt.net.ftp.FTPTransferType;
import com.enterprisedt.net.ftp.ssl.SSLFTPClient;
import com.enterprisedt.util.debug.Level;
import com.enterprisedt.util.debug.Logger;
public class Ftp_testActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String host = "ftp.xyz.com";
String username = "abcd";
String password = "pqr";
String filename = "/mnt/sdcard/video1/747.3gp";
// set up logger so that we get some output
Logger log = Logger.getLogger(Ftp_testActivity.class);
Logger.setLevel(Level.INFO);
SSLFTPClient ftp = null;
try {
// create client
log.info("Creating FTPS (explicit) client");
ftp = new SSLFTPClient();
// disable standard SSL closure
log.info("Setting configuration flags");
ftp.setConfigFlags(SSLFTPClient.ConfigFlags.DISABLE_SSL_CLOSURE);
// set remote host
log.info("Setting remote host");
ftp.setRemoteHost(host);
ftp.setRemotePort(21);
// turn off server validation
log.info("Turning off server validation");
ftp.setValidateServer(false);
// connect to the server
log.info("Connecting to server " + host);
ftp.connect();
// switch to SSL on control channel
log.info("Switching to FTPS (explicit mode)");
ftp.auth(SSLFTPClient.AUTH_TLS);
// log in
log.info("Logging in with username=" + username + " and password="
+ password);
ftp.login(username, password);
log.info("Logged in");
ftp.setConnectMode(FTPConnectMode.PASV);
ftp.setType(FTPTransferType.ASCII);
putGetDelete(filename, ftp);
log.info("Successfully transferred in ASCII mode");
// Shut down client
log.info("Quitting client");
ftp.quit();
log.info("Example complete");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void putGetDelete(String name, FTPClientInterface ftp)
throws Exception {
ftp.put(name, name);
ftp.get(name + ".copy", name);
ftp.delete(name);
File file = new File(name + ".copy");
file.delete();
}
}
You should try:
ftp.setRemotePort(990);
where 990 is port SSL default.

Categories

Resources