View Javadoc

1   package org.apache.maven.wagon.providers.ssh;
2   /*
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   */
20  
21  import org.apache.mina.util.Base64;
22  import org.apache.sshd.server.PublickeyAuthenticator;
23  import org.apache.sshd.server.session.ServerSession;
24  import org.codehaus.plexus.util.IOUtil;
25  
26  import javax.crypto.Cipher;
27  import java.io.InputStream;
28  import java.math.BigInteger;
29  import java.security.KeyFactory;
30  import java.security.PrivateKey;
31  import java.security.PublicKey;
32  import java.security.interfaces.RSAPublicKey;
33  import java.security.spec.DSAPublicKeySpec;
34  import java.security.spec.RSAPublicKeySpec;
35  import java.util.ArrayList;
36  import java.util.List;
37  
38  /**
39   * @author Olivier Lamy
40   */
41  public class TestPublickeyAuthenticator
42      implements PublickeyAuthenticator
43  {
44      public List<PublickeyAuthenticatorRequest> publickeyAuthenticatorRequests =
45          new ArrayList<PublickeyAuthenticatorRequest>();
46  
47      public boolean keyAuthz;
48  
49      public TestPublickeyAuthenticator( boolean keyAuthz )
50      {
51          this.keyAuthz = keyAuthz;
52      }
53  
54      public boolean authenticate( String username, PublicKey key, ServerSession session )
55      {
56          if ( !keyAuthz )
57          {
58              return false;
59          }
60          try
61          {
62              InputStream is =
63                  Thread.currentThread().getContextClassLoader().getResourceAsStream( "ssh-keys/id_rsa.pub" );
64              PublicKey publicKey = decodePublicKey( IOUtil.toString( is ) );
65              publickeyAuthenticatorRequests.add( new PublickeyAuthenticatorRequest( username, key ) );
66  
67              return ( (RSAPublicKey) publicKey ).getModulus().equals( ( (RSAPublicKey) publicKey ).getModulus() );
68          }
69          catch ( Exception e )
70          {
71              throw new RuntimeException( e.getMessage(), e );
72          }
73      }
74  
75      public static byte[] decrypt( byte[] text, PrivateKey key )
76          throws Exception
77      {
78          byte[] dectyptedText = null;
79          Cipher cipher = Cipher.getInstance( "RSA/ECB/PKCS1Padding" );
80          cipher.init( Cipher.DECRYPT_MODE, key );
81          dectyptedText = cipher.doFinal( text );
82          return dectyptedText;
83      }
84  
85      public static class PublickeyAuthenticatorRequest
86      {
87          public String username;
88  
89          public PublicKey publicKey;
90  
91          public PublickeyAuthenticatorRequest( String username, PublicKey publicKey )
92          {
93              this.username = username;
94              this.publicKey = publicKey;
95          }
96  
97          @Override
98          public String toString()
99          {
100             final StringBuilder sb = new StringBuilder();
101             sb.append( "PublickeyAuthenticatorRequest" );
102             sb.append( "{username='" ).append( username ).append( '\'' );
103             sb.append( ", publicKey=" ).append( publicKey );
104             sb.append( '}' );
105             return sb.toString();
106         }
107     }
108 
109     private byte[] bytes;
110 
111     private int pos;
112 
113     public PublicKey decodePublicKey( String keyLine )
114         throws Exception
115     {
116         bytes = null;
117         pos = 0;
118 
119         for ( String part : keyLine.split( " " ) )
120         {
121             if ( part.startsWith( "AAAA" ) )
122             {
123                 bytes = Base64.decodeBase64( part.getBytes() );
124                 break;
125             }
126         }
127         if ( bytes == null )
128         {
129             throw new IllegalArgumentException( "no Base64 part to decode" );
130         }
131 
132         String type = decodeType();
133         if ( type.equals( "ssh-rsa" ) )
134         {
135             BigInteger e = decodeBigInt();
136             BigInteger m = decodeBigInt();
137             RSAPublicKeySpec spec = new RSAPublicKeySpec( m, e );
138             return KeyFactory.getInstance( "RSA" ).generatePublic( spec );
139         }
140         else if ( type.equals( "ssh-dss" ) )
141         {
142             BigInteger p = decodeBigInt();
143             BigInteger q = decodeBigInt();
144             BigInteger g = decodeBigInt();
145             BigInteger y = decodeBigInt();
146             DSAPublicKeySpec spec = new DSAPublicKeySpec( y, p, q, g );
147             return KeyFactory.getInstance( "DSA" ).generatePublic( spec );
148         }
149         else
150         {
151             throw new IllegalArgumentException( "unknown type " + type );
152         }
153     }
154 
155     private String decodeType()
156     {
157         int len = decodeInt();
158         String type = new String( bytes, pos, len );
159         pos += len;
160         return type;
161     }
162 
163     private int decodeInt()
164     {
165         return ( ( bytes[pos++] & 0xFF ) << 24 ) | ( ( bytes[pos++] & 0xFF ) << 16 ) | ( ( bytes[pos++] & 0xFF ) << 8 )
166             | ( bytes[pos++] & 0xFF );
167     }
168 
169     private BigInteger decodeBigInt()
170     {
171         int len = decodeInt();
172         byte[] bigIntBytes = new byte[len];
173         System.arraycopy( bytes, pos, bigIntBytes, 0, len );
174         pos += len;
175         return new BigInteger( bigIntBytes );
176     }
177 
178 }