public OPCUAServer()

in plc4j/tools/opcua-server/src/main/java/org/apache/plc4x/java/opcuaserver/OPCUAServer.java [214:372]


    public OPCUAServer(String[] args) throws Exception {

        readCommandLineArgs(args);

        File securityTempDir = new File(config.getDir(), "security");
        if (!securityTempDir.exists() && !securityTempDir.mkdirs()) {
            logger.error("Unable to create directory please confirm folder permissions on " + securityTempDir);
            System.exit(1);
        }
        logger.info("Security Directory is: {}", securityTempDir.getAbsolutePath()); //

        File pkiDir = FileSystems.getDefault().getPath(config.getDir()).resolve("pki").toFile();
        DefaultTrustListManager trustListManager = new DefaultTrustListManager(pkiDir);
        logger.info("Certificate directory is: {}, Please move certificates from the reject dir to the trusted directory to allow encrypted access", pkiDir.getAbsolutePath());

        DefaultServerCertificateValidator certificateValidator =  new DefaultServerCertificateValidator(trustListManager);

        UsernameIdentityValidator identityValidator = new UsernameIdentityValidator(
            true,
            authChallenge -> {
                boolean check = passwordConfig.checkPassword(authChallenge.getUsername(), authChallenge.getPassword());
                if (!check) {
                    logger.info("Invalid password for user:- " + authChallenge.getUsername());
                }
                return check;
            }
        );

        KeyStore keyStore = KeyStore.getInstance("PKCS12");

        File serverKeyStore = securityTempDir.toPath().resolve(certificateFileName).toFile();

        X509IdentityValidator x509IdentityValidator = new X509IdentityValidator(c -> true);

        CertificateKeyPair certificate = null;
        if (!serverKeyStore.exists()) {
            if (!cmd.hasOption("interactive")) {
                logger.info("Please re-run with the -i switch to setup the security certificate key store");
                System.exit(1);
            }
            certificate = CertificateGenerator.generateCertificate();
            logger.info("Creating new KeyStore at {}", serverKeyStore);
            keyStore.load(null, passwordConfig.getSecurityPassword().toCharArray());
            keyStore.setKeyEntry("plc4x-certificate-alias", certificate.getKeyPair().getPrivate(), passwordConfig.getSecurityPassword().toCharArray(), new X509Certificate[] { certificate.getCertificate() });
            keyStore.store(new FileOutputStream(serverKeyStore), passwordConfig.getSecurityPassword().toCharArray());
        } else {
            logger.info("Loading KeyStore at {}", serverKeyStore);
            keyStore.load(new FileInputStream(serverKeyStore), passwordConfig.getSecurityPassword().toCharArray());
            String alias = keyStore.aliases().nextElement();
            KeyPair kp = new KeyPair(keyStore.getCertificate(alias).getPublicKey(),
                (PrivateKey) keyStore.getKey(alias, passwordConfig.getSecurityPassword().toCharArray()));
            certificate = new CertificateKeyPair(kp,(X509Certificate) keyStore.getCertificate(alias));
        }

        String applicationUri = CertificateUtil
            .getSanUri(certificate.getCertificate())
            .orElseThrow(() -> new UaRuntimeException(
                StatusCodes.Bad_ConfigurationError,
                "certificate is missing the application URI"));

        Set<EndpointConfiguration> endpointConfigurations = new LinkedHashSet<>();

        String hostname = InetAddress.getLocalHost().getHostName();

        EndpointConfiguration.Builder builder = EndpointConfiguration.newBuilder()
            .setBindAddress("0.0.0.0")
            .setHostname(hostname)
            .setPath("/plc4x")
            .setCertificate(certificate.getCertificate())
            .setBindPort(config.getTcpPort())
            .setSecurityMode(MessageSecurityMode.None)
            .addTokenPolicies(
                USER_TOKEN_POLICY_ANONYMOUS,
                USER_TOKEN_POLICY_USERNAME,
                USER_TOKEN_POLICY_X509);

        endpointConfigurations.add(
            builder.copy()
                .setSecurityPolicy(SecurityPolicy.Basic256Sha256)
                .setSecurityMode(MessageSecurityMode.SignAndEncrypt)
                .build()
        );

        endpointConfigurations.add(
            builder.copy()
                .setHostname("127.0.0.1")
                .setSecurityPolicy(SecurityPolicy.Basic256Sha256)
                .setSecurityMode(MessageSecurityMode.SignAndEncrypt)
                .build()
        );

        EndpointConfiguration.Builder discoveryBuilder = builder.copy()
            .setPath("/discovery")
            .setSecurityPolicy(SecurityPolicy.None)
            .setSecurityMode(MessageSecurityMode.None);

        endpointConfigurations.add(discoveryBuilder.build());

        EndpointConfiguration.Builder discoveryLocalBuilder = builder.copy()
            .setPath("/discovery")
            .setHostname("127.0.0.1")
            .setSecurityPolicy(SecurityPolicy.None)
            .setSecurityMode(MessageSecurityMode.None);

        endpointConfigurations.add(discoveryLocalBuilder.build());

        EndpointConfiguration.Builder discoveryLocalPlc4xBuilder = builder.copy()
            .setPath("/plc4x/discovery")
            .setHostname("127.0.0.1")
            .setSecurityPolicy(SecurityPolicy.None)
            .setSecurityMode(MessageSecurityMode.None);

        endpointConfigurations.add(discoveryLocalPlc4xBuilder.build());

        if (!config.getDisableInsecureEndpoint()) {
            EndpointConfiguration.Builder noSecurityBuilder = builder.copy()
                .setSecurityPolicy(SecurityPolicy.None)
                .setTransportProfile(TransportProfile.TCP_UASC_UABINARY);
            endpointConfigurations.add(noSecurityBuilder.build());
        }

        //Always add an unsecured endpoint to localhost, this is a work around for Milo throwing an exception if it isn't here.
        EndpointConfiguration.Builder noSecurityBuilder = builder.copy()
            .setSecurityPolicy(SecurityPolicy.None)
            .setHostname("127.0.0.1")
            .setTransportProfile(TransportProfile.TCP_UASC_UABINARY)
            .setSecurityMode(MessageSecurityMode.None);
        endpointConfigurations.add(noSecurityBuilder.build());

        DefaultCertificateManager certificateManager = new DefaultCertificateManager(
            certificate.getKeyPair(),
            Arrays.stream(keyStore.getCertificateChain(keyStore.getCertificateAlias(certificate.getCertificate())))// Added so that existing certificates are loaded on startup
                .map(X509Certificate.class::cast)
                .toArray(X509Certificate[]::new)
        );

        OpcUaServerConfig serverConfig = OpcUaServerConfig.builder()
            .setApplicationUri(applicationUri)
            .setApplicationName(LocalizedText.english(applicationUri))
            .setEndpoints(endpointConfigurations)
            .setBuildInfo(
                new BuildInfo(
                    "urn:eclipse:milo:plc4x:server",
                    "org.apache.plc4x",
                    config.getName(),
                    OpcUaServer.SDK_VERSION,
                    "", DateTime.now()))
            .setCertificateManager(certificateManager)
            .setTrustListManager(trustListManager)
            .setCertificateValidator(certificateValidator)
            .setIdentityValidator(new CompositeValidator(identityValidator, x509IdentityValidator))
            .setProductUri("urn:eclipse:milo:plc4x:server")
            .build();

        server = new OpcUaServer(serverConfig);

        plc4xNamespace = new Plc4xNamespace(server, config);
        plc4xNamespace.startup();
    }