Просмотр исходного кода

refetch sage key if it has expired or could not be found

tags/v0.9.13
Jonathan Cobb 4 лет назад
Родитель
Сommit
6fbfa6cf4e
4 измененных файлов: 46 добавлений и 16 удалений
  1. +1
    -0
      bubble-server/src/main/java/bubble/ApiConstants.java
  2. +13
    -0
      bubble-server/src/main/java/bubble/resources/account/AuthResource.java
  3. +1
    -0
      bubble-server/src/main/java/bubble/rule/bblock/BubbleBlockRuleDriver.java
  4. +31
    -16
      bubble-server/src/main/java/bubble/service/boot/StandardSelfNodeService.java

+ 1
- 0
bubble-server/src/main/java/bubble/ApiConstants.java Просмотреть файл

@@ -87,6 +87,7 @@ public class ApiConstants {
public static final String EP_FORGOT_PASSWORD = "/forgotPassword"; public static final String EP_FORGOT_PASSWORD = "/forgotPassword";
public static final String EP_CHANGE_PASSWORD = "/changePassword"; public static final String EP_CHANGE_PASSWORD = "/changePassword";
public static final String EP_CA_CERT = "/cacert"; public static final String EP_CA_CERT = "/cacert";
public static final String EP_KEY = "/key";
public static final String EP_SCRIPT = "/script"; public static final String EP_SCRIPT = "/script";
public static final String EP_APPROVE = "/approve"; public static final String EP_APPROVE = "/approve";
public static final String EP_DENY = "/deny"; public static final String EP_DENY = "/deny";


+ 13
- 0
bubble-server/src/main/java/bubble/resources/account/AuthResource.java Просмотреть файл

@@ -10,12 +10,14 @@ import bubble.dao.account.AccountPolicyDAO;
import bubble.dao.account.message.AccountMessageDAO; import bubble.dao.account.message.AccountMessageDAO;
import bubble.dao.bill.BubblePlanDAO; import bubble.dao.bill.BubblePlanDAO;
import bubble.dao.cloud.BubbleNodeDAO; import bubble.dao.cloud.BubbleNodeDAO;
import bubble.dao.cloud.BubbleNodeKeyDAO;
import bubble.model.CertType; import bubble.model.CertType;
import bubble.model.account.*; import bubble.model.account.*;
import bubble.model.account.message.*; import bubble.model.account.message.*;
import bubble.model.boot.ActivationRequest; import bubble.model.boot.ActivationRequest;
import bubble.model.cloud.BubbleNetwork; import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.BubbleNode; import bubble.model.cloud.BubbleNode;
import bubble.model.cloud.BubbleNodeKey;
import bubble.model.cloud.NetworkKeys; import bubble.model.cloud.NetworkKeys;
import bubble.model.cloud.notify.NotificationReceipt; import bubble.model.cloud.notify.NotificationReceipt;
import bubble.model.device.Device; import bubble.model.device.Device;
@@ -85,6 +87,7 @@ public class AuthResource {
@Autowired private StandardAuthenticatorService authenticatorService; @Autowired private StandardAuthenticatorService authenticatorService;
@Autowired private PromotionService promoService; @Autowired private PromotionService promoService;
@Autowired private DeviceIdService deviceIdService; @Autowired private DeviceIdService deviceIdService;
@Autowired private BubbleNodeKeyDAO nodeKeyDAO;


public Account updateLastLogin(Account account) { return accountDAO.update(account.setLastLogin()); } public Account updateLastLogin(Account account) { return accountDAO.update(account.setLastLogin()); }


@@ -484,6 +487,16 @@ public class AuthResource {
return send(new FileSendableResource(certFile).setForceDownload(true)); return send(new FileSendableResource(certFile).setForceDownload(true));
} }


@GET @Path(EP_KEY)
public Response getNodeKey(@Context Request req,
@Context ContainerRequest ctx) {
final BubbleNode thisNode = configuration.getThisNode();
if (thisNode == null) return notFound();
final BubbleNodeKey key = nodeKeyDAO.findFirstByNode(thisNode.getUuid());
if (key == null) return notFound(thisNode.id());
return ok(key);
}

private Account validateCallerForApproveOrDeny(Account caller, AccountMessage message, String token) { private Account validateCallerForApproveOrDeny(Account caller, AccountMessage message, String token) {
if (message == null) throw notFoundEx(token); if (message == null) throw notFoundEx(token);




+ 1
- 0
bubble-server/src/main/java/bubble/rule/bblock/BubbleBlockRuleDriver.java Просмотреть файл

@@ -124,6 +124,7 @@ public class BubbleBlockRuleDriver extends TrafficAnalyticsRuleDriver {
if (refererURI == null) { if (refererURI == null) {
if (log.isInfoEnabled()) log.info(prefix+"invalid referer ("+filter.getReferer()+")"); if (log.isInfoEnabled()) log.info(prefix+"invalid referer ("+filter.getReferer()+")");
} else { } else {
if (log.isInfoEnabled()) log.info(prefix+"decision for URL was ALLOW, checking against referer: host="+refererURI.getHost()+", path="+refererURI.getPath());
final BlockDecision refererDecision = getDecision(refererURI.getHost(), refererURI.getPath(), filter.getUserAgent()); final BlockDecision refererDecision = getDecision(refererURI.getHost(), refererURI.getPath(), filter.getUserAgent());
switch (refererDecision.getDecisionType()) { switch (refererDecision.getDecisionType()) {
case block: case block:


+ 31
- 16
bubble-server/src/main/java/bubble/service/boot/StandardSelfNodeService.java Просмотреть файл

@@ -25,6 +25,9 @@ import bubble.service.notify.NotificationService;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.cache.Refreshable; import org.cobbzilla.util.cache.Refreshable;
import org.cobbzilla.util.http.HttpSchemes;
import org.cobbzilla.util.http.HttpUtil;
import org.cobbzilla.util.io.FileUtil;
import org.cobbzilla.util.string.StringUtil; import org.cobbzilla.util.string.StringUtil;
import org.cobbzilla.util.system.OneWayFlag; import org.cobbzilla.util.system.OneWayFlag;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -36,8 +39,8 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;


import static bubble.ApiConstants.HOME_DIR;
import static bubble.ApiConstants.NULL_NODE;
import static bubble.ApiConstants.*;
import static bubble.ApiConstants.EP_KEY;
import static bubble.model.cloud.BubbleNode.nodeFromFile; import static bubble.model.cloud.BubbleNode.nodeFromFile;
import static bubble.model.cloud.BubbleNodeKey.nodeKeyFromFile; import static bubble.model.cloud.BubbleNodeKey.nodeKeyFromFile;
import static bubble.server.BubbleServer.disableRestoreMode; import static bubble.server.BubbleServer.disableRestoreMode;
@@ -226,25 +229,20 @@ public class StandardSelfNodeService implements SelfNodeService {
} }


private BubbleNode initSageNode(BubbleNode selfNode) { private BubbleNode initSageNode(BubbleNode selfNode) {
final BubbleNode sage = nodeDAO.findByUuid(selfNode.getSageNode());
BubbleNode sage = nodeDAO.findByUuid(selfNode.getSageNode());
if (sage == null) { if (sage == null) {
// do we have a local file we can fall back on? // do we have a local file we can fall back on?
if (!SAGE_NODE_FILE.exists()) { if (!SAGE_NODE_FILE.exists()) {
log.warn("initSageNode: DB contains no entry for selfNode.sage ("+selfNode.getSageNode()+") and "+abs(SAGE_NODE_FILE)+ " does not exist, returning null"); log.warn("initSageNode: DB contains no entry for selfNode.sage ("+selfNode.getSageNode()+") and "+abs(SAGE_NODE_FILE)+ " does not exist, returning null");
return NULL_NODE; return NULL_NODE;
} }
return ensureSageKeyExists(syncSage(selfNode, nodeFromFile(SAGE_NODE_FILE)));
sage = syncSage(selfNode, nodeFromFile(SAGE_NODE_FILE));
} }
return ensureSageKeyExists(syncSage(selfNode, SAGE_NODE_FILE.exists()
sage = syncSage(selfNode, SAGE_NODE_FILE.exists()
? nodeFromFile(SAGE_NODE_FILE) ? nodeFromFile(SAGE_NODE_FILE)
: sage));
}

private BubbleNode ensureSageKeyExists(BubbleNode sageNode) {
final BubbleNodeKey sageKey = initSageKey(sageNode);
return sageKey != null
? sageNode
: die("finalizeRestore: no sage key found in DB and no sage key file, cannot finalize restore. Sage = "+sageNode.id());
: sage);
initSageKey(sage);
return sage;
} }


private BubbleNode syncSage(BubbleNode selfNode, BubbleNode sage) { private BubbleNode syncSage(BubbleNode selfNode, BubbleNode sage) {
@@ -359,13 +357,14 @@ public class StandardSelfNodeService implements SelfNodeService {
} }


// try key from file // try key from file
if (!SAGE_KEY_FILE.exists()) return null;
if (!SAGE_KEY_FILE.exists()) return fetchLatestSageKey(sageNode);
sageKey = nodeKeyFromFile(SAGE_KEY_FILE); sageKey = nodeKeyFromFile(SAGE_KEY_FILE);
final BubbleNodeKey existingByUuid = nodeKeyDAO.findByUuid(sageKey.getUuid()); final BubbleNodeKey existingByUuid = nodeKeyDAO.findByUuid(sageKey.getUuid());
final BubbleNodeKey existingByHash = nodeKeyDAO.findByPublicKeyHash(sageKey.getPublicKeyHash()); final BubbleNodeKey existingByHash = nodeKeyDAO.findByPublicKeyHash(sageKey.getPublicKeyHash());
if (existingByUuid == null && existingByHash == null) { if (existingByUuid == null && existingByHash == null) {
if (sageKey.expired()) { if (sageKey.expired()) {
return die("initSageKey: key not found in DB, but key on disk has expired: "+sageKey);
log.warn("initSageKey: key not found in DB and key on disk has expired, re-keying: "+sageKey);
return fetchLatestSageKey(sageNode);
} }
return nodeKeyDAO.create(sageKey); return nodeKeyDAO.create(sageKey);


@@ -373,7 +372,8 @@ public class StandardSelfNodeService implements SelfNodeService {
if (!existingByHash.getUuid().equals(existingByUuid.getUuid())) { if (!existingByHash.getUuid().equals(existingByUuid.getUuid())) {
// should never happen, but reset just in case // should never happen, but reset just in case
if (sageKey.expired()) { if (sageKey.expired()) {
return die("initSageKey: key found in DB with different entries for uuid/fqdn, and key on disk has expired: "+sageKey);
log.warn("initSageKey: key not found in DB and key on disk has expired, re-keying: "+sageKey);
return fetchLatestSageKey(sageNode);
} }
nodeKeyDAO.delete(existingByUuid.getUuid()); nodeKeyDAO.delete(existingByUuid.getUuid());
nodeKeyDAO.delete(existingByHash.getUuid()); nodeKeyDAO.delete(existingByHash.getUuid());
@@ -391,6 +391,21 @@ public class StandardSelfNodeService implements SelfNodeService {
} }
} }


private BubbleNodeKey fetchLatestSageKey(BubbleNode sageNode) {
log.warn("fetchLatestSageKey: key found in DB with different entries for uuid/fqdn, and key on disk has expired, refreshing: "+sageNode.id());
try {
final String keyUrl = HttpSchemes.SCHEME_HTTPS + sageNode.getFqdn() + ":" + sageNode.getSslPort() + configuration.getHttp().getBaseUri() + AUTH_ENDPOINT + EP_KEY;
log.info("fetchLatestSageKey: fetching sage key from: "+keyUrl);
final String keyJson = HttpUtil.url2string(keyUrl);
final BubbleNodeKey sageKey = json(keyJson, BubbleNodeKey.class);
FileUtil.toFile(SAGE_KEY_FILE, keyJson);
nodeKeyDAO.create(sageKey);
return sageKey;
} catch (Exception e) {
return die("fetchLatestSageKey: error fetching/saving latest sage key: "+e, e);
}
}

@Override public BubblePlan getThisPlan() { @Override public BubblePlan getThisPlan() {
final BubbleNetwork network = safeGetThisNetwork(); final BubbleNetwork network = safeGetThisNetwork();
if (network == null) return null; if (network == null) return null;


Загрузка…
Отмена
Сохранить