Subversion Repositories Programming Utils

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
86 rm5248 1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License.  You may obtain a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
package org.apache.sshd;
20
 
21
import java.io.ByteArrayOutputStream;
22
import java.io.IOException;
23
import java.io.OutputStream;
24
import java.security.KeyPair;
25
import java.security.PublicKey;
26
import java.util.List;
27
 
28
import org.apache.sshd.agent.SshAgent;
29
import org.apache.sshd.agent.local.LocalAgentFactory;
30
import org.apache.sshd.agent.local.ProxyAgentFactory;
31
import org.apache.sshd.agent.unix.AgentClient;
32
import org.apache.sshd.agent.unix.AgentServer;
33
import org.apache.sshd.client.channel.ChannelShell;
34
import org.apache.sshd.common.KeyPairProvider;
35
import org.apache.sshd.common.util.SecurityUtils;
36
import org.apache.sshd.server.Command;
37
import org.apache.sshd.server.Environment;
38
import org.apache.sshd.util.BaseTest;
39
import org.apache.sshd.util.BogusPasswordAuthenticator;
40
import org.apache.sshd.util.BogusPublickeyAuthenticator;
41
import org.apache.sshd.util.EchoShellFactory;
42
import org.apache.sshd.util.Utils;
43
import org.junit.Test;
44
 
45
import static org.apache.sshd.util.Utils.createTestKeyPairProvider;
46
import static org.apache.sshd.util.Utils.getFreePort;
47
import static org.hamcrest.CoreMatchers.notNullValue;
48
import static org.junit.Assert.assertEquals;
49
import static org.junit.Assert.assertNotNull;
50
import static org.junit.Assert.assertTrue;
51
import static org.junit.Assume.assumeThat;
52
 
53
public class AgentTest extends BaseTest {
54
 
55
    @Test
56
    public void testAgent() throws Exception {
57
        // TODO: revisit this test to work without BC
58
        if (!SecurityUtils.isBouncyCastleRegistered()) {
59
            return;
60
        }
61
 
62
        AgentServer agent = new AgentServer();
63
        String authSocket;
64
        try {
65
            authSocket = agent.start();
66
        } catch (UnsatisfiedLinkError e) {
67
            // the native library is not available, so these tests should be skipped
68
            authSocket = null;
69
        }
70
        assumeThat(authSocket, notNullValue());
71
 
72
        SshAgent client = new AgentClient(authSocket);
73
        List<SshAgent.Pair<PublicKey, String>> keys = client.getIdentities();
74
        assertNotNull(keys);
75
        assertEquals(0, keys.size());
76
 
77
        KeyPair k = Utils.createTestHostKeyProvider().loadKey(KeyPairProvider.SSH_RSA);
78
        client.addIdentity(k, "");
79
        keys = client.getIdentities();
80
        assertNotNull(keys);
81
        assertEquals(1, keys.size());
82
 
83
        client.removeIdentity(k.getPublic());
84
        keys = client.getIdentities();
85
        assertNotNull(keys);
86
        assertEquals(0, keys.size());
87
 
88
        client.removeAllIdentities();
89
 
90
        client.close();
91
 
92
        agent.close();
93
    }
94
 
95
    @Test
96
    public void testAgentForwarding() throws Exception {
97
        // TODO: revisit this test to work without BC
98
        if (!SecurityUtils.isBouncyCastleRegistered()) {
99
            return;
100
        }
101
 
102
        int port1 = getFreePort();
103
        int port2 = getFreePort();
104
 
105
        TestEchoShellFactory shellFactory = new TestEchoShellFactory();
106
        ProxyAgentFactory agentFactory = new ProxyAgentFactory();
107
        LocalAgentFactory localAgentFactory = new LocalAgentFactory();
108
 
109
        KeyPair pair = createTestKeyPairProvider("dsaprivkey.pem").loadKey(KeyPairProvider.SSH_DSS);
110
        localAgentFactory.getAgent().addIdentity(pair, "smx");
111
 
112
        SshServer sshd1 = SshServer.setUpDefaultServer();
113
        sshd1.setPort(port1);
114
        sshd1.setKeyPairProvider(Utils.createTestHostKeyProvider());
115
        sshd1.setShellFactory(shellFactory);
116
        sshd1.setPasswordAuthenticator(new BogusPasswordAuthenticator());
117
        sshd1.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
118
        sshd1.setAgentFactory(agentFactory);
119
        sshd1.start();
120
 
121
        SshServer sshd2 = SshServer.setUpDefaultServer();
122
        sshd2.setPort(port2);
123
        sshd2.setKeyPairProvider(Utils.createTestHostKeyProvider());
124
        sshd2.setShellFactory(new TestEchoShellFactory());
125
        sshd2.setPasswordAuthenticator(new BogusPasswordAuthenticator());
126
        sshd2.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
127
        sshd2.setAgentFactory(new ProxyAgentFactory());
128
        sshd2.start();
129
 
130
        SshClient client1 = SshClient.setUpDefaultClient();
131
        client1.setAgentFactory(localAgentFactory);
132
        client1.start();
133
        ClientSession session1 = client1.connect("smx", "localhost", port1).await().getSession();
134
        session1.auth().verify();
135
        ChannelShell channel1 = session1.createShellChannel();
136
        ByteArrayOutputStream out = new ByteArrayOutputStream();
137
        ByteArrayOutputStream err = new ByteArrayOutputStream();
138
        channel1.setOut(out);
139
        channel1.setErr(err);
140
        channel1.setAgentForwarding(true);
141
        channel1.open().await();
142
        OutputStream pipedIn = channel1.getInvertedIn();
143
 
144
        synchronized (shellFactory.shell) {
145
            System.out.println("Possibly waiting for remote shell to start");
146
            if (!shellFactory.shell.started) {
147
                shellFactory.shell.wait();
148
            }
149
        }
150
 
151
        SshClient client2 = SshClient.setUpDefaultClient();
152
        client2.setAgentFactory(agentFactory);
153
        client2.getProperties().putAll(shellFactory.shell.getEnvironment().getEnv());
154
        client2.start();
155
        ClientSession session2 = client2.connect("smx", "localhost", port2).await().getSession();
156
        session2.auth().verify();
157
        ChannelShell channel2 = session2.createShellChannel();
158
        channel2.setIn(shellFactory.shell.getIn());
159
        channel2.setOut(shellFactory.shell.getOut());
160
        channel2.setErr(shellFactory.shell.getErr());
161
        channel2.setAgentForwarding(true);
162
        channel2.open().await();
163
 
164
        pipedIn.write("foo\n".getBytes());
165
        pipedIn.flush();
166
 
167
        Thread.sleep(1000);
168
 
169
        System.out.println(out.toString());
170
        System.err.println(err.toString());
171
 
172
        sshd1.stop(true);
173
        sshd2.stop(true);
174
        client1.stop();
175
        client2.stop();
176
 
177
    }
178
 
179
    public static class TestEchoShellFactory extends EchoShellFactory {
180
 
181
        TestEchoShell shell = new TestEchoShell();
182
 
183
        @Override
184
        public Command create() {
185
            return shell;
186
        }
187
 
188
        public class TestEchoShell extends EchoShell {
189
 
190
            boolean started;
191
 
192
            @Override
193
            public synchronized void start(Environment env) throws IOException {
194
                super.start(env);
195
                started = true;
196
                notifyAll();
197
            }
198
 
199
        }
200
    }
201
 
202
}