Search in sources :

Example 1 with SaslException

use of javax.security.sasl.SaslException in project hadoop by apache.

the class SaslOutputStream method write.

/**
   * Writes <code>len</code> bytes from the specified byte array starting at
   * offset <code>off</code> 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;
    }
}
Also used : DataOutputStream(java.io.DataOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) SaslException(javax.security.sasl.SaslException)

Example 2 with SaslException

use of javax.security.sasl.SaslException in project hadoop by apache.

the class SaslRpcClient method saslConnect.

/**
   * Do client side SASL authentication with server via the given InputStream
   * and OutputStream
   * 
   * @param inS
   *          InputStream to use
   * @param outS
   *          OutputStream to use
   * @return AuthMethod used to negotiate the connection
   * @throws IOException
   */
public AuthMethod saslConnect(IpcStreams ipcStreams) throws IOException {
    // redefined if/when a SASL negotiation starts, can be queried if the
    // negotiation fails
    authMethod = AuthMethod.SIMPLE;
    sendSaslMessage(ipcStreams.out, negotiateRequest);
    // loop until sasl is complete or a rpc error occurs
    boolean done = false;
    do {
        ByteBuffer bb = ipcStreams.readResponse();
        RpcWritable.Buffer saslPacket = RpcWritable.Buffer.wrap(bb);
        RpcResponseHeaderProto header = saslPacket.getValue(RpcResponseHeaderProto.getDefaultInstance());
        switch(header.getStatus()) {
            // might get a RPC error during 
            case ERROR:
            case FATAL:
                throw new RemoteException(header.getExceptionClassName(), header.getErrorMsg());
            default:
                break;
        }
        if (header.getCallId() != AuthProtocol.SASL.callId) {
            throw new SaslException("Non-SASL response during negotiation");
        }
        RpcSaslProto saslMessage = saslPacket.getValue(RpcSaslProto.getDefaultInstance());
        if (saslPacket.remaining() > 0) {
            throw new SaslException("Received malformed response length");
        }
        // handle sasl negotiation process
        RpcSaslProto.Builder response = null;
        switch(saslMessage.getState()) {
            case NEGOTIATE:
                {
                    // create a compatible SASL client, throws if no supported auths
                    SaslAuth saslAuthType = selectSaslClient(saslMessage.getAuthsList());
                    // define auth being attempted, caller can query if connect fails
                    authMethod = AuthMethod.valueOf(saslAuthType.getMethod());
                    byte[] responseToken = null;
                    if (authMethod == AuthMethod.SIMPLE) {
                        // switching to SIMPLE
                        // not going to wait for success ack
                        done = true;
                    } else {
                        byte[] challengeToken = null;
                        if (saslAuthType.hasChallenge()) {
                            // server provided the first challenge
                            challengeToken = saslAuthType.getChallenge().toByteArray();
                            saslAuthType = SaslAuth.newBuilder(saslAuthType).clearChallenge().build();
                        } else if (saslClient.hasInitialResponse()) {
                            challengeToken = new byte[0];
                        }
                        responseToken = (challengeToken != null) ? saslClient.evaluateChallenge(challengeToken) : new byte[0];
                    }
                    response = createSaslReply(SaslState.INITIATE, responseToken);
                    response.addAuths(saslAuthType);
                    break;
                }
            case CHALLENGE:
                {
                    if (saslClient == null) {
                        // demand a specific negotiation
                        throw new SaslException("Server sent unsolicited challenge");
                    }
                    byte[] responseToken = saslEvaluateToken(saslMessage, false);
                    response = createSaslReply(SaslState.RESPONSE, responseToken);
                    break;
                }
            case SUCCESS:
                {
                    // switch to simple
                    if (saslClient == null) {
                        authMethod = AuthMethod.SIMPLE;
                    } else {
                        saslEvaluateToken(saslMessage, true);
                    }
                    done = true;
                    break;
                }
            default:
                {
                    throw new SaslException("RPC client doesn't support SASL " + saslMessage.getState());
                }
        }
        if (response != null) {
            sendSaslMessage(ipcStreams.out, response.build());
        }
    } while (!done);
    return authMethod;
}
Also used : RpcResponseHeaderProto(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto) SaslAuth(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto.SaslAuth) RpcWritable(org.apache.hadoop.ipc.RpcWritable) RemoteException(org.apache.hadoop.ipc.RemoteException) SaslException(javax.security.sasl.SaslException) ByteBuffer(java.nio.ByteBuffer) RpcSaslProto(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto)

