package at.acdp.opcur; /* * ======================================================================== Copyright (c) 2005-2015 * The OPC Foundation, Inc. All rights reserved. * * OPC Foundation MIT License 1.00 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * The complete license agreement can be found here: http://opcfoundation.org/License/MIT/1.00/ * ====================================================================== */ import org.apache.http.conn.ssl.SSLSocketFactory; import org.opcfoundation.ua.application.Application; import org.opcfoundation.ua.application.Server; import org.opcfoundation.ua.builtintypes.*; import org.opcfoundation.ua.common.ServiceFaultException; import org.opcfoundation.ua.common.ServiceResultException; import org.opcfoundation.ua.core.*; import org.opcfoundation.ua.transport.endpoint.EndpointServiceRequest; import org.opcfoundation.ua.transport.security.*; import org.opcfoundation.ua.utils.CryptoUtil; import org.opcfoundation.ua.utils.EndpointUtil; import org.opcfoundation.ua.application.Application; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.interfaces.RSAPrivateKey; import java.util.Random; import java.util.UUID; /** * Simple Server example. This server responds to stack test and endpoint discover service requests. * */ public class OPCTestPlain { static class MyAttributeServiceHandler implements AttributeServiceSetHandler { @Override public void onHistoryRead(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onHistoryUpdate(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onRead(EndpointServiceRequest req) throws ServiceFaultException { ReadRequest request = req.getRequest(); ReadValueId[] nodesToRead = request.getNodesToRead(); DataValue[] results = new DataValue[nodesToRead.length]; for (int i = 0; i < nodesToRead.length; i++) { if (Identifiers.RootFolder.equals(nodesToRead[i].getNodeId())) { if (Attributes.BrowseName.equals(nodesToRead[i].getAttributeId())) { results[i] = new DataValue(new Variant(new QualifiedName("Root"))); } else if (Attributes.DisplayName.equals(nodesToRead[i].getAttributeId())) { results[i] = new DataValue(new Variant(new LocalizedText("Root", LocalizedText.NO_LOCALE))); } else { results[i] = new DataValue(new StatusCode(StatusCodes.Bad_AttributeIdInvalid)); } } else { results[i] = new DataValue(new StatusCode(StatusCodes.Bad_NodeIdUnknown)); } } ReadResponse response = new ReadResponse(null, results, null); req.sendResponse(response); } @Override public void onWrite(EndpointServiceRequest req) throws ServiceFaultException { } }; static class MyNodeManagementServiceHandler implements NodeManagementServiceSetHandler { @Override public void onAddNodes(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onAddReferences(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onBrowse(EndpointServiceRequest req) throws ServiceFaultException { BrowseRequest request = req.getRequest(); BrowseResult[] Results = new BrowseResult[request.getNodesToBrowse().length]; for (int i = 0; i < request.getNodesToBrowse().length; i++) { StatusCode statusCode; if (Identifiers.RootFolder.equals(request.getNodesToBrowse()[i].getNodeId())) { statusCode = StatusCode.GOOD; } else { statusCode = new StatusCode(StatusCodes.Bad_NodeIdUnknown); } Results[i] = new BrowseResult(statusCode, null, null); } BrowseResponse response = new BrowseResponse(null, Results, null); req.sendResponse(response); } @Override public void onBrowseNext(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onDeleteNodes(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onDeleteReferences(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onQueryFirst(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onQueryNext(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onRegisterNodes(EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onTranslateBrowsePathsToNodeIds( EndpointServiceRequest req) throws ServiceFaultException { } @Override public void onUnregisterNodes(EndpointServiceRequest req) throws ServiceFaultException { } } static class MyServerExample extends Server implements SessionServiceSetHandler { public MyServerExample(Application application) throws Exception { super(application); addServiceHandler(this); // Add User Token Policies addUserTokenPolicy(UserTokenPolicy.ANONYMOUS); addUserTokenPolicy(UserTokenPolicy.SECURE_USERNAME_PASSWORD); // Create an endpoint for each network interface String hostname = EndpointUtil.getHostname(); String bindAddress, endpointAddress; for (String addr : EndpointUtil.getInetAddressNames()) { bindAddress = "http://" + addr + ":8443/UAExample"; endpointAddress = "http://" + hostname + ":8443/UAExample"; System.out.println(endpointAddress + " bound at " + bindAddress); // The HTTPS ports are using NONE OPC security bind(bindAddress, endpointAddress, SecurityMode.NONE); bindAddress = "opc.tcp://" + addr + ":8666/UAExample"; endpointAddress = "opc.tcp://" + hostname + ":8666/UAExample"; System.out.println(endpointAddress + " bound at " + bindAddress); bind(bindAddress, endpointAddress, SecurityMode.NONE); } ////////////////////////////////////// } @Override public void onActivateSession(EndpointServiceRequest msgExchange) throws ServiceFaultException { ActivateSessionResponse res = new ActivateSessionResponse(); res.setServerNonce(CryptoUtil.createNonce(32)); res.setResults(new StatusCode[] {StatusCode.GOOD}); msgExchange.sendResponse(res); } @Override public void onCancel(EndpointServiceRequest msgExchange) throws ServiceFaultException { } @Override public void onCloseSession(EndpointServiceRequest msgExchange) throws ServiceFaultException { CloseSessionResponse res = new CloseSessionResponse(); msgExchange.sendResponse(res); } @Override public void onCreateSession(EndpointServiceRequest msgExchange) throws ServiceFaultException { CreateSessionRequest req = msgExchange.getRequest(); CreateSessionResponse res = new CreateSessionResponse(); byte[] token = new byte[32]; byte[] nonce = new byte[32]; Random r = new Random(); r.nextBytes(nonce); r.nextBytes(token); res.setAuthenticationToken(new NodeId(0, token)); EndpointConfiguration endpointConfiguration = EndpointConfiguration.defaults(); res.setMaxRequestMessageSize(UnsignedInteger .valueOf(Math.max(endpointConfiguration.getMaxMessageSize(), req.getMaxResponseMessageSize().longValue()))); res.setRevisedSessionTimeout(Math.max(req.getRequestedSessionTimeout(), 60 * 1000)); KeyPair cert = getApplication().getApplicationInstanceCertificates()[0]; res.setServerCertificate(ByteString.valueOf(cert.getCertificate().getEncoded())); res.setServerEndpoints(this.getEndpointDescriptions()); res.setServerNonce(ByteString.valueOf(nonce)); ByteString clientCertificate = req.getClientCertificate(); ByteString clientNonce = req.getClientNonce(); SecurityPolicy securityPolicy = msgExchange.getChannel().getSecurityPolicy(); res.setServerSignature( getServerSignature(clientCertificate, clientNonce, securityPolicy, cert.getPrivateKey().getPrivateKey())); res.setServerSoftwareCertificates(getApplication().getSoftwareCertificates()); res.setSessionId(new NodeId(0, "Session-" + UUID.randomUUID())); msgExchange.sendResponse(res); } private SignatureData getServerSignature(ByteString clientCertificate, ByteString clientNonce, SecurityPolicy securityPolicy, final RSAPrivateKey privateKey) throws ServiceFaultException { if (clientCertificate != null) { ByteArrayOutputStream s = new ByteArrayOutputStream(); try { s.write(clientCertificate.getValue()); } catch (IOException e) { throw new ServiceFaultException(ServiceFault.createServiceFault(StatusCodes.Bad_SecurityChecksFailed)); } catch (Exception e) { throw new ServiceFaultException(ServiceFault.createServiceFault(StatusCodes.Bad_NonceInvalid)); } try { s.write(clientNonce.getValue()); } catch (IOException e) { throw new ServiceFaultException(ServiceFault.createServiceFault(StatusCodes.Bad_NonceInvalid)); } catch (Exception e) { throw new ServiceFaultException(ServiceFault.createServiceFault(StatusCodes.Bad_NonceInvalid)); } try { SecurityAlgorithm algorithm = securityPolicy.getAsymmetricSignatureAlgorithm(); return new SignatureData(algorithm.getUri(), ByteString.valueOf(CryptoUtil.getCryptoProvider().signAsymm(privateKey, algorithm, s.toByteArray()))); } catch (ServiceResultException e) { throw new ServiceFaultException(e); } } return null; } } public static void main(String[] args) throws Exception { CryptoUtil.setSecurityProviderName("SunJCE"); ////////////// SERVER ////////////// // Create UA Server Application // Create UA Service Server Application myServerApplication = new Application(); MyServerExample myServer = new MyServerExample(myServerApplication); myServer.addServiceHandler(new MyNodeManagementServiceHandler()); myServer.addServiceHandler(new MyAttributeServiceHandler()); ////////////////////////////////////// // Press enter to shutdown System.out.println("Press enter to shutdown"); System.in.read(); ////////////////////////////////////// ///////////// SHUTDOWN ///////////// // Close the server by unbinding all endpoints myServer.getApplication().close(); ////////////////////////////////////// } }