Skip to content

Commit

Permalink
MainService+Activity+cpp: Implemented configurable address binding
Browse files Browse the repository at this point in the history
When applied, this commit tries to implement the feature requests reported on issue bk138#43 and bk138#227.
Basically, with this commit, it is possible to instruct the server to listen only on a certain address.

To do this, there is a further edittext "Listening Address", which can be configured.
Please note that if an invalid ip/address is set, by default, it is assumed 0.0.0.0 is requested
  • Loading branch information
elluisian committed Aug 21, 2024
1 parent 355fda6 commit 8029a64
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 4 deletions.
21 changes: 20 additions & 1 deletion app/src/main/cpp/droidvnc-ng.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncS
}


JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncStartServer(JNIEnv *env, jobject thiz, jint width, jint height, jint port, jstring desktopname, jstring password, jstring httpRootDir) {
JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncStartServer(JNIEnv *env, jobject thiz, jint width, jint height, jstring host, jint port, jstring desktopname, jstring password, jstring httpRootDir) {

int argc = 0;

Expand All @@ -315,6 +315,17 @@ JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncS
theScreen->setXCutTextUTF8 = onCutText;
theScreen->newClientHook = onClientConnected;

in_addr_t address = 0; // Default is 0.0.0.0 (all available interfaces)
if (host != NULL) {
const char *hostNative = (*env)->GetStringUTFChars(env, host, NULL);
if (!rfbStringToAddr((char*)hostNative, &address)) {
address = 0; // Assign 0.0.0.0 (any) in case of errors
}
(*env)->ReleaseStringUTFChars(env, host, hostNative);
}

// With listenInterface one can define where the server will be available
theScreen->listenInterface = address;
theScreen->port = port;
theScreen->ipv6port = port;

Expand Down Expand Up @@ -491,4 +502,12 @@ JNIEXPORT jint JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncGetFr

JNIEXPORT jboolean JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncIsActive(JNIEnv *env, jobject thiz) {
return theScreen && rfbIsActive(theScreen);
}

JNIEXPORT jint JNICALL Java_net_christianbeier_droidvnc_1ng_MainService_vncGetListenInterface(JNIEnv *env, jobject thiz) {
if (!theScreen) {
return -1;
}

return theScreen->listenInterface;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class Constants {
/*
user settings
*/
public static final String PREFS_KEY_SETTINGS_LISTEN_INTERFACE = "settings_listen_interface";
public static final String PREFS_KEY_SETTINGS_PORT = "settings_port";
public static final String PREFS_KEY_SETTINGS_PASSWORD = "settings_password" ;
public static final String PREFS_KEY_SETTINGS_START_ON_BOOT = "settings_start_on_boot" ;
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/net/christianbeier/droidvnc_ng/Defaults.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class Defaults {
private const val PREFS_KEY_DEFAULTS_ACCESS_KEY = "defaults_access_key"
}

@EncodeDefault
var listenInterface = "0.0.0.0"
private set

@EncodeDefault
var port = 5900
private set
Expand Down Expand Up @@ -116,6 +120,7 @@ class Defaults {
try {
val jsonString = jsonFile.readText()
val readDefault = Json.decodeFromString<Defaults>(jsonString)
this.listenInterface = readDefault.listenInterface
this.port = readDefault.port
this.portReverse = readDefault.portReverse
this.portRepeater = readDefault.portRepeater
Expand Down
47 changes: 45 additions & 2 deletions app/src/main/java/net/christianbeier/droidvnc_ng/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ protected void onCreate(Bundle savedInstanceState) {
mButtonToggle.setOnClickListener(view -> {

Intent intent = new Intent(MainActivity.this, MainService.class);
intent.putExtra(MainService.EXTRA_LISTEN_INTERFACE, prefs.getString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, mDefaults.getListenInterface()));
intent.putExtra(MainService.EXTRA_PORT, prefs.getInt(Constants.PREFS_KEY_SETTINGS_PORT, mDefaults.getPort()));
intent.putExtra(MainService.EXTRA_PASSWORD, prefs.getString(Constants.PREFS_KEY_SETTINGS_PASSWORD, mDefaults.getPassword()));
intent.putExtra(MainService.EXTRA_FILE_TRANSFER, prefs.getBoolean(Constants.PREFS_KEY_SETTINGS_FILE_TRANSFER, mDefaults.getFileTransfer()));
Expand Down Expand Up @@ -306,6 +307,35 @@ protected void onCreate(Bundle savedInstanceState) {
});


final EditText listenInterface = findViewById(R.id.settings_listen_interface);
listenInterface.setText(prefs.getString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, mDefaults.getListenInterface()));
listenInterface.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

}

@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
// only save new value if it differs from the default and was not saved before
if(!(prefs.getString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, null) == null && charSequence.toString().equals(mDefaults.getListenInterface()))) {
SharedPreferences.Editor ed = prefs.edit();
ed.putString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, charSequence.toString());
ed.apply();
}
}

@Override
public void afterTextChanged(Editable editable) {

}
});
listenInterface.setOnFocusChangeListener((v, hasFocus) -> {
// move cursor to end of text
listenInterface.setSelection(listenInterface.getText().length());
});


