Merge branch 'release-3.0.x' of https://github.com/wso2/carbon-device-mgt-plugins into release-3.0.x

revert-dabc3590
kamidu 8 years ago
commit c522809bd5

@ -129,7 +129,11 @@ var getConfig, validate, getMode, getSchema, getData, registerCallBackforPush;
var filter = { var filter = {
"query": luceneQuery, "query": luceneQuery,
"start": 0, "start": 0,
"count": limit "count": limit,
"sortBy" : [{
"field" : "timeStamp",
"sortType" : "ASC"
}]
}; };
result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage(); result = connector.search(loggedInUser, tableName, stringify(filter)).getMessage();
} else { } else {

@ -432,7 +432,7 @@
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button> <button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title"> <h4 id = "title" class="modal-title">
WSO2 Geo Dashboard WSO2 Geo Dashboard
</h4> </h4>
</div> </div>

@ -29,8 +29,6 @@ $('body').on('hidden.bs.modal', '.modal', function () {
/*Map layer configurations*/ /*Map layer configurations*/
var map; var map;
initialLoad();
function initialLoad() { function initialLoad() {
if (document.getElementById('map') == null) { if (document.getElementById('map') == null) {
setTimeout(initialLoad, 500); // give everything some time to render setTimeout(initialLoad, 500); // give everything some time to render
@ -56,6 +54,7 @@ function setPageTitle() {
if(deviceInfo) { if(deviceInfo) {
var newTitle = "[ " + deviceInfo.device.id + "]" + " - Geo Dashboard [" + deviceInfo.device.type + "]"; var newTitle = "[ " + deviceInfo.device.id + "]" + " - Geo Dashboard [" + deviceInfo.device.type + "]";
window.parent.document.title = newTitle; window.parent.document.title = newTitle;
$("#title").val(newTitle)
} }
} }
} }
@ -98,12 +97,12 @@ function initializeMap() {
zoom: 14, zoom: 14,
center: [6.927078, 79.861243], center: [6.927078, 79.861243],
layers: [defaultOSM, defaultTFL], layers: [defaultOSM, defaultTFL],
zoomControl: false, zoomControl: true,
attributionControl: false, attributionControl: false,
maxZoom: 20, maxZoom: 20,
maxNativeZoom: 18 maxNativeZoom: 18
}); });
map.zoomControl.setPosition('bottomleft');
map.on('click', function (e) { map.on('click', function (e) {
$.UIkit.offcanvas.hide();//[force = false] no animation $.UIkit.offcanvas.hide();//[force = false] no animation
}); });
@ -354,6 +353,66 @@ function enableRealTime() {
isBatchModeOn = false; isBatchModeOn = false;
} }
function InitSpatialObject() {
var fromDate = new Date();
fromDate.setHours(fromDate.getHours() - 2);
var toDate = new Date();
console.log(fromDate + " " + toDate);
var tableData = getProviderData(fromDate.valueOf(), toDate.valueOf());
for (var i = 0; i < tableData.length; i++) {
var data = tableData[i];
var geoMessage = {
"messageType": "Point",
"type": "Feature",
"id": data.id,
"deviceId": data.id,
"deviceType": data.type,
"properties": {
"speed": data.speed,
"heading": data.heading,
"state": data.state,
"information": data.information,
"notify": data.notify,
"type": data.type
},
"geometry": {
"type": "Point",
"coordinates": [data.longitude, data.latitude]
}
};
processPointMessage(geoMessage);
}
var spatialObject = currentSpatialObjects[deviceId];// (local)
if (!spatialObject) {
$.UIkit.notify({
message: "Spatial Object <span style='color:red'>" + deviceId + "</span> not in the Map!!",
status: 'warning',
timeout: ApplicationOptions.constance.NOTIFY_WARNING_TIMEOUT,
pos: 'top-center'
});
return false;
}
selectedSpatialObject = deviceId;
if (spatialObject.type == "area") {
spatialObject.focusOn(map);
return true;
}
map.setView(spatialObject.marker.getLatLng(), 15, {animate: true}); // TODO: check the map._layersMaxZoom and set the zoom level accordingly
$('#objectInfo').find('#objectInfoId').html(selectedSpatialObject);
spatialObject.marker.openPopup();
if (!toggled) {
$('#objectInfo').animate({width: 'toggle'}, 100);
toggled = true;
}
spatialObject.drawPath();
setTimeout(function () {
createChart();
chart.load({columns: [spatialObject.speedHistory.getArray()]});
}, 100);
}
function focusOnHistorySpatialObject(objectId, timeFrom, timeTo) { function focusOnHistorySpatialObject(objectId, timeFrom, timeTo) {
if (!timeFrom) { if (!timeFrom) {
notifyError('No start time provided to show history. Please provide a suitable value' + timeFrom); notifyError('No start time provided to show history. Please provide a suitable value' + timeFrom);

@ -602,6 +602,8 @@ var webSocketOnAlertError = function (e) {
var webSocketOnOpen = function () { var webSocketOnOpen = function () {
websocket.set_opened(); websocket.set_opened();
initialLoad();
InitSpatialObject();
$.UIkit.notify({ $.UIkit.notify({
message: 'You Are Connected to Spatial Stream !!', message: 'You Are Connected to Spatial Stream !!',
status: 'success', status: 'success',

@ -101,6 +101,7 @@ public class SenseDataReceiverManager {
IntentFilter intentFilter = new IntentFilter(); IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
intentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL); intentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
intentFilter.setPriority(1000);
context.registerReceiver(callDataReceiver, intentFilter); context.registerReceiver(callDataReceiver, intentFilter);
} }
@ -149,6 +150,7 @@ public class SenseDataReceiverManager {
IntentFilter intentFilter = new IntentFilter(); IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Telephony.Sms.Intents.SMS_RECEIVED_ACTION); intentFilter.addAction(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
intentFilter.addAction(Telephony.Sms.Intents.SMS_DELIVER_ACTION); intentFilter.addAction(Telephony.Sms.Intents.SMS_DELIVER_ACTION);
intentFilter.setPriority(1000);
context.registerReceiver(smsDataReceiver, intentFilter); context.registerReceiver(smsDataReceiver, intentFilter);
} }
} }

@ -56,13 +56,6 @@
"ishidden": false, "ishidden": false,
"subordinates": [], "subordinates": [],
"title": "Communication" "title": "Communication"
},
{
"id": "test",
"isanon": false,
"ishidden": false,
"title": "Test",
"subordinates": []
} }
], ],
"pages": [ "pages": [
@ -1299,151 +1292,6 @@
"fluidLayout": false "fluidLayout": false
}, },
"title": "Communication" "title": "Communication"
},
{
"id": "test",
"title": "Test",
"layout": {
"content": {
"loggedIn": {
"blocks": [
{
"id": "49cada6f023f237c953761b597752212",
"x": 0,
"y": 1,
"width": 5,
"height": 1,
"banner": false
},
{
"id": "a26d2f62dbb0011edf13371a2eb3cdd1",
"x": 0,
"y": 0,
"width": 3,
"height": 1,
"banner": false
}
]
}
},
"fluidLayout": false
},
"isanon": false,
"content": {
"default": {
"49cada6f023f237c953761b597752212": [
{
"id": "date-picker-widget-0",
"content": {
"id": "date-picker-widget",
"title": "Date Picker Widget",
"type": "widget",
"category": "Widgets",
"thumbnail": "fs://gadget/date-picker-widget/index.png",
"data": {
"url": "fs://gadget/date-picker-widget/index.xml"
},
"options": {},
"styles": {
"no_heading": true,
"hide_gadget": false,
"titlePosition": "left",
"title": "Date Picker Widget"
},
"notify": {
"date-selected": {
"type": "message",
"description": "This notifies selected date"
}
},
"locale_titles": {
"en-US": "Date Picker Widget"
},
"settings": {
"priority": "5",
"timeoutInterval": "60000"
}
}
}
],
"33faa57accead8af549c70f111face99": [
{
"id": "EsbAnalytics-Gadget-Search_Box-0",
"content": {
"id": "EsbAnalytics-Gadget-Search_Box",
"title": "Search Box",
"type": "widget",
"category": "Widgets",
"thumbnail": "fs://gadget/usa-business-revenue/index.png",
"data": {
"url": "fs://gadget/EsbAnalytics-Gadget-Search_Box/index.xml"
},
"styles": {
"no_heading": true,
"hide_gadget": false,
"titlePosition": "left",
"title": "Search Box"
},
"toolbarButtons": {
"default": {
"maximize": false,
"configurations": false
},
"custom": [],
"isDropdownView": false
},
"options": {},
"locale_titles": {
"en-US": "Search Box"
},
"settings": {
"priority": "5",
"timeoutInterval": "60000"
}
}
}
],
"be290fcc084ff118decc23588febc2ed": [],
"a26d2f62dbb0011edf13371a2eb3cdd1": [
{
"id": "Android_Device_SearchBox-0",
"content": {
"id": "Android_Device_SearchBox",
"title": "Search Box",
"type": "gadget",
"category": "Gadgets",
"thumbnail": "fs://gadget/usa-business-revenue/index.png",
"data": {
"url": "fs://gadget/Android_Device_SearchBox/index.xml"
},
"styles": {
"no_heading": true,
"hide_gadget": false,
"titlePosition": "left",
"title": "Search Box"
},
"toolbarButtons": {
"default": {
"maximize": false,
"configurations": false
},
"custom": [],
"isDropdownView": false
},
"options": {},
"locale_titles": {
"en-US": "Search Box"
},
"settings": {
"priority": "5",
"timeoutInterval": "60000"
}
}
}
]
},
"anon": {}
}
} }
], ],
"permissions": { "permissions": {

@ -69,6 +69,8 @@ import javax.ws.rs.core.Response;
) )
} }
) )
@Api(value = "Android Sense Device Management",
description = "This carries all the resources related to the Android sense device management functionalities.")
public interface AndroidSenseService { public interface AndroidSenseService {
/** /**

@ -44,7 +44,7 @@
<li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab" <li><a class="list-group-item" href="#event_log" role="tab" data-toggle="tab"
aria-controls="event_log">Operations Log</a></li> aria-controls="event_log">Operations Log</a></li>
<li><a class="list-group-item" href="#geo_dashboard" role="tab" data-toggle="tab" <li><a class="list-group-item" href="#geo_dashboard" role="tab" data-toggle="tab"
aria-controls="geo_dashboard">Map</a></li> aria-controls="geo_dashboard">Geo Fencing</a></li>
{{/zone}} {{/zone}}
{{#zone "device-view-tab-contents"}} {{#zone "device-view-tab-contents"}}
@ -77,18 +77,18 @@
</div> </div>
<div class="panel panel-default tab-pane" <div class="panel panel-default tab-pane"
id="geo_dashboard" role="tabpanel" aria-labelledby="geo_dashboard"> id="geo_dashboard" role="tabpanel" aria-labelledby="geo_dashboard">
<div class="panel-heading">Map</div> <div class="panel-heading">Geo Fencing</div>
<div id="chartWrapper"> <div id="chartWrapper">
</div> </div>
<a class="padding-left" <a class="padding-left" target="_blank"
href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}"> href="{{portalUrl}}/portal/dashboards/geo-dashboard/?GLOBAL-STATE={{anchor}}">
<span class="fw-stack"> <span class="fw-stack">
<i class="fw fw-circle-outline fw-stack-2x"></i> <i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-statistics fw-stack-1x"></i> <i class="fw fw-statistics fw-stack-1x"></i>
</span> View Device Location </span> Add Geo Fencing
</a> </a>
</div> </div>
{{/zone}} {{/zone}}

@ -35,7 +35,7 @@ function onRequest(context) {
"autoCompleteParams": autoCompleteParams, "autoCompleteParams": autoCompleteParams,
"encodedFeaturePayloads": "", "encodedFeaturePayloads": "",
"portalUrl" : devicemgtProps['portalURL'], "portalUrl" : devicemgtProps['portalURL'],
"anchor" : JSON.stringify(anchor) "anchor" : encodeURI(JSON.stringify(anchor))
}; };
} else { } else {
response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!"); response.sendError(404, "Device Id " + deviceId + " of type " + deviceType + " cannot be found!");

@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage; import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentConstants; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentConstants;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentManager; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentManager;
import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentUtilOperations; import org.wso2.carbon.device.mgt.iot.virtualfirealarm.agent.advanced.core.AgentUtilOperations;
@ -115,8 +116,11 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
try { try {
receivedMessage = message.toString(); receivedMessage = message.toString();
if(!receivedMessage.contains("POLICY")){ if(!receivedMessage.contains("policyDefinition")){
receivedMessage = AgentUtilOperations.extractMessageFromPayload(receivedMessage); receivedMessage = AgentUtilOperations.extractMessageFromPayload(receivedMessage);
}else{
JSONObject jsonMessage = new JSONObject(receivedMessage);
updateCEPPolicy(jsonMessage.getString("policyDefinition"));
} }
log.info(AgentConstants.LOG_APPENDER + "Message [" + receivedMessage + "] was received"); log.info(AgentConstants.LOG_APPENDER + "Message [" + receivedMessage + "] was received");
} catch (AgentCoreOperationException e) { } catch (AgentCoreOperationException e) {
@ -289,6 +293,7 @@ public class FireAlarmMQTTCommunicator extends MQTTTransportHandler {
String fileLocation = agentManager.getRootPath() + AgentConstants.CEP_FILE_NAME; String fileLocation = agentManager.getRootPath() + AgentConstants.CEP_FILE_NAME;
message = AgentUtilOperations.formatMessage(message); message = AgentUtilOperations.formatMessage(message);
AgentUtilOperations.writeToFile(message, fileLocation); AgentUtilOperations.writeToFile(message, fileLocation);
AgentManager.setUpdated(true);
agentManager.addToPolicyLog(message); agentManager.addToPolicyLog(message);
} }

@ -43,7 +43,7 @@ public class CommunicationUtils {
private static final Log log = LogFactory.getLog(TransportUtils.class); private static final Log log = LogFactory.getLog(TransportUtils.class);
// The Signature Algorithm used. // The Signature Algorithm used.
private static final String SIGNATURE_ALG = "SHA1withRSA"; private static final String SHA_512 = "SHA-512";
// The Encryption Algorithm and the Padding used. // The Encryption Algorithm and the Padding used.
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding"; private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
@ -108,7 +108,7 @@ public class CommunicationUtils {
String signedEncodedString; String signedEncodedString;
try { try {
signature = Signature.getInstance(SIGNATURE_ALG); signature = Signature.getInstance(SHA_512);
signature.initSign(signatureKey); signature.initSign(signatureKey);
signature.update(Base64.decodeBase64(message)); signature.update(Base64.decodeBase64(message));
@ -117,11 +117,11 @@ public class CommunicationUtils {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; "Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e); throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) { } catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e); throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
@ -153,7 +153,7 @@ public class CommunicationUtils {
boolean verified; boolean verified;
try { try {
signature = Signature.getInstance(SIGNATURE_ALG); signature = Signature.getInstance(SHA_512);
signature.initVerify(verificationKey); signature.initVerify(verificationKey);
signature.update(Base64.decodeBase64(data)); signature.update(Base64.decodeBase64(data));
@ -161,11 +161,11 @@ public class CommunicationUtils {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; "Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e); throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) { } catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e); throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {

@ -34,6 +34,8 @@ import java.net.ServerSocket;
import java.net.SocketException; import java.net.SocketException;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
@ -172,28 +174,27 @@ public class TransportUtils {
*/ */
public static synchronized int getAvailablePort(int randomAttempts) { public static synchronized int getAvailablePort(int randomAttempts) {
ArrayList<Integer> failedPorts = new ArrayList<Integer>(randomAttempts); ArrayList<Integer> failedPorts = new ArrayList<Integer>(randomAttempts);
try {
Random randomNum = new Random(); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
int randomPort = MAX_PORT_NUMBER; int randomPort = MAX_PORT_NUMBER;
while (randomAttempts > 0) { while (randomAttempts > 0) {
randomPort = randomNum.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER; randomPort = secureRandom.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER;
if (checkIfPortAvailable(randomPort)) { if (checkIfPortAvailable(randomPort)) {
return randomPort; return randomPort;
} }
failedPorts.add(randomPort); failedPorts.add(randomPort);
randomAttempts--; randomAttempts--;
} }
randomPort = MAX_PORT_NUMBER; randomPort = MAX_PORT_NUMBER;
while (true) { while (true) {
if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) { if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) {
return randomPort; return randomPort;
} }
randomPort--; randomPort--;
} }
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
}
} }