Example 3 with SaslException

use of javax.security.sasl.SaslException in project hadoop by apache.

the class SaslDataTransferServer method doSaslHandshake.

/**
   * This method actually executes the server-side SASL handshake.
   *
   * @param peer connection peer
   * @param underlyingOut connection output stream
   * @param underlyingIn connection input stream
   * @param saslProps properties of SASL negotiation
   * @param callbackHandler for responding to SASL callbacks
   * @return new pair of streams, wrapped after SASL negotiation
   * @throws IOException for any error
   */
private IOStreamPair doSaslHandshake(Peer peer, OutputStream underlyingOut, InputStream underlyingIn, Map<String, String> saslProps, CallbackHandler callbackHandler) throws IOException {
    DataInputStream in = new DataInputStream(underlyingIn);
    DataOutputStream out = new DataOutputStream(underlyingOut);
    SaslParticipant sasl = SaslParticipant.createServerSaslParticipant(saslProps, callbackHandler);
    int magicNumber = in.readInt();
    if (magicNumber != SASL_TRANSFER_MAGIC_NUMBER) {
        throw new InvalidMagicNumberException(magicNumber, dnConf.getEncryptDataTransfer());
    }
    try {
        // step 1
        byte[] remoteResponse = readSaslMessage(in);
        byte[] localResponse = sasl.evaluateChallengeOrResponse(remoteResponse);
        sendSaslMessage(out, localResponse);
        // step 2 (server-side only)
        List<CipherOption> cipherOptions = Lists.newArrayList();
        remoteResponse = readSaslMessageAndNegotiationCipherOptions(in, cipherOptions);
        localResponse = sasl.evaluateChallengeOrResponse(remoteResponse);
        // SASL handshake is complete
        checkSaslComplete(sasl, saslProps);
        CipherOption cipherOption = null;
        if (sasl.isNegotiatedQopPrivacy()) {
            // Negotiate a cipher option
            Configuration conf = dnConf.getConf();
            cipherOption = negotiateCipherOption(conf, cipherOptions);
            if (LOG.isDebugEnabled()) {
                if (cipherOption == null) {
                    // No cipher suite is negotiated
                    String cipherSuites = conf.get(DFS_ENCRYPT_DATA_TRANSFER_CIPHER_SUITES_KEY);
                    if (cipherSuites != null && !cipherSuites.isEmpty()) {
                        // the server accepts some cipher suites, but the client does not.
                        LOG.debug("Server accepts cipher suites {}, " + "but client {} does not accept any of them", cipherSuites, peer.getRemoteAddressString());
                    }
                } else {
                    LOG.debug("Server using cipher suite {} with client {}", cipherOption.getCipherSuite().getName(), peer.getRemoteAddressString());
                }
            }
        }
        // If negotiated cipher option is not null, wrap it before sending.
        sendSaslMessageAndNegotiatedCipherOption(out, localResponse, wrap(cipherOption, sasl));
        // stream pair.
        return cipherOption != null ? createStreamPair(dnConf.getConf(), cipherOption, underlyingOut, underlyingIn, true) : sasl.createStreamPair(out, in);
    } catch (IOException ioe) {
        if (ioe instanceof SaslException && ioe.getCause() != null && ioe.getCause() instanceof InvalidEncryptionKeyException) {
            // This could just be because the client is long-lived and hasn't gotten
            // a new encryption key from the NN in a while. Upon receiving this
            // error, the client will get a new encryption key from the NN and retry
            // connecting to this DN.
            sendInvalidKeySaslErrorMessage(out, ioe.getCause().getMessage());
        } else {
            sendGenericSaslErrorMessage(out, ioe.getMessage());
        }
        throw ioe;
    }
}
Also used : Configuration(org.apache.hadoop.conf.Configuration) DataOutputStream(java.io.DataOutputStream) CipherOption(org.apache.hadoop.crypto.CipherOption) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) SaslException(javax.security.sasl.SaslException) InvalidEncryptionKeyException(org.apache.hadoop.hdfs.protocol.datatransfer.InvalidEncryptionKeyException)

