From 78753bc22f140f863aa3fe56b1c59699ca3e2fa8 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Mon, 26 Sep 2011 22:29:07 -0400 Subject: [PATCH] Protect DownloadZipServlet with an AccessRestrictionFilter. --- src/com/gitblit/utils/FederationUtils.java | 121 ++++++++++++++++++++++++++++++++++------ 1 files changed, 103 insertions(+), 18 deletions(-) diff --git a/src/com/gitblit/utils/FederationUtils.java b/src/com/gitblit/utils/FederationUtils.java index 129fe42..9fd8817 100644 --- a/src/com/gitblit/utils/FederationUtils.java +++ b/src/com/gitblit/utils/FederationUtils.java @@ -26,8 +26,10 @@ import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.text.MessageFormat; +import java.util.ArrayList; import java.util.Collection; -import java.util.Date; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -40,10 +42,15 @@ import javax.net.ssl.X509TrustManager; import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.gitblit.Constants.FederationRequest; -import com.gitblit.Constants.FederationToken; import com.gitblit.FederationServlet; +import com.gitblit.IStoredSettings; +import com.gitblit.Keys; import com.gitblit.models.FederationModel; +import com.gitblit.models.FederationProposal; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.google.gson.Gson; @@ -75,6 +82,8 @@ private static final SSLContext SSL_CONTEXT; private static final DummyHostnameVerifier HOSTNAME_VERIFIER; + + private static final Logger LOGGER = LoggerFactory.getLogger(FederationUtils.class); static { SSLContext context = null; @@ -90,26 +99,102 @@ } /** + * Returns the list of federated gitblit instances that this instance will + * try to pull. + * + * @return list of registered gitblit instances + */ + public static List<FederationModel> getFederationRegistrations(IStoredSettings settings) { + List<FederationModel> federationRegistrations = new ArrayList<FederationModel>(); + List<String> keys = settings.getAllKeys(Keys.federation._ROOT); + keys.remove(Keys.federation.name); + keys.remove(Keys.federation.passphrase); + keys.remove(Keys.federation.allowProposals); + keys.remove(Keys.federation.proposalsFolder); + keys.remove(Keys.federation.defaultFrequency); + keys.remove(Keys.federation.sets); + Collections.sort(keys); + Map<String, FederationModel> federatedModels = new HashMap<String, FederationModel>(); + for (String key : keys) { + String value = key.substring(Keys.federation._ROOT.length() + 1); + List<String> values = StringUtils.getStringsFromValue(value, "\\."); + String server = values.get(0); + if (!federatedModels.containsKey(server)) { + federatedModels.put(server, new FederationModel(server)); + } + String setting = values.get(1); + if (setting.equals("url")) { + // url of the origin Gitblit instance + federatedModels.get(server).url = settings.getString(key, ""); + } else if (setting.equals("token")) { + // token for the origin Gitblit instance + federatedModels.get(server).token = settings.getString(key, ""); + } else if (setting.equals("frequency")) { + // frequency of the pull operation + federatedModels.get(server).frequency = settings.getString(key, ""); + } else if (setting.equals("folder")) { + // destination folder of the pull operation + federatedModels.get(server).folder = settings.getString(key, ""); + } else if (setting.equals("bare")) { + // whether pulled repositories should be bare + federatedModels.get(server).bare = settings.getBoolean(key, true); + } else if (setting.equals("mirror")) { + // are the repositories to be true mirrors of the origin + federatedModels.get(server).mirror = settings.getBoolean(key, true); + } else if (setting.equals("mergeAccounts")) { + // merge remote accounts into local accounts + federatedModels.get(server).mergeAccounts = settings.getBoolean(key, false); + } else if (setting.equals("sendStatus")) { + // send a status acknowledgment to source Gitblit instance + // at end of git pull + federatedModels.get(server).sendStatus = settings.getBoolean(key, false); + } else if (setting.equals("notifyOnError")) { + // notify administrators on federation pull failures + federatedModels.get(server).notifyOnError = settings.getBoolean(key, false); + } else if (setting.equals("exclude")) { + // excluded repositories + federatedModels.get(server).exclusions = settings.getStrings(key); + } else if (setting.equals("include")) { + // included repositories + federatedModels.get(server).inclusions = settings.getStrings(key); + } + } + + // verify that registrations have a url and a token + for (FederationModel model : federatedModels.values()) { + if (StringUtils.isEmpty(model.url)) { + LOGGER.warn(MessageFormat.format( + "Dropping federation registration {0}. Missing url.", model.name)); + continue; + } + if (StringUtils.isEmpty(model.token)) { + LOGGER.warn(MessageFormat.format( + "Dropping federation registration {0}. Missing token.", model.name)); + continue; + } + // set default frequency if unspecified + if (StringUtils.isEmpty(model.frequency)) { + model.frequency = settings.getString(Keys.federation.defaultFrequency, "60 mins"); + } + federationRegistrations.add(model); + } + return federationRegistrations; + } + + /** * Sends a federation proposal to the Gitblit instance at remoteUrl * * @param remoteUrl * the remote Gitblit instance to send a federation proposal to - * @param tokenType - * type of the provided federation token - * @param myToken - * my federation token - * @param myUrl - * my Gitblit url - * @param myRepositories - * the repositories I want to share keyed by their clone url + * @param proposal + * a complete federation proposal * @return true if the proposal was received */ - public static boolean propose(String remoteUrl, FederationToken tokenType, String myToken, - String myUrl, Map<String, RepositoryModel> myRepositories) throws Exception { - String url = FederationServlet.asFederationLink(remoteUrl, tokenType, myToken, - FederationRequest.PROPOSAL, myUrl); + public static boolean propose(String remoteUrl, FederationProposal proposal) throws Exception { + String url = FederationServlet + .asFederationLink(remoteUrl, null, FederationRequest.PROPOSAL); Gson gson = new GsonBuilder().setPrettyPrinting().create(); - String json = gson.toJson(myRepositories); + String json = gson.toJson(proposal); int status = writeJson(url, json); return status == HttpServletResponse.SC_OK; } @@ -126,7 +211,7 @@ */ public static Map<String, RepositoryModel> getRepositories(FederationModel registration, boolean checkExclusions) throws Exception { - String url = FederationServlet.asPullLink(registration.url, registration.token, + String url = FederationServlet.asFederationLink(registration.url, registration.token, FederationRequest.PULL_REPOSITORIES); Map<String, RepositoryModel> models = readGson(url, REPOSITORIES_TYPE); if (checkExclusions) { @@ -149,7 +234,7 @@ * @throws Exception */ public static Collection<UserModel> getUsers(FederationModel registration) throws Exception { - String url = FederationServlet.asPullLink(registration.url, registration.token, + String url = FederationServlet.asFederationLink(registration.url, registration.token, FederationRequest.PULL_USERS); Collection<UserModel> models = readGson(url, USERS_TYPE); return models; @@ -164,7 +249,7 @@ * @throws Exception */ public static Map<String, String> getSettings(FederationModel registration) throws Exception { - String url = FederationServlet.asPullLink(registration.url, registration.token, + String url = FederationServlet.asFederationLink(registration.url, registration.token, FederationRequest.PULL_SETTINGS); Map<String, String> settings = readGson(url, SETTINGS_TYPE); return settings; -- Gitblit v1.9.1