2 * Copyright (c) 2016 Brocade Communication Systems and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netconf.callhome.protocol;
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ImmutableSet;
12 import java.security.KeyPair;
13 import java.util.Collection;
14 import java.util.HashSet;
16 import org.apache.sshd.ClientSession;
17 import org.apache.sshd.client.session.ClientSessionImpl;
20 * Authorization context for incoming call home sessions.
22 * @see CallHomeAuthorizationProvider
24 public abstract class CallHomeAuthorization {
25 private static final CallHomeAuthorization REJECTED = new CallHomeAuthorization() {
28 public boolean isServerAllowed() {
33 protected String getSessionName() {
38 protected void applyTo(ClientSession session) {
39 throw new IllegalStateException("Server is not allowed.");
44 * Returns CallHomeAuthorization object with intent to
45 * reject incoming connection.
48 * {@link CallHomeAuthorizationProvider} may use returned object
50 * {@link CallHomeAuthorizationProvider#provideAuth(java.net.SocketAddress, java.security.PublicKey)}
51 * if the incoming session should be rejected due to policy implemented
54 * @return CallHomeAuthorization with {@code isServerAllowed() == false}
56 public static final CallHomeAuthorization rejected() {
61 * Creates a builder for CallHomeAuthorization with intent
62 * to accept incoming connection and to provide credentials.
65 * Note: If session with same sessionName is already opened and
66 * active, incoming session will be rejected.
68 * @param sessionName Application specific unique identifier for incoming session
69 * @param username Username to be used for authorization
70 * @return Builder which allows to specify credentials.
72 public static final Builder serverAccepted(String sessionName, String username) {
73 return new Builder(sessionName, username);
77 * Returns true if incomming connection is allowed.
79 * @return true if incoming connection from SSH Server is allowed.
81 public abstract boolean isServerAllowed();
84 * Applies provided authentification to Mina SSH Client Session.
86 * @param session Client Session to which authorization parameters will by applied
88 protected abstract void applyTo(ClientSession session);
90 protected abstract String getSessionName();
93 * Builder for CallHomeAuthorization which accepts incoming connection.
96 * Use {@link CallHomeAuthorization#serverAccepted(String, String)} to instantiate
99 public static class Builder implements org.opendaylight.yangtools.concepts.Builder<CallHomeAuthorization> {
101 private final String nodeId;
102 private final String username;
103 private Set<String> passwords = new HashSet<>();
104 private Set<KeyPair> clientKeys = new HashSet<>();
106 private Builder(String nodeId, String username) {
107 this.nodeId = Preconditions.checkNotNull(nodeId);
108 this.username = Preconditions.checkNotNull(username);
112 * Adds password, which will be used for password-based authorization.
114 * @param password Password to be used for password-based authorization.
115 * @return this builder.
117 public Builder addPassword(String password) {
118 this.passwords.add(password);
123 * Adds public / private key pair to be used for public-key based authorization.
125 * @param clientKey Keys to be used for authorization.
126 * @return this builder.
128 public Builder addClientKeys(KeyPair clientKey) {
129 this.clientKeys.add(clientKey);
134 public CallHomeAuthorization build() {
135 return new ServerAllowed(nodeId, username, passwords, clientKeys);
140 private static class ServerAllowed extends CallHomeAuthorization {
142 private final String nodeId;
143 private final String username;
144 private final Set<String> passwords;
145 private final Set<KeyPair> clientKeyPair;
147 ServerAllowed(String nodeId, String username, Collection<String> passwords,
148 Collection<KeyPair> clientKeyPairs) {
149 this.username = Preconditions.checkNotNull(username);
150 this.passwords = ImmutableSet.copyOf(passwords);
151 this.clientKeyPair = ImmutableSet.copyOf(clientKeyPairs);
152 this.nodeId = Preconditions.checkNotNull(nodeId);
156 protected String getSessionName() {
161 public boolean isServerAllowed() {
166 protected void applyTo(ClientSession session) {
167 Preconditions.checkArgument(session instanceof ClientSessionImpl);
168 ((ClientSessionImpl) session).setUsername(username);
170 // First try authentication using server host keys, else try password.
171 for (KeyPair keyPair : clientKeyPair) {
172 session.addPublicKeyIdentity(keyPair);
174 for (String password : passwords) {
175 session.addPasswordIdentity(password);