/** * For subclasses externalizing the storage, for example Zookeeper * based implementations */ protected void updateDelegationKey(DelegationKey key) throws IOException { allKeys.put(key.getKeyId(), key); }
/** * Add a previously used master key to cache (when NN restarts), * should be called before activate(). * */ public synchronized void addKey(DelegationKey key) throws IOException { if (running) // a safety check throw new IOException("Can't add delegation key to a running SecretManager."); if (key.getKeyId() > getCurrentKeyId()) { setCurrentKeyId(key.getKeyId()); } allKeys.put(key.getKeyId(), key); }
/** * For subclasses externalizing the storage, for example Zookeeper * based implementations */ protected void storeDelegationKey(DelegationKey key) throws IOException { allKeys.put(key.getKeyId(), key); storeNewMasterKey(key); }
private void processKeyAddOrUpdate(byte[] data) throws IOException { ByteArrayInputStream bin = new ByteArrayInputStream(data); DataInputStream din = new DataInputStream(bin); DelegationKey key = new DelegationKey(); key.readFields(din); synchronized (this) { allKeys.put(key.getKeyId(), key); } }
/** * Extension of rollMasterKey to remove expired keys from store. * * @throws IOException */ protected void rollMasterKeyExt() throws IOException { Map<Integer, DelegationKey> keys = reloadKeys(); int currentKeyId = super.currentId; MetastoreDelegationTokenSupport.rollMasterKey(TokenStoreDelegationTokenSecretManager.this); List<DelegationKey> keysAfterRoll = Arrays.asList(getAllKeys()); for (DelegationKey key : keysAfterRoll) { keys.remove(key.getKeyId()); if (key.getKeyId() == currentKeyId) { tokenStore.updateMasterKey(currentKeyId, encodeWritable(key)); } } for (DelegationKey expiredKey : keys.values()) { LOGGER.info("Removing expired key id={}", expiredKey.getKeyId()); try { tokenStore.removeMasterKey(expiredKey.getKeyId()); } catch (Exception e) { LOGGER.error("Error removing expired key id={}", expiredKey.getKeyId(), e); } } }
protected Map<Integer, DelegationKey> reloadKeys() { // read keys from token store String[] allKeys = tokenStore.getMasterKeys(); Map<Integer, DelegationKey> keys = new HashMap<>(allKeys.length); for (String keyStr : allKeys) { DelegationKey key = new DelegationKey(); try { decodeWritable(key, keyStr); keys.put(key.getKeyId(), key); } catch (IOException ex) { LOGGER.error("Failed to load master key.", ex); } } synchronized (this) { super.allKeys.clear(); super.allKeys.putAll(keys); } return keys; }
@Override protected void removeStoredMasterKey(DelegationKey key) { String nodeRemovePath = getNodePath(ZK_DTSM_MASTER_KEY_ROOT, DELEGATION_KEY_PREFIX + key.getKeyId()); if (LOG.isDebugEnabled()) { LOG.debug("Removing ZKDTSMDelegationKey_" + key.getKeyId()); } try { if (zkClient.checkExists().forPath(nodeRemovePath) != null) { while(zkClient.checkExists().forPath(nodeRemovePath) != null){ try { zkClient.delete().guaranteed().forPath(nodeRemovePath); } catch (NoNodeException nne) { // It is possible that the node might be deleted between the // check and the actual delete.. which might lead to an // exception that can bring down the daemon running this // SecretManager LOG.debug("Node already deleted by peer " + nodeRemovePath); } } } else { LOG.debug("Attempted to delete a non-existing znode " + nodeRemovePath); } } catch (Exception e) { LOG.debug(nodeRemovePath + " znode could not be removed!!"); } }
@Override public SignedMessage serializeAndSign(Signable message) throws IOException { SignedMessage result = new SignedMessage(); DelegationKey key = secretManager.getCurrentKey(); message.setSignInfo(key.getKeyId()); result.message = message.serialize(); result.signature = secretManager.signWithKey(result.message, key); return result; }
private FakeSecretManager rollKey(FakeSecretManager fsm, int idToPreserve) throws IOException { // Adding keys is PITA - there's no way to plug into timed rolling; just create a new fsm. DelegationKey dk = fsm.getDelegationKey(idToPreserve), curDk = fsm.getCurrentKey(); if (curDk == null || curDk.getKeyId() != idToPreserve) { LOG.warn("The current key is not the one we expect; key rolled in background? Signed with " + idToPreserve + " but got " + (curDk == null ? "null" : curDk.getKeyId())); } // Regardless of the above, we should have the key we've signed with. assertNotNull(dk); assertEquals(idToPreserve, dk.getKeyId()); fsm.stopThreads(); fsm = new FakeSecretManager(); fsm.addKey(dk); assertNotNull("Couldn't add key", fsm.getDelegationKey(dk.getKeyId())); fsm.startThreads(); return fsm; }
@Override protected synchronized byte[] createPassword(TokenIdent identifier) { int sequenceNum; long now = Time.now(); sequenceNum = incrementDelegationTokenSeqNum(); identifier.setIssueDate(now); identifier.setMaxDate(now + tokenMaxLifetime); identifier.setMasterKeyId(currentKey.getKeyId()); identifier.setSequenceNumber(sequenceNum); LOG.info("Creating password for identifier: " + formatTokenId(identifier) + ", currentKey: " + currentKey.getKeyId()); byte[] password = createPassword(identifier.getBytes(), currentKey.getKey()); DelegationTokenInformation tokenInfo = new DelegationTokenInformation(now + tokenRenewInterval, password, getTrackingIdIfEnabled(identifier)); try { storeToken(identifier, tokenInfo); } catch (IOException ioe) { LOG.error("Could not store token " + formatTokenId(identifier) + "!!", ioe); } return password; }
/** * Synchronize master key updates / sequence generation for multiple nodes. * NOTE: {@link AbstractDelegationTokenSecretManager} keeps currentKey private, so we need * to utilize this "hook" to manipulate the key through the object reference. * This .20S workaround should cease to exist when Hadoop supports token store. */ @Override protected void logUpdateMasterKey(DelegationKey key) throws IOException { int keySeq = this.tokenStore.addMasterKey(encodeWritable(key)); // update key with assigned identifier DelegationKey keyWithSeq = new DelegationKey(keySeq, key.getExpiryDate(), key.getKey()); String keyStr = encodeWritable(keyWithSeq); this.tokenStore.updateMasterKey(keySeq, keyStr); decodeWritable(key, keyStr); LOGGER.info("New master key with key id={}", key.getKeyId()); super.logUpdateMasterKey(key); }
public static void delegationKeyToXml(ContentHandler contentHandler, DelegationKey key) throws SAXException { contentHandler.startElement( "", "", "DELEGATION_KEY", new AttributesImpl()); XMLUtils.addSaxString(contentHandler, "KEY_ID", Integer.toString(key.getKeyId())); XMLUtils.addSaxString(contentHandler, "EXPIRY_DATE", Long.toString(key.getExpiryDate())); if (key.getEncodedKey() != null) { XMLUtils.addSaxString(contentHandler, "KEY", Hex.encodeHexString(key.getEncodedKey())); } contentHandler.endElement("", "", "DELEGATION_KEY"); }
.newBuilder().setId(v.getKeyId()).setExpiryDate(v.getExpiryDate()); if (v.getEncodedKey() != null) { b.setKey(ByteString.copyFrom(v.getEncodedKey()));
/** * Add a previously used master key to cache (when NN restarts), * should be called before activate(). * */ public synchronized void addKey(DelegationKey key) throws IOException { if (running) // a safety check throw new IOException("Can't add delegation key to a running SecretManager."); if (key.getKeyId() > getCurrentKeyId()) { setCurrentKeyId(key.getKeyId()); } allKeys.put(key.getKeyId(), key); }
/** * For subclasses externalizing the storage, for example Zookeeper * based implementations */ protected void storeDelegationKey(DelegationKey key) throws IOException { allKeys.put(key.getKeyId(), key); storeNewMasterKey(key); }
private void processKeyAddOrUpdate(byte[] data) throws IOException { ByteArrayInputStream bin = new ByteArrayInputStream(data); DataInputStream din = new DataInputStream(bin); DelegationKey key = new DelegationKey(); key.readFields(din); synchronized (this) { allKeys.put(key.getKeyId(), key); } }
@Override protected void removeStoredMasterKey(DelegationKey key) { try { LOG.info("removing master key with keyID " + key.getKeyId()); rm.getRMContext().getStateStore().removeRMDTMasterKey(key); } catch (Exception e) { if (!shouldIgnoreException(e)) { LOG.error("Error in removing master key with KeyID: " + key.getKeyId()); ExitUtil.terminate(1, e); } } }