@Test public void testDelegationTokenSecretManager() throws Exception { Token<DelegationTokenIdentifier> token = generateDelegationToken( "SomeUser", "JobTracker"); // Fake renewer should not be able to renew try { dtSecretManager.renewToken(token, "FakeRenewer"); Assert.fail("should have failed"); } catch (AccessControlException ace) { // PASS } dtSecretManager.renewToken(token, "JobTracker"); DelegationTokenIdentifier identifier = new DelegationTokenIdentifier(); byte[] tokenId = token.getIdentifier(); identifier.readFields(new DataInputStream( new ByteArrayInputStream(tokenId))); Assert.assertTrue(null != dtSecretManager.retrievePassword(identifier)); LOG.info("Sleep to expire the token"); Thread.sleep(6000); //Token should be expired try { dtSecretManager.retrievePassword(identifier); //Should not come here Assert.fail("Token should have expired"); } catch (InvalidToken e) { //Success } dtSecretManager.renewToken(token, "JobTracker"); LOG.info("Sleep beyond the max lifetime"); Thread.sleep(5000); try { dtSecretManager.renewToken(token, "JobTracker"); Assert.fail("should have been expired"); } catch (InvalidToken it) { // PASS } }
/** * Auxiliary - create token * @param renewer * @return * @throws IOException */ static MyToken createTokens(Text renewer) throws IOException { Text user1= new Text("user1"); MyDelegationTokenSecretManager sm = new MyDelegationTokenSecretManager( DFSConfigKeys.DFS_NAMENODE_DELEGATION_KEY_UPDATE_INTERVAL_DEFAULT, DFSConfigKeys.DFS_NAMENODE_DELEGATION_TOKEN_MAX_LIFETIME_DEFAULT, DFSConfigKeys.DFS_NAMENODE_DELEGATION_TOKEN_RENEW_INTERVAL_DEFAULT, 3600000, null); sm.startThreads(); DelegationTokenIdentifier dtId1 = new DelegationTokenIdentifier(user1, renewer, user1); MyToken token1 = new MyToken(dtId1, sm); token1.setService(new Text("localhost:0")); return token1; }
@Override public synchronized <T extends TokenIdentifier> void setDelegationToken(Token<T> token) { /** * XXX The kind of the token has been changed by DelegationTokenFetcher. We * use the token for renewal, since the reflection utilities needs the value * of the kind field to correctly renew the token. * * For other operations, however, the client has to send a * HDFS_DELEGATION_KIND token over the wire so that it can talk to Hadoop * 0.20.203 clusters. Later releases fix this problem. See HDFS-5440 for * more details. */ renewToken = token; delegationToken = new Token<T>(token); delegationToken.setKind(DelegationTokenIdentifier.HDFS_DELEGATION_KIND); }
@SuppressWarnings("unchecked") @Override public long renewDelegationToken(final Token<?> token) throws IOException { // update the kerberos credentials, if they are coming from a keytab UserGroupInformation connectUgi = ugi.getRealUser(); if (connectUgi == null) { connectUgi = ugi; } try { return connectUgi.doAs(new PrivilegedExceptionAction<Long>() { @Override public Long run() throws Exception { InetSocketAddress serviceAddr = SecurityUtil .getTokenServiceAddr(token); return DelegationTokenFetcher.renewDelegationToken(connectionFactory, DFSUtil.createUri(getUnderlyingProtocol(), serviceAddr), (Token<DelegationTokenIdentifier>) token); } }); } catch (InterruptedException e) { throw new IOException(e); } }
@SuppressWarnings("unchecked") @Override public void cancelDelegationToken(final Token<?> token) throws IOException { UserGroupInformation connectUgi = ugi.getRealUser(); if (connectUgi == null) { connectUgi = ugi; } try { connectUgi.doAs(new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { InetSocketAddress serviceAddr = SecurityUtil .getTokenServiceAddr(token); DelegationTokenFetcher.cancelDelegationToken(connectionFactory, DFSUtil.createUri(getUnderlyingProtocol(), serviceAddr), (Token<DelegationTokenIdentifier>) token); return null; } }); } catch (InterruptedException e) { throw new IOException(e); } }
@Override public Token<DelegationTokenIdentifier> getDelegationToken( final String renewer) throws IOException { final HttpOpParam.Op op = GetOpParam.Op.GETDELEGATIONTOKEN; Token<DelegationTokenIdentifier> token = new FsPathResponseRunner<Token<DelegationTokenIdentifier>>( op, null, new RenewerParam(renewer)) { @Override Token<DelegationTokenIdentifier> decodeResponse(Map<?,?> json) throws IOException { return JsonUtil.toDelegationToken(json); } }.run(); if (token != null) { token.setService(tokenServiceName); } else { if (disallowFallbackToInsecureCluster) { throw new AccessControlException(CANT_FALLBACK_TO_INSECURE_MSG); } } return token; }
/** * @see ClientProtocol#getDelegationToken(Text) */ public Token<DelegationTokenIdentifier> getDelegationToken(Text renewer) throws IOException { assert dtService != null; TraceScope scope = Trace.startSpan("getDelegationToken", traceSampler); try { Token<DelegationTokenIdentifier> token = namenode.getDelegationToken(renewer); if (token != null) { token.setService(this.dtService); LOG.info("Created " + DelegationTokenIdentifier.stringifyToken(token)); } else { LOG.info("Cannot get delegation token from " + renewer); } return token; } finally { scope.close(); } }
private static ClientProtocol getNNProxy( Token<DelegationTokenIdentifier> token, Configuration conf) throws IOException { URI uri = HAUtil.getServiceUriFromToken(HdfsConstants.HDFS_URI_SCHEME, token); if (HAUtil.isTokenForLogicalUri(token) && !HAUtil.isLogicalUri(conf, uri)) { // If the token is for a logical nameservice, but the configuration // we have disagrees about that, we can't actually renew it. // This can be the case in MR, for example, if the RM doesn't // have all of the HA clusters configured in its configuration. throw new IOException("Unable to map logical nameservice URI '" + uri + "' to a NameNode. Local configuration does not have " + "a failover proxy provider configured."); } NameNodeProxies.ProxyAndInfo<ClientProtocol> info = NameNodeProxies.createProxy(conf, uri, ClientProtocol.class); assert info.getDelegationTokenService().equals(token.getService()) : "Returned service '" + info.getDelegationTokenService().toString() + "' doesn't match expected service '" + token.getService().toString() + "'"; return info.getProxy(); }
public static void delegationTokenToXml(ContentHandler contentHandler, DelegationTokenIdentifier token) throws SAXException { contentHandler.startElement("", "", "DELEGATION_TOKEN_IDENTIFIER", new AttributesImpl()); XMLUtils.addSaxString(contentHandler, "KIND", token.getKind().toString()); XMLUtils.addSaxString(contentHandler, "SEQUENCE_NUMBER", Integer.toString(token.getSequenceNumber())); XMLUtils.addSaxString(contentHandler, "OWNER", token.getOwner().toString()); XMLUtils.addSaxString(contentHandler, "RENEWER", token.getRenewer().toString()); XMLUtils.addSaxString(contentHandler, "REALUSER", token.getRealUser().toString()); XMLUtils.addSaxString(contentHandler, "ISSUE_DATE", Long.toString(token.getIssueDate())); XMLUtils.addSaxString(contentHandler, "MAX_DATE", Long.toString(token.getMaxDate())); XMLUtils.addSaxString(contentHandler, "MASTER_KEY_ID", Integer.toString(token.getMasterKeyId())); contentHandler.endElement("", "", "DELEGATION_TOKEN_IDENTIFIER"); }
public static DelegationTokenIdentifier delegationTokenFromXml(Stanza st) throws InvalidXmlException { String kind = st.getValue("KIND"); if (!kind.equals(DelegationTokenIdentifier. HDFS_DELEGATION_KIND.toString())) { throw new InvalidXmlException("can't understand " + "DelegationTokenIdentifier KIND " + kind); } int seqNum = Integer.parseInt(st.getValue("SEQUENCE_NUMBER")); String owner = st.getValue("OWNER"); String renewer = st.getValue("RENEWER"); String realuser = st.getValue("REALUSER"); long issueDate = Long.parseLong(st.getValue("ISSUE_DATE")); long maxDate = Long.parseLong(st.getValue("MAX_DATE")); int masterKeyId = Integer.parseInt(st.getValue("MASTER_KEY_ID")); DelegationTokenIdentifier token = new DelegationTokenIdentifier(new Text(owner), new Text(renewer), new Text(realuser)); token.setSequenceNumber(seqNum); token.setIssueDate(issueDate); token.setMaxDate(maxDate); token.setMasterKeyId(masterKeyId); return token; }
/** * * @param token token to cancel * @throws IOException on error */ void cancelDelegationToken(Token<DelegationTokenIdentifier> token) throws IOException { checkOperation(OperationCategory.WRITE); writeLock(); try { checkOperation(OperationCategory.WRITE); checkNameNodeSafeMode("Cannot cancel delegation token"); String canceller = getRemoteUser().getUserName(); DelegationTokenIdentifier id = dtSecretManager .cancelToken(token, canceller); getEditLog().logCancelDelegationToken(id); } finally { writeUnlock(); } getEditLog().logSync(); }
@Override public GetDelegationTokenResponseProto getDelegationToken( RpcController controller, GetDelegationTokenRequestProto req) throws ServiceException { try { Token<DelegationTokenIdentifier> token = server .getDelegationToken(new Text(req.getRenewer())); GetDelegationTokenResponseProto.Builder rspBuilder = GetDelegationTokenResponseProto.newBuilder(); if (token != null) { rspBuilder.setToken(PBHelper.convert(token)); } return rspBuilder.build(); } catch (IOException e) { throw new ServiceException(e); } }
/** * Tests delegation token APIs in FileContext for Hdfs; and renew and cancel * APIs in Hdfs. * * @throws UnsupportedFileSystemException * @throws IOException * @throws InterruptedException */ @SuppressWarnings({ "unchecked", "deprecation" }) @Test public void testFcDelegationToken() throws UnsupportedFileSystemException, IOException, InterruptedException { FileContext fcHdfs = FileContext.getFileContext(cluster.getFileSystem() .getUri()); final AbstractFileSystem afs = fcHdfs.getDefaultFileSystem(); final List<Token<?>> tokenList = afs.getDelegationTokens(UserGroupInformation.getCurrentUser() .getUserName()); ((Hdfs) afs).renewDelegationToken((Token<DelegationTokenIdentifier>) tokenList .get(0)); ((Hdfs) afs).cancelDelegationToken( (Token<? extends AbstractDelegationTokenIdentifier>) tokenList.get(0)); }
@Override public void handle(Channel channel, Token<DelegationTokenIdentifier> token, String serviceUrl) throws IOException { Assert.assertEquals(testToken, token); Credentials creds = new Credentials(); creds.addToken(new Text(serviceUrl), token); DataOutputBuffer out = new DataOutputBuffer(); creds.write(out); int fileLength = out.getData().length; ChannelBuffer cbuffer = ChannelBuffers.buffer(fileLength); cbuffer.writeBytes(out.getData()); HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(fileLength)); response.setContent(cbuffer); channel.write(response).addListener(ChannelFutureListener.CLOSE); }
private ServerBootstrap startHttpServer(int port, final Token<DelegationTokenIdentifier> token, final URI url) { ServerBootstrap bootstrap = new ServerBootstrap( new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); bootstrap.setPipelineFactory(new ChannelPipelineFactory() { @Override public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline(new HttpRequestDecoder(), new HttpChunkAggregator(65536), new HttpResponseEncoder(), new CredentialsLogicHandler(token, url.toString())); } }); bootstrap.bind(new InetSocketAddress("localhost", port)); return bootstrap; }
private WebHdfsFileSystem getWebHdfsFileSystem(UserGroupInformation ugi, Configuration conf) throws IOException { if (UserGroupInformation.isSecurityEnabled()) { DelegationTokenIdentifier dtId = new DelegationTokenIdentifier(new Text( ugi.getUserName()), null, null); FSNamesystem namesystem = mock(FSNamesystem.class); DelegationTokenSecretManager dtSecretManager = new DelegationTokenSecretManager( 86400000, 86400000, 86400000, 86400000, namesystem); dtSecretManager.startThreads(); Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>( dtId, dtSecretManager); SecurityUtil.setTokenService( token, NetUtils.createSocketAddr(uri.getAuthority())); token.setKind(WebHdfsFileSystem.TOKEN_KIND); ugi.addToken(token); } return (WebHdfsFileSystem) FileSystem.get(uri, conf); }
@Test public void testCancelDelegationToken() throws Exception { Token<DelegationTokenIdentifier> token = generateDelegationToken( "SomeUser", "JobTracker"); //Fake renewer should not be able to renew try { dtSecretManager.cancelToken(token, "FakeCanceller"); Assert.fail("should have failed"); } catch (AccessControlException ace) { // PASS } dtSecretManager.cancelToken(token, "JobTracker"); try { dtSecretManager.renewToken(token, "JobTracker"); Assert.fail("should have failed"); } catch (InvalidToken it) { // PASS } }
@Test(timeout=20000) public void testDelegationTokenWithRealUser() throws IOException { try { Token<?>[] tokens = proxyUgi .doAs(new PrivilegedExceptionAction<Token<?>[]>() { @Override public Token<?>[] run() throws IOException { return cluster.getFileSystem().addDelegationTokens("RenewerUser", null); } }); DelegationTokenIdentifier identifier = new DelegationTokenIdentifier(); byte[] tokenId = tokens[0].getIdentifier(); identifier.readFields(new DataInputStream(new ByteArrayInputStream( tokenId))); Assert.assertEquals(identifier.getUser().getUserName(), PROXY_USER); Assert.assertEquals(identifier.getUser().getRealUser().getUserName(), REAL_USER); } catch (InterruptedException e) { //Do Nothing } }
private static void doRenewOrCancel( final Token<DelegationTokenIdentifier> token, final Configuration conf, final TokenTestAction action) throws IOException, InterruptedException { UserGroupInformation.createRemoteUser("JobTracker").doAs( new PrivilegedExceptionAction<Void>() { @Override public Void run() throws Exception { switch (action) { case RENEW: token.renew(conf); break; case CANCEL: token.cancel(conf); break; default: fail("bad action:" + action); } return null; } }); }
@Override public void run() { FSEditLog editLog = namesystem.getEditLog(); for (int i = 0; i < numTransactions; i++) { try { String renewer = UserGroupInformation.getLoginUser().getUserName(); Token<DelegationTokenIdentifier> token = namesystem .getDelegationToken(new Text(renewer)); namesystem.renewDelegationToken(token); namesystem.cancelDelegationToken(token); editLog.logSync(); } catch (IOException e) { System.out.println("Transaction " + i + " encountered exception " + e); } } }
@Override public Token<DelegationTokenIdentifier> getDelegationToken( final String renewer) throws IOException { final HttpOpParam.Op op = GetOpParam.Op.GETDELEGATIONTOKEN; Token<DelegationTokenIdentifier> token = new FsPathResponseRunner<Token<DelegationTokenIdentifier>>( op, null, new RenewerParam(renewer)) { @Override Token<DelegationTokenIdentifier> decodeResponse(Map<?,?> json) throws IOException { return JsonUtilClient.toDelegationToken(json); } }.run(); if (token != null) { token.setService(tokenServiceName); } else { if (disallowFallbackToInsecureCluster) { throw new AccessControlException(CANT_FALLBACK_TO_INSECURE_MSG); } } return token; }
/** * @see ClientProtocol#getDelegationToken(Text) */ public Token<DelegationTokenIdentifier> getDelegationToken(Text renewer) throws IOException { assert dtService != null; try (TraceScope ignored = tracer.newScope("getDelegationToken")) { Token<DelegationTokenIdentifier> token = namenode.getDelegationToken(renewer); if (token != null) { token.setService(this.dtService); LOG.info("Created " + DelegationTokenIdentifier.stringifyToken(token)); } else { LOG.info("Cannot get delegation token from " + renewer); } return token; } }
private static ClientProtocol getNNProxy( Token<DelegationTokenIdentifier> token, Configuration conf) throws IOException { URI uri = HAUtilClient.getServiceUriFromToken( HdfsConstants.HDFS_URI_SCHEME, token); if (HAUtilClient.isTokenForLogicalUri(token) && !HAUtilClient.isLogicalUri(conf, uri)) { // If the token is for a logical nameservice, but the configuration // we have disagrees about that, we can't actually renew it. // This can be the case in MR, for example, if the RM doesn't // have all of the HA clusters configured in its configuration. throw new IOException("Unable to map logical nameservice URI '" + uri + "' to a NameNode. Local configuration does not have " + "a failover proxy provider configured."); } ProxyAndInfo<ClientProtocol> info = NameNodeProxiesClient.createProxyWithClientProtocol(conf, uri, null); assert info.getDelegationTokenService().equals(token.getService()) : "Returned service '" + info.getDelegationTokenService().toString() + "' doesn't match expected service '" + token.getService().toString() + "'"; return info.getProxy(); }
@Test(timeout=20000) public void testDTRonAppSubmission() throws IOException, InterruptedException, BrokenBarrierException { final Credentials credsx = new Credentials(); final Token<DelegationTokenIdentifier> tokenx = mock(Token.class); when(tokenx.getKind()).thenReturn(new Text("HDFS_DELEGATION_TOKEN")); DelegationTokenIdentifier dtId1 = new DelegationTokenIdentifier(new Text("user1"), new Text("renewer"), new Text("user1")); when(tokenx.decodeIdentifier()).thenReturn(dtId1); credsx.addToken(new Text("token"), tokenx); doReturn(true).when(tokenx).isManaged(); doThrow(new IOException("boom")) .when(tokenx).renew(any(Configuration.class)); // fire up the renewer final DelegationTokenRenewer dtr = createNewDelegationTokenRenewer(conf, counter); RMContext mockContext = mock(RMContext.class); when(mockContext.getSystemCredentialsForApps()).thenReturn( new ConcurrentHashMap<ApplicationId, ByteBuffer>()); ClientRMService mockClientRMService = mock(ClientRMService.class); when(mockContext.getClientRMService()).thenReturn(mockClientRMService); InetSocketAddress sockAddr = InetSocketAddress.createUnresolved("localhost", 1234); when(mockClientRMService.getBindAddress()).thenReturn(sockAddr); dtr.setRMContext(mockContext); when(mockContext.getDelegationTokenRenewer()).thenReturn(dtr); dtr.init(conf); dtr.start(); try { dtr.addApplicationSync(mock(ApplicationId.class), credsx, false, "user"); fail("Catch IOException on app submission"); } catch (IOException e){ Assert.assertTrue(e.getMessage().contains(tokenx.toString())); Assert.assertTrue(e.getCause().toString().contains("boom")); } }
@Override //AbstractFileSystem public List<Token<?>> getDelegationTokens(String renewer) throws IOException { Token<DelegationTokenIdentifier> result = dfs .getDelegationToken(renewer == null ? null : new Text(renewer)); List<Token<?>> tokenList = new ArrayList<Token<?>>(); tokenList.add(result); return tokenList; }
/** Convert a Json map to a Token. */ public static Token<? extends TokenIdentifier> toToken( final Map<?, ?> m) throws IOException { if (m == null) { return null; } final Token<DelegationTokenIdentifier> token = new Token<DelegationTokenIdentifier>(); token.decodeFromUrlString((String)m.get("urlString")); return token; }