GssApiAuthentication.java

  1. /*
  2.  * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */
  10. package org.eclipse.jgit.internal.transport.sshd.auth;

  11. import static java.text.MessageFormat.format;

  12. import java.io.IOException;
  13. import java.net.InetSocketAddress;

  14. import org.eclipse.jgit.internal.transport.sshd.GssApiMechanisms;
  15. import org.eclipse.jgit.internal.transport.sshd.SshdText;
  16. import org.ietf.jgss.GSSContext;

  17. /**
  18.  * An abstract implementation of a GSS-API multi-round authentication.
  19.  *
  20.  * @param <ParameterType>
  21.  *            defining the parameter type for the authentication
  22.  * @param <TokenType>
  23.  *            defining the token type for the authentication
  24.  */
  25. public abstract class GssApiAuthentication<ParameterType, TokenType>
  26.         extends AbstractAuthenticationHandler<ParameterType, TokenType> {

  27.     private GSSContext context;

  28.     /** The last token generated. */
  29.     protected byte[] token;

  30.     /**
  31.      * Creates a new {@link GssApiAuthentication} to authenticate with the given
  32.      * {@code proxy}.
  33.      *
  34.      * @param proxy
  35.      *            the {@link InetSocketAddress} of the proxy to connect to
  36.      */
  37.     public GssApiAuthentication(InetSocketAddress proxy) {
  38.         super(proxy);
  39.     }

  40.     @Override
  41.     public void close() {
  42.         GssApiMechanisms.closeContextSilently(context);
  43.         context = null;
  44.         done = true;
  45.     }

  46.     @Override
  47.     public final void start() throws Exception {
  48.         try {
  49.             context = createContext();
  50.             context.requestMutualAuth(true);
  51.             context.requestConf(false);
  52.             context.requestInteg(false);
  53.             byte[] empty = new byte[0];
  54.             token = context.initSecContext(empty, 0, 0);
  55.         } catch (Exception e) {
  56.             close();
  57.             throw e;
  58.         }
  59.     }

  60.     @Override
  61.     public final void process() throws Exception {
  62.         if (context == null) {
  63.             throw new IOException(
  64.                     format(SshdText.get().proxyCannotAuthenticate, proxy));
  65.         }
  66.         try {
  67.             byte[] received = extractToken(params);
  68.             token = context.initSecContext(received, 0, received.length);
  69.             checkDone();
  70.         } catch (Exception e) {
  71.             close();
  72.             throw e;
  73.         }
  74.     }

  75.     private void checkDone() throws Exception {
  76.         done = context.isEstablished();
  77.         if (done) {
  78.             context.dispose();
  79.             context = null;
  80.         }
  81.     }

  82.     /**
  83.      * Creates the {@link GSSContext} to use.
  84.      *
  85.      * @return a fresh {@link GSSContext} to use
  86.      * @throws Exception
  87.      *             if the context cannot be created
  88.      */
  89.     protected abstract GSSContext createContext() throws Exception;

  90.     /**
  91.      * Extracts the token from the last set parameters.
  92.      *
  93.      * @param input
  94.      *            to extract the token from
  95.      * @return the extracted token, or {@code null} if none
  96.      * @throws Exception
  97.      *             if an error occurs
  98.      */
  99.     protected abstract byte[] extractToken(ParameterType input)
  100.             throws Exception;
  101. }