private TTransportFactory getSASLTransportFactory() { String[] names; try { names = FlumeAuthenticationUtil.splitKerberosName(principal); } catch (IOException e) { throw new FlumeException( "Error while trying to resolve Principal name - " + principal, e); } Map<String, String> saslProperties = new HashMap<String, String>(); saslProperties.put(Sasl.QOP, "auth"); TSaslServerTransport.Factory saslTransportFactory = new TSaslServerTransport.Factory(); saslTransportFactory.addServerDefinition( "GSSAPI", names[0], names[1], saslProperties, FlumeAuthenticationUtil.getSaslGssCallbackHandler()); return saslTransportFactory; }
static SaslClient createSaslClient(final String user, final String password) throws SaslException { return Sasl.createSaslClient(new String[]{"PLAIN"}, user, null, null, null, new CallbackHandler() { @Override public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (final Callback callback : callbacks) { if (callback instanceof PasswordCallback) { ((PasswordCallback) callback).setPassword(password.toCharArray()); } else if (callback instanceof NameCallback) { ((NameCallback) callback).setName(user); } } } }); }
SaslOutputStream(SaslClient sc, OutputStream out) throws SaslException { super(out); this.sc = sc; if (debug) { System.err.println("SaslOutputStream: " + out); } String str = (String) sc.getNegotiatedProperty(Sasl.RAW_SEND_SIZE); if (str != null) { try { rawSendSize = Integer.parseInt(str); } catch (NumberFormatException e) { throw new SaslException(Sasl.RAW_SEND_SIZE + " property must be numeric string: " + str); } } }
SaslInputStream(SaslClient sc, InputStream in) throws SaslException { super(); this.in = in; this.sc = sc; String str = (String) sc.getNegotiatedProperty(Sasl.MAX_BUFFER); if (str != null) { try { recvMaxBufSize = Integer.parseInt(str); } catch (NumberFormatException e) { throw new SaslException(Sasl.MAX_BUFFER + " property must be numeric string: " + str); } } saslBuffer = new byte[recvMaxBufSize]; }
/** * Checks that SASL negotiation has completed for the given participant, and * the negotiated quality of protection is included in the given SASL * properties and therefore acceptable. * * @param sasl participant to check * @param saslProps properties of SASL negotiation * @throws IOException for any error */ public static void checkSaslComplete(SaslParticipant sasl, Map<String, String> saslProps) throws IOException { if (!sasl.isComplete()) { throw new IOException("Failed to complete SASL handshake"); } Set<String> requestedQop = ImmutableSet.copyOf(Arrays.asList( saslProps.get(Sasl.QOP).split(","))); String negotiatedQop = sasl.getNegotiatedQop(); LOG.debug("Verifying QOP, requested QOP = {}, negotiated QOP = {}", requestedQop, negotiatedQop); if (!requestedQop.contains(negotiatedQop)) { throw new IOException(String.format("SASL handshake completed, but " + "channel does not have acceptable quality of protection, " + "requested = %s, negotiated = %s", requestedQop, negotiatedQop)); } }
private void runNegotiation(CallbackHandler clientCbh, CallbackHandler serverCbh) throws SaslException { String mechanism = AuthMethod.PLAIN.getMechanismName(); SaslClient saslClient = Sasl.createSaslClient( new String[]{ mechanism }, null, null, null, null, clientCbh); assertNotNull(saslClient); SaslServer saslServer = Sasl.createSaslServer( mechanism, null, "localhost", null, serverCbh); assertNotNull("failed to find PLAIN server", saslServer); byte[] response = saslClient.evaluateChallenge(new byte[0]); assertNotNull(response); assertTrue(saslClient.isComplete()); response = saslServer.evaluateResponse(response); assertNull(response); assertTrue(saslServer.isComplete()); assertNotNull(saslServer.getAuthorizationID()); }
private void createSaslServer(String mechanism) throws IOException { this.saslMechanism = mechanism; if (!ScramMechanism.isScram(mechanism)) callbackHandler = new SaslServerCallbackHandler(jaasContext, kerberosNamer); else callbackHandler = new ScramServerCallbackHandler(credentialCache.cache(mechanism, ScramCredential.class)); callbackHandler.configure(configs, Mode.SERVER, subject, saslMechanism); if (mechanism.equals(SaslConfigs.GSSAPI_MECHANISM)) { saslServer = createSaslKerberosServer(callbackHandler, configs, subject); } else { try { saslServer = Subject.doAs(subject, new PrivilegedExceptionAction<SaslServer>() { public SaslServer run() throws SaslException { // 调用createSaslServer return Sasl.createSaslServer(saslMechanism, "kafka", host, configs, callbackHandler); } }); } catch (PrivilegedActionException e) { throw new SaslException("Kafka Server failed to create a SaslServer to interact with a client during session authentication", e.getCause()); } } }
private void createSaslServer(String mechanism) throws IOException { this.saslMechanism = mechanism; callbackHandler = new SaslServerCallbackHandler(Configuration.getConfiguration(), kerberosNamer); callbackHandler.configure(configs, Mode.SERVER, subject, saslMechanism); if (mechanism.equals(SaslConfigs.GSSAPI_MECHANISM)) { if (subject.getPrincipals().isEmpty()) throw new IllegalArgumentException("subject must have at least one principal"); saslServer = createSaslKerberosServer(callbackHandler, configs); } else { try { saslServer = Subject.doAs(subject, new PrivilegedExceptionAction<SaslServer>() { public SaslServer run() throws SaslException { return Sasl.createSaslServer(saslMechanism, "kafka", host, configs, callbackHandler); } }); } catch (PrivilegedActionException e) { throw new SaslException("Kafka Server failed to create a SaslServer to interact with a client during session authentication", e.getCause()); } } }
private void refresh() { final Enumeration<SaslServerFactory> factories = Sasl.getSaslServerFactories(); final Map<String, List<SaslServerFactory>> map = Maps.newHashMap(); while (factories.hasMoreElements()) { final SaslServerFactory factory = factories.nextElement(); // Passing null so factory is populated with all possibilities. Properties passed when // instantiating a server are what really matter. See createSaslServer. for (final String mechanismName : factory.getMechanismNames(null)) { if (!map.containsKey(mechanismName)) { map.put(mechanismName, new ArrayList<SaslServerFactory>()); } map.get(mechanismName).add(factory); } } serverFactories = ImmutableMap.copyOf(map); if (logger.isDebugEnabled()) { logger.debug("Registered sasl server factories: {}", serverFactories.keySet()); } }
private void refresh() { final Enumeration<SaslClientFactory> factories = Sasl.getSaslClientFactories(); final Map<String, List<SaslClientFactory>> map = Maps.newHashMap(); while (factories.hasMoreElements()) { final SaslClientFactory factory = factories.nextElement(); // Passing null so factory is populated with all possibilities. Properties passed when // instantiating a client are what really matter. See createSaslClient. for (final String mechanismName : factory.getMechanismNames(null)) { if (!map.containsKey(mechanismName)) { map.put(mechanismName, new ArrayList<SaslClientFactory>()); } map.get(mechanismName).add(factory); } } clientFactories = ImmutableMap.copyOf(map); if (logger.isDebugEnabled()) { logger.debug("Registered sasl client factories: {}", clientFactories.keySet()); } }
public static void init(Configuration conf) { QualityOfProtection saslQOP = QualityOfProtection.AUTHENTICATION; String rpcProtection = conf.get("hadoop.rpc.protection", QualityOfProtection.AUTHENTICATION.name().toLowerCase()); if (QualityOfProtection.INTEGRITY.name().toLowerCase() .equals(rpcProtection)) { saslQOP = QualityOfProtection.INTEGRITY; } else if (QualityOfProtection.PRIVACY.name().toLowerCase().equals( rpcProtection)) { saslQOP = QualityOfProtection.PRIVACY; } SASL_PROPS.put(Sasl.QOP, saslQOP.getSaslQop()); SASL_PROPS.put(Sasl.SERVER_AUTH, "true"); Security.addProvider(new SaslPlainServer.SecurityProvider()); }
/** * Performs the server side of the initial portion of the Thrift SASL protocol. * Receives the initial response from the client, creates a SASL server using * the mechanism requested by the client (if this server supports it), and * sends the first challenge back to the client. */ @Override protected void handleSaslStartMessage() throws TTransportException, SaslException { SaslResponse message = receiveSaslMessage(); LOGGER.debug("Received start message with status {}", message.status); if (message.status != NegotiationStatus.START) { throw sendAndThrowMessage(NegotiationStatus.ERROR, "Expecting START status, received " + message.status); } // Get the mechanism name. String mechanismName = new String(message.payload); TSaslServerDefinition serverDefinition = serverDefinitionMap.get(mechanismName); LOGGER.debug("Received mechanism name '{}'", mechanismName); if (serverDefinition == null) { throw sendAndThrowMessage(NegotiationStatus.BAD, "Unsupported mechanism type " + mechanismName); } SaslServer saslServer = Sasl.createSaslServer(serverDefinition.mechanism, serverDefinition.protocol, serverDefinition.serverName, serverDefinition.props, serverDefinition.cbh); setSaslServer(saslServer); }
private boolean useWrap() { // getNegotiatedProperty throws if client isn't complete String qop = (String) saslClient.getNegotiatedProperty(Sasl.QOP); // SASL wrapping is only used if the connection has a QOP, and // the value is not auth. ex. auth-int & auth-priv return qop != null && !"auth".toLowerCase(Locale.ENGLISH).equals(qop); }
/** * Constructs a SASLOutputStream from an OutputStream and a SaslServer <br> * 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 <br> * 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; } }
static Map<String, String> getSaslProperties(Configuration conf) { Map<String, String> saslProps =new TreeMap<String, String>(); String[] qop = conf.getStrings(HADOOP_RPC_PROTECTION_NON_WHITELIST, QualityOfProtection.PRIVACY.toString()); for (int i=0; i < qop.length; i++) { qop[i] = QualityOfProtection.valueOf( StringUtils.toUpperCase(qop[i])).getSaslQop(); } saslProps.put(Sasl.QOP, StringUtils.join(",", qop)); saslProps.put(Sasl.SERVER_AUTH, "true"); return saslProps; }