diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/PluginConstants.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/PluginConstants.java index b399420af2..b7aead9d84 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/PluginConstants.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/common/PluginConstants.java @@ -31,6 +31,8 @@ public final class PluginConstants { "org.wso2.carbon.device.mgt.mobile.windows.api.services.wstep.CertificateEnrollmentService"; public static final String CERTIFICATE_ENROLLMENT_POLICY_SERVICE_ENDPOINT = "org.wso2.carbon.device.mgt.mobile.windows.api.services.xcep.CertificateEnrollmentPolicyService"; + public static final String ENROLLMENT_SERVICE_ENDPOINT = + "org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.EnrollmentService"; //Services' target namespaces public static final String DISCOVERY_SERVICE_TARGET_NAMESPACE = @@ -81,10 +83,8 @@ public final class PluginConstants { "/ENROLLMENTSERVER/PolicyEnrollmentWebservice.svc"; public static final String CERTIFICATE_ENROLLMENT_SERVICE_URL = "/ENROLLMENTSERVER/DeviceEnrollmentWebservice.svc"; - public static final String ONPREMISE_CERTIFICATE_ENROLLMENT_POLICY = - "/ENROLLMENTSERVER/ONPREMISE/PolicyEnrollmentWebservice.svc"; - public static final String ONPREMISE_CERTIFICATE_ENROLLMENT_SERVICE_URL = - "/ENROLLMENTSERVER/ONPREMISE/DeviceEnrollmentWebservice.svc"; + public static final String ENROLLMENT_SERVICE_URL = + "/ENROLLMENTSERVER/Win10DeviceEnrollmentWebservice.svc"; public static final String WAB_URL = "/windows-web-agent/enrollments/windows/login-agent"; } @@ -153,6 +153,8 @@ public final class PluginConstants { public static final int DOMAIN_POSITION = 7; public static final String ENROLL_SUBDOMAIN = "https://EnterpriseEnrollment."; public static final String SYNCML_PROVISIONING_SERVICE_URL = "/Syncml/initialquery"; + public static final String ENROLLMENT_DISPOSITION_MESSAGE = "http://schemas.microsoft.com/windows/pki/" + + "2009/01/enrollment"; } /** @@ -189,7 +191,7 @@ public final class PluginConstants { public static final int MODEL_POSITION = 5; public static final int MAC_ADDRESS_POSITION = 7; public static final int RESOLUTION_POSITION = 8; - public static final int DEVICE_NAME_POSITION = 9; + public static final int DEVICE_NAME_POSITION = 10; public static final String SYNCML_DATA_ONE = "1"; public static final String SYNCML_DATA_ZERO = "0"; public static final String OS_VERSION = "OS_VERSION"; @@ -289,7 +291,6 @@ public final class PluginConstants { public static final String DEFAULT_AUTH_POLICY = "Federated"; } - /** * Policy Configuration related constants. */ @@ -311,4 +312,32 @@ public final class PluginConstants { public static final String MAX_CONNECTION_PER_HOST = "MaxConnectionsPerHost"; public static final String MAX_TOTAL_CONNECTIONS = "MaxTotalConnections"; } + + /** + * Windows version related constants. + */ + public final class WindowsVersionProperties { + private WindowsVersionProperties() { + throw new AssertionError(); + } + + public static final String REQUESTED_WIN10_VERSION = "3.0"; + public static final String REQUESTED_WIN81_VERSION = "2.0"; + } + + /** + * Windows enrollment property constants. + */ + + public final class WindowsEnrollmentProperties { + private WindowsEnrollmentProperties() { + throw new AssertionError(); + } + + public static final int WIN_DEVICE_ID = 12; + public static final int WIN_DEVICE_NAME = 2; + public static final int WIN_DEVICE_VERSION = 15; + public static final int WIN_DEVICE_IMEI = 3; + + } } diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryRequest.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryRequest.java index d397e3b57a..2c8260fb9c 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryRequest.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryRequest.java @@ -18,14 +18,12 @@ package org.wso2.carbon.device.mgt.mobile.windows.api.services.discovery.beans; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.*; import java.io.Serializable; +import java.util.List; @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "DiscoveryRequest") +@XmlType(name = "DiscoveryRequest", namespace = "http://schemas.microsoft.com/windows/management/2012/01/enrollment") @SuppressWarnings("unused") public class DiscoveryRequest implements Serializable { @@ -38,18 +36,28 @@ public class DiscoveryRequest implements Serializable { @XmlElement(name = "DeviceType") private String deviceType; + @XmlElement(name = "OSEdition") + private String osEdition; + + @XmlElement(name = "ApplicationVersion") + private String applicationVersion; + + @XmlElementWrapper(name = "AuthPolicies") + @XmlElement(name = "AuthPolicy", required = true) + private List authenticationPolicies; + public String getEmailId() { return emailId; } - public String getVersion() { - return version; - } - public void setEmailId(String emailId) { this.emailId = emailId; } + public String getVersion() { + return version; + } + public void setVersion(String version) { this.version = version; } @@ -61,4 +69,21 @@ public class DiscoveryRequest implements Serializable { public void setDeviceType(String deviceType) { this.deviceType = deviceType; } + + public List getAuthenticationPolicies() { + return authenticationPolicies; + } + + public void setAuthenticationPolicies(List authenticationPolicies) { + this.authenticationPolicies = authenticationPolicies; + } + + public String getOsEdition() { + return osEdition; + } + + public void setOsEdition(String osEdition) { + this.osEdition = osEdition; + } + } \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryResponse.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryResponse.java index 7bfea5d379..10a124b06a 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryResponse.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/beans/DiscoveryResponse.java @@ -41,6 +41,9 @@ public class DiscoveryResponse implements Serializable { @XmlElement(name = "AuthenticationServiceUrl") private String authenticationServiceUrl; + @XmlElement(name = "EnrollmentVersion") + private String enrollmentVersion; + public void setAuthenticationServiceUrl(String authenticationServiceUrl) { this.authenticationServiceUrl = authenticationServiceUrl; } @@ -73,4 +76,12 @@ public class DiscoveryResponse implements Serializable { this.enrollmentServiceUrl = enrollmentServiceUrl; } + public String getEnrollmentVersion() { + return enrollmentVersion; + } + + public void setEnrollmentVersion(String enrollmentVersion) { + this.enrollmentVersion = enrollmentVersion; + } + } \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/impl/DiscoveryServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/impl/DiscoveryServiceImpl.java index 7d08082a47..6b7d57fac6 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/impl/DiscoveryServiceImpl.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/discovery/impl/DiscoveryServiceImpl.java @@ -68,18 +68,32 @@ public class DiscoveryServiceImpl implements DiscoveryService { String emailId = discoveryRequest.getEmailId(); String[] userDomains = emailId.split(DELIMITER); String domain = userDomains[DOMAIN_SEGMENT]; + DiscoveryResponse discoveryResponse; + if (PluginConstants.WindowsVersionProperties.REQUESTED_WIN10_VERSION.equals(discoveryRequest.getVersion()) && + FEDERATED.equals(getAuthPolicy())) { + discoveryResponse = new DiscoveryResponse(); - DiscoveryResponse discoveryResponse = new DiscoveryResponse(); - if (FEDERATED.equals(getAuthPolicy())) { discoveryResponse.setAuthPolicy(FEDERATED); + discoveryResponse.setEnrollmentVersion(PluginConstants.WindowsVersionProperties.REQUESTED_WIN10_VERSION); discoveryResponse.setEnrollmentPolicyServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + - domain + PluginConstants.Discovery. + domain + PluginConstants.Discovery. CERTIFICATE_ENROLLMENT_POLICY_SERVICE_URL); discoveryResponse.setEnrollmentServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + - domain + PluginConstants.Discovery. + domain + PluginConstants.Discovery. + ENROLLMENT_SERVICE_URL); + discoveryResponse.setAuthenticationServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + + domain + PluginConstants.Discovery.WAB_URL); + } else { + discoveryResponse = new DiscoveryResponse(); + discoveryResponse.setAuthPolicy(FEDERATED); + discoveryResponse.setEnrollmentPolicyServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + + domain + PluginConstants.Discovery. + CERTIFICATE_ENROLLMENT_POLICY_SERVICE_URL); + discoveryResponse.setEnrollmentServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + + domain + PluginConstants.Discovery. CERTIFICATE_ENROLLMENT_SERVICE_URL); discoveryResponse.setAuthenticationServiceUrl(PluginConstants.Discovery.DEVICE_ENROLLMENT_SUBDOMAIN + - domain + PluginConstants.Discovery.WAB_URL); + domain + PluginConstants.Discovery.WAB_URL); } response.value = discoveryResponse; if (log.isDebugEnabled()) { diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/EnrollmentService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/EnrollmentService.java new file mode 100644 index 0000000000..b81647afc0 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/EnrollmentService.java @@ -0,0 +1,43 @@ +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.AdditionalContext; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestSecurityTokenResponse; + +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebService; +import javax.xml.ws.BindingType; +import javax.xml.ws.RequestWrapper; +import javax.xml.ws.ResponseWrapper; +import javax.xml.ws.soap.SOAPBinding; +import java.io.UnsupportedEncodingException; + +@WebService(targetNamespace = PluginConstants.DEVICE_ENROLLMENT_SERVICE_TARGET_NAMESPACE, name = "enrollment") +@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) +public interface EnrollmentService { + + @RequestWrapper(localName = "RequestSecurityToken", targetNamespace = PluginConstants + .WS_TRUST_TARGET_NAMESPACE) + @WebMethod(operationName = "RequestSecurityToken") + @ResponseWrapper(localName = "RequestSecurityTokenResponseCollection", targetNamespace = + PluginConstants.WS_TRUST_TARGET_NAMESPACE) + void requestSecurityToken( + @WebParam(name = "TokenType", targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + String tokenType, + @WebParam(name = "RequestType", targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + String requestType, + @WebParam(name = "BinarySecurityToken", targetNamespace = PluginConstants + .WS_SECURITY_TARGET_NAMESPACE) + String binarySecurityToken, + @WebParam(name = "AdditionalContext", targetNamespace = PluginConstants + .SOAP_AUTHORIZATION_TARGET_NAMESPACE) + AdditionalContext additionalContext, + @WebParam(mode = WebParam.Mode.OUT, name = "RequestSecurityTokenResponse", + targetNamespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + javax.xml.ws.Holder response) throws + WindowsDeviceEnrolmentException, UnsupportedEncodingException, + WAPProvisioningException; +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/AdditionalContext.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/AdditionalContext.java new file mode 100644 index 0000000000..fd62ef2caf --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/AdditionalContext.java @@ -0,0 +1,48 @@ +/* + * 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.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.ArrayList; +import java.util.List; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "OIDCollection", namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE, + propOrder = {"contextitem"}) +@SuppressWarnings("unused") +public class AdditionalContext { + + @XmlElement(name = "ContextItem", required = true, + namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) + + protected List contextitem; + + public List getcontextitem() { + if (contextitem == null) { + contextitem = new ArrayList(); + } + return this.contextitem; + } +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/BinarySecurityToken.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/BinarySecurityToken.java new file mode 100644 index 0000000000..cf3d3bd5f7 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/BinarySecurityToken.java @@ -0,0 +1,63 @@ +/* + * 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.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.*; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "BinarySecurityToken", namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE, + propOrder = {"ValueType", "EncodingType"}) +@SuppressWarnings("unused") +public class BinarySecurityToken { + + @XmlAttribute(name = "ValueType") + protected String ValueType; + @XmlAttribute(name = "EncodingType") + protected String EncodingType; + @XmlValue + protected String Token; + + public void setValueType(String valuetype) { + this.ValueType = valuetype; + } + + public String getValueType() { + return this.ValueType; + } + + public void setEncodingType(String encodingtype) { + this.EncodingType = encodingtype; + } + + public String getEncodingType() { + return this.EncodingType; + } + + public void setToken(String token) { + this.Token = token; + } + + public String getToken() { + return this.Token; + } + +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/ContextItem.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/ContextItem.java new file mode 100644 index 0000000000..bbbdbd09c0 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/ContextItem.java @@ -0,0 +1,54 @@ +/* + * 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.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ContextItem", namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE, + propOrder = {"Name" , "Value"}) +public class ContextItem { + + @XmlElement(required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) + protected String Name; + @XmlElement(required = true, namespace = PluginConstants.SOAP_AUTHORIZATION_TARGET_NAMESPACE) + protected String Value; + + public String getValue() { + return Value; + } + + public void setValue(String value) { + Value = value; + } + + public String getName() { + return Name; + } + + public void setName(String name) { + Name = name; + } + +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityToken.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityToken.java new file mode 100644 index 0000000000..ebd90792dc --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityToken.java @@ -0,0 +1,42 @@ +/* + * 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.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "RequestedSecurityToken", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE, + propOrder = {"binarySecurityToken"}) +@SuppressWarnings("unused") +public class RequestSecurityToken { + + @XmlElement(name = "BinarySecurityToken", required = true, + namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE) + + protected BinarySecurityToken binarySecurityToken; + + public void setBinarySecurityToken(BinarySecurityToken binarysecuritytoken) { + this.binarySecurityToken = binarysecuritytoken; + } +} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityTokenResponse.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityTokenResponse.java new file mode 100644 index 0000000000..9f1b0c3c8a --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestSecurityTokenResponse.java @@ -0,0 +1,82 @@ +/* + * 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.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.io.Serializable; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "RequestSecurityTokenResponse", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE, + propOrder = {"TokenType", "DispositionMessage", "RequestedSecurityToken", "RequestID"}) +@SuppressWarnings("unused") +public class RequestSecurityTokenResponse implements Serializable { + + @XmlElement(name = "TokenType", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + private String TokenType; + + // Windows 10 property + @XmlElement(name = "DispositionMessage", namespace = PluginConstants.ENROLLMENT_POLICY_TARGET_NAMESPACE) + private String DispositionMessage; + + @XmlElement(name = "RequestedSecurityToken", required = true, + namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE) + private org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken RequestedSecurityToken; + + @XmlElement(name = "RequestID", namespace = PluginConstants.ENROLLMENT_POLICY_TARGET_NAMESPACE) + private int RequestID; + + public String getTokenType() { + return TokenType; + } + + public void setTokenType(String tokenType) { + TokenType = tokenType; + } + + public org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken getRequestedSecurityToken() { + return RequestedSecurityToken; + } + + public void setRequestedSecurityToken(org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.RequestedSecurityToken + requestedSecurityToken) { + RequestedSecurityToken = requestedSecurityToken; + } + + public int getRequestID() { + return RequestID; + } + + public void setRequestID(int requestID) { + RequestID = requestID; + } + + public String getDispositionMessage() { + return DispositionMessage; + } + + public void setDispositionMessage(String dispositionMessage) { + DispositionMessage = dispositionMessage; + } + +} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestedSecurityToken.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestedSecurityToken.java new file mode 100644 index 0000000000..56f1ec571f --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/RequestedSecurityToken.java @@ -0,0 +1,42 @@ +/* + * 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.enrollment.beans; + +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "RequestedSecurityToken", namespace = PluginConstants.WS_TRUST_TARGET_NAMESPACE, + propOrder = {"binarySecurityToken"}) +public class RequestedSecurityToken { + + @XmlElement(name = "BinarySecurityToken", required = true, + namespace = PluginConstants.WS_SECURITY_TARGET_NAMESPACE) + + protected BinarySecurityToken binarySecurityToken; + + public void setBinarySecurityToken(BinarySecurityToken binarysecuritytoken) { + this.binarySecurityToken = binarysecuritytoken; + } +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/package-info.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/package-info.java new file mode 100644 index 0000000000..3ad6ec1b26 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/beans/package-info.java @@ -0,0 +1,27 @@ +/* + * 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. + */ + +@XmlSchema(namespace = "http://www.w3.org/2003/05/soap-envelope", + xmlns = { + @XmlNs(prefix = "", namespaceURI = "http://www.w3.org/2003/05/soap-envelope") + }, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) + +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans; + +import javax.xml.bind.annotation.XmlNs; +import javax.xml.bind.annotation.XmlSchema; \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/impl/EnrollmentServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/impl/EnrollmentServiceImpl.java new file mode 100644 index 0000000000..170476ba83 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/impl/EnrollmentServiceImpl.java @@ -0,0 +1,394 @@ +package org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.impl; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.cxf.headers.Header; +import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.jaxws.context.WrappedMessageContext; +import org.apache.cxf.message.Message; +import org.w3c.dom.*; +import org.wso2.carbon.certificate.mgt.core.exception.KeystoreException; +import org.wso2.carbon.certificate.mgt.core.service.CertificateManagementServiceImpl; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceManagementConstants; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.configuration.mgt.ConfigurationEntry; +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.beans.Device; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.CertificateGenerationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.SyncmlMessageFormatException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WindowsDeviceEnrolmentException; +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.util.SyncmlCredentialUtil; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.EnrollmentService; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.beans.*; +import org.wso2.carbon.device.mgt.mobile.windows.api.services.syncml.beans.WindowsDevice; +import org.xml.sax.SAXException; + +import javax.annotation.Resource; +import javax.jws.WebService; +import javax.servlet.ServletContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.ws.BindingType; +import javax.xml.ws.Holder; +import javax.xml.ws.WebServiceContext; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.soap.Addressing; +import javax.xml.ws.soap.SOAPBinding; +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + + +/** + * Implementation class of CertificateEnrollmentService interface. This class implements MS-WSTEP + * protocol. + */ +@WebService(endpointInterface = PluginConstants.ENROLLMENT_SERVICE_ENDPOINT, + targetNamespace = PluginConstants.DEVICE_ENROLLMENT_SERVICE_TARGET_NAMESPACE) +@Addressing(enabled = true, required = true) +@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) +public class EnrollmentServiceImpl implements EnrollmentService { + private static Log log = LogFactory.getLog(EnrollmentServiceImpl.class); + private X509Certificate rootCACertificate; + private String pollingFrequency; + private String provisioningURL; + private String domain; + + @Resource + private WebServiceContext context; + + @Override + public void requestSecurityToken(String tokenType, String requestType, String binarySecurityToken, + AdditionalContext additionalContext, + Holder response) + throws WindowsDeviceEnrolmentException, UnsupportedEncodingException, WAPProvisioningException { + + String headerBinarySecurityToken = null; + String headerTo = null; + String encodedWap; + List
headers = getHeaders(); + WindowsDevice windowsDevice = new WindowsDevice(); + for (Header headerElement : headers != null ? headers : null) { + String nodeName = headerElement.getName().getLocalPart(); + if (PluginConstants.SECURITY.equals(nodeName)) { + Element element = (Element) headerElement.getObject(); + headerBinarySecurityToken = element.getFirstChild().getNextSibling().getFirstChild().getTextContent(); + } + if (PluginConstants.TO.equals(nodeName)) { + Element toElement = (Element) headerElement.getObject(); + headerTo = toElement.getFirstChild().getTextContent(); + } + } + windowsDevice.setDeviceType(DeviceManagementConstants.MobileDeviceTypes. + MOBILE_DEVICE_TYPE_WINDOWS); + windowsDevice.setUser(getRequestedUser(headerBinarySecurityToken)); + List contextItems = additionalContext.getcontextitem(); + for (int x= 0; x< contextItems.size(); x++) { + switch (x) { + case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_NAME: + windowsDevice.setDeviceName(contextItems.get(x).getValue()); + case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_IMEI: + windowsDevice.setImei(contextItems.get(x).getValue()); + case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_ID: + windowsDevice.setDeviceId(contextItems.get(x).getValue()); + case PluginConstants.WindowsEnrollmentProperties.WIN_DEVICE_VERSION: + windowsDevice.setOsVersion(contextItems.get(x).getValue()); + } + } + + ///////// + + org.wso2.carbon.device.mgt.common.Device device = generateDevice(windowsDevice); + try { + WindowsAPIUtils.getDeviceManagementService().enrollDevice(device); + } catch (DeviceManagementException e) { + e.printStackTrace(); + } + ///////// + String[] splitEmail = headerTo.split("(/ENROLLMENTSERVER)"); + String email = splitEmail[PluginConstants.CertificateEnrolment.EMAIL_SEGMENT]; + + String[] splitDomain = email.split("(EnterpriseEnrollment.)"); + domain = splitDomain[PluginConstants.CertificateEnrolment.DOMAIN_SEGMENT]; + provisioningURL = PluginConstants.CertificateEnrolment.ENROLL_SUBDOMAIN + domain + + PluginConstants.CertificateEnrolment.SYNCML_PROVISIONING_SERVICE_URL; + + List tenantConfigurations; + try { + if ((tenantConfigurations = WindowsAPIUtils.getTenantConfigurationData()) != null) { + for (ConfigurationEntry configurationEntry : tenantConfigurations) { + if ((PluginConstants.TenantConfigProperties.NOTIFIER_FREQUENCY.equals( + configurationEntry.getName()))) { + pollingFrequency = configurationEntry.getValue().toString(); + } else { + pollingFrequency = PluginConstants.TenantConfigProperties.DEFAULT_FREQUENCY; + } + } + } else { + pollingFrequency = PluginConstants.TenantConfigProperties.DEFAULT_FREQUENCY; + String msg = "Tenant configurations are not initialized yet."; + log.error(msg); + } + ServletContext ctx = (ServletContext) context.getMessageContext(). + get(MessageContext.SERVLET_CONTEXT); + File wapProvisioningFile = (File) ctx.getAttribute(PluginConstants.CONTEXT_WAP_PROVISIONING_FILE); + if (log.isDebugEnabled()) { + log.debug("Received CSR from Device:" + binarySecurityToken); + } + + String wapProvisioningFilePath = wapProvisioningFile.getPath(); + RequestSecurityTokenResponse requestSecurityTokenResponse = new RequestSecurityTokenResponse(); + requestSecurityTokenResponse.setTokenType(PluginConstants.CertificateEnrolment.TOKEN_TYPE); + + encodedWap = prepareWapProvisioningXML(binarySecurityToken, wapProvisioningFilePath, + headerBinarySecurityToken); + RequestedSecurityToken requestedSecurityToken = new RequestedSecurityToken(); + BinarySecurityToken binarySecToken = new BinarySecurityToken(); + binarySecToken.setValueType(PluginConstants.CertificateEnrolment.VALUE_TYPE); + binarySecToken.setEncodingType(PluginConstants.CertificateEnrolment.ENCODING_TYPE); + binarySecToken.setToken(encodedWap); + requestedSecurityToken.setBinarySecurityToken(binarySecToken); + requestSecurityTokenResponse.setRequestedSecurityToken(requestedSecurityToken); + requestSecurityTokenResponse.setRequestID(PluginConstants.CertificateEnrolment.REQUEST_ID); + response.value = requestSecurityTokenResponse; + } catch (CertificateGenerationException e) { + String msg = "Problem occurred while generating certificate."; + log.error(msg, e); + throw new WindowsDeviceEnrolmentException(msg, e); + } catch (WAPProvisioningException e) { + String msg = "Problem occurred while generating wap-provisioning file."; + log.error(msg, e); + throw new WindowsDeviceEnrolmentException(msg, e); + } catch (DeviceManagementException e) { + String msg = "Error occurred while getting tenant configurations."; + log.error(msg); + throw new WindowsDeviceEnrolmentException(msg, e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + + } + } + /** + * Method used to Convert the Document object into a String. + * + * @param document - Wap provisioning XML document + * @return - String representation of wap provisioning XML document + * @throws TransformerException + */ + private String convertDocumentToString(Document document) throws TransformerException { + DOMSource DOMSource = new DOMSource(document); + StringWriter stringWriter = new StringWriter(); + StreamResult streamResult = new StreamResult(stringWriter); + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.transform(DOMSource, streamResult); + + return stringWriter.toString(); + } + + /** + * This method prepares the wap-provisioning file by including relevant certificates etc. + * + * @param binarySecurityToken - CSR from device + * @param wapProvisioningFilePath - File path of wap-provisioning file + * @return - base64 encoded final wap-provisioning file as a String + * @throws CertificateGenerationException + * @throws org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException + */ + private String prepareWapProvisioningXML(String binarySecurityToken, String wapProvisioningFilePath, + String headerBst) throws CertificateGenerationException, + WAPProvisioningException, + WindowsDeviceEnrolmentException { + String rootCertEncodedString; + String signedCertEncodedString; + X509Certificate signedCertificate; + String provisioningXmlString; + + CertificateManagementServiceImpl certMgtServiceImpl = CertificateManagementServiceImpl.getInstance(); + Base64 base64Encoder = new Base64(); + try { + rootCACertificate = (X509Certificate) certMgtServiceImpl.getCACertificate(); + rootCertEncodedString = base64Encoder.encodeAsString(rootCACertificate.getEncoded()); + + + signedCertificate = certMgtServiceImpl.getSignedCertificateFromCSR(binarySecurityToken); + signedCertEncodedString = base64Encoder.encodeAsString(signedCertificate.getEncoded()); + + DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + + builder = domFactory.newDocumentBuilder(); + Document document = builder.parse(wapProvisioningFilePath); + NodeList wapParm = document.getElementsByTagName(PluginConstants.CertificateEnrolment.PARM); + Node caCertificatePosition = wapParm.item(PluginConstants.CertificateEnrolment.CA_CERTIFICATE_POSITION); + + //Adding SHA1 CA certificate finger print to wap-provisioning xml. + caCertificatePosition.getParentNode().getAttributes().getNamedItem(PluginConstants. + CertificateEnrolment.TYPE).setTextContent(String.valueOf( + DigestUtils.sha1Hex(rootCACertificate.getEncoded())).toUpperCase()); + //Adding encoded CA certificate to wap-provisioning file after removing new line + // characters. + NamedNodeMap rootCertAttributes = caCertificatePosition.getAttributes(); + Node rootCertNode = + rootCertAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + rootCertEncodedString = rootCertEncodedString.replaceAll("\n", ""); + rootCertNode.setTextContent(rootCertEncodedString); + + if (log.isDebugEnabled()) { + log.debug("Root certificate: " + rootCertEncodedString); + } + + Node signedCertificatePosition = wapParm.item(PluginConstants.CertificateEnrolment. + SIGNED_CERTIFICATE_POSITION); + + //Adding SHA1 signed certificate finger print to wap-provisioning xml. + signedCertificatePosition.getParentNode().getAttributes().getNamedItem(PluginConstants. + CertificateEnrolment.TYPE).setTextContent(String.valueOf( + DigestUtils.sha1Hex(signedCertificate.getEncoded())).toUpperCase()); + + //Adding encoded signed certificate to wap-provisioning file after removing new line + // characters. + NamedNodeMap clientCertAttributes = signedCertificatePosition.getAttributes(); + Node clientEncodedNode = + clientCertAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + signedCertEncodedString = signedCertEncodedString.replaceAll("\n", ""); + + clientEncodedNode.setTextContent(signedCertEncodedString); + if (log.isDebugEnabled()) { + log.debug("Signed certificate: " + signedCertEncodedString); + } + + //Adding domainName to wap-provisioning xml. + Node domainPosition = wapParm.item(PluginConstants.CertificateEnrolment.DOMAIN_POSITION); + NamedNodeMap domainAttribute = domainPosition.getAttributes(); + Node domainNode = domainAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + domainNode.setTextContent(domain); + + //Adding Next provisioning service URL to wap-provisioning xml. + Node syncmlServicePosition = wapParm.item(PluginConstants.CertificateEnrolment. + SYNCML_PROVISIONING_ADDR_POSITION); + NamedNodeMap syncmlServiceAttribute = syncmlServicePosition.getAttributes(); + Node syncmlServiceNode = syncmlServiceAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + syncmlServiceNode.setTextContent(provisioningURL); + + // Adding user name auth token to wap-provisioning xml. + Node userNameAuthPosition = wapParm.item(PluginConstants.CertificateEnrolment.APPAUTH_USERNAME_POSITION); + NamedNodeMap appServerAttribute = userNameAuthPosition.getAttributes(); + Node authNameNode = appServerAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + String userName = getRequestedUser(headerBst); + //CacheEntry cacheEntry = (CacheEntry) DeviceUtil.getCacheEntry(headerBst); + // String userName = cacheEntry.getUsername(); + authNameNode.setTextContent(userName); + DeviceUtil.removeToken(headerBst); + String password = DeviceUtil.generateRandomToken(); + Node passwordAuthPosition = wapParm.item(PluginConstants.CertificateEnrolment.APPAUTH_PASSWORD_POSITION); + NamedNodeMap appSrvPasswordAttribute = passwordAuthPosition.getAttributes(); + Node authPasswordNode = appSrvPasswordAttribute.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + authPasswordNode.setTextContent(password); + String requestSecurityTokenResponse = SyncmlCredentialUtil.generateRST(userName, password); + DeviceUtil.persistChallengeToken(requestSecurityTokenResponse, null, userName); + + // Get device polling frequency from the tenant Configurations. + Node numberOfFirstRetries = wapParm.item(PluginConstants.CertificateEnrolment.POLLING_FREQUENCY_POSITION); + NamedNodeMap pollingAttributes = numberOfFirstRetries.getAttributes(); + Node pollValue = pollingAttributes.getNamedItem(PluginConstants.CertificateEnrolment.VALUE); + pollValue.setTextContent(pollingFrequency); + provisioningXmlString = convertDocumentToString(document); + + } catch (ParserConfigurationException e) { + throw new WAPProvisioningException("Problem occurred while creating configuration request", e); + } catch (CertificateEncodingException e) { + throw new WindowsDeviceEnrolmentException("Error occurred while encoding certificates.", e); + } catch (SAXException e) { + throw new WAPProvisioningException("Error occurred while parsing wap-provisioning.xml file.", e); + } catch (TransformerException e) { + throw new WAPProvisioningException("Error occurred while transforming wap-provisioning.xml file.", e); + } catch (IOException e) { + throw new WAPProvisioningException("Error occurred while getting wap-provisioning.xml file.", e); + } catch (SyncmlMessageFormatException e) { + throw new WindowsDeviceEnrolmentException("Error occurred while generating password hash value.", e); + } catch (KeystoreException e) { + throw new CertificateGenerationException("CA certificate cannot be generated.", e); + } + return base64Encoder.encodeAsString(provisioningXmlString.getBytes()); + } + + /** + * This method get the soap request header contents. + * + * @return List of SOAP headers. + */ + private List
getHeaders() { + MessageContext messageContext = context.getMessageContext(); + if (messageContext == null || !(messageContext instanceof WrappedMessageContext)) { + return null; + } + Message message = ((WrappedMessageContext) messageContext).getWrappedMessage(); + return CastUtils.cast((List) message.get(Header.HEADER_LIST)); + } + + private String getRequestedUser(String bst) { + CacheEntry cacheEntry = (CacheEntry) DeviceUtil.getCacheEntry(bst); + String userName = cacheEntry.getUsername(); + return userName; + } + + private org.wso2.carbon.device.mgt.common.Device generateDevice(WindowsDevice windowsDevice) { + + org.wso2.carbon.device.mgt.common.Device generatedDevice = new org.wso2.carbon.device.mgt.common.Device(); + + org.wso2.carbon.device.mgt.common.Device.Property DeviceNameProperty = new org.wso2.carbon.device.mgt.common.Device.Property(); + DeviceNameProperty.setName(PluginConstants.SyncML.DEVICE_NAME); + DeviceNameProperty.setValue(windowsDevice.getDeviceName()); + + org.wso2.carbon.device.mgt.common.Device.Property OSVersionProperty = new org.wso2.carbon.device.mgt.common.Device.Property(); + OSVersionProperty.setName(PluginConstants.SyncML.OS_VERSION); + OSVersionProperty.setValue(windowsDevice.getOsVersion()); + + org.wso2.carbon.device.mgt.common.Device.Property IMSEIProperty = new org.wso2.carbon.device.mgt.common.Device.Property(); + IMSEIProperty.setName(PluginConstants.SyncML.IMSI); + IMSEIProperty.setValue(windowsDevice.getImsi()); + + org.wso2.carbon.device.mgt.common.Device.Property IMEIProperty = new org.wso2.carbon.device.mgt.common.Device.Property(); + IMEIProperty.setName(PluginConstants.SyncML.IMEI); + IMEIProperty.setValue(windowsDevice.getImei()); + + List propertyList = new ArrayList<>(); + propertyList.add(OSVersionProperty); + propertyList.add(IMSEIProperty); + propertyList.add(IMEIProperty); + propertyList.add(DeviceNameProperty); + + EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); + enrolmentInfo.setOwner(windowsDevice.getUser()); + enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD); + enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE); + + generatedDevice.setEnrolmentInfo(enrolmentInfo); + generatedDevice.setDeviceIdentifier(windowsDevice.getDeviceId()); + generatedDevice.setProperties(propertyList); + generatedDevice.setType(windowsDevice.getDeviceType()); + + return generatedDevice; + } +} + diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/CertificateSigningService.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/CertificateSigningService.java new file mode 100644 index 0000000000..e4eeaf6658 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/CertificateSigningService.java @@ -0,0 +1,141 @@ +/* + * 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.enrollment.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.bouncycastle.asn1.x509.*; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.X509v3CertificateBuilder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.CertificateGenerationException; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.WAPProvisioningException; + +import javax.security.auth.x500.X500Principal; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.List; + +/** + * Class for generating signed certificate for CSR form device. + */ +public class CertificateSigningService { + + private static final long MILLI_SECONDS = 1000L * 60 * 60 * 24; + + private enum PropertyIndex { + COMMON_NAME_INDEX(0), + NOT_BEFORE_DAYS_INDEX(1), + NOT_AFTER_DAYS_INDEX(2); + + private final int itemPosition; + private PropertyIndex(final int itemPosition) { + this.itemPosition = itemPosition; + } + public int getValue() { + return this.itemPosition; + } + } + + private static Log log = LogFactory.getLog( + CertificateSigningService.class); + + /** + * Implement certificate signing task using CSR received from the device and the MDM server key + * store. + * @param jcaRequest - CSR from the device + * @param privateKey - Private key of CA certificate in MDM server + * @param caCert - CA certificate in MDM server + * @param certParameterList - Parameter list for Signed certificate generation + * @return - Signed certificate for CSR from device + * @throws CertificateGenerationException + * @throws WAPProvisioningException + */ + public static X509Certificate signCSR(JcaPKCS10CertificationRequest jcaRequest, + PrivateKey privateKey, X509Certificate caCert, + List certParameterList) throws + CertificateGenerationException, + WAPProvisioningException { + + String commonName = + (String) certParameterList.get(PropertyIndex.COMMON_NAME_INDEX.getValue()); + int notBeforeDays = + (Integer) certParameterList.get(PropertyIndex.NOT_BEFORE_DAYS_INDEX.getValue()); + int notAfterDays = + (Integer) certParameterList.get(PropertyIndex.NOT_AFTER_DAYS_INDEX.getValue()); + X509v3CertificateBuilder certificateBuilder; + X509Certificate signedCertificate; + + try { + ContentSigner signer; + BigInteger serialNumber = BigInteger.valueOf(new SecureRandom(). + nextInt(Integer.MAX_VALUE)); + Date notBeforeDate = new Date(System.currentTimeMillis() - + (MILLI_SECONDS * notBeforeDays)); + Date notAfterDate = new Date(System.currentTimeMillis() + + (MILLI_SECONDS * notAfterDays)); + certificateBuilder = + new JcaX509v3CertificateBuilder(caCert, serialNumber, notBeforeDate, notAfterDate, + new X500Principal(commonName), + jcaRequest.getPublicKey()); + + //Adding extensions to the signed certificate. + certificateBuilder.addExtension(Extension.keyUsage, true, + new KeyUsage(KeyUsage.digitalSignature)); + certificateBuilder.addExtension(Extension.extendedKeyUsage, false, + new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth)); + certificateBuilder.addExtension(Extension.basicConstraints, true, + new BasicConstraints(false)); + + signer = new JcaContentSignerBuilder(PluginConstants.CertificateEnrolment.ALGORITHM). + setProvider(PluginConstants.CertificateEnrolment.PROVIDER).build(privateKey); + + signedCertificate = new JcaX509CertificateConverter().setProvider( + PluginConstants.CertificateEnrolment.PROVIDER).getCertificate( + certificateBuilder.build(signer)); + } catch (InvalidKeyException e) { + throw new CertificateGenerationException("CSR's public key is invalid", e); + } catch (NoSuchAlgorithmException e) { + throw new CertificateGenerationException("Certificate cannot be generated", e); + } + catch (CertIOException e) { + throw new CertificateGenerationException( + "Cannot add extension(s) to signed certificate", e); + } + catch (OperatorCreationException e) { + throw new CertificateGenerationException("Content signer cannot be created", e); + } + catch (CertificateException e) { + throw new CertificateGenerationException("Signed certificate cannot be generated", e); + } + return signedCertificate; + } +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/KeyStoreGenerator.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/KeyStoreGenerator.java new file mode 100644 index 0000000000..ba966f80e9 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/KeyStoreGenerator.java @@ -0,0 +1,94 @@ +/* + * 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.enrollment.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.exceptions.KeyStoreGenerationException; + +import java.io.FileInputStream; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; + +/** + * Class for MDM Keystore operations. + */ +public class KeyStoreGenerator { + + private static final Log log = LogFactory.getLog( + KeyStoreGenerator.class); + + /** + * This method loads the MDM keystore. + * @param keyStore - MDM Keystore + * @param keyStorePassword - Keystore Password + * @param keyStorePath - Keystore path + * @throws KeyStoreGenerationException + */ + public static void loadToStore(KeyStore keyStore, + char[] keyStorePassword, + String keyStorePath) throws KeyStoreGenerationException { + + FileInputStream fileInputStream = null; + + try { + if (keyStorePath != null) { + fileInputStream = new FileInputStream(keyStorePath); + keyStore.load(fileInputStream, keyStorePassword); + } + } catch (NoSuchAlgorithmException e) { + throw new KeyStoreGenerationException( + "Requested cryptographic algorithm is not available in the environment.", e); + } catch (CertificateException e) { + throw new KeyStoreGenerationException("Error working with certificate related to, " + + keyStorePath, e); + } catch (IOException e) { + throw new KeyStoreGenerationException("File error while working with file, " + + keyStorePath, e); + } finally { + try { + if (fileInputStream != null) { + fileInputStream.close(); + } + } catch (IOException e) { + throw new KeyStoreGenerationException("File error while closing the file, " + + keyStorePath, e); + } + } + } + + /** + * This method is for retrieving instance of Key Store. + * @return Keystore object + * @throws KeyStoreGenerationException + */ + public static KeyStore getKeyStore() throws KeyStoreGenerationException { + try { + return KeyStore.getInstance(PluginConstants.CertificateEnrolment.JKS); + } catch (KeyStoreException e) { + String msg = "KeyStore error while creating new JKS."; + log.error(msg, e); + throw new KeyStoreGenerationException(msg, e); + } + } +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/MessageHandler.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/MessageHandler.java new file mode 100644 index 0000000000..616e3db084 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/enrollment/util/MessageHandler.java @@ -0,0 +1,200 @@ +/* + * 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.enrollment.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; +import org.wso2.carbon.device.mgt.mobile.windows.api.common.PluginConstants; + +import javax.ws.rs.core.Response; +import javax.xml.namespace.QName; +import javax.xml.soap.*; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPHandler; +import javax.xml.ws.handler.soap.SOAPMessageContext; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.*; + +/** + * Class responsible for adding Timestamp security header in SOAP message and adding Content-length + * in the HTTP header for avoiding HTTP chunking. + */ +public class MessageHandler implements SOAPHandler { + + public static final String TIME_ZONE = "Z"; + public static final int VALIDITY_TIME = 5; + public static final int TIMESTAMP_END_INDEX = 6; + public static final int TIMESTAMP_BEGIN_INDEX = 0; + private static Log log = LogFactory.getLog( + MessageHandler.class); + + /** + * This method resolves the security header coming in the SOAP message. + * @return - Security Header + */ + @Override + public Set getHeaders() { + QName securityHeader = new QName(PluginConstants.WS_SECURITY_TARGET_NAMESPACE, PluginConstants.SECURITY); + HashSet headers = new HashSet(); + headers.add(securityHeader); + return headers; + } + + /** + * This method adds Timestamp for SOAP header, and adds Content-length for HTTP header for + * avoiding HTTP chunking. + * + * @param context - Context of the SOAP Message + */ + @Override + public boolean handleMessage(SOAPMessageContext context) { + + Boolean outBoundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); + + if (outBoundProperty) { + SOAPMessage message = context.getMessage(); + SOAPHeader header = null; + SOAPEnvelope envelope = null; + try { + header = message.getSOAPHeader(); + envelope = message.getSOAPPart().getEnvelope(); + } catch (SOAPException e) { + Response.serverError().entity("SOAP message content cannot be read.").build(); + } + try { + if ((header == null) && (envelope != null)) { + header = envelope.addHeader(); + } + } catch (SOAPException e) { + Response.serverError().entity("SOAP header cannot be added.").build(); + } + + SOAPFactory soapFactory = null; + try { + soapFactory = SOAPFactory.newInstance(); + } catch (SOAPException e) { + Response.serverError().entity("Cannot get an instance of SOAP factory.").build(); + } + + QName qNamesSecurity = new QName(PluginConstants.WS_SECURITY_TARGET_NAMESPACE, + PluginConstants.CertificateEnrolment.SECURITY); + SOAPHeaderElement Security = null; + Name attributeName = null; + try { + if (header != null) { + Security = header.addHeaderElement(qNamesSecurity); + } + if (soapFactory != null) { + attributeName = + soapFactory.createName(PluginConstants.CertificateEnrolment.TIMESTAMP_ID, + PluginConstants.CertificateEnrolment.TIMESTAMP_U, + PluginConstants.CertificateEnrolment + .WSS_SECURITY_UTILITY); + } + } catch (SOAPException e) { + Response.serverError().entity("Security header cannot be added.").build(); + } + + QName qNameTimestamp = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY, + PluginConstants.CertificateEnrolment.TIMESTAMP); + SOAPHeaderElement timestamp = null; + try { + if (header != null) { + timestamp = header.addHeaderElement(qNameTimestamp); + timestamp.addAttribute(attributeName, + PluginConstants.CertificateEnrolment.TIMESTAMP_0); + } + } catch (SOAPException e) { + Response.serverError().entity("Exception while adding timestamp header.").build(); + } + DateTime dateTime = new DateTime(); + DateTime expiredDateTime = dateTime.plusMinutes(VALIDITY_TIME); + String createdISOTime = dateTime.toString(ISODateTimeFormat.dateTime()); + String expiredISOTime = expiredDateTime.toString(ISODateTimeFormat.dateTime()); + createdISOTime = createdISOTime.substring(TIMESTAMP_BEGIN_INDEX, + createdISOTime.length() - + TIMESTAMP_END_INDEX); + createdISOTime = createdISOTime + TIME_ZONE; + expiredISOTime = expiredISOTime.substring(TIMESTAMP_BEGIN_INDEX, + expiredISOTime.length() - + TIMESTAMP_END_INDEX); + expiredISOTime = expiredISOTime + TIME_ZONE; + QName qNameCreated = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY, + PluginConstants.CertificateEnrolment.CREATED); + SOAPHeaderElement SOAPHeaderCreated = null; + + try { + if (header != null) { + SOAPHeaderCreated = header.addHeaderElement(qNameCreated); + SOAPHeaderCreated.addTextNode(createdISOTime); + } + } catch (SOAPException e) { + Response.serverError().entity("Exception while creating SOAP header.").build(); + } + QName qNameExpires = new QName(PluginConstants.CertificateEnrolment.WSS_SECURITY_UTILITY, + PluginConstants.CertificateEnrolment.EXPIRES); + SOAPHeaderElement SOAPHeaderExpires = null; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + String messageString = null; + try { + if (header != null) { + SOAPHeaderExpires = header.addHeaderElement(qNameExpires); + SOAPHeaderExpires.addTextNode(expiredISOTime); + } + if ((timestamp != null) && (Security != null)) { + timestamp.addChildElement(SOAPHeaderCreated); + timestamp.addChildElement(SOAPHeaderExpires); + Security.addChildElement(timestamp); + } + message.saveChanges(); + message.writeTo(outputStream); + messageString = new String(outputStream.toByteArray(), + PluginConstants.CertificateEnrolment.UTF_8); + } catch (SOAPException e) { + Response.serverError().entity("Exception while creating timestamp SOAP header.") + .build(); + } catch (IOException e) { + Response.serverError().entity("Exception while writing message to output stream.") + .build(); + } + + Map> headers = + (Map>) context.get(MessageContext.HTTP_REQUEST_HEADERS); + headers = new HashMap>(); + if (messageString != null) { + headers.put(PluginConstants.CONTENT_LENGTH, Arrays.asList(String.valueOf( + messageString.length()))); + } + context.put(MessageContext.HTTP_REQUEST_HEADERS, headers); + } + return true; + } + + @Override + public boolean handleFault(SOAPMessageContext context) { + return true; + } + + @Override + public void close(MessageContext context) { + } +} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/beans/WindowsDevice.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/beans/WindowsDevice.java index c531a45df7..272b7875ab 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/beans/WindowsDevice.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/beans/WindowsDevice.java @@ -31,6 +31,7 @@ public class WindowsDevice { private String manufacturer; private String model; private String user; + private String deviceName; public String getImei() { return imei; @@ -96,5 +97,13 @@ public class WindowsDevice { this.user = user; } + public String getDeviceName() { + return deviceName; + } + + public void setDeviceName(String deviceName) { + this.deviceName = deviceName; + } + } diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/impl/SyncmlServiceImpl.java b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/impl/SyncmlServiceImpl.java index e431d9c96a..f74fa8a52c 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/impl/SyncmlServiceImpl.java +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/java/org/wso2/carbon/device/mgt/mobile/windows/api/services/syncml/impl/SyncmlServiceImpl.java @@ -320,19 +320,14 @@ public class SyncmlServiceImpl implements SyncmlService { macAddressProperty.setValue(macAddress); existingProperties.add(macAddressProperty); -// Device.Property resolutionProperty = new Device.Property(); -// resolutionProperty.setName(PluginConstants.SyncML.DEVICE_INFO); -// resolutionProperty.setValue("null"); -// existingProperties.add(resolutionProperty); - Device.Property deviceNameProperty = new Device.Property(); deviceNameProperty.setName(PluginConstants.SyncML.DEVICE_NAME); deviceNameProperty.setValue(deviceName); existingProperties.add(deviceNameProperty); Device.Property deviceModelProperty = new Device.Property(); - deviceNameProperty.setName(PluginConstants.SyncML.MODEL); - deviceNameProperty.setValue(devMod); + deviceModelProperty.setName(PluginConstants.SyncML.MODEL); + deviceModelProperty.setValue(devMod); existingProperties.add(deviceModelProperty); existingDevice.setProperties(existingProperties); diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/cxf-servlet.xml b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/cxf-servlet.xml index 2d54d092b8..ed97a22bd6 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/cxf-servlet.xml +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -59,24 +59,27 @@ - + + id="CertificateEnrollmentService" + implementor="org.wso2.carbon.device.mgt.mobile.windows.api.services.wstep.impl.CertificateEnrollmentServiceImpl" + address="/deviceenrolment/wstep"> - + - + + + + - + + id="EnrollmentService" + implementor="org.wso2.carbon.device.mgt.mobile.windows.api.services.enrollment.impl.EnrollmentServiceImpl" + address="/deviceenrolment/enrollment"> diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/web.xml b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/web.xml index 8087d45a03..1a04409b5e 100644 --- a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/web.xml +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.api/src/main/webapp/WEB-INF/web.xml @@ -67,6 +67,7 @@ nonSecuredEndPoints /services/discovery/get,/services/discovery/post,/services/certificatepolicy/xcep, - ,/services/deviceenrolment/wstep,/services/syncml/devicemanagement/request + ,/services/deviceenrolment/wstep,/services/syncml/devicemanagement/request,/services/deviceenrolment/enrollment + \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.hbs b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.hbs new file mode 100644 index 0000000000..2a59b70243 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.hbs @@ -0,0 +1,127 @@ +{{! + 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. +}} +{{#if control_operations}} +
+ + {{#each control_operations}} + + {{#if iconFont}} + + {{else}} + {{#if icon}} + + {{else}} + + {{/if}} + {{/if}} + {{name}} + + +
+
+
+
+

+ + + + + {{name}} +
+

+

+ {{description}} +
+

+ +
+ {{#each params.0.pathParams}} + +
+ {{/each}} + {{#each params.0.formParams}} + +
+ {{/each}} + {{#each params.0.queryParams}} + +
+ {{/each}} + + + +
+
+
+
+
+ {{/each}} +
+{{else}} +
+

+ Operations Loading Failed!

+
+{{/if}} + + + +{{#zone "bottomJs"}} + {{js "js/operation-bar.js"}} +{{/zone}} diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.js b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.js new file mode 100644 index 0000000000..153b66b966 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.js @@ -0,0 +1,67 @@ +/* + * 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. + */ + +function onRequest(context) { + var log = new Log("operation.js"); + var operationModule = require("/app/modules/business-controllers/operation.js")["operationModule"]; + var device = context.unit.params.device; + var autoCompleteParams = context.unit.params.autoCompleteParams; + var encodedFeaturePayloads=context.unit.params.encodedFeaturePayloads; + var controlOperations = operationModule.getControlOperations(device.type); + var queryParams = []; + var formParams = []; + var pathParams = []; + for (var i = 0; i < controlOperations.length; i++) { + var currentParamList = controlOperations[i]["params"]; + for (var j = 0; j < currentParamList.length; j++) { + var currentParam = currentParamList[j]; + currentParamList[j]["formParams"] = processParams(currentParam["formParams"], autoCompleteParams); + currentParamList[j]["queryParams"] = processParams(currentParam["queryParams"], autoCompleteParams); + currentParamList[j]["pathParams"] = processParams(currentParam["pathParams"], autoCompleteParams); + } + controlOperations[i]["params"] = currentParamList; + if (encodedFeaturePayloads) { + controlOperations[i]["payload"] = getPayload(encodedFeaturePayloads, controlOperations[i]["operation"]); + } + } + return {"control_operations": controlOperations, "device": device}; +} + +function processParams(paramsList, autoCompleteParams) { + var log = new Log(); + log.info("-- Params : "+paramsList.length); + log.info("-- Auto Params : "+autoCompleteParams); + for (var i = 0; i < paramsList.length; i++) { + var paramName = paramsList[i]; + var paramValue = ""; + var paramType = "text"; + for (var k = 0; k < autoCompleteParams.length; k++) { + if (paramName == autoCompleteParams[k].name) { + paramValue = autoCompleteParams[k].value; + paramType = "hidden"; + } + } + paramsList[i] = {"name": paramName, "value": paramValue, "type": paramType}; + } + return paramsList; +} + +function getPayload(featuresPayload, featureCode){ + var featuresJSONPayloads = JSON.parse(featuresPayload); + return featuresJSONPayloads[featureCode]; +} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.json b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.json new file mode 100644 index 0000000000..688e939808 --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/operation-bar.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/public/js/operation-bar.js b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/public/js/operation-bar.js new file mode 100644 index 0000000000..ad893ec2ec --- /dev/null +++ b/components/mobile-plugins/windows-plugin/org.wso2.carbon.device.mgt.mobile.windows.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar/public/js/operation-bar.js @@ -0,0 +1,146 @@ +/* + * 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. + */ + +/* + * On operation click function. + * @param selection: Selected operation + */ +function operationSelect(selection) { + $(modalPopupContent).addClass("operation-data"); + $(modalPopupContent).html($(" .operation[data-operation-code=" + selection + "]").html()); + $(modalPopupContent).data("operation-code", selection); + showPopup(); +} + +function submitForm(formId) { + var form = $("#" + formId); + var uri = form.attr("action"); + var deviceId = form.data("device-id"); + var uriencodedQueryStr = ""; + var uriencodedFormStr = ""; + var payload = {}; + form.find("input").each(function () { + var input = $(this); + if (input.data("param-type") == "path") { + uri = uri.replace("{" + input.attr("id") + "}", input.val()); + } else if (input.data("param-type") == "query") { + var prefix = (uriencodedQueryStr == "") ? "?" : "&"; + uriencodedQueryStr += prefix + input.attr("id") + "=" + input.val(); + } else if (input.data("param-type") == "form") { + var prefix = (uriencodedFormStr == "") ? "" : "&"; + uriencodedFormStr += prefix + input.attr("id") + "=" + input.val(); + //payload[input.attr("id")] = input.val(); + } + }); + uri += uriencodedQueryStr; + var httpMethod = form.attr("method").toUpperCase(); + var contentType = form.attr("enctype"); + console.log("URL "+uri); + console.log("Method "+httpMethod); + console.log("Content Type "+contentType); + var featurePayload = form.attr("data-payload"); + if (featurePayload) { + contentType = "application/json"; + payload = JSON.parse(atob(featurePayload)); + + } else if (contentType == undefined || contentType.isEmpty()) { + contentType = "application/x-www-form-urlencoded"; + payload = uriencodedFormStr; + } + + //setting responses callbacks + var defaultStatusClasses = "fw fw-stack-1x"; + var content = $("#operation-response-template").find(".content"); + var title = content.find("#title"); + var statusIcon = content.find("#status-icon"); + var description = content.find("#description"); + description.html(""); + var successCallBack = function (response) { + var res = response; + try { + res = JSON.parse(response).messageFromServer; + } catch (err) { + //do nothing + } + title.html("Operation Triggered!"); + statusIcon.attr("class", defaultStatusClasses + " fw-check"); + description.html(res); + console.log("success!"); + $(modalPopupContent).html(content.html()); + }; + var errorCallBack = function (response) { + console.log(response); + title.html("An Error Occurred!"); + statusIcon.attr("class", defaultStatusClasses + " fw-error"); + var reason = (response.responseText == "null")?response.statusText:response.responseText; + try { + reason = JSON.parse(reason).message; + } catch (err) { + //do nothing + } + description.html(reason); + console.log("Error!"); + $(modalPopupContent).html(content.html()); + }; + //executing http request + if (httpMethod == "GET") { + invokerUtil.get(uri, successCallBack, errorCallBack, contentType); + } else if (httpMethod == "POST") { + console.log("------ cType "+contentType); + var payloadTest = [deviceId]; + invokerUtil.post(uri, payloadTest, successCallBack, errorCallBack, "application/json"); + } else if (httpMethod == "PUT") { + invokerUtil.put(uri, payload, successCallBack, errorCallBack, contentType); + } else if (httpMethod == "DELETE") { + invokerUtil.delete(uri, successCallBack, errorCallBack, contentType); + } else { + title.html("An Error Occurred!"); + statusIcon.attr("class", defaultStatusClasses + " fw-error"); + description.html("This operation requires http method: " + httpMethod + " which is not supported yet!"); + $(modalPopupContent).html(content.html()); + } +} + +$(document).on('submit', 'form', function (e) { + cosole.log("darn!!"); + e.preventDefault(); + var postOperationRequest = $.ajax({ + url: $(this).attr("action") + '&' + $(this).serialize(), + method: "post" + }); + + var btnSubmit = $('#btnSend', this); + btnSubmit.addClass('hidden'); + + var lblSending = $('#lblSending', this); + lblSending.removeClass('hidden'); + + var lblSent = $('#lblSent', this); + postOperationRequest.done(function (data) { + lblSending.addClass('hidden'); + lblSent.removeClass('hidden'); + setTimeout(function () { + hidePopup(); + }, 3000); + }); + + postOperationRequest.fail(function (jqXHR, textStatus) { + lblSending.addClass('hidden'); + lblSent.addClass('hidden'); + }); +}); \ No newline at end of file diff --git a/features/mobile-plugins-feature/windows-plugin-feature/org.wso2.carbon.device.mgt.mobile.windows.feature/src/main/resources/p2.inf b/features/mobile-plugins-feature/windows-plugin-feature/org.wso2.carbon.device.mgt.mobile.windows.feature/src/main/resources/p2.inf index 915cd258eb..2888d1ef14 100644 --- a/features/mobile-plugins-feature/windows-plugin-feature/org.wso2.carbon.device.mgt.mobile.windows.feature/src/main/resources/p2.inf +++ b/features/mobile-plugins-feature/windows-plugin-feature/org.wso2.carbon.device.mgt.mobile.windows.feature/src/main/resources/p2.inf @@ -22,6 +22,7 @@ org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../dep org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.type-view);\ org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.leaflet);\ org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-bar);\ +org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.new.operation-bar);\ org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.operation-mod);\ org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../deployment/server/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.windows.date-range-picker);\ org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/../../../dbscripts/cdm/plugins/windows);\