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