Add 802.1x network in Android 10+ - android

I am trying to add a 802.1x network programmatically in my Android app.
On an Android 8 device using addNetwork I see that the network is added with credentials but on Android 10 and above, when using addNetworkSuggestions, the credentials are not added.
I am new in this field so it is possible I am missing something vital.
WifiConfiguration wifiConf = new WifiConfiguration();
wifiConf.allowedAuthAlgorithms.clear();
wifiConf.allowedGroupCiphers.clear();
wifiConf.allowedKeyManagement.clear();
wifiConf.allowedPairwiseCiphers.clear();
wifiConf.allowedProtocols.clear();
wifiConf.SSID = TextUtil.convertToQuotedString(apSsid.toString());
wifiConf.enterpriseConfig = eapConfig.asWifiEnterpriseConfig();
wifiConf.enterpriseConfig.setIdentity(......);
wifiConf.enterpriseConfig.setPassword(......);
wifiConf.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
wifiConf.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wifiConf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wifiConfig.status = WifiConfiguration.Status.ENABLED;
wifiConfig.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
wifiConfig.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
wifiConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wifiConf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wifiConf.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wifiConf.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
if (apPass.length() == 64 && WeFiUtilExt.isHex(apPass)) {
// Goes unquoted as hex
wifiConf.preSharedKey = apPass;
}
else {
// Goes quoted as ASCII
wifiConf.preSharedKey = TextUtil.convertToQuotedString(apPass);
}
WifiNetworkSuggestion.Builder wpa2WifiNetworkSuggestionBuilder = new WifiNetworkSuggestion.Builder();
wpa2WifiNetworkSuggestionBuilder.setSsid(ssid).setIsAppInteractionRequired(true);
wpa2WifiNetworkSuggestionBuilder.setWpa2EnterpriseConfig(wifiEnterpriseConfig);
WifiNetworkSuggestion wpa2WifiNetworkSuggestion = wpa2WifiNetworkSuggestionBuilder.build();
WifiNetworkSuggestion.Builder wpa3WifiNetworkSuggestionBuilder = new WifiNetworkSuggestion.Builder();
wpa3WifiNetworkSuggestionBuilder.setSsid(ssid).setIsAppInteractionRequired(false);
wpa3WifiNetworkSuggestionBuilder.setWpa3EnterpriseConfig(wifiEnterpriseConfig);
WifiNetworkSuggestion wpa3WifiNetworkSuggestion = wpa3WifiNetworkSuggestionBuilder.build();
List<WifiNetworkSuggestion> wifiNetworkSuggestionList = new ArrayList<>();
wifiNetworkSuggestionList.add(wpa2WifiNetworkSuggestion);
wifiNetworkSuggestionList.add(wpa3WifiNetworkSuggestion);
int addStatus = m_wifiMngr.addNetworkSuggestions(wifiNetworkSuggestionList);
The return code is 0 implying that the add worked.
Will this not work in Android 10+?

Related

Add 802.1x suggested network

I am trying to add an 802.1x network as a suggested network in Android 10.
When I do the addSuggestedNetwork it returns a code of 0 indicating that it did add it.
I even checked it by trying to add a second time. That returned 3 - network already exists.
Nevertheless, it doesn't fill in any of the parameters of the AP definition:
WifiManager wifiManager = getSystemService(Context.WIFI_SERVICE));
WifiNetworkSuggestion.Builder suggestionBuilder = new WifiNetworkSuggestion.Builder();
String ssid = c8021XAP.getSsid();
WifiNetworkSuggestion suggestion = suggestionBuilder
.setSsid(ssid)
.setWpa3EnterpriseConfig(c8021XAP.eapConfig())
.setPriority(10)
.build();
List<WifiNetworkSuggestion> suggestions = new ArrayList<>();
status = wifiManager.addNetworkSuggestions(suggestions);
Following is the code that creates the eapConfig object:
fun eapConfig(): WifiEnterpriseConfig {
val eap = WifiEnterpriseConfig()
eap.identity = username
eap.password = Base64.encode(password.toByteArray(), Base64.DEFAULT).toString()
eap.anonymousIdentity = anonymousIdentity
eap.phase2Method = phase2
eap.eapMethod = eapMethod
eap.domainSuffixMatch = domainName
return eap
}
I tried changing setWpa3EnterpriseConfig to setWpa2EnterpriseConfig but no change.

