implementing windows10 devicemgt session

revert-dabc3590
Hasunie 8 years ago
parent b57573ecae
commit d3bf748233

@ -125,7 +125,6 @@ public final class PluginConstants {
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary"; "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary";
public static final String CA_CERT = "cacert"; public static final String CA_CERT = "cacert";
public static final String X_509 = "X.509"; public static final String X_509 = "X.509";
public static final String PROPERTIES_XML = "properties.xml";
public static final String WAP_PROVISIONING_XML = "wap-provisioning.xml"; public static final String WAP_PROVISIONING_XML = "wap-provisioning.xml";
public static final String PROVIDER = "BC"; public static final String PROVIDER = "BC";
public static final String ALGORITHM = "SHA1withRSA"; public static final String ALGORITHM = "SHA1withRSA";

@ -69,6 +69,35 @@ public class OperationReply {
this.syncmlDocument = syncmlDocument; this.syncmlDocument = syncmlDocument;
replySyncmlDocument = new SyncmlDocument(); replySyncmlDocument = new SyncmlDocument();
} }
public OperationReply() {
}
/**
* Generate Device payloads.
*
* @param syncmlDocument Parsed syncml payload from the syncml engine.
* @param operations Operations for generate payload.
* @return String type syncml payload.
* @throws WindowsOperationException
* @throws PolicyManagementException
* @throws org.wso2.carbon.policy.mgt.common.FeatureManagementException
*/
public String generateReply(SyncmlDocument syncmlDocument, List<? extends Operation> operations)
throws SyncmlMessageFormatException, SyncmlOperationException {
OperationReply operationReply;
SyncmlGenerator generator;
SyncmlDocument syncmlResponse;
if (operations == null) {
operationReply = new OperationReply(syncmlDocument);
} else {
operationReply = new OperationReply(syncmlDocument, operations);
}
syncmlResponse = operationReply.generateReply();
generator = new SyncmlGenerator();
return generator.generatePayload(syncmlResponse);
}
public SyncmlDocument generateReply() throws SyncmlMessageFormatException, SyncmlOperationException { public SyncmlDocument generateReply() throws SyncmlMessageFormatException, SyncmlOperationException {
generateHeader(); generateHeader();

@ -0,0 +1,122 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.windows.api.services;
import io.swagger.annotations.*;
import org.w3c.dom.Document;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsConfigurationException;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException;
import org.wso2.carbon.device.mgt.mobile.windows.api.operations.WindowsOperationException;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* Interface for Syncml message flow.
*/
@SwaggerDefinition(
info = @Info(
version = "1.0.0",
title = "",
extensions = {
@Extension(properties = {
@ExtensionProperty(name = "name", value = "Syncml Endpoint"),
@ExtensionProperty(name = "context",
value = "/api/device-mgt/windows/v1.0/syncml"),
})
}
),
tags = {
@Tag(name = "devicemgt_windows", description = "")
}
)
@Api(value = "Windows syncml service to initialize management session",
description = "This carries all the resources related to Windows syncml message flow.")
@Path("/devicemgt")
public interface DeviceManagementService {
@Path("/request")
@POST
@Consumes({PluginConstants.SYNCML_MEDIA_TYPE, MediaType.APPLICATION_XML})
@Produces(PluginConstants.SYNCML_MEDIA_TYPE)
@ApiOperation(
httpMethod = "POST",
value = "Getting pending operations for Windows device.",
notes = "Using this API to fetching more information to enroll the Device and " +
"getting pending operations.",
tags = "Windows Device Management Administrative Service",
authorizations = {
@Authorization(
value = "permission",
scopes = {@AuthorizationScope(
scope = "/device-mgt/devices/enroll/windows",
description = "Getting pending operations and " +
"device information to enroll the device")}
)
}
)
@ApiResponses(value = {
@ApiResponse(
code = 201,
message = "Ok. \n Successfully getting pending operations.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "URL of the activity instance that refers to the scheduled operation."),
@ResponseHeader(
name = "Content-Type",
description = "Content type of the body"),
@ResponseHeader(
name = "ETag",
description = "Entity Tag of the response resource.\n" +
"Used by caches, or in conditional requests."),
@ResponseHeader(
name = "Last-Modified",
description = "Date and time the resource was last modified. \n" +
"Used by caches, or in conditional requests.")}),
@ApiResponse(
code = 303,
message = "See Other. \n The source can be retrieved from the URL specified in the location header.",
responseHeaders = {
@ResponseHeader(
name = "Content-Location",
description = "The Source URL of the document.")}),
@ApiResponse(
code = 400,
message = "Bad Request. \n Invalid request or validation error."),
@ApiResponse(
code = 415,
message = "Unsupported media type. \n The format of the requested entity was not supported.\n"),
@ApiResponse(
code = 500,
message = "Internal Server Error. \n " +
"Server error occurred while getting pending operations.")
})
Response getResponse(Document request) throws WindowsDeviceEnrolmentException, WindowsOperationException,
NotificationManagementException, WindowsConfigurationException;
}

@ -0,0 +1,213 @@
/*
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.wso2.carbon.device.mgt.mobile.windows.api.services.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.wso2.carbon.context.PrivilegedCarbonContext;
import org.wso2.carbon.device.mgt.common.Device;
import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
import org.wso2.carbon.device.mgt.common.DeviceManagementConstants;
import org.wso2.carbon.device.mgt.common.DeviceManagementException;
import org.wso2.carbon.device.mgt.common.notification.mgt.NotificationManagementException;
import org.wso2.carbon.device.mgt.common.operation.mgt.Operation;
import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManagementException;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.beans.CacheEntry;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlMessageFormatException;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlOperationException;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsConfigurationException;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.AuthenticationInfo;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.DeviceUtil;
import org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils;
import org.wso2.carbon.device.mgt.mobile.windows.api.operations.*;
import org.wso2.carbon.device.mgt.mobile.windows.api.operations.util.*;
import org.wso2.carbon.device.mgt.mobile.windows.api.services.DeviceManagementService;
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
import org.wso2.carbon.policy.mgt.core.PolicyManagerService;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;
import static org.wso2.carbon.device.mgt.mobile.windows.api.common.util.WindowsAPIUtils.convertToDeviceIdentifierObject;
public class DeviceManagementServiceImpl implements DeviceManagementService {
private static Log log = LogFactory.getLog(
org.wso2.carbon.device.mgt.mobile.windows.api.services.syncml.impl.SyncmlServiceImpl.class);
@Override
public Response getResponse(Document request) throws WindowsDeviceEnrolmentException, WindowsOperationException,
NotificationManagementException, WindowsConfigurationException {
int msgId;
int sessionId;
String user;
String token;
String response;
SyncmlDocument syncmlDocument;
List<Operation> deviceInfoOperations;
List<? extends Operation> pendingOperations;
OperationHandler operationHandler = new OperationHandler();
DeviceInfo deviceInfo = new DeviceInfo();
OperationReply operationReply = new OperationReply();
try {
if (SyncmlParser.parseSyncmlPayload(request) != null) {
syncmlDocument = SyncmlParser.parseSyncmlPayload(request);
SyncmlHeader syncmlHeader = syncmlDocument.getHeader();
sessionId = syncmlHeader.getSessionId();
user = syncmlHeader.getSource().getLocName();
DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject(syncmlHeader.getSource().
getLocURI());
msgId = syncmlHeader.getMsgID();
if ((PluginConstants.SyncML.SYNCML_FIRST_MESSAGE_ID == msgId) &&
(PluginConstants.SyncML.SYNCML_FIRST_SESSION_ID == sessionId)) {
token = syncmlHeader.getCredential().getData();
CacheEntry cacheToken = (CacheEntry) DeviceUtil.getCacheEntry(token);
if ((cacheToken.getUsername() != null) && (cacheToken.getUsername().equals(user))) {
if (modifyEnrollWithMoreDetail(request)) {
pendingOperations = operationHandler.getPendingOperations(syncmlDocument);
response = operationReply.generateReply(syncmlDocument,pendingOperations);
return Response.status(Response.Status.OK).entity(response).build();
} else {
String msg = "Error occurred in device enrollment.";
log.error(msg);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
}
} else {
String msg = "Authentication failure due to incorrect credentials.";
log.error(msg);
return Response.status(Response.Status.UNAUTHORIZED).entity(msg).build();
}
} else if (sessionId >= PluginConstants.SyncML.SYNCML_SECOND_SESSION_ID) {
if ((syncmlDocument.getBody().getAlert() != null)) {
if (!syncmlDocument.getBody().getAlert().getData().equals(Constants.DISENROLL_ALERT_DATA)) {
pendingOperations = operationHandler.getPendingOperations(syncmlDocument);
return Response.ok().entity(operationReply.generateReply(
syncmlDocument, pendingOperations)).build();
} else {
if (WindowsAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier) != null) {
WindowsAPIUtils.getDeviceManagementService().disenrollDevice(deviceIdentifier);
return Response.ok().entity(operationReply.generateReply(syncmlDocument, null)).build();
} else {
String msg = "Enrolled device can not be found in the server.";
log.error(msg);
return Response.status(Response.Status.NOT_FOUND).entity(msg).build();
}
}
} else {
pendingOperations = operationHandler.getPendingOperations(syncmlDocument);
return Response.ok().entity(operationReply.generateReply(
syncmlDocument, pendingOperations)).build();
}
} else {
String msg = "Failure occurred in Device request message.";
log.error(msg);
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
}
}
} catch (SyncmlMessageFormatException e) {
String msg = "Error occurred while parsing syncml request.";
log.error(msg, e);
throw new WindowsOperationException(msg, e);
} catch (OperationManagementException e) {
String msg = "Cannot access operation management service.";
log.error(msg, e);
throw new WindowsOperationException(msg, e);
} catch (SyncmlOperationException e) {
String msg = "Error occurred while getting effective feature.";
log.error(msg, e);
throw new WindowsConfigurationException(msg, e);
} catch (DeviceManagementException e) {
String msg = "Failure occurred in dis-enrollment flow.";
log.error(msg, e);
throw new WindowsOperationException(msg, e);
}
return null;
}
/**
* Enroll phone device
*
* @param request Device syncml request for the server side.
* @return enroll state
* @throws WindowsDeviceEnrolmentException
* @throws WindowsOperationException
*/
private boolean modifyEnrollWithMoreDetail(Document request) throws WindowsDeviceEnrolmentException,
WindowsOperationException {
String devMan;
String devMod;
boolean status = false;
String user;
SyncmlDocument syncmlDocument;
try {
syncmlDocument = SyncmlParser.parseSyncmlPayload(request);
ReplaceTag replace = syncmlDocument.getBody().getReplace();
List<ItemTag> itemList = replace.getItems();
devMan = itemList.get(PluginConstants.SyncML.DEVICE_MAN_POSITION).getData();
devMod = itemList.get(PluginConstants.SyncML.DEVICE_MODEL_POSITION).getData();
user = syncmlDocument.getHeader().getSource().getLocName();
AuthenticationInfo authenticationInfo = new AuthenticationInfo();
authenticationInfo.setUsername(user);
WindowsAPIUtils.startTenantFlow(authenticationInfo);
DeviceIdentifier deviceIdentifier = convertToDeviceIdentifierObject(syncmlDocument.
getHeader().getSource().getLocURI());
Device existingDevice = WindowsAPIUtils.getDeviceManagementService().getDevice(deviceIdentifier);
if (!existingDevice.getProperties().isEmpty()) {
List<Device.Property> existingProperties = new ArrayList<>();
Device.Property vendorProperty = new Device.Property();
vendorProperty.setName(PluginConstants.SyncML.VENDOR);
vendorProperty.setValue(devMan);
existingProperties.add(vendorProperty);
Device.Property deviceModelProperty = new Device.Property();
deviceModelProperty.setName(PluginConstants.SyncML.MODEL);
deviceModelProperty.setValue(devMod);
existingProperties.add(deviceModelProperty);
existingDevice.setProperties(existingProperties);
existingDevice.setDeviceIdentifier(syncmlDocument.getHeader().getSource().getLocURI());
existingDevice.setType(DeviceManagementConstants.MobileDeviceTypes.MOBILE_DEVICE_TYPE_WINDOWS);
status = WindowsAPIUtils.getDeviceManagementService().modifyEnrollment(existingDevice);
// call effective policy for the enrolling device.
PolicyManagerService policyManagerService = WindowsAPIUtils.getPolicyManagerService();
policyManagerService.getEffectivePolicy(deviceIdentifier);
return status;
}
} catch (DeviceManagementException e) {
throw new WindowsDeviceEnrolmentException("Failure occurred while enrolling device.", e);
} catch (PolicyManagementException e) {
throw new WindowsOperationException("Error occurred while getting effective policy.", e);
} finally {
PrivilegedCarbonContext.endTenantFlow();
}
return status;
}
}

