View Javadoc

1   /*
2    * $Id: PGPSecurityFilter.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.module.pgp.filters;
12  
13  import org.mule.api.EncryptionStrategy;
14  import org.mule.api.MuleEvent;
15  import org.mule.api.MuleMessage;
16  import org.mule.api.lifecycle.InitialisationException;
17  import org.mule.api.security.Authentication;
18  import org.mule.api.security.SecurityContext;
19  import org.mule.api.security.UnauthorisedException;
20  import org.mule.api.security.UnknownAuthenticationTypeException;
21  import org.mule.config.i18n.CoreMessages;
22  import org.mule.module.pgp.PGPAuthentication;
23  import org.mule.module.pgp.PGPCryptInfo;
24  import org.mule.module.pgp.PGPKeyRing;
25  import org.mule.module.pgp.i18n.PGPMessages;
26  import org.mule.security.AbstractEndpointSecurityFilter;
27  
28  import cryptix.message.LiteralMessage;
29  import cryptix.message.Message;
30  import cryptix.message.MessageFactory;
31  import cryptix.message.SignedMessage;
32  import cryptix.pki.KeyBundle;
33  
34  import java.io.ByteArrayInputStream;
35  import java.util.Collection;
36  
37  import org.apache.commons.logging.Log;
38  import org.apache.commons.logging.LogFactory;
39  
40  public class PGPSecurityFilter extends AbstractEndpointSecurityFilter
41  {
42      /**
43       * logger used by this class
44       */
45      protected static final Log logger = LogFactory.getLog(PGPSecurityFilter.class);
46  
47      private EncryptionStrategy strategy;
48  
49      private String strategyName;
50  
51      private boolean signRequired;
52  
53      private PGPKeyRing keyManager;
54  
55      @Override
56      protected void authenticateInbound(MuleEvent event)
57          throws SecurityException, UnauthorisedException, UnknownAuthenticationTypeException
58      {
59          MuleMessage message = event.getMessage();
60  
61          String userId = (String)getCredentialsAccessor().getCredentials(event);
62  
63          byte[] creds = null;
64          try
65          {
66              creds = message.getPayloadAsBytes();
67              creds = strategy.decrypt(creds, null);
68          }
69          catch (Exception e1)
70          {
71              throw new UnauthorisedException(CoreMessages.failedToReadPayload(), event, e1);
72          }
73  
74          Authentication authentication;
75          try
76          {
77              authentication = new PGPAuthentication(userId, decodeMsgRaw(creds));
78          }
79          catch (Exception e1)
80          {
81              throw new UnauthorisedException(CoreMessages.failedToReadPayload(), event, e1);
82          }
83  
84          final Authentication authResult;
85          try
86          {
87              authResult = getSecurityManager().authenticate(authentication);
88          }
89          catch (Exception e)
90          {
91              // Authentication failed
92              if (logger.isDebugEnabled())
93              {
94                  logger.debug("Authentication request for user: " + userId + " failed: " + e.toString());
95              }
96  
97              throw new UnauthorisedException(CoreMessages.authFailedForUser(userId), event, e);
98          }
99  
100         // Authentication success
101         if (logger.isDebugEnabled())
102         {
103             logger.debug("Authentication success: " + authResult.toString());
104         }
105 
106         SecurityContext context = getSecurityManager().createSecurityContext(authResult);
107         event.getSession().setSecurityContext(context);
108 
109         try
110         {
111             updatePayload(message, getUnencryptedMessageWithoutSignature((PGPAuthentication)authResult), event);
112 //            TODO RequestContext.rewriteEvent(new DefaultMuleMessage(
113 //                getUnencryptedMessageWithoutSignature((PGPAuthentication)authResult)));
114         }
115         catch (Exception e2)
116         {
117             throw new UnauthorisedException(event, context, event.getEndpoint(), this);
118         }
119     }
120 
121     private Message decodeMsgRaw(byte[] raw) throws Exception
122     {
123         MessageFactory mf = MessageFactory.getInstance("OpenPGP");
124 
125         ByteArrayInputStream in = new ByteArrayInputStream(raw);
126 
127         Collection msgs = mf.generateMessages(in);
128 
129         return (Message)msgs.iterator().next();
130     }
131 
132     private String getUnencryptedMessageWithoutSignature(PGPAuthentication auth) throws Exception
133     {
134         Message msg = (Message)auth.getCredentials();
135 
136         if (msg instanceof SignedMessage)
137         {
138             msg = ((SignedMessage)msg).getContents();
139         }
140 
141         if (msg instanceof LiteralMessage)
142         {
143             return ((LiteralMessage)msg).getTextData();
144         }
145         else
146         {
147             throw new Exception("Wrong data");
148         }
149     }
150 
151     @Override
152     protected void authenticateOutbound(MuleEvent event) throws SecurityException, UnauthorisedException
153     {
154         logger.debug("authenticateOutbound:" + event.getId());
155 
156         if (!isAuthenticate())
157         {
158             return;
159         }
160 
161         MuleMessage message = event.getMessage();
162 
163         KeyBundle userKeyBundle = keyManager.getKeyBundle((String)getCredentialsAccessor().getCredentials(
164             event));
165 
166         final PGPCryptInfo cryptInfo = new PGPCryptInfo(userKeyBundle, signRequired);
167 
168         try
169         {
170             updatePayload(event.getMessage(), strategy.encrypt(message.getPayloadAsBytes(), cryptInfo), event);
171         }
172         catch (Exception e1)
173         {
174             throw new UnauthorisedException(CoreMessages.failedToReadPayload(), event, e1);
175         }
176     }
177 
178     @Override
179     protected void doInitialise() throws InitialisationException
180     {
181         if (strategyName != null)
182         {
183             strategy = endpoint.getMuleContext().getSecurityManager().getEncryptionStrategy(strategyName);
184         }
185 
186         if (strategy == null)
187         {
188             throw new InitialisationException(PGPMessages.encryptionStrategyNotSet(), this);
189         }
190     }
191 
192     public EncryptionStrategy getStrategy()
193     {
194         return strategy;
195     }
196 
197     public void setStrategy(EncryptionStrategy strategy)
198     {
199         this.strategy = strategy;
200     }
201 
202     public void setStrategyName(String name)
203     {
204         strategyName = name;
205     }
206 
207     public boolean isSignRequired()
208     {
209         return signRequired;
210     }
211 
212     public void setSignRequired(boolean signRequired)
213     {
214         this.signRequired = signRequired;
215     }
216 
217     public PGPKeyRing getKeyManager()
218     {
219         return keyManager;
220     }
221 
222     public void setKeyManager(PGPKeyRing keyManager)
223     {
224         this.keyManager = keyManager;
225     }
226 }