Creating Notes in LinkedNotebook

I am trying to create note in a shared notebook which is already shared with me. The notebook is shared with me with priveleges to modify its contents (SharedNotebookPrivilegeLevel.MODIFY_NOTEBOOK_PLUS_ACTIVITY), and I can create notes in that notebook using Evernote web client. But when I trying to create a note using SDK I received an EDAMUserException(errorCode:PERMISSION_DENIED, parameter:authenticationToken). Below is my code
Note note = new Note();
note.setContent(EvernoteUtil.NOTE_PREFIX + content + EvernoteUtil.NOTE_SUFFIX);
note.setTitle(title);
EvernoteSession evernoteSession = EvernoteSession.getInstance();
List<LinkedNotebook> linkedNotebooks = evernoteSession
.getEvernoteClientFactory()
.getNoteStoreClient()
.listLinkedNotebooks();
LinkedNotebook current = null;
for (LinkedNotebook linkedNotebook : linkedNotebooks) {
if (linkedNotebook.getShareName().equals(notebookName)) {
current = linkedNotebook;
}
}
if (current == null)
throw new IllegalStateException();
THttpClient tHttpClient = new THttpClient(current.getNoteStoreUrl());
TBinaryProtocol tBinaryProtocol = new TBinaryProtocol(tHttpClient);
NoteStore.Client client = new NoteStore.Client(tBinaryProtocol, tBinaryProtocol);
AuthenticationResult authenticationResult = client.authenticateToSharedNotebook(current.getShareKey(),
evernoteSession.getAuthToken());
String shareToken = authenticationResult.getAuthenticationToken();
SharedNotebook sharedNotebook = client.getSharedNotebookByAuth(shareToken);
String sharedNotebookGuid = sharedNotebook.getNotebookGuid();
note.setGuid(sharedNotebookGuid);
Note createdNote = client.createNote(shareToken, note);
return createdNote;
I've used this article to create notes.
One mistake I found is that
note.setGuid(sharedNotebookGuid);
has to be
note.setNotebookGuid(sharedNotebookGuid);

Adjust user agent in Android with Volley