Example 4 with SaslException

use of javax.security.sasl.SaslException in project hbase by apache.

the class HBaseInterClusterReplicationEndpoint method replicate.

/**
   * Do the shipping logic
   */
@Override
public boolean replicate(ReplicateContext replicateContext) {
    CompletionService<Integer> pool = new ExecutorCompletionService<>(this.exec);
    List<Entry> entries = replicateContext.getEntries();
    String walGroupId = replicateContext.getWalGroupId();
    int sleepMultiplier = 1;
    int numReplicated = 0;
    if (!peersSelected && this.isRunning()) {
        connectToPeers();
        peersSelected = true;
    }
    int numSinks = replicationSinkMgr.getNumSinks();
    if (numSinks == 0) {
        LOG.warn("No replication sinks found, returning without replicating. The source should retry" + " with the same set of edits.");
        return false;
    }
    // minimum of: configured threads, number of 100-waledit batches,
    //  and number of current sinks
    int n = Math.min(Math.min(this.maxThreads, entries.size() / 100 + 1), numSinks);
    List<List<Entry>> entryLists = new ArrayList<>(n);
    if (n == 1) {
        entryLists.add(entries);
    } else {
        for (int i = 0; i < n; i++) {
            entryLists.add(new ArrayList<>(entries.size() / n + 1));
        }
        // now group by region
        for (Entry e : entries) {
            entryLists.get(Math.abs(Bytes.hashCode(e.getKey().getEncodedRegionName()) % n)).add(e);
        }
    }
    while (this.isRunning() && !exec.isShutdown()) {
        if (!isPeerEnabled()) {
            if (sleepForRetries("Replication is disabled", sleepMultiplier)) {
                sleepMultiplier++;
            }
            continue;
        }
        try {
            if (LOG.isTraceEnabled()) {
                LOG.trace("Replicating " + entries.size() + " entries of total size " + replicateContext.getSize());
            }
            int futures = 0;
            for (int i = 0; i < entryLists.size(); i++) {
                if (!entryLists.get(i).isEmpty()) {
                    if (LOG.isTraceEnabled()) {
                        LOG.trace("Submitting " + entryLists.get(i).size() + " entries of total size " + replicateContext.getSize());
                    }
                    // RuntimeExceptions encountered here bubble up and are handled in ReplicationSource
                    pool.submit(createReplicator(entryLists.get(i), i));
                    futures++;
                }
            }
            IOException iox = null;
            for (int i = 0; i < futures; i++) {
                try {
                    // wait for all futures, remove successful parts
                    // (only the remaining parts will be retried)
                    Future<Integer> f = pool.take();
                    int index = f.get().intValue();
                    int batchSize = entryLists.get(index).size();
                    entryLists.set(index, Collections.<Entry>emptyList());
                    // Now, we have marked the batch as done replicating, record its size
                    numReplicated += batchSize;
                } catch (InterruptedException ie) {
                    iox = new IOException(ie);
                } catch (ExecutionException ee) {
                    // cause must be an IOException
                    iox = (IOException) ee.getCause();
                }
            }
            if (iox != null) {
                // if we had any exceptions, try again
                throw iox;
            }
            if (numReplicated != entries.size()) {
                // Something went wrong here and we don't know what, let's just fail and retry.
                LOG.warn("The number of edits replicated is different from the number received," + " failing for now.");
                return false;
            }
            // update metrics
            this.metrics.setAgeOfLastShippedOp(entries.get(entries.size() - 1).getKey().getWriteTime(), walGroupId);
            return true;
        } catch (IOException ioe) {
            // Didn't ship anything, but must still age the last time we did
            this.metrics.refreshAgeOfLastShippedOp(walGroupId);
            if (ioe instanceof RemoteException) {
                ioe = ((RemoteException) ioe).unwrapRemoteException();
                LOG.warn("Can't replicate because of an error on the remote cluster: ", ioe);
                if (ioe instanceof TableNotFoundException) {
                    if (sleepForRetries("A table is missing in the peer cluster. " + "Replication cannot proceed without losing data.", sleepMultiplier)) {
                        sleepMultiplier++;
                    }
                } else if (ioe instanceof SaslException) {
                    LOG.warn("Peer encountered SaslException, rechecking all sinks: ", ioe);
                    replicationSinkMgr.chooseSinks();
                }
            } else {
                if (ioe instanceof SocketTimeoutException) {
                    // This exception means we waited for more than 60s and nothing
                    // happened, the cluster is alive and calling it right away
                    // even for a test just makes things worse.
                    sleepForRetries("Encountered a SocketTimeoutException. Since the " + "call to the remote cluster timed out, which is usually " + "caused by a machine failure or a massive slowdown", this.socketTimeoutMultiplier);
                } else if (ioe instanceof ConnectException) {
                    LOG.warn("Peer is unavailable, rechecking all sinks: ", ioe);
                    replicationSinkMgr.chooseSinks();
                } else {
                    LOG.warn("Can't replicate because of a local or network error: ", ioe);
                }
            }
            if (sleepForRetries("Since we are unable to replicate", sleepMultiplier)) {
                sleepMultiplier++;
            }
        }
    }
    // in case we exited before replicating
    return false;
}
Also used : ArrayList(java.util.ArrayList) ExecutorCompletionService(java.util.concurrent.ExecutorCompletionService) IOException(java.io.IOException) SaslException(javax.security.sasl.SaslException) HBaseReplicationEndpoint(org.apache.hadoop.hbase.replication.HBaseReplicationEndpoint) TableNotFoundException(org.apache.hadoop.hbase.TableNotFoundException) Entry(org.apache.hadoop.hbase.wal.WAL.Entry) SocketTimeoutException(java.net.SocketTimeoutException) ArrayList(java.util.ArrayList) List(java.util.List) ExecutionException(java.util.concurrent.ExecutionException) RemoteException(org.apache.hadoop.ipc.RemoteException) ConnectException(java.net.ConnectException)

