Skip to content

Commit d3e1ad8

Browse files
committed
Implement HTTPS certificate system and remove Android authentication (v1.27)
- Add certificate generation scripts and web-based downloads - Remove authentication UI and logic from Android app - Fix SSL folder nesting issues in certificate scripts - Update Apache SSL configuration for HTTPS on port 3543 - Add comprehensive documentation and installation guides
1 parent eb37ee0 commit d3e1ad8

39 files changed

+2162
-387
lines changed

AI_MultiBarcodes_Capture/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ android {
1414
applicationId = "com.zebra.ai_multibarcodes_capture.dev"
1515
minSdk = 34
1616
targetSdk = 35
17-
versionCode = 26
18-
versionName = "1.26"
17+
versionCode = 27
18+
versionName = "1.27"
1919

2020
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2121
}

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/helpers/Constants.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,5 @@ public class Constants {
219219
// HTTPS Post preferences
220220
public static final String SHARED_PREFERENCES_HTTPS_ENDPOINT = "SHARED_PREFERENCES_HTTPS_ENDPOINT";
221221
public static final String SHARED_PREFERENCES_HTTPS_ENDPOINT_DEFAULT = "";
222-
public static final String SHARED_PREFERENCES_HTTPS_AUTHENTICATION = "SHARED_PREFERENCES_HTTPS_AUTHENTICATION";
223-
public static final boolean SHARED_PREFERENCES_HTTPS_AUTHENTICATION_DEFAULT = false;
224-
// Note: Username and password are stored securely in Android Keystore via KeystoreHelper
225222

226223
}

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/java/CapturedBarcodesActivity.java

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import com.zebra.ai_multibarcodes_capture.filemanagement.SessionsFilesHelpers;
3838
import com.zebra.ai_multibarcodes_capture.helpers.Constants;
3939
import com.zebra.ai_multibarcodes_capture.helpers.EBarcodesSymbologies;
40-
import com.zebra.ai_multibarcodes_capture.helpers.KeystoreHelper;
4140
import com.zebra.ai_multibarcodes_capture.helpers.LocaleHelper;
4241
import com.zebra.ai_multibarcodes_capture.helpers.SessionData;
4342
import com.google.gson.Gson;
@@ -60,7 +59,6 @@
6059
import java.text.DateFormat;
6160
import java.text.SimpleDateFormat;
6261
import java.util.ArrayList;
63-
import java.util.Base64;
6462
import java.util.Date;
6563
import java.util.HashMap;
6664
import java.util.List;
@@ -849,9 +847,7 @@ private boolean performHttpPost(String endpointUrl, String jsonData) throws IOEx
849847
connection.setReadTimeout(15000); // 15 seconds
850848
android.util.Log.d("CapturedBarcodes", "Headers set: POST, JSON content-type, timeouts configured");
851849

852-
// Add authentication if configured
853-
android.util.Log.d("CapturedBarcodes", "Adding authentication headers if configured");
854-
addAuthenticationHeaders(connection);
850+
// Direct HTTP request - no authentication headers needed
855851

856852
// Send JSON data
857853
android.util.Log.d("CapturedBarcodes", "Sending JSON data to server");
@@ -932,38 +928,6 @@ public boolean verify(String hostname, SSLSession session) {
932928
}
933929
}
934930

935-
private void addAuthenticationHeaders(HttpURLConnection connection) {
936-
android.util.Log.d("CapturedBarcodes", "addAuthenticationHeaders() called");
937-
938-
// Get authentication settings from SharedPreferences
939-
SharedPreferences sharedPreferences = getSharedPreferences(getPackageName(), Context.MODE_PRIVATE);
940-
boolean authEnabled = sharedPreferences.getBoolean(Constants.SHARED_PREFERENCES_HTTPS_AUTHENTICATION, false);
941-
android.util.Log.d("CapturedBarcodes", "Authentication enabled: " + authEnabled);
942-
943-
if (authEnabled) {
944-
android.util.Log.d("CapturedBarcodes", "Loading credentials from keystore");
945-
KeystoreHelper keystoreHelper = new KeystoreHelper(this);
946-
String username = keystoreHelper.getUsername();
947-
String password = keystoreHelper.getPassword();
948-
949-
android.util.Log.d("CapturedBarcodes", "Username loaded: " + (username.isEmpty() ? "empty" : "present"));
950-
android.util.Log.d("CapturedBarcodes", "Password loaded: " + (password.isEmpty() ? "empty" : "present"));
951-
952-
if (!username.isEmpty() && !password.isEmpty()) {
953-
android.util.Log.d("CapturedBarcodes", "Adding Basic Authentication header");
954-
// Use Basic Authentication
955-
String credentials = username + ":" + password;
956-
String basicAuth = "Basic " + Base64.getEncoder().encodeToString(
957-
credentials.getBytes(StandardCharsets.UTF_8));
958-
connection.setRequestProperty("Authorization", basicAuth);
959-
android.util.Log.d("CapturedBarcodes", "Authorization header added successfully");
960-
} else {
961-
android.util.Log.w("CapturedBarcodes", "Authentication enabled but credentials are missing");
962-
}
963-
} else {
964-
android.util.Log.d("CapturedBarcodes", "Authentication disabled, no headers added");
965-
}
966-
}
967931