I am wondering how to adjust the standard user agent in my http requests. I am using the Volley library and I KNOW how to
set a new user agent
retrieve the default user agent as a string (e.g. "Dalvik/1.6.0 (Linux; U; Android 4.0.2; sdk Build/ICS_MR0") => System.getProperty("http.agent")
What I DON'T know is:
how to get the single elements this user agent is build of, so I can replace only the string "Dalvik/1.6.0" with a custom string.
Is that possible, or do I have to make a string replacement?
Thx
In order to set the user agent globally for all requests sent via volley, here is my solution:
When you are initializing the volley request queue, instead of using the convenient method Volley.newRequestQueue(Context);, use the following snippet:
private RequestQueue makeRequestQueue(Context context) {
DiskBasedCache cache = new DiskBasedCache(new File(context.getCacheDir(), DEFAULT_CACHE_DIR), DISK_CACHE_SIZE);
BasicNetwork network = new BasicNetwork(new MyHurlStack());
RequestQueue queue = new RequestQueue(cache, network);
queue.start();
return queue;
}
public static class MyHurlStack extends HurlStack {
#Override
public HttpResponse executeRequest(Request<?> request, Map<String, String> additionalHeaders) throws IOException, AuthFailureError {
if (additionalHeaders == null || Collections.emptyMap().equals(additionalHeaders) {
additionalHeaders = new HashMap<>();
}
additionalHeaders.put("User-Agent", "test_user_agent_in_volley");
return super.executeRequest(request, additionalHeaders);
}
}
This solution assumes you are targeting api level >= 9, so we use the HurlStack
The reason why this works is because in HurlStack.executeRequest(Request<?> request, Map<String, String> additionalHeaders) method, the stuff you add to the additionalHeaders would later be added to an HttpUrlConnection request property as in connection.addRequestProperty(headerName, map.get(headerName));
Yes,
Build.FINGERPRINT contains all the information you need,
https://developer.android.com/reference/android/os/Build.html
To get the individual parts, use the individual constant strings,
For detailed OS Version information use Build.VERSION
import android.util.Log;
import android.os.Bundle;
import android.os.Build;
public class MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("Build","BOARD = "+Build.BOARD);
Log.i("Build","BOOTLOADER = "+Build.BOOTLOADER);
Log.i("Build","BRAND = "+Build.BRAND);
Log.i("Build","CPU_ABI = "+Build.CPU_ABI);
Log.i("Build","CPU_ABI2 = "+Build.CPU_ABI2);
Log.i("Build","DEVICE = "+Build.DEVICE);
Log.i("Build","DISPLAY = "+Build.DISPLAY);
Log.i("Build","FINGERPRINT = "+Build.FINGERPRINT);
Log.i("Build","HARDWARE = "+Build.HARDWARE);
Log.i("Build","HOST = "+Build.HOST);
Log.i("Build","ID = "+Build.ID);
Log.i("Build","MANUFACTURER = "+Build.MANUFACTURER);
Log.i("Build","MODEL = "+Build.MODEL);
Log.i("Build","PRODUCT = "+Build.PRODUCT);
Log.i("Build","RADIO = "+Build.RADIO);
Log.i("Build","SERIAL = "+Build.SERIAL);
Log.i("Build","TAGS = "+Build.TAGS);
Log.i("Build","TYPE = "+Build.TYPE);
Log.i("Build","USER = "+Build.USER);
Log.i("Build","BASE_OS = "+Build.VERSION.BASE_OS);
Log.i("Build","CODENAME = "+ Build.VERSION.CODENAME);
Log.i("Build","INCREMENTAL = "+ Build.VERSION.INCREMENTAL);
Log.i("Build","RELEASE = "+ Build.VERSION.RELEASE);
Log.i("Build","SDK = "+ Build.VERSION.SDK);
Log.i("Build","SECURITY_PATCH = "+ Build.VERSION.SECURITY_PATCH);
Log.i("$TAG#",Build.FINGERPRINT);
}
}
System.getProperty("http.agent") returns something like:
Dalvik/2.1.0 (Linux; U; Android 9; Android SDK built for x86 Build/PSR1.180720.075)
It's possible to build all the parts of this using a combination of android.os.Build and java.lang.System.getProperty().
This is an example of what's in android.os.Build running on an emulator:
Build.BOARD = "goldfish_x86"
Build.BOOTLOADER = "unknown"
Build.BRAND = "google"
Build.DEVICE = "generic_x86"
Build.DISPLAY = "sdk_gphone_x86-userdebug 9 PSR1.180720.075 5124027 dev-keys"
Build.FINGERPRINT = "google/sdk_gphone_x86/generic_x86:9/PSR1.180720.075/5124027:userdebug/dev-keys"
Build.HARDWARE = "ranchu"
Build.HOST = "abfarm904"
Build.ID = "PSR1.180720.075"
Build.MANUFACTURER = "Google"
Build.MODEL = "Android SDK built for x86"
Build.PRODUCT = "sdk_gphone_x86"
Build.SUPPORTED_32_BIT_ABIS = {"x86"}
Build.SUPPORTED_64_BIT_ABIS = {}
Build.SUPPORTED_ABIS = {"x86"}
Build.TAGS = "dev-keys"
Build.TIME = 1541887073000
Build.TYPE = "userdebug"
Build.USER = "android-build"
Build.UNKNOWN = "unknown"
Build.VERSION.BASE_OS = ""
Build.VERSION.CODENAME = "REL"
Build.VERSION.INCREMENTAL = "5124027"
Build.VERSION.PREVIEW_SDK_INT = 0
Build.VERSION.RELEASE = "9"
Build.VERSION.SDK_INT = 28
Build.VERSION.SECURITY_PATCH = "2018-09-05"
These properties are always provided by the Dalvik VM, according to Google's documentation:
file.separator = /
java.class.path = .
java.class.version = 50.0
java.compiler = Empty
java.ext.dirs = Empty
java.home = /system
java.io.tmpdir = /sdcard
java.library.path = /vendor/lib:/system/lib
java.vendor = The Android Project
java.vendor.url = http://www.android.com/
java.version = 0
java.specification.version = 0.9
java.specification.vendor = The Android Project
java.specification.name = Dalvik Core Library
java.vm.version = 1.2.0
java.vm.vendor = The Android Project
java.vm.name = Dalvik
java.vm.specification.version = 0.9
java.vm.specification.vendor = The Android Project
java.vm.specification.name = Dalvik Virtual Machine Specification
line.separator = \n
os.arch = armv7l
os.name = Linux
os.version = 2.6.32.9-g103d848
path.separator = :
user.dir = /
user.home = Empty
user.name = Empty
So, the default user agent appears to be composed of:
System.getProperty("java.vm.name") // Dalvik
System.getProperty("java.vm.version") // 2.1.0
System.getProperty("os.name") // Linux
"U" // not sure where to get this
"Android" // or this, probably safe to hard code though
Build.VERSION.RELEASE // 9
Build.MODEL // Android SDK built for x86
Build.ID // PSR1.180720.075