final EditText port = findViewById(R.id.settings_port);
if(prefs.getInt(Constants.PREFS_KEY_SETTINGS_PORT, mDefaults.getPort()) < 0) {
port.setHint(R.string.main_activity_settings_port_not_listening);
Expand Down Expand Up @@ -757,7 +787,15 @@ private void onServerStarted() {
if(MainService.getPort() >= 0) {
HashMap<ClickableSpan, Pair<Integer,Integer>> spans = new HashMap<>();
// uhh there must be a nice functional way for this
ArrayList<String> hosts = MainService.getIPv4s();
ArrayList<String> hosts = null;

if (MainService.isListeningOnAnyInterface()) {
hosts = MainService.getIPv4s();
} else {
hosts = new ArrayList<>();
hosts.add(MainService.getListenInterface());
}

StringBuilder sb = new StringBuilder();
sb.append(getString(R.string.main_activity_address)).append(" ");
for (int i = 0; i < hosts.size(); ++i) {
Expand All @@ -768,10 +806,13 @@ private void onServerStarted() {
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
final int usedPort = MainService.getPort();
final int usedHttpPort = usedPort - 100;

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT,
"http://" + host + ":5800/vnc.html?autoconnect=true&show_dot=true&&host=" + host + "&port=" + MainService.getPort());
"http://" + host + ":" + usedHttpPort + "/vnc.html?autoconnect=true&show_dot=true&&host=" + host + "&port=" + usedPort);
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, null));
}
Expand All @@ -798,6 +839,7 @@ public void onClick(@NonNull View widget) {
findViewById(R.id.outbound_buttons).setVisibility(View.VISIBLE);

// indicate that changing these settings does not have an effect when the server is running
findViewById(R.id.settings_listen_interface).setEnabled(false);
findViewById(R.id.settings_port).setEnabled(false);
findViewById(R.id.settings_password).setEnabled(false);
findViewById(R.id.settings_access_key).setEnabled(false);
Expand All @@ -823,6 +865,7 @@ private void onServerStopped() {
findViewById(R.id.outbound_buttons).setVisibility(View.GONE);

// indicate that changing these settings does have an effect when the server is stopped
findViewById(R.id.settings_listen_interface).setEnabled(true);
findViewById(R.id.settings_port).setEnabled(true);
findViewById(R.id.settings_password).setEnabled(true);
findViewById(R.id.settings_access_key).setEnabled(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public class MainService extends Service {
public static final String ACTION_CONNECT_REPEATER = "net.christianbeier.droidvnc_ng.ACTION_CONNECT_REPEATER";
public static final String EXTRA_REQUEST_ID = "net.christianbeier.droidvnc_ng.EXTRA_REQUEST_ID";
public static final String EXTRA_REQUEST_SUCCESS = "net.christianbeier.droidvnc_ng.EXTRA_REQUEST_SUCCESS";
public static final String EXTRA_LISTEN_INTERFACE = "net.christianbeier.droidvnc_ng.EXTRA_LISTEN_INTERFACE";
public static final String EXTRA_HOST = "net.christianbeier.droidvnc_ng.EXTRA_HOST";
public static final String EXTRA_PORT = "net.christianbeier.droidvnc_ng.EXTRA_PORT";
public static final String EXTRA_REPEATER_ID = "net.christianbeier.droidvnc_ng.EXTRA_REPEATER_ID";
Expand Down Expand Up @@ -104,6 +105,8 @@ public class MainService extends Service {

final static String ACTION_HANDLE_NOTIFICATION_RESULT = "action_handle_notification_result";

private static final String PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE_WILDCARD = "server_last_listen_interface_wildcard" ;
private static final String PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE = "server_last_listen_interface" ;
private static final String PREFS_KEY_SERVER_LAST_PORT = "server_last_port" ;
private static final String PREFS_KEY_SERVER_LAST_PASSWORD = "server_last_password" ;
private static final String PREFS_KEY_SERVER_LAST_FILE_TRANSFER = "server_last_file_transfer" ;
Expand Down Expand Up @@ -166,9 +169,10 @@ public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
}

@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private native boolean vncStartServer(int width, int height, int port, String desktopName, String password, String httpRootDir);
private native boolean vncStartServer(int width, int height, String host, int port, String desktopName, String password, String httpRootDir);
private native boolean vncStopServer();
private native boolean vncIsActive();
private native int vncGetListenInterface();
private native long vncConnectReverse(String host, int port);
private native long vncConnectRepeater(String host, int port, String repeaterIdentifier);
static native boolean vncNewFramebuffer(int width, int height);
Expand Down Expand Up @@ -331,16 +335,24 @@ public int onStartCommand(Intent intent, int flags, int startId)
startScreenCapture();
} else {
DisplayMetrics displayMetrics = Utils.getDisplayMetrics(this, Display.DEFAULT_DISPLAY);
String listenInterface = PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE, mDefaults.getListenInterface()).toLowerCase();
int port = PreferenceManager.getDefaultSharedPreferences(this).getInt(PREFS_KEY_SERVER_LAST_PORT, mDefaults.getPort());
// get device name
String name = Utils.getDeviceName(this);

boolean status = vncStartServer(displayMetrics.widthPixels,
displayMetrics.heightPixels,
listenInterface,
port,
name,
PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_PASSWORD, mDefaults.getPassword()),
getFilesDir().getAbsolutePath() + File.separator + "novnc");

final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor ed = prefs.edit();
ed.putBoolean(PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE_WILDCARD, this.vncGetListenInterface() == 0);
ed.apply();

Intent answer = new Intent(ACTION_START);
answer.putExtra(EXTRA_REQUEST_ID, PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_START_REQUEST_ID, null));
answer.putExtra(EXTRA_REQUEST_SUCCESS, status);
Expand Down Expand Up @@ -374,15 +386,22 @@ public int onStartCommand(Intent intent, int flags, int startId)
if (mResultCode != 0 && mResultData != null
|| (Build.VERSION.SDK_INT >= 30 && PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PREFS_KEY_SERVER_LAST_FALLBACK_SCREEN_CAPTURE, false))) {
DisplayMetrics displayMetrics = Utils.getDisplayMetrics(this, Display.DEFAULT_DISPLAY);
String listenInterface = PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE, mDefaults.getListenInterface()).toLowerCase();
int port = PreferenceManager.getDefaultSharedPreferences(this).getInt(PREFS_KEY_SERVER_LAST_PORT, mDefaults.getPort());
String name = Utils.getDeviceName(this);
boolean status = vncStartServer(displayMetrics.widthPixels,
displayMetrics.heightPixels,
listenInterface,
port,
name,
PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_PASSWORD, mDefaults.getPassword()),
getFilesDir().getAbsolutePath() + File.separator + "novnc");

