View Javadoc

1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, and individual contributors by the @author
5      tags. See the COPYRIGHT.txt in the distribution for a full listing of
6      individual contributors.
7   
8      All GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
20   */
21  package openr66.protocol.networkhandler.ssl;
22  
23  import goldengate.common.logging.GgInternalLogger;
24  import goldengate.common.logging.GgInternalLoggerFactory;
25  
26  import java.util.concurrent.ConcurrentHashMap;
27  
28  import openr66.protocol.configuration.Configuration;
29  import openr66.protocol.exception.OpenR66ProtocolNetworkException;
30  import openr66.protocol.networkhandler.NetworkServerHandler;
31  import openr66.protocol.utils.R66Future;
32  
33  import org.jboss.netty.channel.Channel;
34  import org.jboss.netty.channel.ChannelFuture;
35  import org.jboss.netty.channel.ChannelFutureListener;
36  import org.jboss.netty.channel.ChannelHandlerContext;
37  import org.jboss.netty.channel.ChannelStateEvent;
38  import org.jboss.netty.handler.ssl.SslHandler;
39  
40  /**
41   * @author Frederic Bregier
42   *
43   */
44  public class NetworkSslServerHandler extends NetworkServerHandler {
45      /**
46       * @param isServer
47       */
48      public NetworkSslServerHandler(boolean isServer) {
49          super(isServer);
50      }
51      /**
52       * Internal Logger
53       */
54      private static final GgInternalLogger logger = GgInternalLoggerFactory
55              .getLogger(NetworkSslServerHandler.class);
56      /**
57       * Waiter for SSL handshake is finished
58       */
59      private static final ConcurrentHashMap<Integer, R66Future> waitForSsl
60          = new ConcurrentHashMap<Integer, R66Future>();
61      /**
62       * Remover from SSL HashMap
63       */
64      private static final ChannelFutureListener remover = new ChannelFutureListener() {
65          public void operationComplete(ChannelFuture future) {
66              logger.debug("SSL remover");
67              waitForSsl.remove(future.getChannel().getId());
68          }
69      };
70      /**
71       * Add the Channel as SSL handshake is over
72       * @param channel
73       */
74      private static void addSslConnectedChannel(Channel channel) {
75          R66Future futureSSL = new R66Future(true);
76          waitForSsl.put(channel.getId(),futureSSL);
77          channel.getCloseFuture().addListener(remover);
78      }
79      /**
80       * Set the future of SSL handshake to status
81       * @param channel
82       * @param status
83       */
84      private static void setStatusSslConnectedChannel(Channel channel, boolean status) {
85          R66Future futureSSL = waitForSsl.get(channel.getId());
86          if (futureSSL != null) {
87              if (status) {
88                  futureSSL.setSuccess();
89              } else {
90                  futureSSL.cancel();
91              }
92          }
93      }
94      /**
95       *
96       * @param channel
97       * @return True if the SSL handshake is over and OK, else False
98       */
99      public static boolean isSslConnectedChannel(Channel channel) {
100         R66Future futureSSL = waitForSsl.get(channel.getId());
101         if (futureSSL == null) {
102             for (int i = 0; i < Configuration.RETRYNB; i++){
103                 futureSSL = waitForSsl.get(channel.getId());
104                 if (futureSSL != null)
105                     break;
106                 try {
107                     Thread.sleep(Configuration.RETRYINMS);
108                 } catch (InterruptedException e) {
109                 }
110             }
111         }
112         if (futureSSL == null) {
113             logger.debug("No wait For SSL found");
114             return false;
115         } else {
116             try {
117                 futureSSL.await(Configuration.configuration.TIMEOUTCON);
118             } catch (InterruptedException e) {
119             }
120             if (futureSSL.isDone()) {
121                 logger.debug("Wait For SSL: "+futureSSL.isSuccess());
122                 return futureSSL.isSuccess();
123             }
124             logger.error("Out of time for wait For SSL");
125             return false;
126         }
127     }
128 
129     /* (non-Javadoc)
130      * @see org.jboss.netty.channel.SimpleChannelHandler#channelOpen(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ChannelStateEvent)
131      */
132     @Override
133     public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
134             throws Exception {
135         Channel channel = e.getChannel();
136         logger.debug("Add channel to ssl");
137         addSslConnectedChannel(channel);
138         isSSL = true;
139         super.channelOpen(ctx, e);
140     }
141     /*
142      * (non-Javadoc)
143      *
144      * @see
145      * openr66.protocol.networkhandler.NetworkServerHandler#channelConnected
146      * (org.jboss.netty.channel.ChannelHandlerContext,
147      * org.jboss.netty.channel.ChannelStateEvent)
148      */
149     @Override
150     public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
151             throws OpenR66ProtocolNetworkException {
152         // Get the SslHandler in the current pipeline.
153         // We added it in NetworkSslServerPipelineFactory.
154         final SslHandler sslHandler = ctx.getPipeline().get(SslHandler.class);
155         if (sslHandler != null) {
156             // Get the SslHandler and begin handshake ASAP.
157             // Get notified when SSL handshake is done.
158             ChannelFuture handshakeFuture;
159             handshakeFuture = sslHandler.handshake();
160             handshakeFuture.addListener(new ChannelFutureListener() {
161                 public void operationComplete(ChannelFuture future)
162                         throws Exception {
163                     logger.debug("Handshake: "+future.isSuccess(),future.getCause());
164                     if (future.isSuccess()) {
165                         setStatusSslConnectedChannel(future.getChannel(), true);
166                     } else {
167                         if (Configuration.configuration.r66Mib != null) {
168                             String error2 = future.getCause() != null ?
169                                     future.getCause().getMessage() : "During Handshake";
170                             Configuration.configuration.r66Mib.notifyError(
171                                     "SSL Connection Error", error2);
172                         }
173                         setStatusSslConnectedChannel(future.getChannel(), false);
174                         future.getChannel().close();
175                     }
176                 }
177             });
178         } else {
179             logger.error("SSL Not found");
180         }
181         super.channelConnected(ctx, e);
182     }
183 }