(Cordova / Phonegap) Problems with WifiManager.addNetwork() method of Android

Currently I am writing an app in Cordova 3.4.0 that should import Wifi settings from a source, like a file or database.
If I use the WifiManager.addNetwork method of Android, it always returns -1 for "failed".
On the other hand: If I use the same code in the onCreate() method of a blank Activity, the settings are added and I return the ID of the new entry.
The app is developed for API 10 to 19 and I call the Cordova code from a plugin context.
The android app has the following permissions:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
My test device: Samsung Galaxy Y (GT-S5360) with Android 2.3.6.
Is that a bug or a feature? There seems to be no details in the logcat e.g. that tells more.
If I look at the official Android code, I only see a hint to an external IWifiManager service that seems to be device specific.
Here is my code:
private void addWifiSettings() {
String ssid = "MY_NETWORK";
String pwd = "my_secrect_password";
Context ctx = this.cordova.getActivity().getApplicationContext();
// in blank activity project it is:
//
// ctx = this.getApplicationContext();
WifiManager man = (WifiManager)ctx.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.status = WifiConfiguration.Status.ENABLED;
wc.priority = 1;
wc.networkId = -1;
wc.hiddenSSID = false;
// SSID and password
wc.SSID = "\"".concat(ssid).concat("\"");
wc.preSharedKey = "\"".concat(pwd).concat("\"");
wc.allowedProtocols.clear();
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wc.allowedKeyManagement.clear();
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.clear();
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedGroupCiphers.clear();
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedAuthAlgorithms.clear();
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
String wifiAction;
int netId;
if (wc.networkId < 0) {
// if network is NEW
wifiAction = "add";
netId = man.addNetwork(wc);
}
else {
// if network EXISTS and should be UPDATED
wifiAction = "update";
netId = man.updateNetwork(wc);
}
// !!! AT THIS POINT IT ALWAYS RETURNS -1 IN CORDOVA/PHONEGAP PROJECT !!!
if (netId < 0) {
throw new Exception(String.format("Could not %s network: %s",
wifiAction,
wc.SSID));
}
if (man.saveConfiguration() == false) {
throw new Exception("Could not save network configuration!");
}
man.enableNetwork(netId, false);
}
networkId is ignored, so you don't need to set it.
I wrote a working Cordova plugin that interfaces with WifiManager. Abbreviated relevant code for WPA:
wifi.SSID = newSSID;
wifi.preSharedKey = newPass;
wifi.status = WifiConfiguration.Status.ENABLED;
wifi.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wifi.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wifi.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wifi.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wifi.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wifiManager.addNetwork(wifi);
wifiManager.saveConfiguration();
That should get you started in figuring out why your code isn't working. I'd guess that you're trying to do too much with the WifiConfiguation object and need to pare it down somewhat. It looks like you're trying to set the wc to accept a WEP or WPA network.

LDAP changing user password on Active Directory

