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