blob: 6e333ccf4513dea665f6f74483af285fc4ca26bd [file] [log] [blame]
// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2012-2014 Monty Program Ab
// Copyright (c) 2015-2021 MariaDB Corporation Ab
package org.mariadb.jdbc.integration;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLException;
import javax.security.auth.x500.X500Principal;
import javax.sql.PooledConnection;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.mariadb.jdbc.Connection;
import org.mariadb.jdbc.MariaDbPoolDataSource;
import org.mariadb.jdbc.Statement;
import org.mariadb.jdbc.client.tls.HostnameVerifier;
import org.slf4j.LoggerFactory;
public class LoggingTest extends Common {
@Test
void basicLogging() throws Exception {
Assumptions.assumeTrue(isMariaDBServer());
File tempFile = File.createTempFile("log", ".tmp");
Logger logger = (Logger) LoggerFactory.getLogger("org.mariadb.jdbc");
Level initialLevel = logger.getLevel();
logger.setLevel(Level.TRACE);
logger.setAdditive(false);
logger.detachAndStopAllAppenders();
LoggerContext context = new LoggerContext();
FileAppender<ILoggingEvent> fa = new FileAppender<>();
fa.setName("FILE");
fa.setImmediateFlush(true);
PatternLayoutEncoder pa = new PatternLayoutEncoder();
pa.setPattern("%r %5p %c [%t] - %m%n");
pa.setContext(context);
pa.start();
fa.setEncoder(pa);
fa.setFile(tempFile.getPath());
fa.setAppend(true);
fa.setContext(context);
fa.start();
logger.addAppender(fa);
try (Connection conn = createCon()) {
Statement stmt = conn.createStatement();
stmt.execute("SELECT 1");
}
try (Connection conn = createCon("useCompression=true")) {
Statement stmt = conn.createStatement();
stmt.execute("SELECT 1");
}
MariaDbPoolDataSource ds =
new MariaDbPoolDataSource(
mDefUrl + "&sessionVariables=wait_timeout=1&maxIdleTime=2&testMinRemovalDelay=2");
Thread.sleep(4000);
PooledConnection pc = ds.getPooledConnection();
pc.getConnection().isValid(1);
pc.close();
ds.close();
try {
String contents = new String(Files.readAllBytes(Paths.get(tempFile.getPath())));
String selectOne =
" +--------------------------------------------------+\n"
+ " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"
+ "+------+--------------------------------------------------+------------------+\n"
+ "|000000| 09 00 00 00 03 53 45 4C 45 43 54 20 31 | .....SELECT 1 |\n"
+ "+------+--------------------------------------------------+------------------+\n";
Assertions.assertTrue(
contents.contains(selectOne) || contents.contains(selectOne.replace("\r\n", "\n")),
contents);
String rowResult =
" +--------------------------------------------------+\n"
+ " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"
+ "+------+--------------------------------------------------+------------------+\n"
+ "|000000| 02 00 00 03 01 31 | .....1 |\n"
+ "+------+--------------------------------------------------+------------------+\n";
String rowResultWithEof =
" +--------------------------------------------------+\n"
+ " | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n"
+ "+------+--------------------------------------------------+------------------+\n"
+ "|000000| 02 00 00 04 01 31 | .....1 |\n"
+ "+------+--------------------------------------------------+------------------+\n";
Assertions.assertTrue(
contents.contains(rowResult)
|| contents.contains(rowResult.replace("\r\n", "\n"))
|| contents.contains(rowResultWithEof)
|| contents.contains(rowResultWithEof.replace("\r\n", "\n")),
contents);
Assertions.assertTrue(
contents.contains("pool MariaDB-pool new physical connection ")
&& contents.contains("created (total:1, active:0, pending:0)"),
contents);
Assertions.assertTrue(
contents.contains("pool MariaDB-pool connection ")
&& contents.contains("removed due to inactivity"),
contents);
} catch (IOException e) {
e.printStackTrace();
Assertions.fail();
} finally {
logger.setLevel(initialLevel);
logger.detachAppender(fa);
}
}
@Test
void certLogging() throws Exception {
File tempFile = File.createTempFile("log", ".tmp");
Logger logger = (Logger) LoggerFactory.getLogger("org.mariadb.jdbc");
Level initialLevel = logger.getLevel();
logger.setLevel(Level.TRACE);
logger.setAdditive(false);
logger.detachAndStopAllAppenders();
LoggerContext context = new LoggerContext();
FileAppender<ILoggingEvent> fa = new FileAppender<>();
fa.setName("FILE");
fa.setImmediateFlush(true);
PatternLayoutEncoder pa = new PatternLayoutEncoder();
pa.setPattern("%r %5p %c [%t] - %m%n");
pa.setContext(context);
pa.start();
fa.setEncoder(pa);
fa.setFile(tempFile.getPath());
fa.setAppend(true);
fa.setContext(context);
fa.start();
logger.addAppender(fa);
String certString =
""
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDfDCCAmSgAwIBAgIURZJQVOWv+oaj+MLlHWc1B0TnOaowDQYJKoZIhvcNAQEL\n"
+ "BQAwUjELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkdEMQswCQYDVQQHDAJTWjESMBAG\n"
+ "A1UECgwJQWNtZSxJbmMuMRUwEwYDVQQDDAxBY21lIFJvb3QgQ0EwIBcNMjEwMzMw\n"
+ "MDkwODAxWhgPMjEyMTAzMDYwOTA4MDFaMFMxCzAJBgNVBAYTAkNOMQswCQYDVQQI\n"
+ "DAJHRDELMAkGA1UEBwwCU1oxEjAQBgNVBAoMCUFjbWUsSW5jLjEWMBQGA1UEAwwN\n"
+ "Ki5tYXJpYWRiLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAJ\n"
+ "xqbqTGmwO5n3kVd6QJPRSh+0M1HIQacyM/tkE7jLw3725/KtknuwuFbPpxKyTCLC\n"
+ "IoNx4yaBbmx783OPP3pokXTWiMdrVZdLltBNamNzekNFN4YhR5oN479M5cKgrk94\n"
+ "Ud+ql0NN5FscrSQ0fSdJf0idJMqThro1MJVp9rp5cdCba6/lKyDbdOybe5f7rmrg\n"
+ "+37J+src67+rqwVT8ZwZgLTGDf4X9OSIzyw6+PCWYWr89aurrOuOyqA3QqXVRZa/\n"
+ "IxOMHIdzXMgLN6+HduwdZ+DNv1NPT2MDlRQvOnDop3NoEVKWekOTv50LbKRgWTYO\n"
+ "TK/dfcsDpZmdyHv7pb8CAwEAAaNHMEUwQwYDVR0RBDwwOoIVbG9jYWxob3N0Lmxv\n"
+ "Y2FsZG9tYWlugglsb2NhbGhvc3SHBH8AAAGHECABDbg5AjRoAAAAAAAABEMwDQYJ\n"
+ "KoZIhvcNAQELBQADggEBAHsiJz9cpmL8BTa/o10S+pmap3iOnYYuJT0llCRLJ+Ji\n"
+ "msO2niyIwqCJHMLcEABCENJt0HDOEKlnunVgc+X/6K8DnPrYhfWQbYI/dwUBoSIQ\n"
+ "siK/yKW0q+S+YjCVpNMA3iMfhJ9Qe9LDO+xdCBhzplgrV8YwG+J2FUNbZfvl5cML\n"
+ "TjKLWrWo9dgZyH/7mjwryRzswfUfr/lRARCyrMotaXfYmjPjwTSRc0aPGrEjs3ns\n"
+ "WMtimgh7Zw3Tbxc51miz9CRy767lq/9BGTdeBLmW0EXssIJb9uO0Ht3C/Pqy0ojk\n"
+ "8e1eYtofjTsqWHZ1s2LhtT0HvXdL6BnWP9GWc/zxiKM=\n"
+ "-----END CERTIFICATE-----\n";
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert =
(X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certString.getBytes()));
assertEquals(
new X500Principal("CN=*.mariadb.org, O=\"Acme,Inc.\", L=SZ, ST=GD, C=CN"),
cert.getSubjectX500Principal());
HostnameVerifier.verify("localhost", cert, -1);
HostnameVerifier.verify("localhost.localdomain", cert, -1);
verifyExceptionEqual(
"local.host",
cert,
"DNS host \"local.host\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+ " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
HostnameVerifier.verify("127.0.0.1", cert, -1);
verifyExceptionEqual(
"127.0.0.2",
cert,
"IPv4 host \"127.0.0.2\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+ " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
HostnameVerifier.verify("2001:db8:3902:3468:0:0:0:443", cert, -1);
verifyExceptionEqual(
"2001:db8:1::",
cert,
"IPv6 host \"2001:db8:1::\" doesn't correspond to certificate CN \"*.mariadb.org\" and"
+ " SAN[{DNS:\"localhost.localdomain\"},{DNS:\"localhost\"},{IP:\"127.0.0.1\"},{IP:\"2001:db8:3902:3468:0:0:0:443\"}]");
try {
String contents = new String(Files.readAllBytes(Paths.get(tempFile.getPath())));
assertTrue(
contents.contains(
"DNS verification of hostname : type=DNS value=localhost.localdomain to local.host"));
assertTrue(
contents.contains(
"IPv4 verification of hostname : type=IP value=127.0.0.1 to 127.0.0.2"));
assertTrue(
contents.contains(
"IPv6 verification of hostname : type=IP value=2001:db8:3902:3468:0:0:0:443 to"
+ " 2001:db8:1::"));
logger.setLevel(initialLevel);
logger.detachAppender(fa);
} catch (IOException e) {
e.printStackTrace();
Assertions.fail();
}
}
private void verifyExceptionEqual(String host, X509Certificate cert, String exceptionMessage) {
Exception e =
Assertions.assertThrows(SSLException.class, () -> HostnameVerifier.verify(host, cert, -1));
Assertions.assertTrue(
e.getMessage().contains(exceptionMessage), "real message:" + e.getMessage());
}
}