Skip to content

Commit

Permalink
[#59672] android-client: ConfigurationProvider.java: Handle incorrect…
Browse files Browse the repository at this point in the history
… config

Covers 'ConfigurationProvider' with try/catch statements in order to
eliminate unexpected errors.
Updates source code of the Android client accordingly.

Signed-off-by: Illia Vysochyn <[email protected]>
  • Loading branch information
ivysochyn authored and msobkowski committed May 24, 2024
1 parent a48b503 commit 9988992
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ public void checkUpdate(DeviceInfoProvider deviceInfo, IConfigurationProvider co
}

try {
String serverAddress = config.getServerAddress();
if (serverAddress == null || serverAddress.isEmpty()) {
throw new RuntimeException("Server address is not set");
}
Request request = new Request.Builder()
.url(config.getServerAddress() + "/api/v1/update/check")
.addHeader("Authorization", "Bearer token=" + token)
Expand Down Expand Up @@ -198,4 +202,4 @@ private String getResponseParam(String responseBody, String param) {
}
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,15 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.main_layout);
this.mTextViewBuild = findViewById(R.id.textViewBuild);
this.mTextViewAddress = findViewById(R.id.textViewUrlAddress);
String serverAddress = mConfig.getServerAddress();
if (serverAddress == null) {
Log.e(TAG, "Server address is not set, aborting");
System.exit(1);
}
Log.d(TAG, "Build version: " + mDeviceInfo.getSoftwareVersion());
Log.d(TAG, "OTA server address: " + mConfig.getServerAddress());
Log.d(TAG, "OTA server address: " + serverAddress);
this.mTextViewBuild.setText(mDeviceInfo.getSoftwareVersion());
this.mTextViewAddress.setText(mConfig.getServerAddress());
this.mTextViewAddress.setText(serverAddress);
updaterLock = new ReentrantLock();

mDeviceAuthorizationProvider = new AuthorizationProvider(mDeviceInfo, mConfig, this);
Expand Down Expand Up @@ -116,10 +121,16 @@ private void setUpdateAlarm() {
new Intent(startUpdateIntent),
PendingIntent.FLAG_IMMUTABLE);

int updateIntervalSeconds = mConfig.getUpdateIntervalSeconds();
if (updateIntervalSeconds < 0) {
Log.e(TAG, "Invalid update interval seconds, aborting");
System.exit(1);
}

startAlarm.setRepeating(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(),
mConfig.getUpdateIntervalSeconds() * 1000L,
updateIntervalSeconds * 1000L,
pendingIntent);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources.NotFoundException;

import androidx.preference.PreferenceManager;
import android.util.Log;

import com.antmicro.update.rdfm.R;

public class ConfigurationProvider implements IConfigurationProvider {
private final Context mContext;
private static final String TAG = "ConfigurationProvider";

public ConfigurationProvider(Context context) {
mContext = context;
Expand All @@ -17,24 +20,75 @@ public ConfigurationProvider(Context context) {
@Override
public String getServerAddress() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
String pref_key = mContext.getResources().getString(R.string.preference_ota_server_address_key);
String default_value = mContext.getResources().getString(R.string.default_rdfm_server_address);
return prefs.getString(pref_key, default_value);

String pref_key;
String default_value;
try {
pref_key = mContext.getResources().getString(R.string.preference_ota_server_address_key);
default_value = mContext.getResources().getString(R.string.default_rdfm_server_address);
} catch (NotFoundException e) {
Log.e(TAG, "Failed to get preference key or default value: " + e.getMessage() + ", aborting");
return null;
}

try {
return prefs.getString(pref_key, default_value);
} catch (ClassCastException e) {
Log.e(TAG, "Failed to get preference value: " + e.getMessage() + ", aborting");
return null;
}
}

@Override
public int getUpdateIntervalSeconds() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
String pref_key = mContext.getResources().getString(R.string.preference_update_check_interval_key);
String default_value = mContext.getResources().getString(R.string.default_update_check_interval_seconds);
return Integer.parseInt(prefs.getString(pref_key, default_value));

String pref_key;
String default_value;
String pref_value;
try {
pref_key = mContext.getResources().getString(R.string.preference_update_check_interval_key);
default_value = mContext.getResources().getString(R.string.default_update_check_interval_seconds);
} catch (NotFoundException e) {
Log.e(TAG, "Failed to get preference key or default value: " + e.getMessage() + ", aborting");
return -1;
}

try {
pref_value = prefs.getString(pref_key, default_value);
} catch (ClassCastException e) {
Log.e(TAG, "Failed to get preference value: " + e.getMessage() + ", aborting");
return -1;
}

try {
return Integer.parseInt(pref_value);
} catch (NumberFormatException e) {
Log.e(TAG, "Failed to parse update interval seconds: " + e.getMessage() + ", aborting");
return -1;
}
}

@Override
public int getMaxShellCount() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
String pref_key = mContext.getResources().getString(R.string.preference_max_shell_count);
String default_value = mContext.getResources().getString(R.string.default_max_shell_count);
return Integer.parseInt(prefs.getString(pref_key, default_value));

String pref_key;
String default_value;

try {
pref_key = mContext.getResources().getString(R.string.preference_max_shell_count);
default_value = mContext.getResources().getString(R.string.default_max_shell_count);
} catch (NotFoundException e) {
Log.e(TAG, "Failed to get preference key or default value: " + e.getMessage() + ", aborting");
return -1;
}

try {
return Integer.parseInt(prefs.getString(pref_key, default_value));
} catch (NumberFormatException e) {
Log.e(TAG, "Failed to parse max shell count: " + e.getMessage() + ", aborting");
return -1;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@ public interface IConfigurationProvider {
/**
* Get the configured RDFM server address
*
* @return RDFM server address to connect to
* @return RDFM server address to connect to, or null if an error occurred
* while reading the configuration
*/
String getServerAddress();

/**
* Get the configured update interval
*
* @return automatic update interval [seconds]
* @return automatic update interval [seconds], or -1 if an error occurred
* while reading the configuration
*/
int getUpdateIntervalSeconds();

/**
* Get the configured maximum reverse shell count
*
* @return max reverse shell count
* @return max reverse shell count, or -1 if an error occurred
* while reading the configuration
*/
int getMaxShellCount();
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,12 @@ private String registerRequest() throws ServerConnectionException, DeviceUnautho

RequestBody reqBody = RequestBody.create(requestBytes, JSON);
try {
String serverAddress = mConfig.getServerAddress();
if (serverAddress == null || serverAddress.isEmpty()) {
throw new RuntimeException("Server address is not set");
}
Request request = new Request.Builder()
.url(mConfig.getServerAddress() + "/api/v1/auth/device")
.url(serverAddress + "/api/v1/auth/device")
.addHeader("X-RDFM-Device-Signature", signature)
.post(reqBody)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,18 @@ public ManagementClient(IConfigurationProvider config, IDeviceTokenProvider toke
new Thread(this::reconnectThread).start();
}

private void connectToWs() throws DeviceUnauthorizedException, ServerConnectionException {
mServerAddress = HttpUtils.replaceHttpSchemeWithWs(mConfig.getServerAddress());
private void connectToWs() throws DeviceUnauthorizedException, ServerConnectionException, RuntimeException {
String serverAddress = mConfig.getServerAddress();
if (serverAddress == null || serverAddress.isEmpty()) {
Log.e(TAG, "Server address is not set");
throw new RuntimeException();
}
mServerAddress = HttpUtils.replaceHttpSchemeWithWs(serverAddress);
mMaxShellCount = mConfig.getMaxShellCount();
if (mMaxShellCount < 1) {
Log.e(TAG, "Invalid maximum shell count: " + mMaxShellCount);
throw new RuntimeException();
}
String token = mTokenProvider.fetchDeviceToken();
Request request = new Request.Builder()
.url(mServerAddress + "/api/v1/devices/ws")
Expand Down Expand Up @@ -151,6 +160,9 @@ private void reconnectThread() {
} catch (DeviceUnauthorizedException e) {
Log.e(TAG, "Cannot connect to the management WebSocket - device unauthorized");
continue;
} catch (RuntimeException e) {
Log.e(TAG, "Cannot connect to the management WebSocket - invalid configuration");
continue;
}

// Wait until the connection dies
Expand Down

0 comments on commit 9988992

Please sign in to comment.