Example 5 with SaslException

use of javax.security.sasl.SaslException in project kafka by apache.

the class ScramSaslClient method handleServerFirstMessage.

private ClientFinalMessage handleServerFirstMessage(char[] password) throws SaslException {
    try {
        byte[] passwordBytes = formatter.normalize(new String(password));
        this.saltedPassword = formatter.hi(passwordBytes, serverFirstMessage.salt(), serverFirstMessage.iterations());
        ClientFinalMessage clientFinalMessage = new ClientFinalMessage("n,,".getBytes(StandardCharsets.UTF_8), serverFirstMessage.nonce());
        byte[] clientProof = formatter.clientProof(saltedPassword, clientFirstMessage, serverFirstMessage, clientFinalMessage);
        clientFinalMessage.proof(clientProof);
        return clientFinalMessage;
    } catch (InvalidKeyException e) {
        throw new SaslException("Client final message could not be created", e);
    }
}
Also used : ClientFinalMessage(org.apache.kafka.common.security.scram.ScramMessages.ClientFinalMessage) InvalidKeyException(java.security.InvalidKeyException) SaslException(javax.security.sasl.SaslException)

Aggregations

SaslException (javax.security.sasl.SaslException)70 IOException (java.io.IOException)24 UnsupportedCallbackException (javax.security.auth.callback.UnsupportedCallbackException)12 NameCallback (javax.security.auth.callback.NameCallback)11 Callback (javax.security.auth.callback.Callback)6 PasswordCallback (javax.security.auth.callback.PasswordCallback)6 SaslClient (javax.security.sasl.SaslClient)6 UndeclaredThrowableException (java.lang.reflect.UndeclaredThrowableException)5 InvalidKeyException (java.security.InvalidKeyException)5 LoginException (javax.security.auth.login.LoginException)5 AuthorizeCallback (javax.security.sasl.AuthorizeCallback)5 RpcException (org.apache.drill.exec.rpc.RpcException)5 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)4 PrivilegedActionException (java.security.PrivilegedActionException)4 CallbackHandler (javax.security.auth.callback.CallbackHandler)4 GSSException (org.ietf.jgss.GSSException)4 UserNotFoundException (org.jivesoftware.openfire.user.UserNotFoundException)4 ByteString (com.google.protobuf.ByteString)3 Principal (java.security.Principal)3 SaslServer (javax.security.sasl.SaslServer)3