001package org.apache.maven.wagon.providers.ssh;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.mina.core.session.IoSession;
023import org.apache.sshd.SshServer;
024import org.apache.sshd.common.Session;
025import org.apache.sshd.common.session.AbstractSession;
026import org.apache.sshd.server.Command;
027import org.apache.sshd.server.CommandFactory;
028import org.apache.sshd.server.FileSystemFactory;
029import org.apache.sshd.server.FileSystemView;
030import org.apache.sshd.server.PasswordAuthenticator;
031import org.apache.sshd.server.SshFile;
032import org.apache.sshd.server.auth.UserAuthPassword;
033import org.apache.sshd.server.auth.UserAuthPublicKey;
034import org.apache.sshd.server.filesystem.NativeSshFile;
035import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
036import org.apache.sshd.server.session.SessionFactory;
037import org.apache.sshd.server.shell.ProcessShellFactory;
038import org.codehaus.plexus.util.FileUtils;
039
040import java.io.File;
041import java.io.IOException;
042import java.util.ArrayList;
043import java.util.Arrays;
044import java.util.List;
045
046/**
047 * @author Olivier Lamy
048 */
049public class SshServerEmbedded
050{
051    private String wagonProtocol;
052
053    private int port;
054
055    private SshServer sshd;
056
057    private List<String> sshKeysResources = new ArrayList<String>();
058
059    private TestPublickeyAuthenticator publickeyAuthenticator;
060
061    TestPasswordAuthenticator passwordAuthenticator = new TestPasswordAuthenticator();
062
063    private boolean keyAuthz;
064
065
066    /**
067     * @param wagonProtocol    scp scpexe
068     * @param sshKeysResources paths in the classlaoder with ssh keys
069     */
070    public SshServerEmbedded( String wagonProtocol, List<String> sshKeysResources, boolean keyAuthz )
071    {
072        this.wagonProtocol = wagonProtocol;
073
074        this.sshKeysResources = sshKeysResources;
075
076        this.sshd = SshServer.setUpDefaultServer();
077
078        //this.sshd.setKeyExchangeFactories(  );
079
080        this.keyAuthz = keyAuthz;
081
082        publickeyAuthenticator = new TestPublickeyAuthenticator( this.keyAuthz );
083    }
084
085    /**
086     * @return random port used
087     */
088    public int start()
089        throws IOException
090    {
091        sshd.setPort( 0 );
092
093        sshd.setUserAuthFactories( Arrays.asList( new UserAuthPublicKey.Factory(), new UserAuthPassword.Factory() ) );
094
095        sshd.setPublickeyAuthenticator( this.publickeyAuthenticator );
096
097        sshd.setPasswordAuthenticator( this.passwordAuthenticator );
098
099        sshd.setUserAuthFactories( Arrays.asList( new UserAuthPublicKey.Factory(), new UserAuthPassword.Factory() ) );
100
101        //ResourceKeyPairProvider resourceKeyPairProvider =
102        //    new ResourceKeyPairProvider( sshKeysResources.toArray( new String[sshKeysResources.size()] ) );
103
104        File path = new File( "target/keys" );
105        path.mkdirs();
106        path = new File( path, "simple.key" );
107        path.delete();
108
109        PEMGeneratorHostKeyProvider provider = new PEMGeneratorHostKeyProvider();
110        provider.setAlgorithm( "RSA" );
111        provider.setKeySize( 1024 );
112        provider.setPath( path.getPath() );
113
114        sshd.setKeyPairProvider( provider );
115        SessionFactory sessionFactory = new SessionFactory()
116        {
117            @Override
118            protected AbstractSession doCreateSession( IoSession ioSession )
119                throws Exception
120            {
121                return super.doCreateSession( ioSession );
122            }
123        };
124        sshd.setSessionFactory( sessionFactory );
125
126        //sshd.setFileSystemFactory(  );
127
128        final ProcessShellFactory processShellFactory =
129            new ProcessShellFactory( new String[]{ "/bin/sh", "-i", "-l" } );
130        sshd.setShellFactory( processShellFactory );
131
132        CommandFactory delegateCommandFactory = new CommandFactory()
133        {
134            public Command createCommand( String command )
135            {
136                return new ShellCommand( command );
137            }
138        };
139
140        ScpCommandFactory commandFactory = new ScpCommandFactory( delegateCommandFactory );
141        sshd.setCommandFactory( commandFactory );
142
143        FileSystemFactory fileSystemFactory = new FileSystemFactory()
144        {
145            public FileSystemView createFileSystemView( Session session )
146                throws IOException
147            {
148                return new FileSystemView()
149                {
150                    public SshFile getFile( String file )
151                    {
152                        file = file.replace( "\\", "" );
153                        file = file.replace( "\"", "" );
154                        File f = new File( FileUtils.normalize( file ) );
155
156                        return new SshServerEmbedded.TestSshFile( f.getAbsolutePath(), f,
157                                                                  System.getProperty( "user.name" ) );
158                    }
159
160                    public SshFile getFile( SshFile baseDir, String file )
161                    {
162                        file = file.replace( "\\", "" );
163                        file = file.replace( "\"", "" );
164                        File f = new File( FileUtils.normalize( file ) );
165                        return new SshServerEmbedded.TestSshFile( f.getAbsolutePath(), f,
166                                                                  System.getProperty( "user.name" ) );
167                    }
168                };
169            }
170        };
171        sshd.setNioWorkers( 0 );
172        //sshd.setScheduledExecutorService(  );
173        sshd.setFileSystemFactory( fileSystemFactory );
174        sshd.start();
175        this.port = sshd.getPort();
176        return this.port;
177    }
178
179
180    public void stop()
181        throws InterruptedException
182    {
183        sshd.stop( Boolean.getBoolean( "sshd.stopImmediatly" ) );
184    }
185
186    public int getPort()
187    {
188        return port;
189    }
190
191    public PasswordAuthenticator getPasswordAuthenticator()
192    {
193        return passwordAuthenticator;
194    }
195    /**
196     * 
197     */
198    public static class TestSshFile
199        extends NativeSshFile
200    {
201        public TestSshFile( String fileName, File file, String userName )
202        {
203
204            super( FileUtils.normalize( fileName ), file, userName );
205        }
206    }
207
208}