Explorar el Código

Merge pull request #111 from ShaneMcC/master

Try to keep track of channel keys (Close Issue #108)
pull/117/head
Greg Holmes hace 8 años
padre
commit
fe7484315a

+ 5
- 0
common/src/com/dmdirc/parser/common/BaseChannelInfo.java Ver fichero

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

+ 48
- 0
common/src/com/dmdirc/parser/events/ChannelPasswordChangedEvent.java Ver fichero

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 Ver fichero

42
      */
42
      */
43
     String getName();
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
      * Changes the topic of this channel.
53
      * Changes the topic of this channel.
47
      *
54
      *

+ 26
- 0
irc/src/com/dmdirc/parser/irc/IRCChannelInfo.java Ver fichero

24
 import com.dmdirc.parser.common.ChannelListModeItem;
24
 import com.dmdirc.parser.common.ChannelListModeItem;
25
 import com.dmdirc.parser.common.ParserError;
25
 import com.dmdirc.parser.common.ParserError;
26
 import com.dmdirc.parser.common.QueuePriority;
26
 import com.dmdirc.parser.common.QueuePriority;
27
+import com.dmdirc.parser.events.ChannelPasswordChangedEvent;
27
 import com.dmdirc.parser.interfaces.ChannelClientInfo;
28
 import com.dmdirc.parser.interfaces.ChannelClientInfo;
28
 import com.dmdirc.parser.interfaces.ChannelInfo;
29
 import com.dmdirc.parser.interfaces.ChannelInfo;
29
 import com.dmdirc.parser.interfaces.ClientInfo;
30
 import com.dmdirc.parser.interfaces.ClientInfo;
30
 import com.dmdirc.parser.interfaces.Parser;
31
 import com.dmdirc.parser.interfaces.Parser;
31
 
32
 
33
+import java.time.LocalDateTime;
32
 import java.util.ArrayList;
34
 import java.util.ArrayList;
33
 import java.util.Collection;
35
 import java.util.Collection;
34
 import java.util.Collections;
36
 import java.util.Collections;
72
     private final PrefixModeManager prefixModeManager;
74
     private final PrefixModeManager prefixModeManager;
73
     /** Channel Name. */
75
     /** Channel Name. */
74
     private final String name;
76
     private final String name;
77
+    /** Channel Key. */
78
+    private String password = "";
75
     /** Hashtable containing references to ChannelClients. */
79
     /** Hashtable containing references to ChannelClients. */
76
     private final Map<String, IRCChannelClientInfo> clients = Collections.synchronizedMap(new HashMap<>());
80
     private final Map<String, IRCChannelClientInfo> clients = Collections.synchronizedMap(new HashMap<>());
77
     /** Hashtable storing values for modes set in the channel that use parameters. */
81
     /** Hashtable storing values for modes set in the channel that use parameters. */
440
         return topicUser;
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
      * Set the channel modes.
463
      * Set the channel modes.
445
      *
464
      *
487
             }
506
             }
488
         } else {
507
         } else {
489
             paramModes.put(cMode, sValue);
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 Ver fichero

234
     private final WhoisResponseHandler whoisHandler;
234
     private final WhoisResponseHandler whoisHandler;
235
     /** Used to synchronize calls to resetState. */
235
     /** Used to synchronize calls to resetState. */
236
     private final Object resetStateSync = new Object();
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
      * Default constructor, ServerInfo and MyInfo need to be added separately (using IRC.me and IRC.server).
243
      * Default constructor, ServerInfo and MyInfo need to be added separately (using IRC.me and IRC.server).
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
         return true;
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
     @Override
1106
     @Override
1064
     public String getNetworkName() {
1107
     public String getNetworkName() {
1065
         return networkName;
1108
         return networkName;

+ 17
- 3
irc/src/com/dmdirc/parser/irc/processors/ProcessJoin.java Ver fichero

67
     public ProcessJoin(final IRCParser parser, final PrefixModeManager prefixModeManager,
67
     public ProcessJoin(final IRCParser parser, final PrefixModeManager prefixModeManager,
68
             @Named("user") final ModeManager userModeManager,
68
             @Named("user") final ModeManager userModeManager,
69
             @Named("channel") final ModeManager chanModeManager) {
69
             @Named("channel") final ModeManager chanModeManager) {
70
-        super(parser, "JOIN", "329");
70
+        super(parser, "JOIN", "329", "471", "473", "474", "475", "476", "477", "479");
71
         this.prefixModeManager = prefixModeManager;
71
         this.prefixModeManager = prefixModeManager;
72
         this.userModeManager = userModeManager;
72
         this.userModeManager = userModeManager;
73
         this.chanModeManager = chanModeManager;
73
         this.chanModeManager = chanModeManager;
95
                     // Oh well, not a normal ircd I guess
95
                     // Oh well, not a normal ircd I guess
96
                 }
96
                 }
97
             }
97
             }
98
-        } else {
98
+        } else if ("JOIN".equals(sParam)) {
99
             // :nick!ident@host JOIN (:)#Channel
99
             // :nick!ident@host JOIN (:)#Channel
100
             if (token.length < 3) {
100
             if (token.length < 3) {
101
                 return;
101
                 return;
102
             }
102
             }
103
             final boolean extendedJoin = parser.getCapabilityState("extended-join") == CapabilityState.ENABLED;
103
             final boolean extendedJoin = parser.getCapabilityState("extended-join") == CapabilityState.ENABLED;
104
 
104
 
105
-
106
             IRCClientInfo iClient = getClientInfo(token[0]);
105
             IRCClientInfo iClient = getClientInfo(token[0]);
107
             final String realName;
106
             final String realName;
108
             final String accountName;
107
             final String accountName;
172
             parser.addChannel(iChannel);
171
             parser.addChannel(iChannel);
173
             sendString("MODE " + iChannel.getName(), QueuePriority.LOW);
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
             callChannelSelfJoin(iChannel);
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…
Cancelar
Guardar