968932
private static class ViewHolder {
969933
View foregroundContainer;

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/settings/SettingsActivity.java

Lines changed: 2 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import com.zebra.ai_multibarcodes_capture.adapters.LanguageAdapter;
3333
import com.zebra.ai_multibarcodes_capture.filemanagement.EExportMode;
3434
import com.zebra.ai_multibarcodes_capture.helpers.EProcessingMode;
35-
import com.zebra.ai_multibarcodes_capture.helpers.KeystoreHelper;
3635
import com.zebra.ai_multibarcodes_capture.helpers.LocaleHelper;
3736
import com.zebra.ai_multibarcodes_capture.helpers.LogUtils;
3837
import com.zebra.ai_multibarcodes_capture.managedconfig.ManagedConfigurationReceiver;
@@ -66,11 +65,10 @@ public class SettingsActivity extends AppCompatActivity {
6665

6766
private static final String TAG = "SettingsActivity";
6867

69-
private EditText etPrefix, etHttpsEndpoint, etUsername, etPassword;
68+
private EditText etPrefix, etHttpsEndpoint;
7069
private RadioButton rbCSV, rbTXT, rbXSLX;
71-
private CheckBox cbAuthentication;
7270
private ImageView ivToggleSymbologies, ivToggleFileTypes, ivToggleAdvanced, ivToggleHttpsPost;
73-
private LinearLayout llSymbologies, llAdvancedContent, llFileProcessingContent, llHttpsPost, llAuthenticationGroup, llFileProcessing, llHttpsPostContent;
71+
private LinearLayout llSymbologies, llAdvancedContent, llFileProcessingContent, llHttpsPost, llFileProcessing, llHttpsPostContent;
7472
private RadioGroup rgFileTypes, rgModelInputSize, rgCameraResolution, rgInferenceType;
7573
private RadioButton rbSmallInputSize, rbMediumInputSize, rbLargeInputSize;
7674
private RadioButton rb1MPResolution, rb2MPResolution, rb4MPResolution, rb8MPResolution;
@@ -84,8 +82,6 @@ public class SettingsActivity extends AppCompatActivity {
8482
private LanguageAdapter languageAdapter;
8583
private List<LanguageItem> languageList;
8684
private String pendingLanguageCode = null; // Track pending language changes
87-
private KeystoreHelper keystoreHelper;
88-
private String originalDummyPassword = null; // Track original dummy password to detect changes
8985
private CheckBox cbAUSTRALIAN_POSTAL, cbAZTEC, cbCANADIAN_POSTAL, cbCHINESE_2OF5, cbCODABAR;
9086
private CheckBox cbCODE11, cbCODE39, cbCODE93, cbCODE128, cbCOMPOSITE_AB, cbCOMPOSITE_C;
9187
private CheckBox cbD2OF5, cbDATAMATRIX, cbDOTCODE, cbDUTCH_POSTAL, cbEAN_8, cbEAN_13;
@@ -130,14 +126,8 @@ protected void onCreate(Bundle savedInstanceState) {
130126
Toolbar toolbar = findViewById(R.id.toolbar);
131127
setSupportActionBar(toolbar);
132128

133-
// Initialize KeystoreHelper
134-
keystoreHelper = new KeystoreHelper(this);
135-
136129
etPrefix = findViewById(R.id.etPrefix);
137130
etHttpsEndpoint = findViewById(R.id.etHttpsEndpoint);
138-
etUsername = findViewById(R.id.etUsername);
139-
etPassword = findViewById(R.id.etPassword);
140-
cbAuthentication = findViewById(R.id.cbAuthentication);
141131
rbCSV = findViewById(R.id.rbCSV);
142132
rbTXT = findViewById(R.id.rbTxt);
143133
rbXSLX = findViewById(R.id.rbXSLX);
@@ -151,7 +141,6 @@ protected void onCreate(Bundle savedInstanceState) {
151141
llFileProcessing = findViewById(R.id.llFileProcessing);
152142
llHttpsPost = findViewById(R.id.llHttpsPost);
153143
llHttpsPostContent = findViewById(R.id.llHttpsPostContent);
154-
llAuthenticationGroup = findViewById(R.id.llAuthenticationGroup);
155144
rgFileTypes = findViewById(R.id.rgFileTypes);
156145
rgModelInputSize = findViewById(R.id.rgModelInputSize);
157146
rgCameraResolution = findViewById(R.id.rgCameraResolution);
@@ -279,27 +268,6 @@ public void onClick(View v) {
279268
}
280269
});
281270

282-
// Set up authentication checkbox listener
283-
cbAuthentication.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
284-
@Override
285-
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
286-
if (isChecked) {
287-
llAuthenticationGroup.setVisibility(View.VISIBLE);
288-
} else {
289-
llAuthenticationGroup.setVisibility(View.GONE);
290-
// Clear credentials when authentication is disabled for security
291-
etUsername.setText("");
292-
etPassword.setText("");
293-
originalDummyPassword = "";
294-
try {
295-
keystoreHelper.clearAllCredentials();
296-
LogUtils.d(TAG, "Cleared credentials when authentication disabled");
297-
} catch (Exception e) {
298-
LogUtils.e(TAG, "Error clearing credentials: " + e.getMessage());
299-
}
300-
}
301-
}
302-
});
303271