final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor ed = prefs.edit();
ed.putBoolean(PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE_WILDCARD, this.vncGetListenInterface() == 0);
ed.apply();

Intent answer = new Intent(ACTION_START);
answer.putExtra(EXTRA_REQUEST_ID, PreferenceManager.getDefaultSharedPreferences(this).getString(PREFS_KEY_SERVER_LAST_START_REQUEST_ID, null));
answer.putExtra(EXTRA_REQUEST_SUCCESS, status);
Expand Down Expand Up @@ -445,6 +464,8 @@ public int onStartCommand(Intent intent, int flags, int startId)
// Step 0: persist given arguments to be able to recover from possible crash later
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor ed = prefs.edit();

ed.putString(PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE, intent.getStringExtra(EXTRA_LISTEN_INTERFACE) != null ? intent.getStringExtra(EXTRA_LISTEN_INTERFACE) : prefs.getString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, mDefaults.getListenInterface()));
ed.putInt(PREFS_KEY_SERVER_LAST_PORT, intent.getIntExtra(EXTRA_PORT, prefs.getInt(Constants.PREFS_KEY_SETTINGS_PORT, mDefaults.getPort())));
ed.putString(PREFS_KEY_SERVER_LAST_PASSWORD, intent.getStringExtra(EXTRA_PASSWORD) != null ? intent.getStringExtra(EXTRA_PASSWORD) : prefs.getString(Constants.PREFS_KEY_SETTINGS_PASSWORD, mDefaults.getPassword()));
ed.putBoolean(PREFS_KEY_SERVER_LAST_FILE_TRANSFER, intent.getBooleanExtra(EXTRA_FILE_TRANSFER, prefs.getBoolean(Constants.PREFS_KEY_SETTINGS_FILE_TRANSFER, mDefaults.getFileTransfer())));
Expand Down Expand Up @@ -793,6 +814,25 @@ static ArrayList<String> getIPv4s() {
return hosts;
}


