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 static java.util.Objects.requireNonNull;
12 import com.google.common.collect.ImmutableSet;
13 import java.security.KeyPair;
14 import java.util.Collection;
15 import java.util.HashSet;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.netconf.shaded.sshd.client.session.ClientSession;
21 * Authorization context for incoming call home sessions.
23 * @see CallHomeAuthorizationProvider
25 public abstract class CallHomeAuthorization {
26 private static final CallHomeAuthorization REJECTED = new CallHomeAuthorization() {
29 public boolean isServerAllowed() {
34 protected String getSessionName() {
39 protected void applyTo(final ClientSession session) {
40 throw new IllegalStateException("Server is not allowed.");
45 * Returns CallHomeAuthorization object with intent to
46 * reject incoming connection.
49 * {@link CallHomeAuthorizationProvider} may use returned object
51 * {@link CallHomeAuthorizationProvider#provideAuth(java.net.SocketAddress, java.security.PublicKey)}
52 * if the incoming session should be rejected due to policy implemented
55 * @return CallHomeAuthorization with {@code isServerAllowed() == false}
57 public static final CallHomeAuthorization rejected() {
62 * Creates a builder for CallHomeAuthorization with intent
63 * to accept incoming connection and to provide credentials.
66 * Note: If session with same sessionName is already opened and
67 * active, incoming session will be rejected.
69 * @param sessionName Application specific unique identifier for incoming session
70 * @param username Username to be used for authorization
71 * @return Builder which allows to specify credentials.
73 public static final Builder serverAccepted(final String sessionName, final String username) {
74 return new Builder(sessionName, username);
78 * Returns true if incomming connection is allowed.
80 * @return true if incoming connection from SSH Server is allowed.
82 public abstract boolean isServerAllowed();
85 * Applies provided authentification to Mina SSH Client Session.
87 * @param session Client Session to which authorization parameters will by applied
89 protected abstract void applyTo(ClientSession session);
91 protected abstract String getSessionName();
94 * Builder for CallHomeAuthorization which accepts incoming connection.
97 * Use {@link CallHomeAuthorization#serverAccepted(String, String)} to instantiate builder.
99 public static class Builder {
100 private final String nodeId;
101 private final String username;
102 private final Set<String> passwords = new HashSet<>();
103 private final Set<KeyPair> clientKeys = new HashSet<>();
105 Builder(final String nodeId, final String username) {
106 this.nodeId = requireNonNull(nodeId);
107 this.username = requireNonNull(username);
111 * Adds password, which will be used for password-based authorization.
113 * @param password Password to be used for password-based authorization.
114 * @return this builder.
116 public Builder addPassword(final String password) {
117 passwords.add(password);
122 * Adds public / private key pair to be used for public-key based authorization.
124 * @param clientKey Keys to be used for authorization.
125 * @return this builder.
127 public Builder addClientKeys(final KeyPair clientKey) {
128 clientKeys.add(clientKey);
132 public @NonNull CallHomeAuthorization build() {
133 return new ServerAllowed(nodeId, username, passwords, clientKeys);
137 private static final class ServerAllowed extends CallHomeAuthorization {
138 private final String nodeId;
139 private final String username;
140 private final Set<String> passwords;
141 private final Set<KeyPair> clientKeyPair;
143 ServerAllowed(final String nodeId, final String username, final Collection<String> passwords,
144 final Collection<KeyPair> clientKeyPairs) {
145 this.username = requireNonNull(username);
146 this.passwords = ImmutableSet.copyOf(passwords);
147 clientKeyPair = ImmutableSet.copyOf(clientKeyPairs);
148 this.nodeId = requireNonNull(nodeId);
152 protected String getSessionName() {
157 public boolean isServerAllowed() {
162 protected void applyTo(final ClientSession session) {
163 session.setUsername(username);
165 // First try authentication using server host keys, else try password.
166 for (KeyPair keyPair : clientKeyPair) {
167 session.addPublicKeyIdentity(keyPair);
169 for (String password : passwords) {
170 session.addPasswordIdentity(password);