304272
// Setup symbology checkboxes change listeners
305273
setupSymbologyListeners();
@@ -782,81 +750,14 @@ private void saveProcessingMode(SharedPreferences.Editor editor) {
782750

783751
private void loadHttpsPostSettings(SharedPreferences sharedPreferences) {
784752
String endpoint = sharedPreferences.getString(SHARED_PREFERENCES_HTTPS_ENDPOINT, SHARED_PREFERENCES_HTTPS_ENDPOINT_DEFAULT);
785-
boolean authentication = sharedPreferences.getBoolean(SHARED_PREFERENCES_HTTPS_AUTHENTICATION, SHARED_PREFERENCES_HTTPS_AUTHENTICATION_DEFAULT);
786753

787754
// Load endpoint as-is, supporting both HTTP and HTTPS
788-
789755
etHttpsEndpoint.setText(endpoint);
790-
cbAuthentication.setChecked(authentication);
791-
792-
// Load username from secure keystore and show dummy password
793-
try {
794-
String username = keystoreHelper.getUsername();
795-
etUsername.setText(username);
796-
797-
// Show dummy characters matching the stored password length for security
798-
int passwordLength = keystoreHelper.getPasswordLength();
799-
if (passwordLength > 0) {
800-
// Create dummy password with bullet characters (•)
801-
StringBuilder dummyPassword = new StringBuilder();
802-
for (int i = 0; i < passwordLength; i++) {
803-
dummyPassword.append("•");
804-
}
805-
originalDummyPassword = dummyPassword.toString();
806-
etPassword.setText(originalDummyPassword);
807-
LogUtils.d(TAG, "Loaded username and displayed dummy password with length: " + passwordLength);
808-
} else {
809-
originalDummyPassword = "";
810-
etPassword.setText("");
811-
LogUtils.d(TAG, "No stored password found");
812-
}
813-
} catch (Exception e) {
814-
LogUtils.e(TAG, "Error loading credentials from keystore: " + e.getMessage());
815-
etUsername.setText("");
816-
etPassword.setText("");
817-
originalDummyPassword = "";
818-
}
819-
820-
// Set initial visibility of authentication group
821-
if (authentication) {
822-
llAuthenticationGroup.setVisibility(View.VISIBLE);
823-
} else {
824-
llAuthenticationGroup.setVisibility(View.GONE);
825-
}
826756
}
827757

828758
private void saveHttpsPostSettings(SharedPreferences.Editor editor) {
829759
String endpoint = etHttpsEndpoint.getText().toString();
830-
boolean authentication = cbAuthentication.isChecked();
831-
String username = etUsername.getText().toString();
832-
String password = etPassword.getText().toString();
833-
834760
editor.putString(SHARED_PREFERENCES_HTTPS_ENDPOINT, endpoint);
835-
editor.putBoolean(SHARED_PREFERENCES_HTTPS_AUTHENTICATION, authentication);
836-
837-
// Save username and password securely in keystore
838-
try {
839-
boolean usernameStored = keystoreHelper.storeUsername(username);
840-
boolean passwordStored = true;
841-
842-
// Only save password if it has been modified by the user (not the dummy password)
843-
if (!password.equals(originalDummyPassword)) {
844-
passwordStored = keystoreHelper.storePassword(password);
845-
LogUtils.d(TAG, "Password was modified, storing new password");
846-
} else {
847-
LogUtils.d(TAG, "Password unchanged (dummy), keeping existing stored password");
848-
}
849-
850-
if (usernameStored && passwordStored) {
851-
LogUtils.d(TAG, "Successfully stored credentials in keystore");
852-
} else {
853-
LogUtils.w(TAG, "Warning: Some credentials may not have been stored properly");
854-
}
855-
} catch (Exception e) {
856-
LogUtils.e(TAG, "Error storing credentials in keystore: " + e.getMessage());
857-
// Show user-friendly error message
858-
Toast.makeText(this, "Warning: Could not securely store credentials", Toast.LENGTH_LONG).show();
859-
}
860761
}
861762

862763
private String getSelectedExtension()

AI_MultiBarcodes_Capture/src/main/res/layout/activity_setup.xml

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -308,62 +308,6 @@
308308
android:minHeight="48dp"
309309
android:padding="12dp" />
310310

311-
<CheckBox
312-
android:id="@+id/cbAuthentication"
313-
android:layout_width="match_parent"
314-
android:layout_height="wrap_content"
315-
android:layout_marginTop="16dp"
316-
android:layout_marginStart="8dp"
317-
android:layout_marginEnd="8dp"
318-
android:text="@string/authentication"
319-
android:textStyle="bold"
320-
android:buttonTint="@color/zebra" />
321-
322-
<LinearLayout
323-
android:id="@+id/llAuthenticationGroup"
324-
android:layout_width="match_parent"
325-
android:layout_height="wrap_content"
326-
android:orientation="vertical"
327-
android:visibility="gone"
328-
android:layout_marginStart="24dp"
329-
android:layout_marginEnd="8dp"
330-
android:layout_marginBottom="8dp">
331-
332-
<TextView
333-
android:layout_width="match_parent"
334-
android:layout_height="wrap_content"
335-
android:text="@string/username"
336-
android:textStyle="bold"
337-
android:layout_marginTop="8dp" />
338-
339-
<EditText
340-
android:id="@+id/etUsername"
341-
android:layout_width="match_parent"
342-
android:layout_height="wrap_content"
343-
android:layout_marginTop="4dp"
344-
android:hint="@string/username_hint"
345-
android:inputType="text"
346-
android:minHeight="48dp"
347-
android:padding="12dp" />
348-
349-
<TextView
350-
android:layout_width="match_parent"
351-
android:layout_height="wrap_content"
352-
android:text="@string/password"
353-
android:textStyle="bold"
354-
android:layout_marginTop="16dp" />
355-
356-
<EditText
357-
android:id="@+id/etPassword"
358-
android:layout_width="match_parent"
359-
android:layout_height="wrap_content"
360-
android:layout_marginTop="4dp"
361-
android:hint="@string/password_hint"
362-
android:inputType="textPassword"
363-
android:minHeight="48dp"
364-
android:padding="12dp" />
365-
366-
</LinearLayout>
367311

368312
</LinearLayout>
369313

AI_MultiBarcodes_Capture/src/main/res/values/strings.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,6 @@
468468
<string name="https_post">HTTP(s) Post</string>
469469
<string name="https_endpoint">HTTP(s) Endpoint</string>
470470
<string name="https_endpoint_hint">https://example.com/api/data or http://192.168.1.100/api/data</string>
471-
<string name="authentication">Authentication</string>
472-
<string name="username">Username</string>
473-
<string name="password">Password</string>
474-
<string name="username_hint">Enter username</string>
475-
<string name="password_hint">Enter password</string>
476471

477472
<!-- Managed Configuration Messages -->
478473
<string name="managed_configuration_updated">Settings updated by administrator</string>

AI_MultiBarcodes_Capture/src/main/res/xml/app_restrictions.xml

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<restriction
4444
android:key="https_configuration"
4545
android:title="HTTP/HTTPS Configuration"
46-
description="Configure HTTP/HTTPS endpoint and authentication settings"
46+
description="Configure HTTP/HTTPS endpoint settings"
4747
android:restrictionType="bundle">
4848

4949
<!-- HTTPS Endpoint Configuration -->
@@ -54,29 +54,6 @@
5454
android:restrictionType="string"
5555
android:defaultValue="" />
5656

57-
<!-- Authentication Configuration -->
58-
<restriction
59-
android:key="authentication_enabled"
60-
android:title="Enable Authentication"
61-
description="Enable HTTP authentication for the endpoint"
62-
android:restrictionType="bool"
63-
android:defaultValue="false" />
64-
65-
<!-- Username Configuration -->
66-
<restriction
67-
android:key="username"
68-
android:title="Username"
69-
description="Username for HTTP authentication (only used if authentication is enabled)"
70-
android:restrictionType="string"
71-
android:defaultValue="" />
72-
73-
<!-- Password Configuration -->
74-
<restriction
75-
android:key="password"
76-
android:title="Password"
77-
description="Password for HTTP authentication (only used if authentication is enabled)"
78-
android:restrictionType="string"
79-
android:defaultValue="" />
8057

8158
</restriction>
8259

0 commit comments

Comments
 (0)