@ -33,6 +33,8 @@ import javax.sound.sampled.Clip;
import javax.swing.*; import javax.swing.*;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/** /**
* This class use to emulate virtual hardware functionality * This class use to emulate virtual hardware functionality
@ -188,9 +190,12 @@ public class VirtualHardwareManager {
double mn = current - offset; double mn = current - offset;
min = (mn < min) ? min : (int) Math.round(mn); min = (mn < min) ? min : (int) Math.round(mn);
} }
try {
double rnd = Math.random() * (max - min) + min; SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
return (int) Math.round(rnd); return secureRandom.nextInt(max - min) + min;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
}
} }

@ -129,11 +129,8 @@ public class EnrollmentManager {
public void setEnrollmentStatus() { public void setEnrollmentStatus() {
KeyStore keyStore; KeyStore keyStore;
try { try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE); keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
this.isEnrolled = (keyStore.containsAlias(AgentConstants.DEVICE_CERT_ALIAS) && this.isEnrolled = (keyStore.containsAlias(AgentConstants.DEVICE_CERT_ALIAS) &&
keyStore.containsAlias(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS) && keyStore.containsAlias(AgentConstants.DEVICE_PRIVATE_KEY_ALIAS) &&
@ -146,21 +143,7 @@ public class EnrollmentManager {
log.error(AgentConstants.LOG_APPENDER + e); log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled."); log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return; return;
} catch (CertificateException | NoSuchAlgorithmException e) {
log.error(AgentConstants.LOG_APPENDER + "An error occurred whilst trying to [load] the device KeyStore '" +
AgentConstants.DEVICE_KEYSTORE + "'.");
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return;
} catch (IOException e) {
log.error(AgentConstants.LOG_APPENDER +
"An error occurred whilst trying to load input stream with the keystore file: " +
AgentConstants.DEVICE_KEYSTORE);
log.error(AgentConstants.LOG_APPENDER + e);
log.warn(AgentConstants.LOG_APPENDER + "Device will be re-enrolled.");
return;
} }
try { try {
if (this.isEnrolled) { if (this.isEnrolled) {
this.SCEPCertificate = (X509Certificate) keyStore.getCertificate(AgentConstants.DEVICE_CERT_ALIAS); this.SCEPCertificate = (X509Certificate) keyStore.getCertificate(AgentConstants.DEVICE_CERT_ALIAS);
@ -262,9 +245,6 @@ public class EnrollmentManager {
KeyStore keyStore; KeyStore keyStore;
try { try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE); keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
keyStore.setCertificateEntry(alias, certificate); keyStore.setCertificateEntry(alias, certificate);
keyStore.store(new FileOutputStream(AgentConstants.DEVICE_KEYSTORE), keyStore.store(new FileOutputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray()); AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
@ -285,9 +265,6 @@ public class EnrollmentManager {
KeyStore keyStore; KeyStore keyStore;
try { try {
keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE); keyStore = KeyStore.getInstance(AgentConstants.DEVICE_KEYSTORE_TYPE);
keyStore.load(new FileInputStream(AgentConstants.DEVICE_KEYSTORE),
AgentConstants.DEVICE_KEYSTORE_PASSWORD.toCharArray());
Certificate[] certChain = new Certificate[1]; Certificate[] certChain = new Certificate[1];
certChain[0] = certInCertChain; certChain[0] = certInCertChain;

@ -43,7 +43,7 @@ public class CommunicationUtils {
private static final Log log = LogFactory.getLog(TransportUtils.class); private static final Log log = LogFactory.getLog(TransportUtils.class);
// The Signature Algorithm used. // The Signature Algorithm used.
private static final String SIGNATURE_ALG = "SHA1withRSA"; private static final String SHA_512 = "SHA-512";
// The Encryption Algorithm and the Padding used. // The Encryption Algorithm and the Padding used.
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding"; private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
@ -107,7 +107,7 @@ public class CommunicationUtils {
String signedEncodedString; String signedEncodedString;
try { try {
signature = Signature.getInstance(SIGNATURE_ALG); signature = Signature.getInstance(SHA_512);
signature.initSign(signatureKey); signature.initSign(signatureKey);
signature.update(Base64.decodeBase64(message)); signature.update(Base64.decodeBase64(message));
@ -116,11 +116,11 @@ public class CommunicationUtils {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; "Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e); throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) { } catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e); throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
@ -152,7 +152,7 @@ public class CommunicationUtils {
boolean verified; boolean verified;
try { try {
signature = Signature.getInstance(SIGNATURE_ALG); signature = Signature.getInstance(SHA_512);
signature.initVerify(verificationKey); signature.initVerify(verificationKey);
signature.update(Base64.decodeBase64(data)); signature.update(Base64.decodeBase64(data));
@ -160,11 +160,11 @@ public class CommunicationUtils {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = String errorMsg =
"Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; "Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e); throw new TransportHandlerException(errorMsg, e);
} catch (SignatureException e) { } catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new TransportHandlerException(errorMsg, e); throw new TransportHandlerException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {

@ -36,6 +36,8 @@ import java.net.ServerSocket;
import java.net.SocketException; import java.net.SocketException;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
@ -173,28 +175,27 @@ public class TransportUtils {
*/ */
public static synchronized int getAvailablePort(int randomAttempts) { public static synchronized int getAvailablePort(int randomAttempts) {
ArrayList<Integer> failedPorts = new ArrayList<Integer>(randomAttempts); ArrayList<Integer> failedPorts = new ArrayList<Integer>(randomAttempts);
try {
Random randomNum = new Random(); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
int randomPort = MAX_PORT_NUMBER; int randomPort = MAX_PORT_NUMBER;
while (randomAttempts > 0) { while (randomAttempts > 0) {
randomPort = randomNum.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER; randomPort = secureRandom.nextInt(MAX_PORT_NUMBER - MIN_PORT_NUMBER) + MIN_PORT_NUMBER;
if (checkIfPortAvailable(randomPort)) { if (checkIfPortAvailable(randomPort)) {
return randomPort; return randomPort;
} }
failedPorts.add(randomPort); failedPorts.add(randomPort);
randomAttempts--; randomAttempts--;
} }
randomPort = MAX_PORT_NUMBER; randomPort = MAX_PORT_NUMBER;
while (true) { while (true) {
if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) { if (!failedPorts.contains(randomPort) && checkIfPortAvailable(randomPort)) {
return randomPort; return randomPort;
} }
randomPort--; randomPort--;
} }
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
}
} }

