]> WPIA git - gigi.git/blob - tests/club/wpia/gigi/ping/TestTiming.java
chg: revoke certificates if repeated ping failed
[gigi.git] / tests / club / wpia / gigi / ping / TestTiming.java
1 package club.wpia.gigi.ping;
2
3 import static org.junit.Assert.*;
4 import static org.junit.Assume.*;
5
6 import java.io.IOException;
7 import java.security.GeneralSecurityException;
8 import java.security.KeyPair;
9 import java.util.Date;
10 import java.util.List;
11
12 import org.hamcrest.CoreMatchers;
13 import org.junit.Test;
14
15 import club.wpia.gigi.GigiApiException;
16 import club.wpia.gigi.dbObjects.Certificate;
17 import club.wpia.gigi.dbObjects.Certificate.CSRType;
18 import club.wpia.gigi.dbObjects.Certificate.CertificateStatus;
19 import club.wpia.gigi.dbObjects.Certificate.SANType;
20 import club.wpia.gigi.dbObjects.CertificateProfile;
21 import club.wpia.gigi.dbObjects.Digest;
22 import club.wpia.gigi.dbObjects.Domain;
23 import club.wpia.gigi.dbObjects.DomainPingConfiguration;
24 import club.wpia.gigi.dbObjects.DomainPingExecution;
25 import club.wpia.gigi.dbObjects.DomainPingType;
26 import club.wpia.gigi.ping.DomainPinger.PingState;
27 import club.wpia.gigi.testUtils.PingTest;
28 import club.wpia.gigi.testUtils.TestEmailReceiver.TestMail;
29 import club.wpia.gigi.util.RandomToken;
30 import club.wpia.gigi.util.SimpleSigner;
31
32 public class TestTiming extends PingTest {
33
34     @Test
35     public void httpAndMailSuccessCert() throws GigiApiException, IOException, InterruptedException, GeneralSecurityException {
36         httpAndMailSuccess(true, false);
37     }
38
39     @Test
40     public void httpAndMailSuccessCertAndCorrect() throws GigiApiException, IOException, InterruptedException, GeneralSecurityException {
41         httpAndMailSuccess(true, true);
42     }
43
44     @Test
45     public void httpAndMailSuccessNoCert() throws GigiApiException, IOException, InterruptedException, GeneralSecurityException {
46         httpAndMailSuccess(false, false);
47     }
48
49     public void httpAndMailSuccess(boolean certs, boolean correct) throws GigiApiException, IOException, InterruptedException, GeneralSecurityException {
50         String test = getTestProps().getProperty("domain.http");
51         assumeNotNull(test);
52
53         // When we have a domain.
54         Domain d = new Domain(u, u, test);
55         String token = RandomToken.generateToken(16);
56         String value = RandomToken.generateToken(16);
57
58         // If we run the sub case that we have certificates on the domain,
59         // create a certificate now.
60         Certificate c = null;
61         if (certs) {
62             KeyPair kp = generateKeypair();
63             String key = generatePEMCSR(kp, "CN=testmail@example.com");
64             c = new Certificate(u, u, Certificate.buildDN("CN", "testmail@example.com"), Digest.SHA256, key, CSRType.CSR, CertificateProfile.getByName("server"), new Certificate.SubjectAlternateName(SANType.DNS, test));
65             await(c.issue(null, "2y", u));
66         }
67
68         // Register HTTP and Email pings.
69         updateService(token, value, "http");
70         d.addPing(DomainPingType.EMAIL, "postmaster");
71         d.addPing(DomainPingType.HTTP, token + ":" + value);
72
73         // Two successful pings
74         getMailReceiver().receive("postmaster@" + test).verify();
75         waitForPings(2);
76
77         assertEquals(0, countFailed(d.getPings(), 2));
78
79         // An own Pinger Daemon to control ping execution locally.
80         PingerDaemon pd = new PingerDaemon(null);
81         pd.initializeConnectionUsage();
82
83         // After 6 months the pings are executed again
84         pd.executeNeededPings(new Date(System.currentTimeMillis() + 6 * 31 * 24 * 60 * 60L * 1000));
85         getMailReceiver().receive("postmaster@" + test).verify();
86         waitForPings(4);
87         assertEquals(0, countFailed(d.getPings(), 4));
88
89         // After 6 months the pings are executed again, but when the HTTP file
90         // is wrong, that ping fails.
91         updateService(token, value + "broken", "http");
92         // Note that the time is still 6 months in the future, as the pings from
93         // before were still executed (and logged)
94         // as executed now.
95         pd.executeNeededPings(new Date(System.currentTimeMillis() + 6 * 31 * 24 * 60 * 60L * 1000));
96         getMailReceiver().receive("postmaster@" + test).verify();
97         waitForPings(6);
98         assertEquals(1, countFailed(d.getPings(), 6));
99         // Which renders the domain invalid
100         assertFalse(d.isVerified());
101
102         if (certs) {
103             // And the user gets a warning-mail if there was a cert
104             TestMail mail = getMailReceiver().receive(u.getEmail());
105             assertThat(mail.getMessage(), CoreMatchers.containsString(d.getSuffix()));
106             assertThat(mail.getMessage(), CoreMatchers.containsString(c.getSerial()));
107             if ( !correct) {
108                 // If the user ignores the warning, after two weeks
109                 pd.executeNeededPings(new Date(System.currentTimeMillis() + 15 * 24 * 60 * 60L * 1000));
110                 // The user receives another warning mail.
111                 mail = getMailReceiver().receive(u.getEmail());
112                 assertThat(mail.getMessage(), CoreMatchers.containsString(d.getSuffix()));
113                 assertThat(mail.getMessage(), CoreMatchers.containsString(c.getSerial()));
114                 // And when the revocation is carried out
115                 SimpleSigner.ping();
116                 // ... and the certificate gets revoked.
117                 assertEquals(CertificateStatus.REVOKED, c.getStatus());
118             } else {
119                 // But if the user corrects the ping, ...
120                 updateService(token, value, "http");
121                 // ... and the ping is re-executed,
122                 pd.handle(getPing(d.getConfiguredPings(), DomainPingType.HTTP));
123                 waitForPings(7);
124                 assertEquals(1, countFailed(d.getPings(), 7));
125
126                 // Even after two weeks
127                 pd.executeNeededPings(new Date(System.currentTimeMillis() + 15 * 24 * 60 * 60L * 1000));
128                 // and all resulting jobs are executed
129                 SimpleSigner.ping();
130                 // ... the certificate stays valid.
131                 assertEquals(CertificateStatus.ISSUED, c.getStatus());
132             }
133         } else {
134             // otherwise there is no mail
135         }
136
137     }
138
139     private DomainPingConfiguration getPing(List<DomainPingConfiguration> cp, DomainPingType tp) {
140         for (DomainPingConfiguration d : cp) {
141             if (d.getType() == tp) {
142                 return d;
143             }
144         }
145         throw new Error("Type not found.");
146     }
147
148     private int countFailed(DomainPingExecution[] pg, int count) {
149         assertEquals(count, pg.length);
150         int fld = 0;
151         for (DomainPingExecution e : pg) {
152             PingState state = e.getState();
153             if (e.getConfig().getType() == DomainPingType.HTTP) {
154                 if (state == PingState.FAILED) {
155                     fld++;
156                     continue;
157                 }
158             }
159             assertEquals(PingState.SUCCESS, state);
160         }
161         return fld;
162     }
163
164 }