All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.security.SaslOutputStream Maven / Gradle / Ivy

There is a newer version: 3.4.0
Show newest version
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hadoop.security;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

/**
 * A SaslOutputStream is composed of an OutputStream and a SaslServer (or
 * SaslClient) so that write() methods first process the data before writing
 * them out to the underlying OutputStream. The SaslServer (or SaslClient)
 * object must be fully initialized before being used by a SaslOutputStream.
 */
@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
@InterfaceStability.Evolving
public class SaslOutputStream extends OutputStream {

  private final OutputStream outStream;
  // processed data ready to be written out
  private byte[] saslToken;

  private final SaslClient saslClient;
  private final SaslServer saslServer;
  // buffer holding one byte of incoming data
  private final byte[] ibuffer = new byte[1];
  private final boolean useWrap;

  /**
   * Constructs a SASLOutputStream from an OutputStream and a SaslServer 
* Note: if the specified OutputStream or SaslServer is null, a * NullPointerException may be thrown later when they are used. * * @param outStream * the OutputStream to be processed * @param saslServer * an initialized SaslServer object */ public SaslOutputStream(OutputStream outStream, SaslServer saslServer) { this.saslServer = saslServer; this.saslClient = null; String qop = (String) saslServer.getNegotiatedProperty(Sasl.QOP); this.useWrap = qop != null && !"auth".equalsIgnoreCase(qop); if (useWrap) { this.outStream = new BufferedOutputStream(outStream, 64*1024); } else { this.outStream = outStream; } } /** * Constructs a SASLOutputStream from an OutputStream and a SaslClient
* Note: if the specified OutputStream or SaslClient is null, a * NullPointerException may be thrown later when they are used. * * @param outStream * the OutputStream to be processed * @param saslClient * an initialized SaslClient object */ public SaslOutputStream(OutputStream outStream, SaslClient saslClient) { this.saslServer = null; this.saslClient = saslClient; String qop = (String) saslClient.getNegotiatedProperty(Sasl.QOP); this.useWrap = qop != null && !"auth".equalsIgnoreCase(qop); if (useWrap) { this.outStream = new BufferedOutputStream(outStream, 64*1024); } else { this.outStream = outStream; } } /** * Disposes of any system resources or security-sensitive information Sasl * might be using. * * @exception SaslException * if a SASL error occurs. */ private void disposeSasl() throws SaslException { if (saslClient != null) { saslClient.dispose(); } if (saslServer != null) { saslServer.dispose(); } } /** * Writes the specified byte to this output stream. * * @param b * the byte. * @exception IOException * if an I/O error occurs. */ @Override public void write(int b) throws IOException { if (!useWrap) { outStream.write(b); return; } ibuffer[0] = (byte) b; write(ibuffer, 0, 1); } /** * Writes b.length bytes from the specified byte array to this * output stream. *

* The write method of SASLOutputStream calls the * write method of three arguments with the three arguments * b, 0, and b.length. * * @param b * the data. * @exception NullPointerException * if b is null. * @exception IOException * if an I/O error occurs. */ @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } /** * Writes len bytes from the specified byte array starting at * offset off to this output stream. * * @param inBuf * the data. * @param off * the start offset in the data. * @param len * the number of bytes to write. * @exception IOException * if an I/O error occurs. */ @Override public void write(byte[] inBuf, int off, int len) throws IOException { if (!useWrap) { outStream.write(inBuf, off, len); return; } try { if (saslServer != null) { // using saslServer saslToken = saslServer.wrap(inBuf, off, len); } else { // using saslClient saslToken = saslClient.wrap(inBuf, off, len); } } catch (SaslException se) { try { disposeSasl(); } catch (SaslException ignored) { } throw se; } if (saslToken != null) { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); DataOutputStream dout = new DataOutputStream(byteOut); dout.writeInt(saslToken.length); outStream.write(byteOut.toByteArray()); outStream.write(saslToken, 0, saslToken.length); saslToken = null; } } /** * Flushes this output stream * * @exception IOException * if an I/O error occurs. */ @Override public void flush() throws IOException { outStream.flush(); } /** * Closes this output stream and releases any system resources associated with * this stream. * * @exception IOException * if an I/O error occurs. */ @Override public void close() throws IOException { disposeSasl(); outStream.close(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy