diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java index 346e20685f..3ffefc0f0f 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpNioSSLConnectionSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import java.security.GeneralSecurityException; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; import org.springframework.context.ApplicationEventPublisher; import org.springframework.util.Assert; @@ -31,15 +32,33 @@ import org.springframework.util.Assert; /** * Implementation of {@link TcpNioConnectionSupport} for SSL * NIO connections. + * * @author Gary Russell + * * @since 2.2 * */ public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupport implements TcpNioConnectionSupport { - private volatile SSLContext sslContext; + private final SSLContext sslContext; + private final boolean sslVerifyHost; + + /** + * Create an instance with host verification disabled. + * @param sslContextSupport the ssl context support. + */ public DefaultTcpNioSSLConnectionSupport(TcpSSLContextSupport sslContextSupport) { + this(sslContextSupport, false); + } + + /** + * Create an instance. + * @param sslContextSupport the ssl context support. + * @param sslVerifyHost true to verify the host during handshake. + * @since 5.0.8 + */ + public DefaultTcpNioSSLConnectionSupport(TcpSSLContextSupport sslContextSupport, boolean sslVerifyHost) { Assert.notNull(sslContextSupport, "TcpSSLContextSupport must not be null"); try { this.sslContext = sslContextSupport.getSSLContext(); @@ -48,6 +67,7 @@ public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupp throw new IllegalArgumentException("Invalid TcpSSLContextSupport - it failed to provide an SSLContext", e); } Assert.notNull(this.sslContext, "SSLContext retrieved from context support must not be null"); + this.sslVerifyHost = sslVerifyHost; } /** @@ -56,8 +76,19 @@ public class DefaultTcpNioSSLConnectionSupport extends AbstractTcpConnectionSupp @Override public TcpNioConnection createNewConnection(SocketChannel socketChannel, boolean server, boolean lookupHost, ApplicationEventPublisher applicationEventPublisher, String connectionFactoryName) throws Exception { + SSLEngine sslEngine = this.sslContext.createSSLEngine(); postProcessSSLEngine(sslEngine); + if (this.sslVerifyHost) { + SSLParameters sslParameters = sslEngine.getSSLParameters(); + if (sslParameters == null) { + sslParameters = new SSLParameters(); + } + // HTTPS works for any TCP connection. + // It checks SAN (Subject Alternative Name) as well as CN. + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslEngine.setSSLParameters(sslParameters); + } TcpNioSSLConnection tcpNioSSLConnection; if (isPushbackCapable()) { tcpNioSSLConnection = new PushBackTcpNioSSLConnection(socketChannel, server, lookupHost, diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java index bce4c44431..30cb1fbe0c 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSSLContextSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,12 +32,18 @@ import org.springframework.util.Assert; * Default implementation of {@link TcpSSLContextSupport}; uses a * 'TLS' (by default) {@link SSLContext}, initialized with 'JKS' * keystores, managed by 'SunX509' Key and Trust managers. + * * @author Gary Russell + * * @since 2.1 * */ public class DefaultTcpSSLContextSupport implements TcpSSLContextSupport { + private static final String DEFAULT_KEY_STORE_TYPE = "JKS"; + + private static final String DEFAULT_TRUST_STORE_TYPE = "JKS"; + private final Resource keyStore; private final Resource trustStore; @@ -46,7 +52,11 @@ public class DefaultTcpSSLContextSupport implements TcpSSLContextSupport { private final char[] trustStorePassword; - private volatile String protocol = "TLS"; + private String protocol = "TLS"; + + private String keyStoreType = DEFAULT_KEY_STORE_TYPE; + + private String trustStoreType = DEFAULT_TRUST_STORE_TYPE; /** * Prepares for the creation of an SSLContext using the supplied @@ -69,9 +79,30 @@ public class DefaultTcpSSLContextSupport implements TcpSSLContextSupport { this.trustStorePassword = trustStorePassword.toCharArray(); } - public SSLContext getSSLContext() throws GeneralSecurityException, IOException { - KeyStore ks = KeyStore.getInstance("JKS"); - KeyStore ts = KeyStore.getInstance("JKS"); + /** + * Set the key store type. Default JKS. + * @param keyStoreType the type. + * @since 5.0.8 + */ + public void setKeyStoreType(String keyStoreType) { + Assert.hasText(keyStoreType, "'keyStoreType' cannot be empty"); + this.keyStoreType = keyStoreType; + } + + /** + * Set the trust store type. Default JKS. + * @param trustStoreType the type. + * @since 5.0.8 + */ + public void setTrustStoreType(String trustStoreType) { + Assert.hasText(trustStoreType, "'trustStoreType' cannot be empty"); + this.trustStoreType = trustStoreType; + } + + @Override + public SSLContext getSSLContext() throws GeneralSecurityException, IOException { + KeyStore ks = KeyStore.getInstance(this.keyStoreType); + KeyStore ts = KeyStore.getInstance(this.trustStoreType); ks.load(this.keyStore.getInputStream(), this.keyStorePassword); ts.load(this.trustStore.getInputStream(), this.trustStorePassword); diff --git a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java index a4712a751e..06760eca66 100644 --- a/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java +++ b/spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/DefaultTcpSocketSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,25 +19,61 @@ package org.springframework.integration.ip.tcp.connection; import java.net.ServerSocket; import java.net.Socket; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSocket; + /** * Default implementation of {@link TcpSocketSupport}; makes no * changes to sockets. + * * @author Gary Russell + * * @since 2.2 * */ public class DefaultTcpSocketSupport implements TcpSocketSupport { + private final boolean sslVerifyHost; + + /** + * Construct an instance with host verification disabled. + */ + public DefaultTcpSocketSupport() { + this(false); + } + + /** + * Construct an instance with the provided sslVerifyHost. + * @param sslVerifyHost true to verify host during SSL handshake. + * @since 5.0.8. + */ + public DefaultTcpSocketSupport(boolean sslVerifyHost) { + this.sslVerifyHost = sslVerifyHost; + } + /** * No-Op. */ + @Override public void postProcessServerSocket(ServerSocket serverSocket) { } /** - * No-Op. + * Enables host verification for SSL, if so configured. */ + @Override public void postProcessSocket(Socket socket) { + if (this.sslVerifyHost && socket instanceof SSLSocket) { + SSLSocket sslSocket = (SSLSocket) socket; + SSLParameters sslParameters = sslSocket.getSSLParameters(); + if (sslParameters == null) { + sslParameters = new SSLParameters(); + } + // HTTPS works for any TCP connection. + // It checks SAN (Subject Alternative Name) as well as CN. + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslSocket.setSSLParameters(sslParameters); + } } } diff --git a/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml b/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml index 7a38a45b42..993735276d 100644 --- a/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml +++ b/spring-integration-ip/src/test/java/org/springframework/integration/ip/config/ParserUnitTests-context.xml @@ -81,7 +81,9 @@ + class="org.springframework.integration.ip.tcp.connection.DefaultTcpNioSSLConnectionSupport"> + + - (RETURN if same as keystore password): + Enter key password for + (RETURN if same as keystore password): -$ keytool -list -v -keystore src/test/resources/test.ks -Enter keystore password: secret + $ keytool -list -v -keystore src/test/resources/test.ks + Enter keystore password: secret -Keystore type: JKS -Keystore provider: SUN + Keystore type: JKS + Keystore provider: SUN -Your keystore contains 1 entry + Your keystore contains 1 entry -Alias name: sitestcertkey -Creation date: Feb 25, 2012 -Entry type: PrivateKeyEntry -Certificate chain length: 1 -Certificate[1]: -Owner: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Issuer: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Serial number: 4f491902 -Valid from: Sat Feb 25 12:23:14 EST 2012 until: Mon Feb 01 12:23:14 EST 2112 -Certificate fingerprints: - MD5: 4F:A9:76:0E:A9:C0:A8:B7:26:E7:7E:C7:E8:22:1F:8B - SHA1: 88:AC:9E:4D:29:0D:3A:59:3B:73:95:4A:E1:BB:D0:22:89:37:64:4C - Signature algorithm name: SHA1withRSA - Version: 3 + Alias name: sitestcertkey + Creation date: Aug 29, 2018 + Entry type: PrivateKeyEntry + Certificate chain length: 1 + Certificate[1]: + Owner: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Issuer: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Serial number: 3f2ab6ef + Valid from: Wed Aug 29 14:58:27 EDT 2018 until: Fri Aug 05 14:58:27 EDT 2118 + Certificate fingerprints: + MD5: 74:14:93:3C:6E:7B:14:59:30:A3:90:C4:A2:AD:52:5E + SHA1: 12:BE:77:93:ED:C3:20:23:75:D7:D5:D9:FE:D9:5E:D1:D3:3E:E2:DC + SHA256: 6B:90:65:8D:AA:F6:F3:89:38:AE:92:8E:F0:83:26:17:DD:8A:2C:F6:7E:C5:39:F0:7E:DC:60:A3:6D:73:E1:7A + Signature algorithm name: SHA256withRSA + Subject Public Key Algorithm: 2048-bit RSA key + Version: 3 + + Extensions: + + #1: ObjectId: 2.5.29.17 Criticality=false + SubjectAlternativeName [ + DNSName: localhost + ] + + #2: ObjectId: 2.5.29.14 Criticality=false + SubjectKeyIdentifier [ + KeyIdentifier [ + 0000: 78 2D FA 48 D8 21 73 86 68 CE 77 B9 98 5A BA 0F x-.H.!s.h.w..Z.. + 0010: E2 FE CD 8C .... + ] + ] -******************************************* -******************************************* -$ keytool -export -alias sitestcertkey -keystore src/test/resources/test.ks -rfc -file src/test/resources/test.cer -Enter keystore password: -Certificate stored in file - -$ keytool -import -alias sitestcertkey -file src/test/resources/test.cer -keystore src/test/resources/test.truststore.ks -Enter keystore password: secret -Re-enter new password: secret -Owner: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Issuer: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Serial number: 4f491902 -Valid from: Sat Feb 25 12:23:14 EST 2012 until: Mon Feb 01 12:23:14 EST 2112 -Certificate fingerprints: - MD5: 4F:A9:76:0E:A9:C0:A8:B7:26:E7:7E:C7:E8:22:1F:8B - SHA1: 88:AC:9E:4D:29:0D:3A:59:3B:73:95:4A:E1:BB:D0:22:89:37:64:4C - Signature algorithm name: SHA1withRSA - Version: 3 -Trust this certificate? [no]: yes -Certificate was added to keystore - -$ keytool -list -v -keystore src/test/resources/test.truststore.ks -Enter keystore password: secret - -Keystore type: JKS -Keystore provider: SUN - -Your keystore contains 1 entry - -Alias name: sitestcertkey -Creation date: Feb 25, 2012 -Entry type: trustedCertEntry - -Owner: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Issuer: CN=Spring Integration, OU=SpringSource, O=VMware, L=Palo Alto, ST=CA, C=US -Serial number: 4f491902 -Valid from: Sat Feb 25 12:23:14 EST 2012 until: Mon Feb 01 12:23:14 EST 2112 -Certificate fingerprints: - MD5: 4F:A9:76:0E:A9:C0:A8:B7:26:E7:7E:C7:E8:22:1F:8B - SHA1: 88:AC:9E:4D:29:0D:3A:59:3B:73:95:4A:E1:BB:D0:22:89:37:64:4C - Signature algorithm name: SHA1withRSA - Version: 3 + ******************************************* + ******************************************* -******************************************* -******************************************* + $ keytool -export -alias sitestcertkey -keystore src/test/resources/test.ks -rfc -file src/test/resources/test.cer + Enter keystore password: + Certificate stored in file - */ + $ keytool -import -alias sitestcertkey -file src/test/resources/test.cer -keystore src/test/resources/test.truststore.ks + Enter keystore password: secret + Re-enter new password: secret + Owner: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Issuer: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Serial number: 3f2ab6ef + Valid from: Wed Aug 29 14:58:27 EDT 2018 until: Fri Aug 05 14:58:27 EDT 2118 + Certificate fingerprints: + MD5: 74:14:93:3C:6E:7B:14:59:30:A3:90:C4:A2:AD:52:5E + SHA1: 12:BE:77:93:ED:C3:20:23:75:D7:D5:D9:FE:D9:5E:D1:D3:3E:E2:DC + SHA256: 6B:90:65:8D:AA:F6:F3:89:38:AE:92:8E:F0:83:26:17:DD:8A:2C:F6:7E:C5:39:F0:7E:DC:60:A3:6D:73:E1:7A + Signature algorithm name: SHA256withRSA + Subject Public Key Algorithm: 2048-bit RSA key + Version: 3 + + Extensions: + + #1: ObjectId: 2.5.29.17 Criticality=false + SubjectAlternativeName [ + DNSName: localhost + ] + + #2: ObjectId: 2.5.29.14 Criticality=false + SubjectKeyIdentifier [ + KeyIdentifier [ + 0000: 78 2D FA 48 D8 21 73 86 68 CE 77 B9 98 5A BA 0F x-.H.!s.h.w..Z.. + 0010: E2 FE CD 8C .... + ] + ] + + Trust this certificate? [no]: yes + Certificate was added to keystore + + $ keytool -list -v -keystore src/test/resources/test.truststore.ks + Enter keystore password: secret + + Keystore type: JKS + Keystore provider: SUN + + Your keystore contains 1 entry + + Alias name: sitestcertkey + Creation date: Aug 29, 2018 + Entry type: trustedCertEntry + + Owner: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Issuer: CN=Spring Integration, OU=Spring, O=Pivotal Software Inc., L=San Francisco, ST=CA, C=US + Serial number: 3f2ab6ef + Valid from: Wed Aug 29 14:58:27 EDT 2018 until: Fri Aug 05 14:58:27 EDT 2118 + Certificate fingerprints: + MD5: 74:14:93:3C:6E:7B:14:59:30:A3:90:C4:A2:AD:52:5E + SHA1: 12:BE:77:93:ED:C3:20:23:75:D7:D5:D9:FE:D9:5E:D1:D3:3E:E2:DC + SHA256: 6B:90:65:8D:AA:F6:F3:89:38:AE:92:8E:F0:83:26:17:DD:8A:2C:F6:7E:C5:39:F0:7E:DC:60:A3:6D:73:E1:7A + Signature algorithm name: SHA256withRSA + Subject Public Key Algorithm: 2048-bit RSA key + Version: 3 + + Extensions: + + #1: ObjectId: 2.5.29.17 Criticality=false + SubjectAlternativeName [ + DNSName: localhost + ] + + #2: ObjectId: 2.5.29.14 Criticality=false + SubjectKeyIdentifier [ + KeyIdentifier [ + 0000: 78 2D FA 48 D8 21 73 86 68 CE 77 B9 98 5A BA 0F x-.H.!s.h.w..Z.. + 0010: E2 FE CD 8C .... + ] + ] + + + + ******************************************* + ******************************************* + */ @Test public void testNetClientAndServerSSL() throws Exception { System.setProperty("javax.net.debug", "all"); // SSL activity in the console @@ -299,6 +353,7 @@ Certificate fingerprints: TcpNetClientConnectionFactory client = new TcpNetClientConnectionFactory("localhost", server.getPort()); client.setTcpSocketFactorySupport(tcpSocketFactorySupport); + client.setTcpSocketSupport(new DefaultTcpSocketSupport(true)); client.start(); TcpConnection connection = client.getConnection(); @@ -402,7 +457,8 @@ Certificate fingerprints: client.setSslHandshakeTimeout(34); client.setTcpNioConnectionSupport(tcpNioConnectionSupport); client.registerListener(message -> false); - client.setApplicationEventPublisher(e -> { }); + client.setApplicationEventPublisher(e -> { + }); client.start(); TcpConnection connection = client.getConnection(); @@ -533,7 +589,8 @@ Certificate fingerprints: return false; }); client.setDeserializer(deserializer); - client.setApplicationEventPublisher(e -> { }); + client.setApplicationEventPublisher(e -> { + }); client.start(); TcpConnection connection = client.getConnection(); diff --git a/spring-integration-ip/src/test/resources/test.cer b/spring-integration-ip/src/test/resources/test.cer index e46e6ae864..faebc34c6b 100644 --- a/spring-integration-ip/src/test/resources/test.cer +++ b/spring-integration-ip/src/test/resources/test.cer @@ -1,13 +1,22 @@ -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/spring-integration-ip/src/test/resources/test.ks b/spring-integration-ip/src/test/resources/test.ks index 243b3d0244..235a45c499 100644 Binary files a/spring-integration-ip/src/test/resources/test.ks and b/spring-integration-ip/src/test/resources/test.ks differ diff --git a/spring-integration-ip/src/test/resources/test.truststore.ks b/spring-integration-ip/src/test/resources/test.truststore.ks index 24ead4bc6d..f60c4cd5c4 100644 Binary files a/spring-integration-ip/src/test/resources/test.truststore.ks and b/spring-integration-ip/src/test/resources/test.truststore.ks differ diff --git a/src/reference/asciidoc/ip.adoc b/src/reference/asciidoc/ip.adoc index ac714e46f6..400199ffcc 100644 --- a/src/reference/asciidoc/ip.adoc +++ b/src/reference/asciidoc/ip.adoc @@ -655,7 +655,7 @@ For both inbound and outbound, if the adapter is started, you may force the adap The inbound TCP gateway `TcpInboundGateway` and outbound TCP gateway `TcpOutboundGateway` use a server and client connection factory respectively. Each connection can process a single request/response at a time. -The inbound gateway, after constructing a message with the incoming payload and sending it to the requestChannel, waits for a response and sends the payload from the response message by writing it to the connection. +The inbound gateway, after constructing a message with the incoming payload and sending it to the `requestChannel`, waits for a response and sends the payload from the response message by writing it to the connection. NOTE: For the inbound gateway, care must be taken to retain, or populate, the _ip_connectionId_ header because it is used to correlate the message to a connection. Messages that originate at the gateway will automatically have the header set. @@ -1014,6 +1014,45 @@ The keystore file names (first two constructor arguments) use the Spring `Resour Starting with _version 4.3.6_, when using NIO, you can specify an `ssl-handshake-timeout` (seconds) on the connection factory. This timeout (default 30) is used during SSL handshake when waiting for data; if the timeout is exceeded, the process is aborted and the socket closed. +[[tcp-ssl-host-verification]] +==== Host Verification + +Starting with version 5.0.8, you can configure whether or not to enable host verification. +Starting with version 5.1, it will be enabled by default; before that version, the mechanism to enable it depends on whether or not you are using NIO. + +Host verification is used to ensure the server you are connected to matches information in the certificate, even if the certificate is trusted. + +When using NIO, configure the `DefaultTcpNioSSLConnectionSupport`, for example. + +==== +[source, java] +---- +@Bean +public DefaultTcpNioSSLConnectionSupport connectionSupport() { + DefaultTcpSSLContextSupport sslContextSupport = new DefaultTcpSSLContextSupport("test.ks", + "test.truststore.ks", "secret", "secret"); + sslContextSupport.setProtocol("SSL"); + DefaultTcpNioSSLConnectionSupport tcpNioConnectionSupport = + new DefaultTcpNioSSLConnectionSupport(sslContextSupport, true); + return tcpNioConnectionSupport; +} +---- +==== + +The second constructor argument enables host verification. +The `connectionSupport` bean is then injected into the NIO connection factory. + +When not using NIO, the configuration is in the `TcpSocketSupport`: + +==== +[source, java] +---- +connectionFactory.setTcpSocketSupport(new DefaultTcpSocketSupport(true)); +---- +==== + +Again, the constructor argument enables host verification. + [[tcp-advanced-techniques]] === Advanced Techniques diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc index fe0a8b848c..e879a115f0 100644 --- a/src/reference/asciidoc/whats-new.adoc +++ b/src/reference/asciidoc/whats-new.adoc @@ -314,6 +314,14 @@ See <> for more information. IMPORTANT: Changes were made to the Micrometer `Meters` in _version 5.0.3_ to make them more suitable for use in dimensional systems. Further changes were made in 5.0.4; if using Micrometer, a minimum of version 5.0.4 is recommended. +[[x51.-tcp]] +=== TCP Support + +When using SSL, host verification can be configured, to prevent man-in-the-middle attacks with a trusted certificate. +See <> for more information. + +In addition the key and trust store types can now be configured on the `DefaultTcpSSLContextSupport`. + ==== @EndpointId Annotations @@ -325,4 +333,3 @@ See <> for more information. Starting with _version 5.0.5_, generated bean names for the components in an `IntegrationFlow` include the flow bean name, followed by a dot, as a prefix. See <> for more information. -