Kaynağa Gözat

Merge pull request #111 from ShaneMcC/master

Try to keep track of channel keys (Close Issue #108)
pull/117/head
Greg Holmes 8 yıl önce
ebeveyn
işleme
fe7484315a

+ 5
- 0
common/src/com/dmdirc/parser/common/BaseChannelInfo.java Dosyayı Görüntüle

@@ -68,6 +68,11 @@ public abstract class BaseChannelInfo implements ChannelInfo {
68 68
         return parser;
69 69
     }
70 70
 
71
+    @Override
72
+    public String getPassword() {
73
+        return "";
74
+    }
75
+
71 76
     @Override
72 77
     public void sendMessage(final String message) {
73 78
         parser.sendMessage(name, message);

+ 48
- 0
common/src/com/dmdirc/parser/events/ChannelPasswordChangedEvent.java Dosyayı Görüntüle

@@ -0,0 +1,48 @@
1
+/*
2
+ * Copyright (c) 2006-2014 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.parser.events;
24
+
25
+import com.dmdirc.parser.interfaces.ChannelInfo;
26
+import com.dmdirc.parser.interfaces.Parser;
27
+
28
+import java.time.LocalDateTime;
29
+
30
+import static com.google.common.base.Preconditions.checkNotNull;
31
+
32
+/**
33
+ * Called when a channel password changes.
34
+ */
35
+public class ChannelPasswordChangedEvent extends ParserEvent {
36
+
37
+    private final ChannelInfo channel;
38
+
39
+    public ChannelPasswordChangedEvent(final Parser parser, final LocalDateTime date,
40
+                                  final ChannelInfo channel) {
41
+        super(parser, date);
42
+        this.channel = checkNotNull(channel);
43
+    }
44
+
45
+    public ChannelInfo getChannel() {
46
+        return channel;
47
+    }
48
+}

+ 7
- 0
common/src/com/dmdirc/parser/interfaces/ChannelInfo.java Dosyayı Görüntüle

@@ -42,6 +42,13 @@ public interface ChannelInfo {
42 42
      */
43 43
     String getName();
44 44
 
45
+    /**
46
+     * Returns the password for this channel.
47
+     *
48
+     * @return The password for this channel
49
+     */
50
+    String getPassword();
51
+
45 52
     /**
46 53
      * Changes the topic of this channel.
47 54
      *

+ 26
- 0
irc/src/com/dmdirc/parser/irc/IRCChannelInfo.java Dosyayı Görüntüle

@@ -24,11 +24,13 @@ package com.dmdirc.parser.irc;
24 24
 import com.dmdirc.parser.common.ChannelListModeItem;
25 25
 import com.dmdirc.parser.common.ParserError;
26 26
 import com.dmdirc.parser.common.QueuePriority;
27
+import com.dmdirc.parser.events.ChannelPasswordChangedEvent;
27 28
 import com.dmdirc.parser.interfaces.ChannelClientInfo;
28 29
 import com.dmdirc.parser.interfaces.ChannelInfo;
29 30
 import com.dmdirc.parser.interfaces.ClientInfo;
30 31
 import com.dmdirc.parser.interfaces.Parser;
31 32
 
33
+import java.time.LocalDateTime;
32 34
 import java.util.ArrayList;
33 35
 import java.util.Collection;
34 36
 import java.util.Collections;
@@ -72,6 +74,8 @@ public class IRCChannelInfo implements ChannelInfo {
72 74
     private final PrefixModeManager prefixModeManager;
73 75
     /** Channel Name. */
74 76
     private final String name;
77
+    /** Channel Key. */
78
+    private String password = "";
75 79
     /** Hashtable containing references to ChannelClients. */
76 80
     private final Map<String, IRCChannelClientInfo> clients = Collections.synchronizedMap(new HashMap<>());
77 81
     /** Hashtable storing values for modes set in the channel that use parameters. */
@@ -440,6 +444,21 @@ public class IRCChannelInfo implements ChannelInfo {
440 444
         return topicUser;
441 445
     }
442 446
 
447
+    @Override
448
+    public String getPassword() {
449
+        return password;
450
+    }
451
+
452
+    /**
453
+     * Set the internal value of the channel password,
454
+     *
455
+     * @param newValue New Value to set
456
+     */
457
+    public void setInternalPassword(final String newValue) {
458
+        password = newValue;
459
+        parser.getCallbackManager().publish(new ChannelPasswordChangedEvent(parser, LocalDateTime.now(), this));
460
+    }
461
+
443 462
     /**
444 463
      * Set the channel modes.
445 464
      *
@@ -487,6 +506,13 @@ public class IRCChannelInfo implements ChannelInfo {
487 506
             }
488 507
         } else {
489 508
             paramModes.put(cMode, sValue);
509
+            if (cMode == 'k') {
510
+                if (sValue.equalsIgnoreCase("*") && !getPassword().equalsIgnoreCase("*")) {
511
+                    // Don't overwrite a guessed password with a hidden one.
512
+                    return;
513
+                }
514
+                setInternalPassword(sValue);
515
+            }
490 516
         }
491 517
     }
492 518
 

+ 43
- 0
irc/src/com/dmdirc/parser/irc/IRCParser.java Dosyayı Görüntüle

@@ -234,6 +234,10 @@ public class IRCParser extends BaseSocketAwareParser implements SecureParser, En
234 234
     private final WhoisResponseHandler whoisHandler;
235 235
     /** Used to synchronize calls to resetState. */
236 236
     private final Object resetStateSync = new Object();
237
+    /** Pending Joins. */
238
+    private final Queue<String> pendingJoins = new LinkedList<>();
239
+    /** Pending Join Keys. */
240
+    private final Queue<String> pendingJoinKeys = new LinkedList<>();
237 241
 
238 242
     /**
239 243
      * Default constructor, ServerInfo and MyInfo need to be added separately (using IRC.me and IRC.server).
@@ -1055,11 +1059,50 @@ public class IRCParser extends BaseSocketAwareParser implements SecureParser, En
1055 1059
                     }
1056 1060
                 }
1057 1061
             }
1062
+        } else if ("join".equalsIgnoreCase(newLine[0]) && newLine.length > 1) {
1063
+            final Queue<String> keys = new LinkedList<>();
1064
+
1065
+            if (newLine.length > 2) {
1066
+                keys.addAll(Arrays.asList(newLine[2].split(",")));
1067
+            }
1068
+
1069
+            // PendingJoins and PendingJoinKeys should always be the same length (even if no key was given).
1070
+            //
1071
+            // We don't get any errors for channels we try to join that we are already in
1072
+            // But the IRCD will still swallow the key attempt.
1073
+            //
1074
+            // Make sure that we always have a guessed key for every channel (even if null) and that we
1075
+            // don't have guesses for channels we are already in.
1076
+            for (final String chan : newLine[1].split(",")) {
1077
+                final String key = keys.poll();
1078
+                if (getChannel(chan) == null) {
1079
+                    pendingJoins.add(chan);
1080
+                    pendingJoinKeys.add(key);
1081
+                }
1082
+            }
1058 1083
         }
1059 1084
 
1060 1085
         return true;
1061 1086
     }
1062 1087
 
1088
+    /**
1089
+     * Get the current pending Joins.
1090
+     *
1091
+     * @return Current pending Joins
1092
+     */
1093
+    public Queue<String> getPendingJoins() {
1094
+        return pendingJoins;
1095
+    }
1096
+
1097
+    /**
1098
+     * Get the current pending join keys.
1099
+     *
1100
+     * @return Current pending join keys.
1101
+     */
1102
+    public Queue<String> getPendingJoinKeys() {
1103
+        return pendingJoinKeys;
1104
+    }
1105
+
1063 1106
     @Override
1064 1107
     public String getNetworkName() {
1065 1108
         return networkName;

+ 17
- 3
irc/src/com/dmdirc/parser/irc/processors/ProcessJoin.java Dosyayı Görüntüle

@@ -67,7 +67,7 @@ public class ProcessJoin extends IRCProcessor {
67 67
     public ProcessJoin(final IRCParser parser, final PrefixModeManager prefixModeManager,
68 68
             @Named("user") final ModeManager userModeManager,
69 69
             @Named("channel") final ModeManager chanModeManager) {
70
-        super(parser, "JOIN", "329");
70
+        super(parser, "JOIN", "329", "471", "473", "474", "475", "476", "477", "479");
71 71
         this.prefixModeManager = prefixModeManager;
72 72
         this.userModeManager = userModeManager;
73 73
         this.chanModeManager = chanModeManager;
@@ -95,14 +95,13 @@ public class ProcessJoin extends IRCProcessor {
95 95
                     // Oh well, not a normal ircd I guess
96 96
                 }
97 97
             }
98
-        } else {
98
+        } else if ("JOIN".equals(sParam)) {
99 99
             // :nick!ident@host JOIN (:)#Channel
100 100
             if (token.length < 3) {
101 101
                 return;
102 102
             }
103 103
             final boolean extendedJoin = parser.getCapabilityState("extended-join") == CapabilityState.ENABLED;
104 104
 
105
-
106 105
             IRCClientInfo iClient = getClientInfo(token[0]);
107 106
             final String realName;
108 107
             final String accountName;
@@ -172,7 +171,22 @@ public class ProcessJoin extends IRCProcessor {
172 171
             parser.addChannel(iChannel);
173 172
             sendString("MODE " + iChannel.getName(), QueuePriority.LOW);
174 173
 
174
+            final String pendingJoin = parser.getPendingJoins().poll();
175
+            final String pendingJoinKey = parser.getPendingJoinKeys().poll();
176
+            if (pendingJoin.equalsIgnoreCase(channelName)) {
177
+                callDebugInfo(IRCParser.DEBUG_INFO, "processJoin: Guessing channel Key: " + pendingJoin + " -> " + pendingJoinKey);
178
+                iChannel.setInternalPassword(pendingJoinKey == null ? "" : pendingJoinKey);
179
+            } else {
180
+                // Out of sync, clear.
181
+                parser.getPendingJoins().clear();
182
+                parser.getPendingJoinKeys().clear();
183
+            }
184
+
175 185
             callChannelSelfJoin(iChannel);
186
+        } else {
187
+            // Some kind of failed to join, pop the pending join queues.
188
+            parser.getPendingJoins().poll();
189
+            parser.getPendingJoinKeys().poll();
176 190
         }
177 191
     }
178 192
 

Loading…
İptal
Kaydet