How to Execute Commands Remotely via SSH in Android? - GeeksforGeeks

23 Feb, 2021
The SSH protocol uses encryption to secure the connection between a client and a server. All user authentication, commands, output, and file transfers are encrypted to protect against attacks in the network. More often than not you would need to SSH into your cloud Virtual Machines or a remote shell. Usually, we need an SSH client to establish an SSH connection. For Windows, the free (libre) GUI client PuTTY is used for this purpose. Here is how it looks like accessing a remote Linux shell in PuTTY:
The following tutorial illustrates how the same can be achieved in android. Note that we are going to implement this project using the Java language. Library: Apache MINA SSHD
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.
Step 2: Adding dependencies
Now we need to add the required dependencies in order to use the apache mina sshd library. Open app/src/build.gradle file in your project directory and add the following under dependencies:
// Adding implementations required for apache mina library
implementation ‘org.apache.mina:mina-core:3.0.0-M2’
implementation ‘org.apache.sshd:sshd-core:2.1.0’
implementation ‘org.apache.sshd:sshd-putty:2.1.0’
implementation ‘org.apache.sshd:sshd-common:2.1.0’
implementation ‘org.slf4j:slf4j-api:1.7.5’
implementation ‘org.slf4j:slf4j-simple:1.6.4’
Step 3: Add permission to the internet in your AndroidManifest.xml file
Add below two lines inside your src/res/AndroidManifest.xml file inside <manifest></manifest> tags.
<uses-permission android:name=”android.permission.INTERNET” />
Step 4: Modify the strings.xml file
Open app > src > main > res > values > strings.xml and add the following code:
XML
<resources>    <string name="app_name">gfg_ssh</string>    <string name="host">Host</string>    <string name="port">Port</string>    <string name="defaultPort">22</string>    <string name="username">Username</string>    <string name="password">Password</string>    <string name="button_send">SEND</string></resources>
Step 5: Building the UI
We are going to have two activities in our app.
MainActivity: Here, we’ll enter the login details
sshActivity: Here, we’ll see the shell output.
Working with the activity_main.xml file:
Now, Navigate to the app > src > main > res > layout > activity_main.xml and add the below code to the file.
XML
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/black"    tools:context=".MainActivity">      <LinearLayout        android:id="@+id/linear"        android:layout_width="270dp"        android:layout_height="413dp"        android:layout_margin="50dp"        android:orientation="vertical"        app:layout_constraintBottom_toBottomOf="parent"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="parent"        app:layout_constraintWidth_percent=".8">          <EditText            android:id="@+id/editText"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:autofillHints="host"            android:background="@color/white"            android:ems="10"            android:hint="@string/host"            android:inputType="textPersonName"            android:padding="10dp"            android:textColor="@color/black"            android:textColorHint="@color/black"            app:layout_constraintWidth_percent=".8" />          <EditText            android:id="@+id/portField"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginTop="22dp"            android:autofillHints="port"            android:background="@color/white"            android:ems="10"            android:hint="@string/port"            android:inputType="textPersonName"            android:padding="10dp"            android:textColor="@color/black"            android:textColorHint="@color/black"            app:layout_constraintHorizontal_bias="0.5"            app:layout_constraintWidth_percent=".8"            tools:text="@string/defaultPort" />          <EditText            android:id="@+id/usernameField"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginTop="22dp"            android:autofillHints="username"            android:background="@color/white"            android:ems="10"            android:hint="@string/username"            android:inputType="textPersonName"            android:padding="10dp"            android:textColor="@color/black"            android:textColorHint="@color/black"            app:layout_constraintBottom_toTopOf="@+id/passwordField"            app:layout_constraintEnd_toEndOf="parent"            app:layout_constraintHorizontal_bias="0.5"            app:layout_constraintStart_toStartOf="parent"            app:layout_constraintTop_toBottomOf="@+id/portField"            app:layout_constraintWidth_percent=".8" />          <EditText            android:id="@+id/passwordField"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginTop="22dp"            android:autofillHints="password"            android:background="@color/white"            android:ems="10"            android:hint="@string/password"            android:inputType="textPassword"            android:padding="10dp"            android:textColor="@color/black"            android:textColorHint="@color/black"            app:layout_constraintWidth_percent=".8" />          <Button            android:id="@+id/button"            android:layout_width="194dp"            android:layout_height="61dp"            android:layout_gravity="center"            android:layout_marginTop="69dp"            android:layout_marginBottom="373dp"            android:background="#594FAA"            android:onClick="authenticate"            android:text="@string/button_send"            android:textColor="@android:color/background_light"            tools:text="@string/button_send" />    </LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>
First, create a new activity sshActivity by right-clicking on the activity folder (com.example.gfg_ssh) and then select New > Activity > Empty Activity and Now add the below code to the activity_ssh.xml file for UI of this activity.
XML
<?xml version="1.0" encoding="utf-8"?><androidx.coordinatorlayout.widget.CoordinatorLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".sshActivity">      <TextView        android:id="@+id/textView"        android:layout_width="match_parent"        android:layout_height="688dp"        android:background="@android:color/black"        android:textColor="@color/white"        android:textSize="18sp" />  </androidx.coordinatorlayout.widget.CoordinatorLayout>
Step 6: Working with the MainActivity.java file
Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.EditText;  import androidx.appcompat.app.AppCompatActivity;  public class MainActivity extends AppCompatActivity {      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }      public void authenticate(View view) {                // Create an intent for sshActivity        Intent intent = new Intent(this, sshActivity.class);          // Declare fields        EditText editText = (EditText) findViewById(R.id.editText);        EditText portField = (EditText) findViewById(R.id.portField);        EditText usernameField = (EditText) findViewById(R.id.usernameField);        EditText passwordField = (EditText) findViewById(R.id.passwordField);                  // Get input data from fields        String host = editText.getText().toString();        String port = portField.getText().toString();        String username = usernameField.getText().toString();        String password = passwordField.getText().toString();          // Pass on data to sshActivity via intent        intent.putExtra("host", host);        intent.putExtra("port", port);        intent.putExtra("username", username);        intent.putExtra("password", password);        startActivity(intent);        finish();    }}
Step 7: Working with the sshActivity.java file
This is the activity where we import the Apache MINA SSHD library and connect to our remote machine via SSH. We obtain the login data from the intent. Below is the code for the sshActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.widget.TextView;  import androidx.appcompat.app.AppCompatActivity;  import org.apache.sshd.client.SshClient;import org.apache.sshd.client.channel.ClientChannel;import org.apache.sshd.client.channel.ClientChannelEvent;import org.apache.sshd.client.session.ClientSession;import org.apache.sshd.common.channel.Channel;import org.apache.sshd.server.forward.AcceptAllForwardingFilter;  import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.EnumSet;import java.util.concurrent.TimeUnit;  public class sshActivity extends AppCompatActivity {      ClientChannel channel;    TextView shellOutput;    String host, username, password;    Integer port;    String command;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_ssh);          // set output field        shellOutput = findViewById(R.id.textView);          // Get user credentials from indent        Intent intent = getIntent();        host = intent.getStringExtra("host");        port = Integer.parseInt(intent.getStringExtra("port"));        username = intent.getStringExtra("username");        password = intent.getStringExtra("password");          // Command which will be executed        command = "pwd\n";                  // Setting user.com property manually         // since isn't set by default in android        String key = "user.home";        Context Syscontext;        Syscontext = getApplicationContext();        String val = Syscontext.getApplicationInfo().dataDir;        System.setProperty(key, val);          // Creating a client instance        SshClient client = SshClient.setUpDefaultClient();        client.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE);        client.start();          // Starting new thread because network processes         // can interfere with UI if started in main thread        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                try {                    // Connection establishment and authentication                    try (ClientSession session = client.connect(username, host, port).verify(10000).getSession()) {                        session.addPasswordIdentity(password);                        session.auth().verify(50000);                        System.out.println("Connection establihed");                          // Create a channel to communicate                        channel = session.createChannel(Channel.CHANNEL_SHELL);                        System.out.println("Starting shell");                          ByteArrayOutputStream responseStream = new ByteArrayOutputStream();                        channel.setOut(responseStream);                          // Open channel                        channel.open().verify(5, TimeUnit.SECONDS);                        try (OutputStream pipedIn = channel.getInvertedIn()) {                            pipedIn.write(command.getBytes());                            pipedIn.flush();                        }                          // Close channel                        channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED),                                TimeUnit.SECONDS.toMillis(5));                          // Output after converting to string type                        String responseString = new String(responseStream.toByteArray());                        System.out.println(responseString);                        shellOutput.setText(responseString);                                              } catch (IOException e) {                        e.printStackTrace();                    } finally {                        client.stop();                    }                } catch (Exception e) {                    e.printStackTrace();                }            }        });        thread.start();    }}
Logging in:
SSH command execution:
Android-Misc
Android
Java
Java
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Flutter - Custom Bottom Navigation Bar
How to Read Data from SQLite Database in Android?
Android Listview in Java with Example
Retrofit with Kotlin Coroutine in Android
How to Change the Background Color After Clicking the Button in Android?
Arrays in Java
Split() String method in Java with examples
For-each loop in Java
Arrays.sort() in Java with examples
Reverse a string in Java