ソースを参照

Merge branch 'master' of https://github.com/DMDirc/DMDirc

pull/512/head
Greg Holmes 9年前
コミット
02db128a17

+ 0
- 10
src/com/dmdirc/ChannelMap.java ファイルの表示

@@ -131,14 +131,4 @@ public class ChannelMap {
131 131
                 .collect(Collectors.toList());
132 132
     }
133 133
 
134
-    /**
135
-     * Creates a runnable that, when run, will cause each channel in the map at that time to check
136
-     * its 'who' status.
137
-     *
138
-     * @return A new runnable.
139
-     */
140
-    public Runnable getWhoRunnable() {
141
-        return () -> channels.values().forEach(Channel::checkWho);
142
-    }
143
-
144 134
 }

+ 21
- 3
src/com/dmdirc/DMDircMBassador.java ファイルの表示

@@ -35,6 +35,8 @@ import net.engio.mbassy.bus.config.Feature;
35 35
  */
36 36
 public class DMDircMBassador extends MBassador<DMDircEvent> {
37 37
 
38
+    private final Object errorHandlerLock = new Object();
39
+
38 40
     public DMDircMBassador() {
39 41
         super(new BusConfiguration().addFeature(Feature.SyncPubSub.Default())
40 42
                 .addFeature(Feature.AsynchronousHandlerInvocation.Default(1, 1)).addFeature(
@@ -49,11 +51,27 @@ public class DMDircMBassador extends MBassador<DMDircEvent> {
49 51
         setupErrorHandler();
50 52
     }
51 53
 
54
+    @SuppressWarnings({
55
+            "ThrowableResultOfMethodCallIgnored",
56
+            "CallToPrintStackTrace",
57
+            "UseOfSystemOutOrSystemErr"
58
+    })
52 59
     private void setupErrorHandler() {
53 60
         addErrorHandler(e -> {
54
-            @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
55
-            final Throwable error = e.getCause().getCause();
56
-            publish(new AppErrorEvent(ErrorLevel.HIGH, error.getCause(), error.getMessage(), ""));
61
+            if (Thread.holdsLock(errorHandlerLock)) {
62
+                // ABORT ABORT ABORT - we're publishing an error on the same thread we just tried
63
+                // to publish an error on. Something in the error reporting pipeline must be
64
+                // breaking, so don't try adding any more errors.
65
+                System.err.println("ERROR: Error when reporting error");
66
+                e.getCause().printStackTrace();
67
+                return;
68
+            }
69
+
70
+            synchronized (errorHandlerLock) {
71
+                final Throwable error = e.getCause().getCause();
72
+                publish(new AppErrorEvent(ErrorLevel.HIGH, error.getCause(), error.getMessage(),
73
+                        ""));
74
+            }
57 75
         });
58 76
     }
59 77
 }

+ 2
- 1
src/com/dmdirc/FrameContainer.java ファイルの表示

@@ -331,8 +331,9 @@ public abstract class FrameContainer implements WindowModel {
331 331
     }
332 332
 
333 333
     @Override
334
+    @Deprecated
334 335
     public void addLine(final String line, final boolean timestamp) {
335
-        addLine(line, timestamp ? new Date() : null);
336
+        addLine(line, new Date());
336 337
     }
337 338
 
338 339
     @Override

+ 1
- 20
src/com/dmdirc/GroupChatManagerImpl.java ファイルの表示

@@ -39,9 +39,6 @@ import java.util.Date;
39 39
 import java.util.HashSet;
40 40
 import java.util.List;
41 41
 import java.util.Optional;
42
-import java.util.concurrent.ScheduledExecutorService;
43
-import java.util.concurrent.ScheduledFuture;
44
-import java.util.concurrent.TimeUnit;
45 42
 import java.util.stream.Collectors;
46 43
 
47 44
 import net.engio.mbassy.listener.Handler;
@@ -65,19 +62,12 @@ public class GroupChatManagerImpl implements GroupChatManager {
65 62
     /** A set of channels we want to join without focusing. */
66 63
     private final Collection<String> backgroundChannels = new HashSet<>();
67 64
 
68
-    private final ScheduledExecutorService executorService;
69
-
70
-    /** The future used when a who timer is scheduled. */
71
-    private ScheduledFuture<?> whoTimerFuture;
72
-
73 65
     public GroupChatManagerImpl(final Connection connection,
74 66
             final IdentityFactory identityFactory,
75
-            final ChannelFactory channelFactory,
76
-            final ScheduledExecutorService executorService) {
67
+            final ChannelFactory channelFactory) {
77 68
         this.connection = connection;
78 69
         this.identityFactory = identityFactory;
79 70
         this.channelFactory = channelFactory;
80
-        this.executorService = executorService;
81 71
     }
82 72
 
83 73
     @Override
@@ -188,10 +178,6 @@ public class GroupChatManagerImpl implements GroupChatManager {
188 178
     }
189 179
 
190 180
     public void handleSocketClosed() {
191
-        if (whoTimerFuture != null) {
192
-            whoTimerFuture.cancel(false);
193
-        }
194
-
195 181
         channels.resetAll();
196 182
 
197 183
         if (connection.getWindowModel().getConfigManager()
@@ -209,11 +195,6 @@ public class GroupChatManagerImpl implements GroupChatManager {
209 195
             requests.addAll(channels.asJoinRequests());
210 196
         }
211 197
         join(requests.toArray(new ChannelJoinRequest[requests.size()]));
212
-
213
-        final int whoTime = connection.getWindowModel().getConfigManager()
214
-                .getOptionInt("general", "whotime");
215
-        whoTimerFuture = executorService.scheduleAtFixedRate(
216
-                channels.getWhoRunnable(), whoTime, whoTime, TimeUnit.MILLISECONDS);
217 198
     }
218 199
 
219 200
     @Handler

+ 2
- 7
src/com/dmdirc/GroupChatManagerImplFactory.java ファイルの表示

@@ -25,8 +25,6 @@ package com.dmdirc;
25 25
 import com.dmdirc.interfaces.Connection;
26 26
 import com.dmdirc.interfaces.config.IdentityFactory;
27 27
 
28
-import java.util.concurrent.ScheduledExecutorService;
29
-
30 28
 import javax.inject.Inject;
31 29
 import javax.inject.Provider;
32 30
 import javax.inject.Singleton;
@@ -48,11 +46,8 @@ public class GroupChatManagerImplFactory {
48 46
         this.channelFactory = channelFactory;
49 47
     }
50 48
 
51
-    public GroupChatManagerImpl create(
52
-            final Connection connection,
53
-            final ScheduledExecutorService executorService) {
54
-        return new GroupChatManagerImpl(connection, identityFactory, channelFactory.get(),
55
-                executorService);
49
+    public GroupChatManagerImpl create(final Connection connection) {
50
+        return new GroupChatManagerImpl(connection, identityFactory, channelFactory.get());
56 51
     }
57 52
 
58 53
 }

+ 1
- 1
src/com/dmdirc/Server.java ファイルの表示

@@ -213,7 +213,7 @@ public class Server extends FrameContainer implements Connection {
213 213
         this.userSettings = userSettings;
214 214
         this.messageEncoderFactory = messageEncoderFactory;
215 215
         this.userManager = userManager;
216
-        this.groupChatManager = groupChatManagerFactory.create(this, executorService);
216
+        this.groupChatManager = groupChatManagerFactory.create(this);
217 217
         this.inviteManager = new InviteManagerImpl(this);
218 218
 
219 219
         awayMessage = Optional.empty();

+ 2
- 0
src/com/dmdirc/interfaces/WindowModel.java ファイルの表示

@@ -188,7 +188,9 @@ public interface WindowModel {
188 188
      *
189 189
      * @param line      The line to be added
190 190
      * @param timestamp Whether or not to display the timestamp for this line
191
+     * @deprecated Timestamps are always displayed.
191 192
      */
193
+    @Deprecated
192 194
     void addLine(String line, boolean timestamp);
193 195
 
194 196
     /**

+ 55
- 41
src/com/dmdirc/tls/CertificateManager.java ファイルの表示

@@ -285,24 +285,55 @@ public class CertificateManager implements X509TrustManager {
285 285
     @Override
286 286
     public void checkServerTrusted(final X509Certificate[] chain, final String authType)
287 287
             throws CertificateException {
288
-        this.chain = chain;
288
+        this.chain = Arrays.copyOf(chain, chain.length);
289 289
         problems.clear();
290 290
 
291
-        boolean verified = false;
292
-        boolean manual = false;
291
+        checkHost(chain);
293 292
 
294
-        if (checkHost) {
295
-            // Check that the cert is issued to the correct host
296
-            verified = isValidHost(chain[0]);
293
+        if (checkIssuer(chain)) {
294
+            problems.clear();
295
+        }
297 296
 
298
-            if (!verified) {
299
-                problems.add(new CertificateDoesntMatchHostException(
300
-                        "Certificate was not issued to " + serverName));
297
+        if (!problems.isEmpty()) {
298
+            eventBus.publishAsync(new ServerCertificateProblemEncounteredEvent(connection, this,
299
+                    Arrays.asList(chain), problems));
300
+
301
+            try {
302
+                actionSem.acquire();
303
+            } catch (InterruptedException ie) {
304
+                throw new CertificateException("Thread aborted", ie);
305
+            } finally {
306
+                problems.clear();
307
+                eventBus.publishAsync(new ServerCertificateProblemResolvedEvent(connection, this));
301 308
             }
302 309
 
303
-            verified = false;
310
+            switch (action) {
311
+                case DISCONNECT:
312
+                    throw new CertificateException("Not trusted");
313
+                case IGNORE_PERMANENTLY:
314
+                    final List<String> list = new ArrayList<>(config
315
+                            .getOptionList("ssl", "trusted"));
316
+                    list.add(Base64.getEncoder().encodeToString(chain[0].getSignature()));
317
+                    userSettings.setOption("ssl", "trusted", list);
318
+                    break;
319
+                case IGNORE_TEMPORARILY:
320
+                    // Do nothing, continue connecting
321
+                    break;
322
+            }
304 323
         }
324
+    }
305 325
 
326
+    /**
327
+     * Checks that some issuer in the certificate chain is trusted, either by the global CA list,
328
+     * or manually by the user.
329
+     *
330
+     * @param chain The chain of certificates to check.
331
+     * @return True if the certificate is trusted manually, false otherwise (i.e., trusted globally
332
+     * OR untrusted).
333
+     */
334
+    private boolean checkIssuer(final X509Certificate... chain) {
335
+        boolean manual = false;
336
+        boolean verified = false;
306 337
         for (X509Certificate cert : chain) {
307 338
             final TrustResult trustResult = isTrusted(cert);
308 339
 
@@ -317,7 +348,6 @@ public class CertificateManager implements X509TrustManager {
317 348
 
318 349
             if (checkIssuer) {
319 350
                 // Check that we trust an issuer
320
-
321 351
                 verified |= trustResult.isTrusted();
322 352
             }
323 353
 
@@ -329,38 +359,22 @@ public class CertificateManager implements X509TrustManager {
329 359
         if (!verified && checkIssuer) {
330 360
             problems.add(new CertificateNotTrustedException("Issuer is not trusted"));
331 361
         }
362
+        return manual;
363
+    }
332 364
 
333
-        if (!problems.isEmpty() && !manual) {
334
-            eventBus.publishAsync(new ServerCertificateProblemEncounteredEvent(
335
-                    connection, this, Arrays.asList(chain), problems));
336
-
337
-            try {
338
-                actionSem.acquire();
339
-            } catch (InterruptedException ie) {
340
-                throw new CertificateException("Thread aborted", ie);
341
-            } finally {
342
-                problems.clear();
343
-
344
-                eventBus.publishAsync(new ServerCertificateProblemResolvedEvent(connection, this));
345
-            }
346
-
347
-            switch (action) {
348
-                case DISCONNECT:
349
-                    throw new CertificateException("Not trusted");
350
-                case IGNORE_PERMANENTLY:
351
-                    final List<String> list = new ArrayList<>(config
352
-                            .getOptionList("ssl", "trusted"));
353
-                    list.add(Base64.getEncoder().encodeToString(chain[0].getSignature()));
354
-                    userSettings.setOption("ssl", "trusted", list);
355
-                    break;
356
-                case IGNORE_TEMPORARILY:
357
-                    // Do nothing, continue connecting
358
-                    break;
365
+    /**
366
+     * Checks that the host of the leaf certificate is the same as the server we are connected to.
367
+     *
368
+     * @param chain The chain of certificates to check.
369
+     */
370
+    private void checkHost(final X509Certificate... chain) {
371
+        if (checkHost) {
372
+            // Check that the cert is issued to the correct host
373
+            if (!isValidHost(chain[0])) {
374
+                problems.add(new CertificateDoesntMatchHostException(
375
+                        "Certificate was not issued to " + serverName));
359 376
             }
360 377
         }
361
-        if (manual) {
362
-            problems.clear();
363
-        }
364 378
     }
365 379
 
366 380
     /**
@@ -429,4 +443,4 @@ public class CertificateManager implements X509TrustManager {
429 443
         return globalTrustedCAs.toArray(new X509Certificate[globalTrustedCAs.size()]);
430 444
     }
431 445
 
432
-}
446
+}

読み込み中…
キャンセル
保存