I state that I am a complete beginner to LDAP.
I have to let a user change its own password through an Android device. User has NOT administrative privileges.
Using the UnboudId LDAP SDK for Java I'm able to bind to server and get the user entry using this code:
final SocketFactory _socket_factory;
final SSLUtil _ssl_util = new SSLUtil(new TrustAllTrustManager());
try {
_socket_factory = _ssl_util.createSSLSocketFactory();
}
catch (Exception e) {
Log.e(LOG_TAG, "*** Unable to initialize ssl", e);
}
LDAPConnectionOptions _ldap_connection_options = new LDAPConnectionOptions();
_ldap_connection_options.setAutoReconnect(true);
_ldap_connection_options.setConnectTimeoutMillis(30000);
_ldap_connection_options.setFollowReferrals(false);
_ldap_connection_options.setMaxMessageSize(1024*1024);
LDAPConnection _ldap_connection = new LDAPConnection(_socket_factory, _ldap_connection_options, [host ip], 636, [username], [password]);
Filter _filter = Filter.create("(userPrincipalName=" + [username] + ")");
SearchRequest _search_request = new SearchRequest([base DN], SearchScope.SUB, _filter);
_search_request.setSizeLimit(1000);
_search_request.setTimeLimitSeconds(30);
SearchResult _search_result = _connection.search(_search_request);
This works and I get 1 entry and all the relative attributes. Now my task is to change the password [password] with a new [new password].
My attempts:
PasswordModifyExtendedRequest _password_modify_request = new PasswordModifyExtendedRequest([found entry DN], [password], [new password]);
PasswordModifyExtendedResult _password_modify_result = (PasswordModifyExtendedResult)_ldap_connection.processExtendedOperation(_password_modify_request);
This doesn't work due to LDAPException
LDAPException(resultCode=2 (protocol error), errorMessage='0000203D: LdapErr: DSID-0C090C7D, comment: Unknown extended request OID, data 0, vece��', diagnosticMessage='0000203D: LdapErr: DSID-0C090C7D, comment: Unknown extended request OID, data 0, vece��')
Then I've tryed
final Modification _replace_modification = new Modification(ModificationType.REPLACE, "unicodePwd", _get_quoted_string_bytes([new password]));
LDAPResult _result = _connection.modify([found entry DN], _replace_modification);
This doesn't work due to LDAPException
LDAPException(resultCode=50 (insufficient access rights), errorMessage='00000005: SecErr: DSID-031A0F44, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0)
Finally I've tryed
final Modification _delete_old_modification = new Modification(ModificationType.DELETE, "unicodePwd", _get_quoted_string_bytes([password]));
final Modification _add_new_modification = new Modification(ModificationType.ADD, "unicodePwd", _get_quoted_string_bytes([new password]));
final ArrayList<Modification> _modifications = new ArrayList<Modification>();
_modifications.add(_delete_old_modification);
_modifications.add(_add_new_modification);
LDAPResult _result = _connection.modify([found entry DN], _modifications);
This doesn't work due to LDAPException
LDAPException(resultCode=19 (constraint violation), errorMessage='00000005: AtrErr: DSID-03190F00, #1:0: 00000005: DSID-03190F00, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 9005a (unicodePwd)��', diagnosticMessage='00000005: AtrErr: DSID-03190F00, #1: 0: 00000005: DSID-03190F00, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 9005a (unicodePwd) ��')
And now i have no more ideas... Any help will be appreciated, thanks in advance
final Modification _delete_old_modification = new Modification(ModificationType.DELETE, "unicodePwd", ('"' + oldPassword + '"').getBytes("UTF-16LE"));
final Modification _add_new_modification = new Modification(ModificationType.ADD, "unicodePwd", ('"' + newPassword + '"').getBytes("UTF-16LE"));
Did the trick.
Finally, I was able to resolve CONSTRAINT_ATT_TYPE issue in password change. I had set minimum password age as 4 days, so AD wasn’t allowing me to update the password. AD throws generic error CONSTRAINT_ATT_TYPE for all such violations. After setting minimum password age as 0 (None), everything works fine. AD password history also gets updated.
Refer:
http://www.javaxt.com/Tutorials/Windows/How_to_Authenticate_Users_with_Active_Directory
"Minimum password age" was the source of my problem CONSTRAINT_ATT_TYPE

Categories

Resources