@ -0,0 +1,76 @@
<wap-provisioningdoc version="1.1">
<characteristic type="CertificateStore">
<characteristic type="Root">
<characteristic type="System">
<characteristic type="031336C933CC7E228B88880D78824FB2909A0A2F">
<parm name="EncodedCertificate" value="B64 encoded cert insert here" />
</characteristic>
</characteristic>
</characteristic>
</characteristic>
<characteristic type="CertificateStore">
<characteristic type="My" >
<characteristic type="User">
<characteristic type="F9A4F20FC50D990FDD0E3DB9AFCBF401818D5462">
<parm name="EncodedCertificate" value="B64EncodedCertInsertedHere" />
</characteristic>
<characteristic type="PrivateKeyContainer"/>
<!-- This tag must be present for XML syntax correctness. -->
</characteristic>
<characteristic type="WSTEP">
<characteristic type="Renew">
<!--If the datatype for ROBOSupport, RenewPeriod, and RetryInterval tags exist, they must be set explicitly. -->
<parm name="ROBOSupport" value="true" datatype="boolean"/>
<parm name="RenewPeriod" value="60" datatype="integer"/>
<parm name="RetryInterval" value="4" datatype="integer"/>
</characteristic>
</characteristic>
</characteristic>
</characteristic>
<characteristic type="APPLICATION">
<parm name="APPID" value="w7"/>
<parm name="PROVIDER-ID" value="TestMDMServer"/>
<parm name="NAME" value="Microsoft"/>
<parm name="ADDR" value="https://DM.contoso.com:443/omadm/Windows.ashx"/>
<parm name="CONNRETRYFREQ" value="6" />
<parm name="INITIALBACKOFFTIME" value="30000" />
<parm name="MAXBACKOFFTIME" value="120000" />
<parm name="BACKCOMPATRETRYDISABLED" />
<parm name="DEFAULTENCODING" value="application/vnd.syncml.dm+wbxml" />
<parm name="SSLCLIENTCERTSEARCHCRITERIA" value=
"Subject=DC%3dcom%2cDC%3dmicrosoft%2cCN%3dUsers%2cCN%3dAdministrator&amp;amp;Stores=My%5CUser"/>
<characteristic type="APPAUTH">
<parm name="AAUTHLEVEL" value="CLIENT"/>
<parm name="AAUTHTYPE" value="DIGEST"/>
<parm name="AAUTHSECRET" value="password1"/>
<parm name="AAUTHDATA" value="B64encodedBinaryNonceInsertedHere"/>
</characteristic>
<characteristic type="APPAUTH">
<parm name="AAUTHLEVEL" value="APPSRV"/>
<parm name="AAUTHTYPE" value="BASIC"/>
<parm name="AAUTHNAME" value="testclient"/>
<parm name="AAUTHSECRET" value="password2"/>
</characteristic>
</characteristic>
<characteristic type="DMClient"> <!-- In Windows 10, an enrollment server should use DMClient CSP XML to configure DM polling schedules. -->
<characteristic type="Provider">
<!-- ProviderID in DMClient CSP must match to PROVIDER-ID in w7 APPLICATION characteristics -->
<characteristic type="TestMDMServer">
<parm name="UPN" value="UserPrincipalName@contoso.com" datatype="string" />
<characteristic type="Poll">
<parm name="NumberOfFirstRetries" value="8" datatype="integer" />
<parm name="IntervalForFirstSetOfRetries" value="15" datatype="integer" />
<parm name="NumberOfSecondRetries" value="5" datatype="integer" />
<parm name="IntervalForSecondSetOfRetries" value="3" datatype="integer" />
<parm name="NumberOfRemainingScheduledRetries" value="0" datatype="integer" />
<!-- Windows 10 supports MDM push for real-time communication. The DM client long term polling schedules retry waiting interval should be more than 24 hours (1440) to reduce the impact to data consumption and battery life. Refer to the DMClient Configuration Service Provider section for information about polling schedule parameters.-->
<parm name="IntervalForRemainingScheduledRetries" value="1560" datatype="integer" />
<parm name="PollOnLogin" value="true" datatype="boolean" />
</characteristic>
<parm name="EntDeviceName" value="Administrator_Windows" datatype="string" />
</characteristic>
</characteristic>
</characteristic>
<!-- For Windows 10, we removed EnterpriseAppManagement from the enrollment
protocol. -->
</wap-provisioningdoc>
Loading…
Cancel
Save