static boolean isListeningOnAnyInterface() {
try {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(instance);
return prefs.getBoolean(PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE_WILDCARD, false);
} catch (Exception e) {
return false;
}
}

static String getListenInterface() {
try {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(instance);
return prefs.getString(PREFS_KEY_SERVER_LAST_LISTEN_INTERFACE, new Defaults(instance).getListenInterface());
} catch (Exception e) {
return null;
}
}

static int getPort() {
try {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public void onReceive(Context context, Intent arg1)

Intent intent = new Intent(context, MainService.class);
intent.setAction(MainService.ACTION_START);
intent.putExtra(MainService.EXTRA_LISTEN_INTERFACE, prefs.getString(Constants.PREFS_KEY_SETTINGS_LISTEN_INTERFACE, defaults.getListenInterface()));
intent.putExtra(MainService.EXTRA_PORT, prefs.getInt(Constants.PREFS_KEY_SETTINGS_PORT, defaults.getPort()));
intent.putExtra(MainService.EXTRA_PASSWORD, prefs.getString(Constants.PREFS_KEY_SETTINGS_PASSWORD, defaults.getPassword()));
intent.putExtra(MainService.EXTRA_FILE_TRANSFER, prefs.getBoolean(Constants.PREFS_KEY_SETTINGS_FILE_TRANSFER, defaults.getFileTransfer()));
Expand Down
30 changes: 30 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,36 @@
android:layout_marginBottom="1dp"
android:padding="10dp">

<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:padding="10dp"
android:text="@string/main_activity_settings_listening_address" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:padding="10dp"
android:text="@string/main_activity_colon" />

<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:padding="10dp"
android:hint="@string/settings_listen_interface_hint"
android:layout_weight="1"
android:inputType="textUri"
android:maxLines="1"
android:id="@+id/settings_listen_interface"/>
</TableRow>

<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<resources>
<string name="main_activity_title">droidVNC-NG Admin-Panel</string>
<string name="main_activity_settings">Einstellungen</string>
<string name="main_activity_settings_listening_address">Höradresse</string>
<string name="main_activity_settings_port">Port</string>
<string name="main_activity_settings_port_not_listening">Eingehende Verbindungen deaktiviert</string>
<string name="main_activity_settings_password">Passwort</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<string name="app_name" translatable="false">droidVNC-NG</string>
<string name="main_activity_title">Amministrazione di droidVNC-NG</string>
<string name="main_activity_settings">Impostazioni</string>
<string name="main_activity_settings_listening_address">Indirizzo d\'ascolto</string>
<string name="main_activity_settings_port">Porta</string>
<string name="main_activity_settings_port_not_listening">Connessioni in entrata disabilitate</string>
<string name="main_activity_settings_password">Password</string>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values-ja/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<string name="app_name" translatable="false">droidVNC-NG</string>
<string name="main_activity_title">droidVNC-NG管理パネル</string>
<string name="main_activity_settings">設定</string>
<string name="main_activity_settings_listening_address">リスニングアドレス</string>
<string name="main_activity_settings_port">ポート</string>
<string name="main_activity_settings_port_not_listening">インバウンド接続は無効です</string>
<string name="main_activity_settings_password">パスワード</string>
Expand Down
Loading

0 comments on commit 8029a64

Please sign in to comment.