1 package org.apache.maven.wagon.providers.ssh;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.mina.util.Base64;
23 import org.apache.sshd.server.PublickeyAuthenticator;
24 import org.apache.sshd.server.session.ServerSession;
25 import org.codehaus.plexus.util.IOUtil;
26
27 import javax.crypto.Cipher;
28 import java.io.InputStream;
29 import java.math.BigInteger;
30 import java.security.KeyFactory;
31 import java.security.PrivateKey;
32 import java.security.PublicKey;
33 import java.security.interfaces.RSAPublicKey;
34 import java.security.spec.DSAPublicKeySpec;
35 import java.security.spec.RSAPublicKeySpec;
36 import java.util.ArrayList;
37 import java.util.List;
38
39
40
41
42 public class TestPublickeyAuthenticator
43 implements PublickeyAuthenticator
44 {
45 private List<PublickeyAuthenticatorRequest> publickeyAuthenticatorRequests =
46 new ArrayList<PublickeyAuthenticatorRequest>();
47
48 private boolean keyAuthz;
49
50 public TestPublickeyAuthenticator( boolean keyAuthz )
51 {
52 this.keyAuthz = keyAuthz;
53 }
54
55 public boolean authenticate( String username, PublicKey key, ServerSession session )
56 {
57 if ( !keyAuthz )
58 {
59 return false;
60 }
61 InputStream in = null;
62 try
63 {
64 in = Thread.currentThread().getContextClassLoader().getResourceAsStream( "ssh-keys/id_rsa.pub" );
65 PublicKey publicKey = decodePublicKey( IOUtil.toString( in ) );
66 in.close();
67 in = null;
68
69 publickeyAuthenticatorRequests.add( new PublickeyAuthenticatorRequest( username, key ) );
70
71 return ( (RSAPublicKey) publicKey ).getModulus().equals( ( (RSAPublicKey) publicKey ).getModulus() );
72 }
73 catch ( Exception e )
74 {
75 throw new RuntimeException( e.getMessage(), e );
76 }
77 finally
78 {
79 IOUtil.close( in );
80 }
81 }
82
83 public static byte[] decrypt( byte[] text, PrivateKey key )
84 throws Exception
85 {
86 byte[] dectyptedText = null;
87 Cipher cipher = Cipher.getInstance( "RSA/ECB/PKCS1Padding" );
88 cipher.init( Cipher.DECRYPT_MODE, key );
89 dectyptedText = cipher.doFinal( text );
90 return dectyptedText;
91 }
92
93
94
95
96 public static class PublickeyAuthenticatorRequest
97 {
98 private String username;
99
100 private PublicKey publicKey;
101
102 public PublickeyAuthenticatorRequest( String username, PublicKey publicKey )
103 {
104 this.username = username;
105 this.publicKey = publicKey;
106 }
107
108 @Override
109 public String toString()
110 {
111 final StringBuilder sb = new StringBuilder();
112 sb.append( "PublickeyAuthenticatorRequest" );
113 sb.append( "{username='" ).append( username ).append( '\'' );
114 sb.append( ", publicKey=" ).append( publicKey );
115 sb.append( '}' );
116 return sb.toString();
117 }
118 }
119
120 private byte[] bytes;
121
122 private int pos;
123
124 public PublicKey decodePublicKey( String keyLine )
125 throws Exception
126 {
127 bytes = null;
128 pos = 0;
129
130 for ( String part : keyLine.split( " " ) )
131 {
132 if ( part.startsWith( "AAAA" ) )
133 {
134 bytes = Base64.decodeBase64( part.getBytes() );
135 break;
136 }
137 }
138 if ( bytes == null )
139 {
140 throw new IllegalArgumentException( "no Base64 part to decode" );
141 }
142
143 String type = decodeType();
144 if ( type.equals( "ssh-rsa" ) )
145 {
146 BigInteger e = decodeBigInt();
147 BigInteger m = decodeBigInt();
148 RSAPublicKeySpec spec = new RSAPublicKeySpec( m, e );
149 return KeyFactory.getInstance( "RSA" ).generatePublic( spec );
150 }
151 else if ( type.equals( "ssh-dss" ) )
152 {
153 BigInteger p = decodeBigInt();
154 BigInteger q = decodeBigInt();
155 BigInteger g = decodeBigInt();
156 BigInteger y = decodeBigInt();
157 DSAPublicKeySpec spec = new DSAPublicKeySpec( y, p, q, g );
158 return KeyFactory.getInstance( "DSA" ).generatePublic( spec );
159 }
160 else
161 {
162 throw new IllegalArgumentException( "unknown type " + type );
163 }
164 }
165
166 private String decodeType()
167 {
168 int len = decodeInt();
169 String type = new String( bytes, pos, len );
170 pos += len;
171 return type;
172 }
173
174 private int decodeInt()
175 {
176
177 return ( ( bytes[pos++] & 0xFF ) << 24 ) | ( ( bytes[pos++] & 0xFF ) << 16 ) | ( ( bytes[pos++] & 0xFF ) << 8 )
178 | ( bytes[pos++] & 0xFF );
179
180 }
181
182 private BigInteger decodeBigInt()
183 {
184 int len = decodeInt();
185 byte[] bigIntBytes = new byte[len];
186 System.arraycopy( bytes, pos, bigIntBytes, 0, len );
187 pos += len;
188 return new BigInteger( bigIntBytes );
189 }
190
191 }