diff --git a/lib/installer-exclude/irc-api-1.0-sources.jar b/lib/installer-exclude/irc-api-1.0-sources.jar
index ca6388bd6..70b7393b0 100644
Binary files a/lib/installer-exclude/irc-api-1.0-sources.jar and b/lib/installer-exclude/irc-api-1.0-sources.jar differ
diff --git a/lib/installer-exclude/irc-api-1.0.jar b/lib/installer-exclude/irc-api-1.0.jar
index db98348bf..b97ac133b 100644
Binary files a/lib/installer-exclude/irc-api-1.0.jar and b/lib/installer-exclude/irc-api-1.0.jar differ
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/IrcActivator.java b/src/net/java/sip/communicator/impl/protocol/irc/IrcActivator.java
index fc867f5e8..b69d4a2f0 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/IrcActivator.java
+++ b/src/net/java/sip/communicator/impl/protocol/irc/IrcActivator.java
@@ -8,6 +8,7 @@
import java.util.*;
+import net.java.sip.communicator.service.certificate.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.util.*;
@@ -37,10 +38,15 @@ public class IrcActivator
/**
* The currently valid bundle context.
*/
- public static BundleContext bundleContext = null;
+ private static BundleContext bundleContext = null;
private static ResourceManagementService resourceService;
+ /**
+ * Certificate Service instance.
+ */
+ private static CertificateService certiticateService;
+
/**
* Called when this bundle is started. In here we'll export the
* IRC ProtocolProviderFactory implementation so that it could be
@@ -112,4 +118,33 @@ public static ResourceManagementService getResources()
= ResourceManagementServiceUtils.getService(bundleContext);
return resourceService;
}
+
+ /**
+ * Bundle Context
+ *
+ * @return returns bundle context
+ */
+ public static BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
+ /**
+ * Return the certificate verification service impl.
+ *
+ * @return the CertificateVerification service.
+ */
+ public static CertificateService getCertificateVerificationService()
+ {
+ if(certiticateService == null)
+ {
+ ServiceReference guiVerifyReference
+ = IrcActivator.getBundleContext().getServiceReference(
+ CertificateService.class.getName());
+ if(guiVerifyReference != null)
+ certiticateService = (CertificateService)
+ IrcActivator.getBundleContext().getService(
+ guiVerifyReference);
+ }
+ return certiticateService;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java b/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java
index 6a3076cc9..b3e5e6bce 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java
+++ b/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java
@@ -7,9 +7,13 @@
package net.java.sip.communicator.impl.protocol.irc;
import java.io.*;
+import java.security.*;
import java.util.*;
+import javax.net.ssl.*;
+
import net.java.sip.communicator.impl.protocol.irc.ModeParser.ModeEntry;
+import net.java.sip.communicator.service.certificate.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
@@ -61,7 +65,7 @@ public class IrcStack
* Connection state of a successful IRC connection.
*/
private IIRCState connectionState;
-
+
/**
* The cached channel list.
*
@@ -133,20 +137,16 @@ public void connect(String host, int port, String password,
this.joined.clear();
this.irc = new IRCApiImpl(true);
- // FIXME Currently, the secure connection is created by
- // explicitly creating an SSLContext for 'SSL'. According
- // to Ingo (in a mailing list conversation) it is better to
- // use the CertificateService for this. This should be
- // implemented in the irc-api library, though.
- this.params.setServer(new IRCServer(host, port, password,
- secureConnection));
synchronized (this.irc)
{
+ this.params.setServer(new IRCServer(host, port, password,
+ secureConnection));
+ this.params.setCustomContext(getCustomSSLContext(host));
this.irc.addListener(new ServerListener());
connectSynchronized();
}
}
-
+
/**
* Perform synchronized connect operation.
*
@@ -195,7 +195,7 @@ public void onFailure(Exception e)
.trace("Waiting for the connection to be established ...");
result.wait();
}
-
+
this.connectionState = result.getValue();
// TODO Implement connection timeout and a way to recognize that
// the timeout occurred.
@@ -232,6 +232,30 @@ public void onFailure(Exception e)
}
}
+ /**
+ * Create a custom SSL context for this particular server.
+ *
+ * @return returns a customized SSL context or null if one cannot
+ * be created.
+ */
+ private SSLContext getCustomSSLContext(String hostname)
+ {
+ SSLContext context = null;
+ try
+ {
+ CertificateService cs =
+ IrcActivator.getCertificateVerificationService();
+ X509TrustManager tm =
+ cs.getTrustManager(hostname);
+ context = cs.getSSLContext(tm);
+ }
+ catch (GeneralSecurityException e)
+ {
+ LOGGER.error("failed to create custom SSL context", e);
+ }
+ return context;
+ }
+
/**
* Disconnect from the IRC server
*/
@@ -239,8 +263,8 @@ public void disconnect()
{
if (this.connectionState == null && this.irc == null)
return;
-
- synchronized(this.joined)
+
+ synchronized (this.joined)
{
// Leave all joined channels.
for (ChatRoomIrcImpl channel : this.joined.values())
@@ -248,7 +272,7 @@ public void disconnect()
leave(channel);
}
}
- synchronized(this.irc)
+ synchronized (this.irc)
{
// Disconnect and clean up
this.irc.disconnect();
@@ -575,7 +599,7 @@ public void onFailure(Exception e)
.trace("Finished waiting for join operation for channel '"
+ chatroom.getIdentifier() + "' to complete.");
// TODO How to handle 480 (+j): Channel throttle exceeded?
-
+
Exception e = joinSignal.getException();
if (e != null)
{
@@ -666,10 +690,12 @@ public void command(ChatRoomIrcImpl chatroom, String command)
int endOfNick = command.indexOf(' ');
if (endOfNick == -1)
{
- throw new IllegalArgumentException("Invalid private message format. Message was not sent.");
+ throw new IllegalArgumentException(
+ "Invalid private message format. "
+ + "Message was not sent.");
}
- target = command.substring(0, endOfNick);
- command = command.substring(endOfNick+1);
+ target = command.substring(0, endOfNick);
+ command = command.substring(endOfNick + 1);
}
else
{
@@ -703,12 +729,12 @@ private static ChatRoomMemberRole convertMemberMode(char modeSymbol)
}
/**
- * A listener for server-level messages (any messages that are related to the
- * server, the connection, that are not related to any chatroom in
+ * A listener for server-level messages (any messages that are related to
+ * the server, the connection, that are not related to any chatroom in
* particular) or that are personal message from user to local user.
*/
private class ServerListener
- extends VariousMessageListenerAdapter
+ extends VariousMessageListenerAdapter
{
/**
* Print out server notices for debugging purposes and for simply
@@ -744,10 +770,9 @@ public void onServerNumericMessage(ServerNumericMessage msg)
@Override
public void onError(ErrorMessage msg)
{
- LOGGER.debug("ERROR: " + msg.getSource() + ": "
- + msg.getText());
+ LOGGER.debug("ERROR: " + msg.getSource() + ": " + msg.getText());
}
-
+
/**
* Upon receiving a private message from a user, deliver that to a
* private chat room and create one if it does not exist. We can ignore
@@ -780,8 +805,8 @@ public void onUserPrivMessage(UserPrivMsg msg)
* @param user the source user
* @param text the message
*/
- private void deliverReceivedMessageToPrivateChat(ChatRoomIrcImpl chatroom,
- String user, String text)
+ private void deliverReceivedMessageToPrivateChat(
+ ChatRoomIrcImpl chatroom, String user, String text)
{
ChatRoomMember member = chatroom.getChatRoomMember(user);
MessageIrcImpl message =
@@ -813,7 +838,7 @@ private ChatRoomIrcImpl initiatePrivateChatRoom(String user)
return chatroom;
}
}
-
+
/**
* A chat room listener.
*
@@ -924,9 +949,10 @@ public void onChannelPart(ChanPartMessage msg)
}
catch (NullPointerException e)
{
- System.err
- .println("This should not have happened. Please report this as it is a bug.");
- e.printStackTrace();
+ LOGGER
+ .warn(
+ "This should not have happened. Please report this as it is a bug.",
+ e);
}
}
}
@@ -959,8 +985,7 @@ public void onChannelKick(ChannelKick msg)
{
ChatRoomMember kicker =
this.chatroom.getChatRoomMember(user);
- this.chatroom.fireMemberPresenceEvent(kickedMember,
- kicker,
+ this.chatroom.fireMemberPresenceEvent(kickedMember, kicker,
ChatRoomMemberPresenceChangeEvent.MEMBER_KICKED,
msg.getText());
}
@@ -1214,9 +1239,9 @@ sourceMember, new Date(),
ChatRoomMessageReceivedEvent.SYSTEM_MESSAGE_RECEIVED);
break;
case UNKNOWN:
- LOGGER.info("Unknown mode: "
- + (mode.isAdded() ? "+" : "-") + mode.getParams()[0]
- + ". Original mode string: '" + msg.getModeStr() + "'");
+ LOGGER.info("Unknown mode: " + (mode.isAdded() ? "+" : "-")
+ + mode.getParams()[0] + ". Original mode string: '"
+ + msg.getModeStr() + "'");
break;
default:
LOGGER.info("Unsupported mode '"
@@ -1395,16 +1420,43 @@ private static class ServerParameters
implements IServerParameters
{
+ /**
+ * Nick name.
+ */
private String nick;
+ /**
+ * Alternative nick names.
+ */
private List alternativeNicks = new ArrayList();
+ /**
+ * Real name.
+ */
private String real;
+ /**
+ * Ident.
+ */
private String ident;
+ /**
+ * IRC server.
+ */
private IRCServer server;
+
+ /**
+ * Custom SSL Context.
+ */
+ private SSLContext sslContext = null;
+ /**
+ * Construct ServerParameters instance.
+ * @param nickName nick name
+ * @param realName real name
+ * @param ident ident
+ * @param server IRC server instance
+ */
private ServerParameters(String nickName, String realName,
String ident, IRCServer server)
{
@@ -1415,54 +1467,128 @@ private ServerParameters(String nickName, String realName,
this.server = server;
}
+ /**
+ * Get nick name.
+ *
+ * @return returns nick name
+ */
@Override
public String getNickname()
{
return this.nick;
}
+ /**
+ * Set new nick name.
+ *
+ * @param nick nick name
+ */
public void setNickname(String nick)
{
this.nick = checkNick(nick);
}
-
+
+ /**
+ * Verify nick name.
+ *
+ * @param nick nick name
+ * @return returns nick name
+ * @throws IllegalArgumentException throws
+ * IllegalArgumentException if an invalid nick name
+ * is provided.
+ */
private String checkNick(String nick)
{
if (nick == null)
- throw new IllegalArgumentException("a nick name must be provided");
- if (nick.startsWith("#"))
- throw new IllegalArgumentException("the nick name must not start with '#' since this is reserved for IRC channels");
+ throw new IllegalArgumentException(
+ "a nick name must be provided");
+ if (nick.startsWith("#"))
+ throw new IllegalArgumentException(
+ "the nick name must not start with '#' "
+ + "since this is reserved for IRC channels");
return nick;
}
+ /**
+ * Get alternative nick names.
+ *
+ * @return returns list of alternatives
+ */
@Override
public List getAlternativeNicknames()
{
return this.alternativeNicks;
}
+ /**
+ * Get ident string.
+ *
+ * @return returns ident
+ */
@Override
public String getIdent()
{
return this.ident;
}
+ /**
+ * Get real name
+ *
+ * @return returns real name
+ */
@Override
public String getRealname()
{
return this.real;
}
+ /**
+ * Get server
+ *
+ * @return returns server instance
+ */
@Override
public IRCServer getServer()
{
return this.server;
}
+ /**
+ * Set server instance.
+ *
+ * @param server IRC server instance
+ */
public void setServer(IRCServer server)
{
+ if (server == null)
+ throw new IllegalArgumentException("server cannot be null");
+
this.server = server;
}
+
+ /**
+ * Get the SSL Context.
+ *
+ * Returns the custom SSLContext or null in case there is no
+ * custom implementation.
+ *
+ * @return returns the SSLContext or null
+ */
+ @Override
+ public SSLContext getCustomContext()
+ {
+ return this.sslContext;
+ }
+
+ /**
+ * Set custom SSLContext.
+ *
+ * @param context the custom SSLContext
+ */
+ public void setCustomContext(SSLContext context)
+ {
+ this.sslContext = context;
+ }
}
/**
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderFactoryIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderFactoryIrcImpl.java
index fafe1394e..b0b9393c3 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderFactoryIrcImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderFactoryIrcImpl.java
@@ -24,7 +24,7 @@ public class ProtocolProviderFactoryIrcImpl
{
public ProtocolProviderFactoryIrcImpl()
{
- super(IrcActivator.bundleContext, ProtocolNames.IRC);
+ super(IrcActivator.getBundleContext(), ProtocolNames.IRC);
}
/**
@@ -42,7 +42,7 @@ public ProtocolProviderFactoryIrcImpl()
public AccountID installAccount( String userIDStr,
Map accountProperties)
{
- BundleContext context = IrcActivator.bundleContext;
+ BundleContext context = IrcActivator.getBundleContext();
if (context == null)
throw new NullPointerException(
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java
index b3e4d7fda..5524419e3 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java
@@ -6,6 +6,7 @@
*/
package net.java.sip.communicator.impl.protocol.irc;
+import net.java.sip.communicator.service.certificate.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
@@ -25,7 +26,7 @@ public class ProtocolProviderServiceIrcImpl
/**
* The irc server.
*/
- private IrcStack ircStack;
+ private IrcStack ircStack = null;
/**
* The id of the account that this protocol provider represents.
@@ -150,6 +151,7 @@ public RegistrationState getRegistrationState()
{
return currentRegistrationState;
}
+
/**
* Starts the registration process.
diff --git a/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf
index 391100899..bf48200b9 100644
--- a/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf
+++ b/src/net/java/sip/communicator/impl/protocol/irc/irc.provider.manifest.mf
@@ -9,6 +9,7 @@ Import-Package: org.osgi.framework,
org.jitsi.service.resources,
net.java.sip.communicator.service.resources,
net.java.sip.communicator.util,
+ net.java.sip.communicator.service.certificate,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.event,
org.slf4j,