private boolean authorize(final Authorization authorization) throws AcmeException { final Challenge challenge = httpChallenge(authorization); if (challenge == null) { throw new AcmeException("HTTP challenge is null"); } if (challenge.getStatus() == Status.VALID) { return false; } challenge.trigger(); try { int attempts = config.getRetryCount(); while (challenge.getStatus() != Status.VALID && attempts-- > 0) { if (challenge.getStatus() == Status.INVALID) { throw new AcmeException("Invalid challenge status, exiting refresh iteration"); } Thread.sleep(config.getRetryTimeoutMs()); challenge.update(); } } catch (final InterruptedException ex) { Thread.currentThread().interrupt(); } if (challenge.getStatus() != Status.VALID) { throw new AcmeException("Challenge for domain " + authorization.getDomain() + ", is invalid, exiting iteration"); } return true; }
/** * Finds a {@link Challenge} of the given type. Responding to this {@link Challenge} * is sufficient for authorization. * * @param type * Challenge name (e.g. "http-01") * @return {@link Challenge} matching that name, or {@code null} if there is no such * challenge, or if the challenge alone is not sufficient for authorization. * @throws ClassCastException * if the type does not match the expected Challenge class type */ @SuppressWarnings("unchecked") @CheckForNull public <T extends Challenge> T findChallenge(final String type) { return (T) getChallenges().stream() .filter(ch -> type.equals(ch.getType())) .reduce((a, b) -> {throw new AcmeProtocolException("Found more than one challenge of type " + type);}) .orElse(null); }
if (challenge.getStatus() == Status.VALID) { messages.add("challenge already successeded", LOG); return; challenge.trigger(); while (challenge.getStatus() != Status.VALID) { if (challenge.getStatus() == Status.INVALID) { messages.add("Authorization failed: " + challenge.getError().getDetail()); throw new AcmeException("Challenge failed..."); challenge.update(); } catch (AcmeRetryAfterException e) { retryTimeout = e.getRetryAfter().toEpochMilli() - System.currentTimeMillis(); if (challenge.getStatus() != Status.VALID) { throw new AcmeException("Failed to pass the challenge for domain " + domain + ", ... Giving up.");
@Override protected void setJSON(JSON json) { String type = json.get(KEY_TYPE).asString(); if (!acceptable(type)) { throw new AcmeProtocolException("incompatible type " + type + " for this challenge"); } String loc = json.get(KEY_URL).asString(); if (loc != null && !loc.equals(getLocation().toString())) { throw new AcmeProtocolException("challenge has changed its location"); } super.setJSON(json); }
/** * {@inheritDoc} * <p> * This implementation handles the standard challenge types. For unknown types, * generic {@link Challenge} or {@link TokenChallenge} instances are created. * <p> * Custom provider implementations may override this method to provide challenges that * are unique to the provider. */ @Override public Challenge createChallenge(Login login, JSON data) { Objects.requireNonNull(login, "login"); Objects.requireNonNull(data, "data"); String type = data.get("type").asString(); BiFunction<Login, JSON, Challenge> constructor = CHALLENGES.get(type); if (constructor != null) { return constructor.apply(login, data); } if (data.contains("token")) { return new TokenChallenge(login, data); } else { return new Challenge(login, data); } }
@Override protected void setJSON(JSON json) { String type = json.get(KEY_TYPE).asString(); if (!acceptable(type)) { throw new AcmeProtocolException("incompatible type " + type + " for this challenge"); } String loc = json.get(KEY_URL).asString(); if (loc != null && !loc.equals(getLocation().toString())) { throw new AcmeProtocolException("challenge has changed its location"); } super.setJSON(json); }
/** * {@inheritDoc} * <p> * This implementation handles the standard challenge types. For unknown types, * generic {@link Challenge} or {@link TokenChallenge} instances are created. * <p> * Custom provider implementations may override this method to provide challenges that * are unique to the provider. */ @Override public Challenge createChallenge(Login login, JSON data) { Objects.requireNonNull(login, "login"); Objects.requireNonNull(data, "data"); String type = data.get("type").asString(); BiFunction<Login, JSON, Challenge> constructor = CHALLENGES.get(type); if (constructor != null) { return constructor.apply(login, data); } if (data.contains("token")) { return new TokenChallenge(login, data); } else { return new Challenge(login, data); } }
if (challenge.getStatus() == Status.VALID) { return; challenge.trigger(); while (challenge.getStatus() != Status.VALID && attempts-- > 0) { if (challenge.getStatus() == Status.INVALID) { throw new AcmeException("Challenge failed... Giving up."); challenge.update(); if (challenge.getStatus() != Status.VALID) { throw new AcmeException("Failed to pass the challenge for domain " + aDomain + ", ... Giving up.");
/** * Finds a {@link Challenge} of the given type. Responding to this {@link Challenge} * is sufficient for authorization. * * @param type * Challenge name (e.g. "http-01") * @return {@link Challenge} matching that name, or {@code null} if there is no such * challenge, or if the challenge alone is not sufficient for authorization. * @throws ClassCastException * if the type does not match the expected Challenge class type */ @SuppressWarnings("unchecked") @CheckForNull public <T extends Challenge> T findChallenge(final String type) { return (T) getChallenges().stream() .filter(ch -> type.equals(ch.getType())) .reduce((a, b) -> {throw new AcmeProtocolException("Found more than one challenge of type " + type);}) .orElse(null); }
if (challenge.getStatus() == Status.VALID) { return; challenge.trigger(); while (challenge.getStatus() != Status.VALID && attempts-- > 0) { if (challenge.getStatus() == Status.INVALID) { throw new AcmeException("Challenge failed... Giving up."); challenge.update(); if (challenge.getStatus() != Status.VALID) { throw new AcmeException("Failed to pass the challenge for domain " + auth.getIdentifier().getDomain() + ", ... Giving up.");
@Override public Tuple2<Order, Dns01Challenge> challengeInit(String domainName) { AssertTools.assertNotNull(account, "You need to log in first"); Order order; try { order = account.newOrder() // .domains(domainName) // .create(); } catch (AcmeException e) { LOGGER.error("Could not ask for domain {}", domainName, e); throw new LetsencryptException("Could not ask for domain " + domainName, e); } // Get the DNS challenge Dns01Challenge challenge = null; List<String> availableChallenges = new ArrayList<>(); for (Authorization auth : order.getAuthorizations()) { auth.getChallenges().stream().map(it -> it.getType()).forEach(it -> availableChallenges.add(it)); challenge = auth.findChallenge(Dns01Challenge.TYPE); } if (challenge == null) { throw new LetsencryptException("DNS Challenge not found for " + domainName + " ; Available challenges are: [" + Joiner.on(", ").join(availableChallenges) + "]"); } return new Tuple2<>(order, challenge); }