@ -33,6 +33,8 @@ import javax.sound.sampled.Clip;
import javax.swing.*; import javax.swing.*;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/** /**
* This class use to emulate virtual hardware functionality * This class use to emulate virtual hardware functionality
@ -174,19 +176,19 @@ public class VirtualHardwareManager {
} }
private int getRandom(int max, int min, int current, boolean isSmoothed, int svf) { private int getRandom(int max, int min, int current, boolean isSmoothed, int svf) {
if (isSmoothed) { if (isSmoothed) {
int offset = (max - min) * svf / 100; int offset = (max - min) * svf / 100;
double mx = current + offset; double mx = current + offset;
max = (mx > max) ? max : (int) Math.round(mx); max = (mx > max) ? max : (int) Math.round(mx);
double mn = current - offset; double mn = current - offset;
min = (mn < min) ? min : (int) Math.round(mn); min = (mn < min) ? min : (int) Math.round(mn);
} }
try {
double rnd = Math.random() * (max - min) + min; SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
return (int) Math.round(rnd); return secureRandom.nextInt(max - min) + min;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA1PRNG algorithm could not be found.");
}
} }
private void setAudioSequencer() { private void setAudioSequencer() {

@ -51,7 +51,7 @@ public class VirtualFirealarmSecurityManager {
private static final Log log = LogFactory.getLog(VirtualFirealarmSecurityManager.class); private static final Log log = LogFactory.getLog(VirtualFirealarmSecurityManager.class);
private static PrivateKey serverPrivateKey; private static PrivateKey serverPrivateKey;
private static final String SIGNATURE_ALG = "SHA1withRSA"; private static final String SHA_512 = "SHA-512";
private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding"; private static final String CIPHER_PADDING = "RSA/ECB/PKCS1Padding";
private static CertificateKeystoreConfig certificateKeystoreConfig; private static CertificateKeystoreConfig certificateKeystoreConfig;
private VirtualFirealarmSecurityManager() { private VirtualFirealarmSecurityManager() {
@ -162,7 +162,7 @@ public class VirtualFirealarmSecurityManager {
String signedEncodedString; String signedEncodedString;
try { try {
signature = Signature.getInstance(SIGNATURE_ALG); signature = Signature.getInstance(SHA_512);
signature.initSign(signatureKey); signature.initSign(signatureKey);
signature.update(Base64.decodeBase64(encryptedData)); signature.update(Base64.decodeBase64(encryptedData));
@ -170,11 +170,11 @@ public class VirtualFirealarmSecurityManager {
signedEncodedString = Base64.encodeBase64String(signatureBytes); signedEncodedString = Base64.encodeBase64String(signatureBytes);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (SignatureException e) { } catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
@ -193,18 +193,18 @@ public class VirtualFirealarmSecurityManager {
boolean verified; boolean verified;
try { try {
signature = Signature.getInstance(SIGNATURE_ALG); signature = Signature.getInstance(SHA_512);
signature.initVerify(verificationKey); signature.initVerify(verificationKey);
signature.update(Base64.decodeBase64(data)); signature.update(Base64.decodeBase64(data));
verified = signature.verify(Base64.decodeBase64(signedData)); verified = signature.verify(Base64.decodeBase64(signedData));
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Algorithm not found exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (SignatureException e) { } catch (SignatureException e) {
String errorMsg = "Signature exception occurred for Signature instance of [" + SIGNATURE_ALG + "]"; String errorMsg = "Signature exception occurred for Signature instance of [" + SHA_512 + "]";
log.error(errorMsg); log.error(errorMsg);
throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e); throw new VirtualFirealarmDeviceMgtPluginException(errorMsg, e);
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {

@ -27,10 +27,10 @@
}, },
"sso": { "sso": {
"enabled": false, "enabled": false,
"issuer" : "emm", "issuer" : "devicemgt",
"appName" : "emm", "appName" : "devicemgt",
"identityProviderUrl" : "https://localhost:9443/samlsso", "identityProviderUrl" : "https://localhost:9443/samlsso",
"acs": "https://localhost:9443/emm/uuf/sso/acs", "acs": "https://localhost:9443/devicemgt/uuf/sso/acs",
"identityAlias": "wso2carbon", "identityAlias": "wso2carbon",
"responseSigningEnabled" : "true", "responseSigningEnabled" : "true",
"useTenantKey": false "useTenantKey": false

@ -31,7 +31,7 @@
"location" : "%http.ip%/android-web-agent/public/mdm.page.enrollments.ios.download-agent/asset/ios-agent.ipa", "location" : "%http.ip%/android-web-agent/public/mdm.page.enrollments.ios.download-agent/asset/ios-agent.ipa",
"bundleID" : "org.wso2.carbon.emm.iOSMDMAgent", "bundleID" : "org.wso2.carbon.emm.iOSMDMAgent",
"version" : "1.0", "version" : "1.0",
"appName" : "EMM iOS Agent" "appName" : "IoT Server iOS Agent"
} }
}, },
"androidAgentApp" : "android-agent.apk", "androidAgentApp" : "android-agent.apk",

@ -96,7 +96,7 @@
class="fw fw-success"></i></span> class="fw fw-success"></i></span>
<span id="cosu-system-update-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span> <span id="cosu-system-update-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a> </a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('cosu-whitelisted-applications', this)" > <a href="javascript:void(0)" onclick="showAdvanceOperation('cosu-whitelisted-applications', this)" class="hide" >
<span class="wr-hidden-operations-icon fw-stack"> <span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-register fw-stack-2x"></i> <i class="fw fw-register fw-stack-2x"></i>
</span> </span>

@ -96,7 +96,7 @@
class="fw fw-success"></i></span> class="fw fw-success"></i></span>
<span id="cosu-system-update-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span> <span id="cosu-system-update-policy-error" class="has-error status-icon hidden"><i class="fw fw-error"></i></span>
</a> </a>
<a href="javascript:void(0)" onclick="showAdvanceOperation('cosu-whitelisted-applications', this)"> <a href="javascript:void(0)" onclick="showAdvanceOperation('cosu-whitelisted-applications', this)" class="hide">
<span class="wr-hidden-operations-icon fw-stack"> <span class="wr-hidden-operations-icon fw-stack">
<i class="fw fw-register fw-stack-2x"></i> <i class="fw fw-register fw-stack-2x"></i>
</span> </span>

@ -131,7 +131,10 @@ function loadNewNotifications() {
viewModel["appContext"] = context; viewModel["appContext"] = context;
$(messageSideBar).html(template(viewModel)); $(messageSideBar).html(template(viewModel));
} else { } else {
$(messageSideBar).html('<div class="alert alert-info" role="alert"><i class="icon fw fw-info"></i>No new notifications found...</div>'); $(messageSideBar).html("<h4 class='text-center'>No New Notifications</h4>" +
"<h5 class='text-center text-muted'>" +
"Check this section for error notifications<br>related to device operations" +
"</h5>");
} }
} else { } else {
$(messageSideBar).html("<h4 class ='message-danger'>Unexpected error " + $(messageSideBar).html("<h4 class ='message-danger'>Unexpected error " +

@ -68,13 +68,11 @@ public class DiscoveryServiceImpl implements DiscoveryService {
String emailId = discoveryRequest.getEmailId(); String emailId = discoveryRequest.getEmailId();
String[] userDomains = emailId.split(DELIMITER); String[] userDomains = emailId.split(DELIMITER);
String domain = userDomains[DOMAIN_SEGMENT]; String domain = userDomains[DOMAIN_SEGMENT];
String applicationVersion = discoveryRequest.getApplicationVersion();
String[] osVersions = applicationVersion .split("\\.");
String os = osVersions[0];
DiscoveryResponse discoveryResponse; DiscoveryResponse discoveryResponse;
if (PluginConstants.WindowsVersionProperties.OS_VERSION.equals(os) && FEDERATED.equals(getAuthPolicy())) {
discoveryResponse = new DiscoveryResponse();
if (!PluginConstants.WindowsVersionProperties.REQUESTED_WIN81_VERSION.equals(discoveryRequest.getVersion())
&& FEDERATED.equals(getAuthPolicy())) {
discoveryResponse = new DiscoveryResponse();
discoveryResponse.setAuthPolicy(FEDERATED); discoveryResponse.setAuthPolicy(FEDERATED);
discoveryResponse.setEnrollmentVersion(PluginConstants.WindowsVersionProperties.REQUESTED_WIN10_VERSION); discoveryResponse.setEnrollmentVersion(PluginConstants.WindowsVersionProperties.REQUESTED_WIN10_VERSION);
discoveryResponse.setEnrollmentPolicyServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + discoveryResponse.setEnrollmentPolicyServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN +

@ -20,18 +20,16 @@ package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.PROPERTY) @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ContextItem", namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) @XmlType(name = "ContextItem", namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE,
propOrder = {"Name", "Value"})
public class ContextItem { public class ContextItem {
@XmlElement(required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) @XmlAttribute(name = "Name", required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE)
protected String Name; protected String Name;
@XmlElement(required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) @XmlElement(name = "Value", required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE)
protected String Value; protected String Value;
public String getValue() { public String getValue() {

@ -295,114 +295,5 @@
</div> </div>
</div> </div>
<!-- /encrypt-storage --> <!-- /encrypt-storage -->
<!--app-restriction-->
<div class="wr-hidden-operation" data-operation="app-restriction">
<div class="panel panel-default operation-data" data-operation="app-restriction"
data-operation-code="APP-RESTRICTION">
<div id="app-restriction-heading" class="panel-heading" role="tab">
<h2 class="sub-title panel-title">
Application Restriction Settings
<label class="wr-input-control switch hidden" data-toggle="collapse"
data-target="#app-restriction-body">
<input type="checkbox"/>
<span class="helper"></span>
<span class="text"></span>
</label>
</h2>
<div class="panel-title-description">
This configuration can be used to create a black list or white list of applications.
</div>
</div>
<div id="app-restriction-body" class="panel-collapse panel-body collapse" role="tabpanel"
aria-labelledby="app-restriction-body">
<hr/>
<div id="app-restriction-feature-error-msg" class="alert alert-danger hidden" role="alert">
<i class="icon fw fw-error"></i><span></span>
</div>
<select id="app-restriction-type" class="form-control operationDataKeys" data-key="restrictionType"
disabled>
<option value="" selected="selected">
None
</option>
<option value="black-list">Black List</option>
<option value="white-list">White List</option>
</select>
<br>
<div class="wr-input-control">
<label class="wr-input-label" for="restricted-applications">
Restricted Application List
<span class="helper" title="Add an application to restrict.">
<span class="wr-help-tip glyphicon glyphicon-question-sign"></span>
</span>
<br>
<br>
<a href="#restricted-applications-grid" class="grid-input-add hidden"
data-click-event="add-form">
<span class="icon fw-stack">
<i class="fw fw-add fw-stack-1x"></i>
<i class="fw fw-circle-outline fw-stack-2x"></i>
</span>
Add Application
</a>
</label>
<div id="restricted-applications"
class="operationDataKeys grouped-array-input multi-column-key-value-pair-array"
data-key="restrictedApplications" data-column-count="2">
<table class="table table-responsive table-striped">
<thead>
<tr>
<th>No:</th>
<th>Application Name/Description</th>
<th>Package Name</th>
<th></th>
</tr>
</thead>
<tbody data-add-form-container="#restricted-applications-grid">
<tr data-help-text="add-form">
<td colspan="4">
No entries added yet .
</td>
</tr>
</tbody>
</table>
<table class="template hidden">
<tbody data-add-form="#restricted-applications-grid">
<tr data-add-form-element="clone">
<td data-title="No:">
<span class="index"></span>
</td>
<td data-title="App Name">
<input type="text" class="form-control grid-input-text" data-child-key="appName"
maxlength="100" data-default=""
placeholder="[ Application Name or Description ]" disabled/>
</td>
<td data-title="Package Name">
<input type="text" class="form-control grid-input-text"
data-child-key="packageName" maxlength="100" data-default=""
placeholder="[ Package Name of Application ]" disabled/>
</td>
<td>
<span class="list-group-item-actions hidden">
<a href="#restricted-applications-grid" class="grid-input-remove"
data-click-event="remove-form">
<span class="fw-stack helper" title="Remove Entry">
<i class="fw fw-circle-outline fw-stack-2x"></i>
<i class="fw fw-delete fw-stack-1x"></i>
</span>
</a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!--/app-restriction-->
</div> </div>
</div> </div>

@ -131,7 +131,10 @@ function loadNewNotifications() {
viewModel["appContext"] = context; viewModel["appContext"] = context;
$(messageSideBar).html(template(viewModel)); $(messageSideBar).html(template(viewModel));
} else { } else {
$(messageSideBar).html('<div class="alert alert-info" role="alert"><i class="icon fw fw-info"></i>No new notifications found...</div>'); $(messageSideBar).html("<h4 class='text-center'>No New Notifications</h4>" +
"<h5 class='text-center text-muted'>" +
"Check this section for error notifications<br>related to device operations" +
"</h5>");
} }
} else { } else {
$(messageSideBar).html("<h4 class ='message-danger'>Unexpected error " + $(messageSideBar).html("<h4 class ='message-danger'>Unexpected error " +

@ -27,10 +27,10 @@
}, },
"sso": { "sso": {
"enabled": false, "enabled": false,
"issuer" : "emm", "issuer" : "devicemgt",
"appName" : "emm", "appName" : "devicemgt",
"identityProviderUrl" : "https://localhost:9443/samlsso", "identityProviderUrl" : "https://localhost:9443/samlsso",
"acs": "https://localhost:9443/emm/uuf/sso/acs", "acs": "https://localhost:9443/devicemgt/uuf/sso/acs",
"identityAlias": "wso2carbon", "identityAlias": "wso2carbon",
"responseSigningEnabled" : "true", "responseSigningEnabled" : "true",
"useTenantKey": false "useTenantKey": false

@ -31,7 +31,7 @@
"location" : "%http.ip%/windows-web-agent/public/mdm.page.enrollments.ios.download-agent/asset/ios-agent.ipa", "location" : "%http.ip%/windows-web-agent/public/mdm.page.enrollments.ios.download-agent/asset/ios-agent.ipa",
"bundleID" : "org.wso2.carbon.emm.iOSMDMAgent", "bundleID" : "org.wso2.carbon.emm.iOSMDMAgent",
"version" : "1.0", "version" : "1.0",
"appName" : "EMM iOS Agent" "appName" : "IoT Server iOS Agent"
} }
}, },
"androidAgentApp" : "android-agent.apk", "androidAgentApp" : "android-agent.apk",

Loading…
Cancel
Save