You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2013/07/17 16:32:15 UTC
[2/4] git commit: Code formatting
Code formatting
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/34098dac
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/34098dac
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/34098dac
Branch: refs/heads/master
Commit: 34098dac637f452f8a14ef19cc55511b6d261924
Parents: 5bb8366
Author: Guillaume Nodet <gn...@apache.org>
Authored: Wed Jul 17 09:03:35 2013 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Wed Jul 17 09:03:35 2013 +0200
----------------------------------------------------------------------
.../apache/sshd/server/HandshakingUserAuth.java | 96 ++--
.../sshd/server/auth/gss/CredentialHelper.java | 162 +++---
.../sshd/server/auth/gss/GSSAuthenticator.java | 180 +++---
.../sshd/server/auth/gss/UserAuthGSS.java | 550 +++++++++----------
.../sshd/server/session/ServerSession.java | 106 ++--
5 files changed, 539 insertions(+), 555 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/34098dac/sshd-core/src/main/java/org/apache/sshd/server/HandshakingUserAuth.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/HandshakingUserAuth.java b/sshd-core/src/main/java/org/apache/sshd/server/HandshakingUserAuth.java
index 485e00f..625f7ba 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/HandshakingUserAuth.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/HandshakingUserAuth.java
@@ -24,57 +24,55 @@ import org.apache.sshd.server.session.ServerSession;
/**
* Extension of UserAuth for use with methods which require handshakes, such as gssapi-with-mic.
- *
+ *
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public interface HandshakingUserAuth extends UserAuth {
-
- /**
- * Set the service name from the original request. This may be required for MIC verification later.
- *
- * @param service The service name
- */
-
- void setServiceName(String service);
-
- /**
- * Check whether a particular message is handled here.
- *
- * @param msg The message
- *
- * @return <code>true</code> if the message is handled
- */
-
- boolean handles(SshConstants.Message msg);
-
- /**
- * Handle another step in the authentication process.
- *
- * @param session the current ssh session
- * @param msg The message type
- * @param buffer the request buffer containing parameters specific to this request
- * @return <code>true</code> if the authentication succeeded, <code>false</code> if the authentication
- * is not finished yet
- * @throws Exception if the authentication fails
- */
-
- Boolean next(ServerSession session, SshConstants.Message msg, Buffer buffer) throws Exception;
-
- /**
- * Get a user name which has been derived from the handshaking process, or the intial name if
- * nothing has been found.
- *
- * @return The user name
- *
- * @throws Exception if the request fails
- */
-
- String getUserName() throws Exception;
-
- /**
- * Free any system resources used by the module.
- */
-
- void destroy();
+
+ /**
+ * Set the service name from the original request. This may be required for MIC verification later.
+ *
+ * @param service The service name
+ */
+
+ void setServiceName(String service);
+
+ /**
+ * Check whether a particular message is handled here.
+ *
+ * @param msg The message
+ * @return <code>true</code> if the message is handled
+ */
+
+ boolean handles(SshConstants.Message msg);
+
+ /**
+ * Handle another step in the authentication process.
+ *
+ * @param session the current ssh session
+ * @param msg The message type
+ * @param buffer the request buffer containing parameters specific to this request
+ * @return <code>true</code> if the authentication succeeded, <code>false</code> if the authentication
+ * is not finished yet
+ * @throws Exception if the authentication fails
+ */
+
+ Boolean next(ServerSession session, SshConstants.Message msg, Buffer buffer) throws Exception;
+
+ /**
+ * Get a user name which has been derived from the handshaking process, or the intial name if
+ * nothing has been found.
+ *
+ * @return The user name
+ * @throws Exception if the request fails
+ */
+
+ String getUserName() throws Exception;
+
+ /**
+ * Free any system resources used by the module.
+ */
+
+ void destroy();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/34098dac/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/CredentialHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/CredentialHelper.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/CredentialHelper.java
index 91cca9f..37ce5d3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/CredentialHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/CredentialHelper.java
@@ -39,94 +39,92 @@ import org.ietf.jgss.GSSManager;
*/
public class CredentialHelper {
-
- public static GSSCredential creds(GSSManager mgr, String spn, String keytab) throws LoginException, GSSException {
- LoginContext lc = new LoginContext("x", null, null, new FixedLoginConfiguration(spn, keytab));
-
- lc.login();
-
- try {
- return (GSSCredential) Subject.doAs(lc.getSubject(), new G(mgr));
- } catch (PrivilegedActionException e) {
- throw (GSSException) e.getCause();
- }
- }
-
- /**
- * A login configuration which is defined from code.
- *
- * @author Richard Evans
- */
-
- private static class FixedLoginConfiguration extends Configuration {
-
- private AppConfigurationEntry entry;
-
- /**
- * Constructor.
- */
-
- private FixedLoginConfiguration(String spn, String keytab) {
- Map<String, String> parms = new HashMap<String, String>();
-
- parms.put("isInitiator", "false");
- parms.put("principal", spn);
- parms.put("useKeyTab", "true");
- parms.put("storeKey", "true");
-
- if (keytab != null) {
- parms.put("keyTab", keytab);
- }
-
- entry = new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, parms);
- }
-
- /**
- * Get the configuration entries for a name.
- *
- * @param name The name
- *
- * @return The entries, or <code>null</code> if the name is not known
- */
-
- public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
- return new AppConfigurationEntry [] { entry };
- }
- /**
- * Refresh the configuration. Nothing to do here.
- */
-
- public void refresh() {
+ public static GSSCredential creds(GSSManager mgr, String spn, String keytab) throws LoginException, GSSException {
+ LoginContext lc = new LoginContext("x", null, null, new FixedLoginConfiguration(spn, keytab));
+
+ lc.login();
+
+ try {
+ return (GSSCredential) Subject.doAs(lc.getSubject(), new G(mgr));
+ } catch (PrivilegedActionException e) {
+ throw (GSSException) e.getCause();
+ }
}
- }
-
- /**
- * Privileged action which runs as the subject to get the credentials.
- */
-
- private static final class G implements PrivilegedExceptionAction<GSSCredential> {
-
- private GSSManager mgr;
-
+
/**
- * @param mgr The existing GSS manager
+ * A login configuration which is defined from code.
+ *
+ * @author Richard Evans
*/
-
- private G(GSSManager mgr) {
- this.mgr = mgr;
+
+ private static class FixedLoginConfiguration extends Configuration {
+
+ private AppConfigurationEntry entry;
+
+ /**
+ * Constructor.
+ */
+
+ private FixedLoginConfiguration(String spn, String keytab) {
+ Map<String, String> parms = new HashMap<String, String>();
+
+ parms.put("isInitiator", "false");
+ parms.put("principal", spn);
+ parms.put("useKeyTab", "true");
+ parms.put("storeKey", "true");
+
+ if (keytab != null) {
+ parms.put("keyTab", keytab);
+ }
+
+ entry = new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule", AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, parms);
+ }
+
+ /**
+ * Get the configuration entries for a name.
+ *
+ * @param name The name
+ * @return The entries, or <code>null</code> if the name is not known
+ */
+
+ public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+ return new AppConfigurationEntry[]{entry};
+ }
+
+ /**
+ * Refresh the configuration. Nothing to do here.
+ */
+
+ public void refresh() {
+ }
}
-
+
/**
- * Do the action.
- *
- * @return The new credentials
- *
- * @throws GSSException If an error occurred
+ * Privileged action which runs as the subject to get the credentials.
*/
-
- public GSSCredential run() throws GSSException {
- return mgr.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, UserAuthGSS.KRB5_MECH, GSSCredential.ACCEPT_ONLY);
+
+ private static final class G implements PrivilegedExceptionAction<GSSCredential> {
+
+ private GSSManager mgr;
+
+ /**
+ * @param mgr The existing GSS manager
+ */
+
+ private G(GSSManager mgr) {
+ this.mgr = mgr;
+ }
+
+ /**
+ * Do the action.
+ *
+ * @return The new credentials
+ * @throws GSSException If an error occurred
+ */
+
+ public GSSCredential run() throws GSSException {
+ return mgr.createCredential(null, GSSCredential.INDEFINITE_LIFETIME, UserAuthGSS.KRB5_MECH, GSSCredential.ACCEPT_ONLY);
+ }
}
- }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/34098dac/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/GSSAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/GSSAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/GSSAuthenticator.java
index fd988b9..96ef66b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/GSSAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/GSSAuthenticator.java
@@ -31,101 +31,97 @@ import org.ietf.jgss.GSSManager;
/**
* Class providing basic GSS authentication services. Can be used as-is, but is often extended to provide environment
* specific implementations.
- *
+ *
* @author Richard Evans
*/
public class GSSAuthenticator {
-
- // Options:
- //
- // Service principal name: if unset, use host/hostname
-
- private String servicePrincipalName;
-
- // Location of Kerberos key table; if unset use default
-
- private String keytabFile;
-
- /**
- * Overridable method to get GSS manager suitable for current environment.
- *
- * @return A new manager
- */
-
- public GSSManager getGSSManager() {
- return GSSManager.getInstance();
- }
-
- /**
- * Overridable method to get GSS accept credential suitable for the current environment. The default
- * implementation uses a Kerberos key table.
- *
- * @param mgr The GSS manager
- *
- * @return The credential; if the result is <code>null</code> gssapi authentication fails immediately
- *
- * @throws UnknownHostException If the local host name could not be determined
- * @throws LoginException If the subject could not be found
- * @throws GSSException If the credential could not be obtained
- */
-
- public GSSCredential getGSSCredential(GSSManager mgr) throws UnknownHostException, LoginException, GSSException {
-
- String name = servicePrincipalName;
-
- if (name == null) {
- name = "host/" + InetAddress.getLocalHost().getCanonicalHostName();
+
+ // Options:
+ //
+ // Service principal name: if unset, use host/hostname
+
+ private String servicePrincipalName;
+
+ // Location of Kerberos key table; if unset use default
+
+ private String keytabFile;
+
+ /**
+ * Overridable method to get GSS manager suitable for current environment.
+ *
+ * @return A new manager
+ */
+
+ public GSSManager getGSSManager() {
+ return GSSManager.getInstance();
+ }
+
+ /**
+ * Overridable method to get GSS accept credential suitable for the current environment. The default
+ * implementation uses a Kerberos key table.
+ *
+ * @param mgr The GSS manager
+ * @return The credential; if the result is <code>null</code> gssapi authentication fails immediately
+ * @throws UnknownHostException If the local host name could not be determined
+ * @throws LoginException If the subject could not be found
+ * @throws GSSException If the credential could not be obtained
+ */
+
+ public GSSCredential getGSSCredential(GSSManager mgr) throws UnknownHostException, LoginException, GSSException {
+
+ String name = servicePrincipalName;
+
+ if (name == null) {
+ name = "host/" + InetAddress.getLocalHost().getCanonicalHostName();
+ }
+
+ return CredentialHelper.creds(mgr, name, keytabFile);
+ }
+
+ /**
+ * Validate the user name passed in the initial SSH_MSG_USERAUTH_REQUEST message. This is sort of mandated by RFC 4462, but it
+ * may be more useful to wait for the GSS negotiation to complete. The default implementation here always succeeds.
+ *
+ * @param session The current session
+ * @param user The user name from the initial request
+ * @return <code>true</code> if the user is valid, <code>false</code> if invalid
+ */
+
+ public boolean validateInitialUser(ServerSession session, String user) {
+ return true;
+ }
+
+ /**
+ * Validate the source identity obtained from the context after negotiation is complete.
+ * The default implementation here always succeeds.
+ *
+ * @param session The current session
+ * @param identity The identity from the GSS context
+ * @return <code>true</code> if the identity is valid, <code>false</code> if invalid
+ */
+
+ public boolean validateIdentity(ServerSession session, String identity) {
+ return true;
+ }
+
+ /**
+ * Set the service principal name to be used. The default is host/hostname.
+ *
+ * @param servicePrincipalName The principal name
+ */
+
+ public void setServicePrincipalName(String servicePrincipalName) {
+ this.servicePrincipalName = servicePrincipalName;
+ }
+
+ /**
+ * Set the location of the Kerberos keytab. The default is defined by the JRE.
+ *
+ * @param keytabFile The location of the keytab
+ */
+
+ public void setKeytabFile(String keytabFile) {
+ this.keytabFile = keytabFile;
}
-
- return CredentialHelper.creds(mgr, name, keytabFile);
- }
-
- /**
- * Validate the user name passed in the initial SSH_MSG_USERAUTH_REQUEST message. This is sort of mandated by RFC 4462, but it
- * may be more useful to wait for the GSS negotiation to complete. The default implementation here always succeeds.
- *
- * @param session The current session
- * @param user The user name from the initial request
- *
- * @return <code>true</code> if the user is valid, <code>false</code> if invalid
- */
-
- public boolean validateInitialUser(ServerSession session, String user) {
- return true;
- }
-
- /**
- * Validate the source identity obtained from the context after negotiation is complete.
- * The default implementation here always succeeds.
- *
- * @param session The current session
- * @param identity The identity from the GSS context
- *
- * @return <code>true</code> if the identity is valid, <code>false</code> if invalid
- */
-
- public boolean validateIdentity(ServerSession session, String identity) {
- return true;
- }
-
- /**
- * Set the service principal name to be used. The default is host/hostname.
- *
- * @param servicePrincipalName The principal name
- */
-
- public void setServicePrincipalName(String servicePrincipalName) {
- this.servicePrincipalName = servicePrincipalName;
- }
-
- /**
- * Set the location of the Kerberos keytab. The default is defined by the JRE.
- *
- * @param keytabFile The location of the keytab
- */
-
- public void setKeytabFile(String keytabFile) {
- this.keytabFile = keytabFile;
- }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/34098dac/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
index c2518dc..afcca3a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
@@ -36,304 +36,296 @@ import org.slf4j.LoggerFactory;
/**
* Prototype user authentication handling gssapi-with-mic. Implements <code>HandshakingUserAuth</code> because
* the process involves several steps.
- *
+ * <p/>
* Several methods are available for overriding in specific circumstances.
*/
public class UserAuthGSS implements HandshakingUserAuth {
-
- // Oids for the Kerberos 5 mechanism and principal
-
- public static final Oid KRB5_MECH = createOID("1.2.840.113554.1.2.2");
- public static final Oid KRB5_NT_PRINCIPAL = createOID("1.2.840.113554.1.2.2.1");
-
- // Options:
- //
- // Service principal name: if unset, use host/hostname
-
- private String servicePrincipalName;
-
- // Location of Kerberos key table; if unset use default
-
- private String keytabFile;
-
- // The on-going GSS context.
-
- private GSSContext ctxt;
-
- // Accept credentials
-
- private GSSCredential creds;
-
- // Original request data
-
- private String user;
- private String service;
-
- // Identity from context
-
- private String identity;
-
- // Logging
-
- private Logger log = LoggerFactory.getLogger(getClass());
-
- /**
- * Handle the first authentication step.
- *
- * @param sess The server session
- * @param user The user name from the request
- * @param buff The request buffer
- *
- * @return True or false if the authentication succeeded, or <code>null</code> to continue further
- *
- * @throws Exception If something went wrong
- */
-
- public Boolean auth(ServerSession sess, String user, Buffer buff) throws Exception {
- GSSAuthenticator auth = getAuthenticator(sess);
-
- this.user = user;
-
- // Get mechanism count from buffer and look for Kerberos 5.
-
- int num = buff.getInt();
-
- for (int i = 0; i < num; i++) {
- Oid oid = new Oid(buff.getBytes());
-
- if (oid.equals(KRB5_MECH)) {
- log.debug("UserAuthGSS: found Kerberos 5");
-
- // Validate initial user before proceeding
-
- if (!auth.validateInitialUser(sess, user)) {
- return Boolean.FALSE;
- }
- GSSManager mgr = auth.getGSSManager();
- GSSCredential creds = auth.getGSSCredential(mgr);
-
- if (creds == null) {
- return Boolean.FALSE;
+ // Oids for the Kerberos 5 mechanism and principal
+
+ public static final Oid KRB5_MECH = createOID("1.2.840.113554.1.2.2");
+ public static final Oid KRB5_NT_PRINCIPAL = createOID("1.2.840.113554.1.2.2.1");
+
+ // Options:
+ //
+ // Service principal name: if unset, use host/hostname
+
+ private String servicePrincipalName;
+
+ // Location of Kerberos key table; if unset use default
+
+ private String keytabFile;
+
+ // The on-going GSS context.
+
+ private GSSContext ctxt;
+
+ // Accept credentials
+
+ private GSSCredential creds;
+
+ // Original request data
+
+ private String user;
+ private String service;
+
+ // Identity from context
+
+ private String identity;
+
+ // Logging
+
+ private Logger log = LoggerFactory.getLogger(getClass());
+
+ /**
+ * Handle the first authentication step.
+ *
+ * @param sess The server session
+ * @param user The user name from the request
+ * @param buff The request buffer
+ * @return True or false if the authentication succeeded, or <code>null</code> to continue further
+ * @throws Exception If something went wrong
+ */
+
+ public Boolean auth(ServerSession sess, String user, Buffer buff) throws Exception {
+ GSSAuthenticator auth = getAuthenticator(sess);
+
+ this.user = user;
+
+ // Get mechanism count from buffer and look for Kerberos 5.
+
+ int num = buff.getInt();
+
+ for (int i = 0; i < num; i++) {
+ Oid oid = new Oid(buff.getBytes());
+
+ if (oid.equals(KRB5_MECH)) {
+ log.debug("UserAuthGSS: found Kerberos 5");
+
+ // Validate initial user before proceeding
+
+ if (!auth.validateInitialUser(sess, user)) {
+ return Boolean.FALSE;
+ }
+
+ GSSManager mgr = auth.getGSSManager();
+ GSSCredential creds = auth.getGSSCredential(mgr);
+
+ if (creds == null) {
+ return Boolean.FALSE;
+ }
+
+ ctxt = mgr.createContext(creds);
+
+ // Send the matching mechanism back to the client
+
+ Buffer b = sess.createBuffer(SshConstants.Message.SSH_MSG_USERAUTH_INFO_REQUEST, 0);
+ byte[] out = oid.getDER();
+
+ b.putBytes(out);
+ sess.writePacket(b);
+
+ return null;
+ }
}
- ctxt = mgr.createContext(creds);
-
- // Send the matching mechanism back to the client
+ // No matching mechanism found
+
+ return Boolean.FALSE;
+ }
- Buffer b = sess.createBuffer(SshConstants.Message.SSH_MSG_USERAUTH_INFO_REQUEST, 0);
- byte [] out = oid.getDER();
+ /**
+ * Set the service name from the original request. This may be required for MIC verification later.
+ *
+ * @param service The service name
+ */
- b.putBytes(out);
- sess.writePacket(b);
-
- return null;
- }
+ public void setServiceName(String service) {
+ this.service = service;
}
-
- // No matching mechanism found
-
- return Boolean.FALSE;
- }
-
- /**
- * Set the service name from the original request. This may be required for MIC verification later.
- *
- * @param service The service name
- */
-
- public void setServiceName(String service) {
- this.service = service;
- }
-
- /**
- * Check whether a particular message is handled here.
- *
- * @param msg The message
- *
- * @return <code>true</code> if the message is handled
- */
-
- public boolean handles(SshConstants.Message msg) {
- return msg == SshConstants.Message.SSH_MSG_USERAUTH_INFO_RESPONSE || msg == SshConstants.Message.SSH_MSG_USERAUTH_GSSAPI_MIC && ctxt.isEstablished();
- }
-
- /**
- * Handle another step in the authentication process.
- *
- * @param session the current ssh session
- * @param buffer the request buffer containing parameters specific to this request
- *
- * @return <code>true</code> if the authentication succeeded, <code>false</code> if the authentication
- * is not finished yet
- *
- * @throws Exception if the authentication fails
- */
-
- public Boolean next(ServerSession session, SshConstants.Message msg, Buffer buffer) throws Exception {
- GSSAuthenticator auth = getAuthenticator(session);
-
- log.debug("In krb5.next: msg = " + msg);
-
- // If the context is established, this must be a MIC message
-
- if (ctxt.isEstablished()) {
-
- if (msg != SshConstants.Message.SSH_MSG_USERAUTH_GSSAPI_MIC) {
- return Boolean.FALSE;
- }
-
- // Make the MIC message so the token can be verified
-
- Buffer msgbuf = new Buffer();
-
- msgbuf.putString(session.getSessionId());
- msgbuf.putByte(SshConstants.Message.SSH_MSG_USERAUTH_REQUEST.toByte());
- msgbuf.putString(user.getBytes("UTF-8"));
- msgbuf.putString(service);
- msgbuf.putString("gssapi-with-mic");
-
- byte [] msgbytes = msgbuf.getCompactData();
- byte [] inmic = buffer.getBytes();
-
- try {
- ctxt.verifyMIC(inmic, 0, inmic.length, msgbytes, 0, msgbytes.length, new MessageProp(false));
- log.debug("MIC verified");
- return Boolean.TRUE;
- } catch (GSSException e) {
- log.info("GSS verification error: {}", e.toString());
- return Boolean.FALSE;
- }
-
- } else {
-
- // Not established - new token to process
-
- byte [] tok = buffer.getBytes();
- byte [] out = ctxt.acceptSecContext(tok, 0, tok.length);
- boolean established = ctxt.isEstablished();
-
- // Validate identity if context is now established
-
- if (established && identity == null) {
- identity = ctxt.getSrcName().toString();
- log.info("GSS identity is {}", identity);
-
- if (!auth.validateIdentity(session, identity)) {
- return Boolean.FALSE;
- }
- }
-
- // Send return token if necessary
-
- if (out != null && out.length > 0) {
- Buffer b = session.createBuffer(SshConstants.Message.SSH_MSG_USERAUTH_INFO_RESPONSE, 0);
-
- b.putBytes(out);
- session.writePacket(b);
- return null;
- } else {
- return Boolean.valueOf(established);
- }
+
+ /**
+ * Check whether a particular message is handled here.
+ *
+ * @param msg The message
+ * @return <code>true</code> if the message is handled
+ */
+
+ public boolean handles(SshConstants.Message msg) {
+ return msg == SshConstants.Message.SSH_MSG_USERAUTH_INFO_RESPONSE || msg == SshConstants.Message.SSH_MSG_USERAUTH_GSSAPI_MIC && ctxt.isEstablished();
}
- }
-
- /**
- * Get a user name which has been derived from the handshaking process, or the initial name if
- * nothing has been found.
- *
- * @return The user name
- */
-
- public String getUserName() throws GSSException {
- return identity;
- }
-
- /**
- * Free any system resources used by the module.
- */
-
- public void destroy() {
- if (creds != null) {
- try {
- creds.dispose();
- } catch (GSSException e) {
- // ignore
- }
-
- if (ctxt != null) {
-
- try {
- ctxt.dispose();
- } catch (GSSException e) {
- // ignore
+
+ /**
+ * Handle another step in the authentication process.
+ *
+ * @param session the current ssh session
+ * @param buffer the request buffer containing parameters specific to this request
+ * @return <code>true</code> if the authentication succeeded, <code>false</code> if the authentication
+ * is not finished yet
+ * @throws Exception if the authentication fails
+ */
+
+ public Boolean next(ServerSession session, SshConstants.Message msg, Buffer buffer) throws Exception {
+ GSSAuthenticator auth = getAuthenticator(session);
+
+ log.debug("In krb5.next: msg = " + msg);
+
+ // If the context is established, this must be a MIC message
+
+ if (ctxt.isEstablished()) {
+
+ if (msg != SshConstants.Message.SSH_MSG_USERAUTH_GSSAPI_MIC) {
+ return Boolean.FALSE;
+ }
+
+ // Make the MIC message so the token can be verified
+
+ Buffer msgbuf = new Buffer();
+
+ msgbuf.putString(session.getSessionId());
+ msgbuf.putByte(SshConstants.Message.SSH_MSG_USERAUTH_REQUEST.toByte());
+ msgbuf.putString(user.getBytes("UTF-8"));
+ msgbuf.putString(service);
+ msgbuf.putString("gssapi-with-mic");
+
+ byte[] msgbytes = msgbuf.getCompactData();
+ byte[] inmic = buffer.getBytes();
+
+ try {
+ ctxt.verifyMIC(inmic, 0, inmic.length, msgbytes, 0, msgbytes.length, new MessageProp(false));
+ log.debug("MIC verified");
+ return Boolean.TRUE;
+ } catch (GSSException e) {
+ log.info("GSS verification error: {}", e.toString());
+ return Boolean.FALSE;
+ }
+
+ } else {
+
+ // Not established - new token to process
+
+ byte[] tok = buffer.getBytes();
+ byte[] out = ctxt.acceptSecContext(tok, 0, tok.length);
+ boolean established = ctxt.isEstablished();
+
+ // Validate identity if context is now established
+
+ if (established && identity == null) {
+ identity = ctxt.getSrcName().toString();
+ log.info("GSS identity is {}", identity);
+
+ if (!auth.validateIdentity(session, identity)) {
+ return Boolean.FALSE;
+ }
+ }
+
+ // Send return token if necessary
+
+ if (out != null && out.length > 0) {
+ Buffer b = session.createBuffer(SshConstants.Message.SSH_MSG_USERAUTH_INFO_RESPONSE, 0);
+
+ b.putBytes(out);
+ session.writePacket(b);
+ return null;
+ } else {
+ return Boolean.valueOf(established);
+ }
}
- }
}
- }
-
- /**
- * Utility to get the configured GSS authenticator for the server, throwing an exception if none is available.
- *
- * @param session The current session
- *
- * @return The GSS authenticator
- *
- * @throws Exception If no GSS authenticator is defined
- */
-
- private GSSAuthenticator getAuthenticator(ServerSession session) throws Exception {
- GSSAuthenticator ga = session.getServerFactoryManager().getGSSAuthenticator();
-
- if (ga == null) {
- throw new Exception("No GSSAuthenticator configured");
- } else {
- return ga;
+
+ /**
+ * Get a user name which has been derived from the handshaking process, or the initial name if
+ * nothing has been found.
+ *
+ * @return The user name
+ */
+
+ public String getUserName() throws GSSException {
+ return identity;
+ }
+
+ /**
+ * Free any system resources used by the module.
+ */
+
+ public void destroy() {
+ if (creds != null) {
+ try {
+ creds.dispose();
+ } catch (GSSException e) {
+ // ignore
+ }
+
+ if (ctxt != null) {
+
+ try {
+ ctxt.dispose();
+ } catch (GSSException e) {
+ // ignore
+ }
+ }
+ }
}
- }
-
- /**
- * Utility to construct an Oid from a string, ignoring the annoying exception.
- *
- * @param rep The string form
- *
- * @return The Oid
- */
-
- private static Oid createOID(String rep) {
- try {
- return new Oid(rep);
- } catch (GSSException e) {
- // won't happen
- return null;
+
+ /**
+ * Utility to get the configured GSS authenticator for the server, throwing an exception if none is available.
+ *
+ * @param session The current session
+ * @return The GSS authenticator
+ * @throws Exception If no GSS authenticator is defined
+ */
+
+ private GSSAuthenticator getAuthenticator(ServerSession session) throws Exception {
+ GSSAuthenticator ga = session.getServerFactoryManager().getGSSAuthenticator();
+
+ if (ga == null) {
+ throw new Exception("No GSSAuthenticator configured");
+ } else {
+ return ga;
+ }
}
- }
-
- /**
- * Factory class.
- */
-
- public static class Factory implements NamedFactory<UserAuth> {
-
+
/**
- * Get the name of the authentication method.
- *
- * @return Tge name, always 'gssapi-with-mic' here.
+ * Utility to construct an Oid from a string, ignoring the annoying exception.
+ *
+ * @param rep The string form
+ * @return The Oid
*/
-
- public String getName() {
- return "gssapi-with-mic";
+
+ private static Oid createOID(String rep) {
+ try {
+ return new Oid(rep);
+ } catch (GSSException e) {
+ // won't happen
+ return null;
+ }
}
-
+
/**
- * Create a new authenticator instance.
- *
- * @return The instance
+ * Factory class.
*/
-
- public UserAuth create() {
- return new UserAuthGSS();
+
+ public static class Factory implements NamedFactory<UserAuth> {
+
+ /**
+ * Get the name of the authentication method.
+ *
+ * @return Tge name, always 'gssapi-with-mic' here.
+ */
+
+ public String getName() {
+ return "gssapi-with-mic";
+ }
+
+ /**
+ * Create a new authenticator instance.
+ *
+ * @return The instance
+ */
+
+ public UserAuth create() {
+ return new UserAuthGSS();
+ }
}
- }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/34098dac/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
index f095ed7..d87fdd4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
@@ -364,69 +364,69 @@ public class ServerSession extends AbstractSession {
if (nbAuthRequests++ > maxAuthRequests) {
throw new SshException(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR, "Too may authentication failures");
}
-
- Boolean authed = null;
- String username = null;
+
+ Boolean authed = null;
+ String username = null;
if (cmd == SshConstants.Message.SSH_MSG_USERAUTH_REQUEST) {
- username = buffer.getString();
-
- String svcName = buffer.getString();
- String method = buffer.getString();
-
- log.debug("Authenticating user '{}' with method '{}'", username, method);
- NamedFactory<UserAuth> factory = NamedFactory.Utils.get(userAuthFactories, method);
- if (factory != null) {
- UserAuth auth = factory.create();
- try {
- authed = auth.auth(this, username, buffer);
- if (authed == null) {
- // authentication is still ongoing
- log.debug("Authentication not finished");
-
- if (auth instanceof HandshakingUserAuth) {
- currentAuth = (HandshakingUserAuth) auth;
-
- // GSSAPI needs the user name and service to verify the MIC
-
- currentAuth.setServiceName(svcName);
+ username = buffer.getString();
+
+ String svcName = buffer.getString();
+ String method = buffer.getString();
+
+ log.debug("Authenticating user '{}' with method '{}'", username, method);
+ NamedFactory<UserAuth> factory = NamedFactory.Utils.get(userAuthFactories, method);
+ if (factory != null) {
+ UserAuth auth = factory.create();
+ try {
+ authed = auth.auth(this, username, buffer);
+ if (authed == null) {
+ // authentication is still ongoing
+ log.debug("Authentication not finished");
+
+ if (auth instanceof HandshakingUserAuth) {
+ currentAuth = (HandshakingUserAuth) auth;
+
+ // GSSAPI needs the user name and service to verify the MIC
+
+ currentAuth.setServiceName(svcName);
+ }
+ return;
+ } else {
+ log.debug(authed ? "Authentication succeeded" : "Authentication failed");
+ }
+ } catch (Exception e) {
+ // Continue
+ authed = false;
+ log.debug("Authentication failed: {}", e.getMessage());
}
- return;
- } else {
- log.debug(authed ? "Authentication succeeded" : "Authentication failed");
- }
- } catch (Exception e) {
- // Continue
- authed = false;
- log.debug("Authentication failed: {}", e.getMessage());
+
+ } else {
+ log.debug("Unsupported authentication method '{}'", method);
}
-
- } else {
- log.debug("Unsupported authentication method '{}'", method);
- }
} else {
- try {
- authed = currentAuth.next(this, cmd, buffer);
-
- if (authed == null) {
- // authentication is still ongoing
- log.debug("Authentication still not finished");
- return;
- } else if (authed.booleanValue()) {
- username = currentAuth.getUserName();
+ try {
+ authed = currentAuth.next(this, cmd, buffer);
+
+ if (authed == null) {
+ // authentication is still ongoing
+ log.debug("Authentication still not finished");
+ return;
+ } else if (authed.booleanValue()) {
+ username = currentAuth.getUserName();
+ }
+ } catch (Exception e) {
+ // failed
+ authed = false;
+ log.debug("Authentication next failed: {}", e.getMessage());
}
- } catch (Exception e) {
- // failed
- authed = false;
- log.debug("Authentication next failed: {}", e.getMessage());
- }
}
// No more handshakes now - clean up if necessary
-
+
if (currentAuth != null) {
- currentAuth.destroy();
- currentAuth = null;
+ currentAuth.destroy();
+ currentAuth = null;
}
if (authed != null && authed) {