Merge branch 'master' of https://github.com/gitblit/gitblit into enhancedLdap
Conflicts:
distrib/gitblit.properties
4 files added
29 files modified
| | |
| | | <classpathentry kind="lib" path="ext/unboundid-ldapsdk-2.3.0.jar" sourcepath="ext/src/unboundid-ldapsdk-2.3.0-sources.jar" /> |
| | | <classpathentry kind="lib" path="ext/ivy-2.2.0.jar" sourcepath="ext/src/ivy-2.2.0-sources.jar" /> |
| | | <classpathentry kind="lib" path="ext/jcalendar-1.3.2.jar" /> |
| | | <classpathentry kind="lib" path="ext/commons-compress-1.4.1.jar" sourcepath="ext/src/commons-compress-1.4.1-sources.jar" /> |
| | | <classpathentry kind="lib" path="ext/xz-1.0.jar" sourcepath="ext/src/xz-1.0-sources.jar" /> |
| | | <classpathentry kind="lib" path="ext/junit-4.10.jar" sourcepath="ext/src/junit-4.10-sources.jar" /> |
| | | <classpathentry kind="lib" path="ext/hamcrest-core-1.1.jar" /> |
| | | <classpathentry kind="output" path="bin/classes" /> |
| | |
| | |
|
| | | http://www.toedter.com/en/jcalendar
|
| | | |
| | | ---------------------------------------------------------------------------
|
| | | Commons-Compress
|
| | | ---------------------------------------------------------------------------
|
| | | Commons-Compress, released under the
|
| | | Apache Software License, Version 2.0.
|
| | |
|
| | | http://commons.apache.org/compress
|
| | |
|
| | | ---------------------------------------------------------------------------
|
| | | XZ for Java
|
| | | ---------------------------------------------------------------------------
|
| | | XZ for Java, released under the
|
| | | Public Domain
|
| | |
|
| | | http://tukaani.org/xz/java.html
|
| | |
|
| | |
| | | <property name="authority.zipfile" value="authority-${gb.version}.zip" />
|
| | | <property name="gbapi.zipfile" value="gbapi-${gb.version}.zip" />
|
| | | <property name="express.zipfile" value="express-${gb.version}.zip" />
|
| | | <property name="distribution.pomfileTmplt" value="tmplt.pom.xml" />
|
| | | </target>
|
| | |
|
| | |
|
| | |
| | | <exclude name="com/gitblit/Launcher*.class" />
|
| | | </fileset>
|
| | | </copy>
|
| | | <copy todir="${project.jar.dir}/static">
|
| | | <fileset dir="${project.resources.dir}">
|
| | | <exclude name="thumbs.db" />
|
| | | </fileset>
|
| | | </copy>
|
| | |
|
| | | <!-- Build the JAR file -->
|
| | | <jar basedir="${project.jar.dir}" destfile="${distribution.jarfile}" compress="true" />
|
| | |
| | | <resource file="${basedir}/resources/settings_32x32.png" />
|
| | | <resource file="${basedir}/resources/search-icon.png" />
|
| | | <resource file="${basedir}/resources/mail_16x16.png" />
|
| | | <resource file="${basedir}/resources/script_16x16.png" />
|
| | | <resource file="${basedir}/resources/blank.png" />
|
| | | <resource file="${basedir}/resources/bullet_green.png" />
|
| | | <resource file="${basedir}/resources/bullet_orange.png" />
|
| | |
| | | # SINCE 0.5.0 |
| | | web.allowZipDownloads = true |
| | | |
| | | # If *web.allowZipDownloads=true* the following formats will be displayed for |
| | | # download compressed archive links: |
| | | # |
| | | # zip = standard .zip |
| | | # tar = standard tar format (preserves *nix permissions and symlinks) |
| | | # gz = gz-compressed tar |
| | | # xz = xz-compressed tar |
| | | # bzip2 = bzip2-compressed tar |
| | | # |
| | | # SPACE-DELIMITED |
| | | # SINCE 1.2.0 |
| | | web.compressedDownloads = zip gz |
| | | |
| | | # Allow optional Lucene integration. Lucene indexing is an opt-in feature. |
| | | # A repository may specify branches to index with Lucene instead of using Git |
| | | # commit traversal. There are scenarios where you may want to completely disable |
| | |
| | | - [UnboundID](http://www.unboundid.com) (LGPL 2.1)
|
| | | - [Ivy](http://ant.apache.org/ivy) (Apache 2.0)
|
| | | - [JCalendar](http://www.toedter.com/en/jcalendar) (LGPL 2.1)
|
| | | - [Commons-Compress](http://commons.apache.org/compress) (Apache 2.0)
|
| | | - [XZ for Java](http://tukaani.org/xz/java.html) (Public Domain)
|
| | |
|
| | | ### Other Build Dependencies
|
| | | - [Fancybox image viewer](http://fancybox.net) (MIT and GPL dual-licensed)
|
| | |
| | | - Added Gitblit Certificate Authority, an X509 certificate generation tool for Gitblit GO to encourage use of client certificate authentication.
|
| | | - Added setting to control length of shortened commit ids
|
| | | **New:** *web.shortCommitIdLength=8*
|
| | | - Added alternate compressed download formats: tar.gz, tar.xz, tar.bzip2 (issue 174) |
| | | **New:** *web.compressedDownloads = zip gz*
|
| | | - Added simple project pages. A project is a subfolder off the *git.repositoriesFolder*.
|
| | | - Added support for X-Forwarded-Context for Apache subdomain proxy configurations (issue 135)
|
| | | - Delete branch feature (issue 121, Github/ajermakovics)
|
| | |
| | |
|
| | | #### changes
|
| | |
|
| | | - Access restricted servlets (e.g. DownloadZip, RSS, etc) will try to authenticate any Gitblit cookie found in the request before resorting to BASIC authentication.
|
| | | - Added *groovy* and *scala* to *web.prettyPrintExtensions*
|
| | | - Added short commit id column to log and history tables (issue 168)
|
| | | - Teams can now specify the *admin*, *create*, and *fork* roles to simplify user administration
|
| | |
| | | - updated to Lucene 3.6.1
|
| | | - updated to BouncyCastle 1.47
|
| | | - added JCalendar 1.3.2
|
| | |
|
| | | - added Commons-Compress 1.4.1
|
| | | - added XZ for Java 1.0
|
| | | <hr/>
|
| | |
|
| | | ### Older Releases
|
| | |
| | | white-space: nowrap;
|
| | | }
|
| | |
|
| | | span.sha1, span.sha1 a, span.sha1 a span, .commit_message {
|
| | | span.sha1, span.sha1 a, span.sha1 a span, .commit_message, span.shortsha1 {
|
| | | font-family: consolas, monospace;
|
| | | font-size: 13px;
|
| | | }
|
| | |
|
| | | span.shortsha1 {
|
| | | font-size: 12px;
|
| | | }
|
| | |
|
| | | td.mode {
|
| | | text-align: right;
|
| | | font-family: monospace;
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | public static enum AuthenticationType {
|
| | | CREDENTIALS, COOKIE, CERTIFICATE;
|
| | | |
| | | public boolean isStandard() {
|
| | | return ordinal() <= COOKIE.ordinal();
|
| | | }
|
| | | }
|
| | |
|
| | | @Documented
|
| | | @Retention(RetentionPolicy.RUNTIME)
|
| | | public @interface Unused {
|
| | |
| | | import org.slf4j.Logger;
|
| | | import org.slf4j.LoggerFactory;
|
| | |
|
| | | import com.gitblit.utils.CompressionUtils;
|
| | | import com.gitblit.utils.JGitUtils;
|
| | | import com.gitblit.utils.MarkdownUtils;
|
| | | import com.gitblit.utils.StringUtils;
|
| | |
| | |
|
| | | private transient Logger logger = LoggerFactory.getLogger(DownloadZipServlet.class);
|
| | |
|
| | | public static enum Format {
|
| | | zip(".zip"), tar(".tar"), gz(".tar.gz"), xz(".tar.xz"), bzip2(".tar.bzip2");
|
| | | |
| | | public final String extension;
|
| | | |
| | | Format(String ext) {
|
| | | this.extension = ext;
|
| | | }
|
| | | |
| | | public static Format fromName(String name) {
|
| | | for (Format format : values()) {
|
| | | if (format.name().equalsIgnoreCase(name)) {
|
| | | return format;
|
| | | }
|
| | | }
|
| | | return zip;
|
| | | }
|
| | | }
|
| | |
|
| | | public DownloadZipServlet() {
|
| | | super();
|
| | | }
|
| | |
| | | * @param repository
|
| | | * @param objectId
|
| | | * @param path
|
| | | * @param format
|
| | | * @return an url
|
| | | */
|
| | | public static String asLink(String baseURL, String repository, String objectId, String path) {
|
| | | public static String asLink(String baseURL, String repository, String objectId, String path, Format format) {
|
| | | if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') {
|
| | | baseURL = baseURL.substring(0, baseURL.length() - 1);
|
| | | }
|
| | | return baseURL + Constants.ZIP_PATH + "?r=" + repository
|
| | | + (path == null ? "" : ("&p=" + path))
|
| | | + (objectId == null ? "" : ("&h=" + objectId));
|
| | | + (objectId == null ? "" : ("&h=" + objectId))
|
| | | + (format == null ? "" : ("&format=" + format.name()));
|
| | | }
|
| | |
|
| | | /**
|
| | |
| | | return;
|
| | | }
|
| | |
|
| | | Format format = Format.zip;
|
| | | String repository = request.getParameter("r");
|
| | | String basePath = request.getParameter("p");
|
| | | String objectId = request.getParameter("h");
|
| | | String f = request.getParameter("format");
|
| | | if (!StringUtils.isEmpty(f)) {
|
| | | format = Format.fromName(f);
|
| | | }
|
| | |
|
| | | try {
|
| | | String name = repository;
|
| | | if (name.indexOf('/') > -1) {
|
| | | name = name.substring(name.lastIndexOf('/') + 1);
|
| | | }
|
| | | name = StringUtils.stripDotGit(name);
|
| | |
|
| | | if (!StringUtils.isEmpty(basePath)) {
|
| | | name += "-" + basePath.replace('/', '_');
|
| | |
| | |
|
| | | String contentType = "application/octet-stream";
|
| | | response.setContentType(contentType + "; charset=" + response.getCharacterEncoding());
|
| | | response.setHeader("Content-Disposition", "attachment; filename=\"" + name + ".zip"
|
| | | + "\"");
|
| | | response.setHeader("Content-Disposition", "attachment; filename=\"" + name + format.extension + "\"");
|
| | | response.setDateHeader("Last-Modified", date.getTime());
|
| | | response.setHeader("Cache-Control", "no-cache");
|
| | | response.setHeader("Pragma", "no-cache");
|
| | | response.setDateHeader("Expires", 0);
|
| | |
|
| | | try {
|
| | | JGitUtils.zip(r, basePath, objectId, response.getOutputStream());
|
| | | switch (format) {
|
| | | case zip:
|
| | | CompressionUtils.zip(r, basePath, objectId, response.getOutputStream());
|
| | | break;
|
| | | case tar:
|
| | | CompressionUtils.tar(r, basePath, objectId, response.getOutputStream());
|
| | | break;
|
| | | case gz:
|
| | | CompressionUtils.gz(r, basePath, objectId, response.getOutputStream());
|
| | | break;
|
| | | case xz:
|
| | | CompressionUtils.xz(r, basePath, objectId, response.getOutputStream());
|
| | | break;
|
| | | case bzip2:
|
| | | CompressionUtils.bzip2(r, basePath, objectId, response.getOutputStream());
|
| | | break;
|
| | | }
|
| | | |
| | | response.flushBuffer();
|
| | | } catch (Throwable t) {
|
| | | logger.error("Failed to write attachment to client", t);
|
| | |
| | | import javax.servlet.http.Cookie;
|
| | | import javax.servlet.http.HttpServletRequest;
|
| | |
|
| | | import org.apache.wicket.RequestCycle;
|
| | | import org.apache.wicket.protocol.http.WebResponse;
|
| | | import org.apache.wicket.resource.ContextRelativeResource;
|
| | | import org.apache.wicket.util.resource.ResourceStreamNotFoundException;
|
| | |
| | |
|
| | | import com.gitblit.Constants.AccessPermission;
|
| | | import com.gitblit.Constants.AccessRestrictionType;
|
| | | import com.gitblit.Constants.AuthenticationType;
|
| | | import com.gitblit.Constants.AuthorizationControl;
|
| | | import com.gitblit.Constants.FederationRequest;
|
| | | import com.gitblit.Constants.FederationStrategy;
|
| | |
| | | import com.gitblit.utils.ObjectCache;
|
| | | import com.gitblit.utils.StringUtils;
|
| | | import com.gitblit.utils.TimeUtils;
|
| | | import com.gitblit.utils.X509Utils.X509Metadata;
|
| | | import com.gitblit.wicket.GitBlitWebSession;
|
| | | import com.gitblit.wicket.WicketUtils;
|
| | |
|
| | | /**
|
| | |
| | | * @param cookies
|
| | | * @return a user object or null
|
| | | */
|
| | | public UserModel authenticate(Cookie[] cookies) {
|
| | | protected UserModel authenticate(Cookie[] cookies) {
|
| | | if (userService == null) {
|
| | | return null;
|
| | | }
|
| | |
| | | }
|
| | |
|
| | | /**
|
| | | * Authenticate a user based on HTTP request paramters.
|
| | | * This method is inteded to be used as fallback when other
|
| | | * means of authentication are failing (username / password or cookies).
|
| | | * Authenticate a user based on HTTP request parameters.
|
| | | * |
| | | * Authentication by X509Certificate is tried first and then by cookie.
|
| | | * |
| | | * @param httpRequest
|
| | | * @return a user object or null
|
| | | */
|
| | | public UserModel authenticate(HttpServletRequest httpRequest) {
|
| | | // try to authenticate by certificate
|
| | | boolean checkValidity = settings.getBoolean(Keys.git.enforceCertificateValidity, true);
|
| | | String [] oids = getStrings(Keys.git.certificateUsernameOIDs).toArray(new String[0]);
|
| | | UserModel model = HttpUtils.getUserModelFromCertificate(httpRequest, checkValidity, oids);
|
| | | if (model != null) {
|
| | | UserModel user = GitBlit.self().getUserModel(model.username);
|
| | | logger.info(MessageFormat.format("{0} authenticated by client certificate from {1}",
|
| | | // grab real user model and preserve certificate serial number
|
| | | UserModel user = getUserModel(model.username);
|
| | | if (user != null) {
|
| | | RequestCycle requestCycle = RequestCycle.get();
|
| | | if (requestCycle != null) {
|
| | | // flag the Wicket session, if this is a Wicket request
|
| | | GitBlitWebSession session = GitBlitWebSession.get();
|
| | | session.authenticationType = AuthenticationType.CERTIFICATE;
|
| | | }
|
| | | X509Metadata metadata = HttpUtils.getCertificateMetadata(httpRequest);
|
| | | logger.info(MessageFormat.format("{0} authenticated by client certificate {1} from {2}",
|
| | | user.username, metadata.serialNumber, httpRequest.getRemoteAddr()));
|
| | | return user;
|
| | | }
|
| | | }
|
| | | |
| | | // try to authenticate by cookie
|
| | | Cookie[] cookies = httpRequest.getCookies();
|
| | | if (allowCookieAuthentication() && cookies != null && cookies.length > 0) {
|
| | | // Grab cookie from Browser Session
|
| | | UserModel user = authenticate(cookies);
|
| | | if (user != null) {
|
| | | RequestCycle requestCycle = RequestCycle.get();
|
| | | if (requestCycle != null) {
|
| | | // flag the Wicket session, if this is a Wicket request
|
| | | GitBlitWebSession session = GitBlitWebSession.get();
|
| | | session.authenticationType = AuthenticationType.COOKIE;
|
| | | }
|
| | | logger.info(MessageFormat.format("{0} authenticated by cookie from {1}",
|
| | | user.username, httpRequest.getRemoteAddr()));
|
| | | return user;
|
| | | }
|
| | | }
|
| | | return null;
|
| | | }
|
| | |
|
| | |
| | | import javax.swing.JScrollPane;
|
| | | import javax.swing.JSplitPane;
|
| | | import javax.swing.JTable;
|
| | | import javax.swing.JTextArea;
|
| | | import javax.swing.JTextField;
|
| | | import javax.swing.RowFilter;
|
| | | import javax.swing.SwingConstants;
|
| | |
| | | import com.gitblit.client.Translation;
|
| | | import com.gitblit.models.UserModel;
|
| | | import com.gitblit.utils.ArrayUtils;
|
| | | import com.gitblit.utils.FileUtils;
|
| | | import com.gitblit.utils.StringUtils;
|
| | | import com.gitblit.utils.TimeUtils;
|
| | | import com.gitblit.utils.X509Utils;
|
| | |
| | |
|
| | | X509Metadata metadata = new X509Metadata("localhost", caKeystorePassword);
|
| | | setMetadataDefaults(metadata);
|
| | | metadata.notAfter = new Date(System.currentTimeMillis() + 10*TimeUtils.ONEYEAR);
|
| | | X509Utils.prepareX509Infrastructure(metadata, folder, this);
|
| | | return true;
|
| | | }
|
| | |
| | | }
|
| | | });
|
| | |
|
| | | JButton logButton = new JButton(new ImageIcon(getClass().getResource("/script_16x16.png")));
|
| | | logButton.setFocusable(false);
|
| | | logButton.setToolTipText(Translation.get("gb.log")); |
| | | logButton.addActionListener(new ActionListener() {
|
| | | @Override
|
| | | public void actionPerformed(ActionEvent e) {
|
| | | File log = new File(folder, X509Utils.CERTS + File.separator + "log.txt");
|
| | | if (log.exists()) {
|
| | | String content = FileUtils.readContent(log, "\n");
|
| | | JTextArea textarea = new JTextArea(content);
|
| | | JScrollPane scrollPane = new JScrollPane(textarea);
|
| | | scrollPane.setPreferredSize(new Dimension(700, 400));
|
| | | JOptionPane.showMessageDialog(GitblitAuthority.this, scrollPane, log.getAbsolutePath(), JOptionPane.INFORMATION_MESSAGE);
|
| | | }
|
| | | }
|
| | | });
|
| | | |
| | | final JTextField filterTextfield = new JTextField(15);
|
| | | filterTextfield.addActionListener(new ActionListener() {
|
| | | public void actionPerformed(ActionEvent e) {
|
| | |
| | | buttonControls.add(certificateDefaultsButton);
|
| | | buttonControls.add(newSSLCertificate);
|
| | | buttonControls.add(emailBundle);
|
| | | buttonControls.add(logButton);
|
| | |
|
| | | JPanel userControls = new JPanel(new FlowLayout(FlowLayout.RIGHT, Utils.MARGIN, Utils.MARGIN));
|
| | | userControls.add(new JLabel(Translation.get("gb.filter")));
|
| | |
| | | downloadFromApache(MavenObject.UNBOUND_ID, BuildType.RUNTIME);
|
| | | downloadFromApache(MavenObject.IVY, BuildType.RUNTIME);
|
| | | downloadFromApache(MavenObject.JCALENDAR, BuildType.RUNTIME);
|
| | | downloadFromApache(MavenObject.COMMONS_COMPRESS, BuildType.RUNTIME);
|
| | | downloadFromApache(MavenObject.XZ, BuildType.RUNTIME);
|
| | |
|
| | | downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME);
|
| | | downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.RUNTIME);
|
| | |
| | | downloadFromApache(MavenObject.UNBOUND_ID, BuildType.COMPILETIME);
|
| | | downloadFromApache(MavenObject.IVY, BuildType.COMPILETIME);
|
| | | downloadFromApache(MavenObject.JCALENDAR, BuildType.COMPILETIME);
|
| | | downloadFromApache(MavenObject.COMMONS_COMPRESS, BuildType.COMPILETIME);
|
| | | downloadFromApache(MavenObject.XZ, BuildType.COMPILETIME);
|
| | |
|
| | | downloadFromEclipse(MavenObject.JGIT, BuildType.COMPILETIME);
|
| | | downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.COMPILETIME);
|
| | |
| | | "323a672aeacb5f5f4461be3b7f7d9d3e4bda80d4",
|
| | | null, "");
|
| | |
|
| | | public static final MavenObject COMMONS_COMPRESS = new MavenObject(
|
| | | "commons-compress", "org/apache/commons", "commons-compress", "1.4.1",
|
| | | 242000, 265000, 0,
|
| | | "b02e84a993d88568417536240e970c4b809126fd",
|
| | | "277d39267403965a7a192474794a29bac6760a25", "");
|
| | |
|
| | | public static final MavenObject XZ = new MavenObject(
|
| | | "xz", "org/tukaani", "xz", "1.0",
|
| | | 95000, 120000, 0,
|
| | | "ecff5cb8b1189514c9d1d8d68eb77ac372e000c9",
|
| | | "f95e32a5d2dd8da643c4419814415b9704312993", "");
|
| | |
|
| | | public final String name;
|
| | | public final String group;
|
| | | public final String artifact;
|
New file |
| | |
| | | /*
|
| | | * Copyright 2012 gitblit.com.
|
| | | *
|
| | | * Licensed under the Apache License, Version 2.0 (the "License");
|
| | | * you may not use this file except in compliance with the License.
|
| | | * You may obtain a copy of the License at
|
| | | *
|
| | | * http://www.apache.org/licenses/LICENSE-2.0
|
| | | *
|
| | | * Unless required by applicable law or agreed to in writing, software
|
| | | * distributed under the License is distributed on an "AS IS" BASIS,
|
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| | | * See the License for the specific language governing permissions and
|
| | | * limitations under the License.
|
| | | */
|
| | | package com.gitblit.utils;
|
| | |
|
| | | import java.io.ByteArrayOutputStream;
|
| | | import java.io.IOException;
|
| | | import java.io.InputStream;
|
| | | import java.io.OutputStream;
|
| | | import java.text.MessageFormat;
|
| | | import java.util.ArrayList;
|
| | | import java.util.List;
|
| | | import java.util.zip.ZipEntry;
|
| | | import java.util.zip.ZipOutputStream;
|
| | |
|
| | | import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
| | | import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
|
| | | import org.apache.commons.compress.compressors.CompressorException;
|
| | | import org.apache.commons.compress.compressors.CompressorStreamFactory;
|
| | | import org.apache.commons.compress.utils.IOUtils;
|
| | | import org.eclipse.jgit.lib.Constants;
|
| | | import org.eclipse.jgit.lib.FileMode;
|
| | | import org.eclipse.jgit.lib.ObjectId;
|
| | | import org.eclipse.jgit.lib.ObjectLoader;
|
| | | import org.eclipse.jgit.lib.Repository;
|
| | | import org.eclipse.jgit.revwalk.RevBlob;
|
| | | import org.eclipse.jgit.revwalk.RevCommit;
|
| | | import org.eclipse.jgit.revwalk.RevWalk;
|
| | | import org.eclipse.jgit.treewalk.TreeWalk;
|
| | | import org.eclipse.jgit.treewalk.filter.PathFilter;
|
| | | import org.slf4j.Logger;
|
| | | import org.slf4j.LoggerFactory;
|
| | |
|
| | | /**
|
| | | * Collection of static methods for retrieving information from a repository.
|
| | | * |
| | | * @author James Moger
|
| | | * |
| | | */
|
| | | public class CompressionUtils {
|
| | |
|
| | | static final Logger LOGGER = LoggerFactory.getLogger(CompressionUtils.class);
|
| | |
|
| | | /**
|
| | | * Log an error message and exception.
|
| | | * |
| | | * @param t
|
| | | * @param repository
|
| | | * if repository is not null it MUST be the {0} parameter in the
|
| | | * pattern.
|
| | | * @param pattern
|
| | | * @param objects
|
| | | */
|
| | | private static void error(Throwable t, Repository repository, String pattern, Object... objects) {
|
| | | List<Object> parameters = new ArrayList<Object>();
|
| | | if (objects != null && objects.length > 0) {
|
| | | for (Object o : objects) {
|
| | | parameters.add(o);
|
| | | }
|
| | | }
|
| | | if (repository != null) {
|
| | | parameters.add(0, repository.getDirectory().getAbsolutePath());
|
| | | }
|
| | | LOGGER.error(MessageFormat.format(pattern, parameters.toArray()), t);
|
| | | }
|
| | |
|
| | | /**
|
| | | * Zips the contents of the tree at the (optionally) specified revision and
|
| | | * the (optionally) specified basepath to the supplied outputstream.
|
| | | * |
| | | * @param repository
|
| | | * @param basePath
|
| | | * if unspecified, entire repository is assumed.
|
| | | * @param objectId
|
| | | * if unspecified, HEAD is assumed.
|
| | | * @param os
|
| | | * @return true if repository was successfully zipped to supplied output
|
| | | * stream
|
| | | */
|
| | | public static boolean zip(Repository repository, String basePath, String objectId,
|
| | | OutputStream os) {
|
| | | RevCommit commit = JGitUtils.getCommit(repository, objectId);
|
| | | if (commit == null) {
|
| | | return false;
|
| | | }
|
| | | boolean success = false;
|
| | | RevWalk rw = new RevWalk(repository);
|
| | | TreeWalk tw = new TreeWalk(repository);
|
| | | try {
|
| | | tw.addTree(commit.getTree());
|
| | | ZipOutputStream zos = new ZipOutputStream(os);
|
| | | zos.setComment("Generated by Gitblit");
|
| | | if (!StringUtils.isEmpty(basePath)) {
|
| | | PathFilter f = PathFilter.create(basePath);
|
| | | tw.setFilter(f);
|
| | | }
|
| | | tw.setRecursive(true);
|
| | | while (tw.next()) {
|
| | | if (tw.getFileMode(0) == FileMode.GITLINK) {
|
| | | continue;
|
| | | }
|
| | | ZipEntry entry = new ZipEntry(tw.getPathString());
|
| | | entry.setSize(tw.getObjectReader().getObjectSize(tw.getObjectId(0),
|
| | | Constants.OBJ_BLOB));
|
| | | entry.setComment(commit.getName());
|
| | | zos.putNextEntry(entry);
|
| | |
|
| | | ObjectId entid = tw.getObjectId(0);
|
| | | FileMode entmode = tw.getFileMode(0);
|
| | | RevBlob blob = (RevBlob) rw.lookupAny(entid, entmode.getObjectType());
|
| | | rw.parseBody(blob);
|
| | |
|
| | | ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB);
|
| | | byte[] tmp = new byte[4096];
|
| | | InputStream in = ldr.openStream();
|
| | | int n;
|
| | | while ((n = in.read(tmp)) > 0) {
|
| | | zos.write(tmp, 0, n);
|
| | | }
|
| | | in.close();
|
| | | }
|
| | | zos.finish();
|
| | | success = true;
|
| | | } catch (IOException e) {
|
| | | error(e, repository, "{0} failed to zip files from commit {1}", commit.getName());
|
| | | } finally {
|
| | | tw.release();
|
| | | rw.dispose();
|
| | | }
|
| | | return success;
|
| | | }
|
| | | |
| | | /**
|
| | | * tar the contents of the tree at the (optionally) specified revision and
|
| | | * the (optionally) specified basepath to the supplied outputstream.
|
| | | * |
| | | * @param repository
|
| | | * @param basePath
|
| | | * if unspecified, entire repository is assumed.
|
| | | * @param objectId
|
| | | * if unspecified, HEAD is assumed.
|
| | | * @param os
|
| | | * @return true if repository was successfully zipped to supplied output
|
| | | * stream
|
| | | */
|
| | | public static boolean tar(Repository repository, String basePath, String objectId,
|
| | | OutputStream os) {
|
| | | return tar(null, repository, basePath, objectId, os);
|
| | | }
|
| | | |
| | | /**
|
| | | * tar.gz the contents of the tree at the (optionally) specified revision and
|
| | | * the (optionally) specified basepath to the supplied outputstream.
|
| | | * |
| | | * @param repository
|
| | | * @param basePath
|
| | | * if unspecified, entire repository is assumed.
|
| | | * @param objectId
|
| | | * if unspecified, HEAD is assumed.
|
| | | * @param os
|
| | | * @return true if repository was successfully zipped to supplied output
|
| | | * stream
|
| | | */
|
| | | public static boolean gz(Repository repository, String basePath, String objectId,
|
| | | OutputStream os) {
|
| | | return tar(CompressorStreamFactory.GZIP, repository, basePath, objectId, os);
|
| | | }
|
| | | |
| | | /**
|
| | | * tar.xz the contents of the tree at the (optionally) specified revision and
|
| | | * the (optionally) specified basepath to the supplied outputstream.
|
| | | * |
| | | * @param repository
|
| | | * @param basePath
|
| | | * if unspecified, entire repository is assumed.
|
| | | * @param objectId
|
| | | * if unspecified, HEAD is assumed.
|
| | | * @param os
|
| | | * @return true if repository was successfully zipped to supplied output
|
| | | * stream
|
| | | */
|
| | | public static boolean xz(Repository repository, String basePath, String objectId,
|
| | | OutputStream os) {
|
| | | return tar(CompressorStreamFactory.XZ, repository, basePath, objectId, os);
|
| | | }
|
| | | |
| | | /**
|
| | | * tar.bzip2 the contents of the tree at the (optionally) specified revision and
|
| | | * the (optionally) specified basepath to the supplied outputstream.
|
| | | * |
| | | * @param repository
|
| | | * @param basePath
|
| | | * if unspecified, entire repository is assumed.
|
| | | * @param objectId
|
| | | * if unspecified, HEAD is assumed.
|
| | | * @param os
|
| | | * @return true if repository was successfully zipped to supplied output
|
| | | * stream
|
| | | */
|
| | | public static boolean bzip2(Repository repository, String basePath, String objectId,
|
| | | OutputStream os) {
|
| | | |
| | | return tar(CompressorStreamFactory.BZIP2, repository, basePath, objectId, os);
|
| | | }
|
| | | |
| | | /**
|
| | | * Compresses/archives the contents of the tree at the (optionally)
|
| | | * specified revision and the (optionally) specified basepath to the
|
| | | * supplied outputstream.
|
| | | * |
| | | * @param algorithm
|
| | | * compression algorithm for tar (optional)
|
| | | * @param repository
|
| | | * @param basePath
|
| | | * if unspecified, entire repository is assumed.
|
| | | * @param objectId
|
| | | * if unspecified, HEAD is assumed.
|
| | | * @param os
|
| | | * @return true if repository was successfully zipped to supplied output
|
| | | * stream
|
| | | */
|
| | | private static boolean tar(String algorithm, Repository repository, String basePath, String objectId,
|
| | | OutputStream os) {
|
| | | RevCommit commit = JGitUtils.getCommit(repository, objectId);
|
| | | if (commit == null) {
|
| | | return false;
|
| | | }
|
| | | |
| | | OutputStream cos = os;
|
| | | if (!StringUtils.isEmpty(algorithm)) {
|
| | | try {
|
| | | cos = new CompressorStreamFactory().createCompressorOutputStream(algorithm, os);
|
| | | } catch (CompressorException e1) {
|
| | | error(e1, repository, "{0} failed to open {1} stream", algorithm);
|
| | | }
|
| | | }
|
| | | boolean success = false;
|
| | | RevWalk rw = new RevWalk(repository);
|
| | | TreeWalk tw = new TreeWalk(repository);
|
| | | try {
|
| | | tw.addTree(commit.getTree());
|
| | | TarArchiveOutputStream tos = new TarArchiveOutputStream(cos);
|
| | | tos.setAddPaxHeadersForNonAsciiNames(true);
|
| | | tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
|
| | | if (!StringUtils.isEmpty(basePath)) {
|
| | | PathFilter f = PathFilter.create(basePath);
|
| | | tw.setFilter(f);
|
| | | }
|
| | | tw.setRecursive(true);
|
| | | while (tw.next()) {
|
| | | FileMode mode = tw.getFileMode(0);
|
| | | if (mode == FileMode.GITLINK) {
|
| | | continue;
|
| | | }
|
| | | ObjectId id = tw.getObjectId(0);
|
| | | |
| | | // new entry
|
| | | TarArchiveEntry entry = new TarArchiveEntry(tw.getPathString());
|
| | | entry.setSize(tw.getObjectReader().getObjectSize(id, Constants.OBJ_BLOB));
|
| | | |
| | | if (FileMode.SYMLINK.equals(mode)) {
|
| | | // symlink
|
| | | entry.setMode(mode.getBits());
|
| | | |
| | | // read the symlink target
|
| | | ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
| | | RevBlob blob = (RevBlob) rw.lookupAny(id, mode.getObjectType());
|
| | | rw.parseBody(blob); |
| | | ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB);
|
| | | IOUtils.copy(ldr.openStream(), bs);
|
| | | entry.setLinkName(bs.toString("UTF-8"));
|
| | | } else {
|
| | | // regular file or executable file
|
| | | entry.setMode(mode.getBits());
|
| | | } |
| | | entry.setModTime(commit.getAuthorIdent().getWhen());
|
| | |
|
| | | tos.putArchiveEntry(entry);
|
| | | |
| | | if (!FileMode.SYMLINK.equals(mode)) {
|
| | | // write the blob
|
| | | RevBlob blob = (RevBlob) rw.lookupAny(id, mode.getObjectType());
|
| | | rw.parseBody(blob); |
| | | ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB);
|
| | | IOUtils.copy(ldr.openStream(), tos);
|
| | | }
|
| | | |
| | | // close entry
|
| | | tos.closeArchiveEntry();
|
| | | }
|
| | | tos.finish();
|
| | | tos.close();
|
| | | cos.close();
|
| | | success = true;
|
| | | } catch (IOException e) {
|
| | | error(e, repository, "{0} failed to {1} stream files from commit {2}", algorithm, commit.getName());
|
| | | } finally {
|
| | | tw.release();
|
| | | rw.dispose();
|
| | | }
|
| | | return success;
|
| | | }
|
| | | }
|
| | |
| | | import java.security.cert.X509Certificate;
|
| | | import java.text.MessageFormat;
|
| | | import java.util.Date;
|
| | | import java.util.HashMap;
|
| | | import java.util.Map;
|
| | |
|
| | | import javax.servlet.http.HttpServletRequest;
|
| | |
|
| | | import org.slf4j.LoggerFactory;
|
| | |
|
| | | import com.gitblit.models.UserModel;
|
| | | import com.gitblit.utils.X509Utils.X509Metadata;
|
| | |
|
| | | /**
|
| | | * Collection of utility methods for http requests.
|
| | |
| | | * @return
|
| | | */
|
| | | public static UserModel getUserModelFromCertificate(X509Certificate cert, String... usernameOIDs) {
|
| | | UserModel user = new UserModel(null);
|
| | | user.isAuthenticated = false;
|
| | | X509Metadata metadata = X509Utils.getMetadata(cert);
|
| | |
|
| | | // manually split DN into OID components
|
| | | // this is instead of parsing with LdapName which:
|
| | | // (1) I don't trust the order of values
|
| | | // (2) it filters out values like EMAILADDRESS
|
| | | String dn = cert.getSubjectDN().getName();
|
| | | Map<String, String> oids = new HashMap<String, String>();
|
| | | for (String kvp : dn.split(",")) {
|
| | | String [] val = kvp.trim().split("=");
|
| | | String oid = val[0].toUpperCase().trim();
|
| | | String data = val[1].trim();
|
| | | oids.put(oid, data);
|
| | | }
|
| | | UserModel user = new UserModel(metadata.commonName);
|
| | | user.emailAddress = metadata.emailAddress;
|
| | | user.isAuthenticated = false;
|
| | |
|
| | | if (usernameOIDs == null || usernameOIDs.length == 0) {
|
| | | // use default usename<->CN mapping
|
| | |
| | | // determine username from OID fingerprint
|
| | | StringBuilder an = new StringBuilder();
|
| | | for (String oid : usernameOIDs) {
|
| | | String val = getOIDValue(oid.toUpperCase(), oids);
|
| | | String val = metadata.getOID(oid.toUpperCase(), null);
|
| | | if (val != null) {
|
| | | an.append(val).append(' ');
|
| | | }
|
| | | }
|
| | | user.username = an.toString().trim();
|
| | | |
| | | // extract email address, if available
|
| | | user.emailAddress = getOIDValue("E", oids);
|
| | | if (user.emailAddress == null) {
|
| | | user.emailAddress = getOIDValue("EMAILADDRESS", oids);
|
| | | } |
| | | return user;
|
| | | }
|
| | |
|
| | | private static String getOIDValue(String oid, Map<String, String> oids) {
|
| | | if (oids.containsKey(oid)) {
|
| | | return oids.get(oid);
|
| | | public static X509Metadata getCertificateMetadata(HttpServletRequest httpRequest) {
|
| | | if (httpRequest.getAttribute("javax.servlet.request.X509Certificate") != null) {
|
| | | X509Certificate[] certChain = (X509Certificate[]) httpRequest
|
| | | .getAttribute("javax.servlet.request.X509Certificate");
|
| | | if (certChain != null) {
|
| | | X509Certificate cert = certChain[0];
|
| | | return X509Utils.getMetadata(cert);
|
| | | }
|
| | | }
|
| | | return null;
|
| | | }
|
| | |
| | | import java.io.File;
|
| | | import java.io.IOException;
|
| | | import java.io.InputStream;
|
| | | import java.io.OutputStream;
|
| | | import java.text.MessageFormat;
|
| | | import java.util.ArrayList;
|
| | | import java.util.Arrays;
|
| | |
| | | import java.util.Map;
|
| | | import java.util.Map.Entry;
|
| | | import java.util.regex.Pattern;
|
| | | import java.util.zip.ZipEntry;
|
| | | import java.util.zip.ZipOutputStream;
|
| | |
|
| | | import org.eclipse.jgit.api.CloneCommand;
|
| | | import org.eclipse.jgit.api.FetchCommand;
|
| | |
| | | try {
|
| | | // search for the branch in local heads
|
| | | for (RefModel ref : JGitUtils.getLocalBranches(repository, false, -1)) {
|
| | | if (ref.displayName.endsWith(name)) {
|
| | | if (ref.reference.getName().endsWith(name)) {
|
| | | branch = ref;
|
| | | break;
|
| | | }
|
| | |
| | | // search for the branch in remote heads
|
| | | if (branch == null) {
|
| | | for (RefModel ref : JGitUtils.getRemoteBranches(repository, false, -1)) {
|
| | | if (ref.displayName.endsWith(name)) {
|
| | | if (ref.reference.getName().endsWith(name)) {
|
| | | branch = ref;
|
| | | break;
|
| | | }
|
| | |
| | | }
|
| | | } catch (Throwable t) {
|
| | | error(t, repository, "Failed to create orphan branch {1} in repository {0}", branchName);
|
| | | }
|
| | | return success;
|
| | | }
|
| | |
|
| | | /**
|
| | | * Zips the contents of the tree at the (optionally) specified revision and
|
| | | * the (optionally) specified basepath to the supplied outputstream.
|
| | | * |
| | | * @param repository
|
| | | * @param basePath
|
| | | * if unspecified, entire repository is assumed.
|
| | | * @param objectId
|
| | | * if unspecified, HEAD is assumed.
|
| | | * @param os
|
| | | * @return true if repository was successfully zipped to supplied output
|
| | | * stream
|
| | | */
|
| | | public static boolean zip(Repository repository, String basePath, String objectId,
|
| | | OutputStream os) {
|
| | | RevCommit commit = getCommit(repository, objectId);
|
| | | if (commit == null) {
|
| | | return false;
|
| | | }
|
| | | boolean success = false;
|
| | | RevWalk rw = new RevWalk(repository);
|
| | | TreeWalk tw = new TreeWalk(repository);
|
| | | try {
|
| | | tw.addTree(commit.getTree());
|
| | | ZipOutputStream zos = new ZipOutputStream(os);
|
| | | zos.setComment("Generated by Gitblit");
|
| | | if (!StringUtils.isEmpty(basePath)) {
|
| | | PathFilter f = PathFilter.create(basePath);
|
| | | tw.setFilter(f);
|
| | | }
|
| | | tw.setRecursive(true);
|
| | | while (tw.next()) {
|
| | | if (tw.getFileMode(0) == FileMode.GITLINK) {
|
| | | continue;
|
| | | }
|
| | | ZipEntry entry = new ZipEntry(tw.getPathString());
|
| | | entry.setSize(tw.getObjectReader().getObjectSize(tw.getObjectId(0),
|
| | | Constants.OBJ_BLOB));
|
| | | entry.setComment(commit.getName());
|
| | | zos.putNextEntry(entry);
|
| | |
|
| | | ObjectId entid = tw.getObjectId(0);
|
| | | FileMode entmode = tw.getFileMode(0);
|
| | | RevBlob blob = (RevBlob) rw.lookupAny(entid, entmode.getObjectType());
|
| | | rw.parseBody(blob);
|
| | |
|
| | | ObjectLoader ldr = repository.open(blob.getId(), Constants.OBJ_BLOB);
|
| | | byte[] tmp = new byte[4096];
|
| | | InputStream in = ldr.openStream();
|
| | | int n;
|
| | | while ((n = in.read(tmp)) > 0) {
|
| | | zos.write(tmp, 0, n);
|
| | | }
|
| | | in.close();
|
| | | }
|
| | | zos.finish();
|
| | | success = true;
|
| | | } catch (IOException e) {
|
| | | error(e, repository, "{0} failed to zip files from commit {1}", commit.getName());
|
| | | } finally {
|
| | | tw.release();
|
| | | rw.dispose();
|
| | | }
|
| | | return success;
|
| | | }
|
| | |
| | |
|
| | | private static final String BC = org.bouncycastle.jce.provider.BouncyCastleProvider.PROVIDER_NAME;
|
| | |
|
| | | private static final int KEY_LENGTH = 2048;
|
| | | |
| | | private static final String KEY_ALGORITHM = "RSA";
|
| | | |
| | | private static final String SIGNING_ALGORITHM = "SHA512withRSA";
|
| | | |
| | | public static final boolean unlimitedStrength;
|
| | |
|
| | | private static final Logger logger = LoggerFactory.getLogger(X509Utils.class);
|
| | |
| | |
|
| | | // displayname of user for README in bundle
|
| | | public String userDisplayname;
|
| | |
|
| | | // serialnumber of generated or read certificate
|
| | | public String serialNumber;
|
| | |
|
| | | public X509Metadata(String cn, String pwd) {
|
| | | if (StringUtils.isEmpty(cn)) {
|
| | |
| | | * @throws Exception
|
| | | */
|
| | | private static KeyPair newKeyPair() throws Exception {
|
| | | KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", BC);
|
| | | kpGen.initialize(2048, new SecureRandom());
|
| | | KeyPairGenerator kpGen = KeyPairGenerator.getInstance(KEY_ALGORITHM, BC);
|
| | | kpGen.initialize(KEY_LENGTH, new SecureRandom());
|
| | | return kpGen.generateKeyPair();
|
| | | }
|
| | |
|
| | |
| | | certBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
|
| | | certBuilder.addExtension(X509Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert.getPublicKey()));
|
| | |
|
| | | ContentSigner caSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption")
|
| | | ContentSigner caSigner = new JcaContentSignerBuilder(SIGNING_ALGORITHM)
|
| | | .setProvider(BC).build(caPrivateKey);
|
| | | X509Certificate cert = new JcaX509CertificateConverter().setProvider(BC)
|
| | | .getCertificate(certBuilder.build(caSigner));
|
| | |
| | | saveKeyStore(targetStoreFile, serverStore, sslMetadata.password);
|
| | |
|
| | | x509log.log(MessageFormat.format("New SSL certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getSubjectDN().getName()));
|
| | | |
| | | // update serial number in metadata object
|
| | | sslMetadata.serialNumber = cert.getSerialNumber().toString();
|
| | |
|
| | | return cert;
|
| | | } catch (Throwable t) {
|
| | | throw new RuntimeException("Failed to generate SSL certificate!", t);
|
| | |
| | | try {
|
| | | KeyPair caPair = newKeyPair();
|
| | |
|
| | | ContentSigner caSigner = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(caPair.getPrivate());
|
| | | ContentSigner caSigner = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPair.getPrivate());
|
| | |
|
| | | // clone metadata
|
| | | X509Metadata caMetadata = metadata.clone(CA_CN, metadata.password);
|
| | |
| | |
|
| | | x509log.log(MessageFormat.format("New CA certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getIssuerDN().getName()));
|
| | |
|
| | | // update serial number in metadata object
|
| | | caMetadata.serialNumber = cert.getSerialNumber().toString();
|
| | |
|
| | | return cert;
|
| | | } catch (Throwable t) {
|
| | | throw new RuntimeException("Failed to generate Gitblit CA certificate!", t);
|
| | |
| | | X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(issuerDN, new Date());
|
| | |
|
| | | // build and sign CRL with CA private key
|
| | | ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(caPrivateKey);
|
| | | ContentSigner signer = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPrivateKey);
|
| | | X509CRLHolder crl = crlBuilder.build(signer);
|
| | |
|
| | | File tmpFile = new File(caRevocationList.getParentFile(), Long.toHexString(System.currentTimeMillis()) + ".tmp");
|
| | |
| | | zos.write(FileUtils.readContent(pemFile));
|
| | | zos.closeEntry();
|
| | | }
|
| | | |
| | | // include user's public certificate
|
| | | zos.putNextEntry(new ZipEntry(clientMetadata.commonName + ".cer"));
|
| | | zos.write(cert.getEncoded());
|
| | | zos.closeEntry();
|
| | | |
| | | // include CA public certificate
|
| | | zos.putNextEntry(new ZipEntry("ca.cer"));
|
| | | zos.write(caCert.getEncoded());
|
| | | zos.closeEntry();
|
| | | |
| | | if (readme != null) {
|
| | | zos.putNextEntry(new ZipEntry("README.TXT"));
|
| | | zos.write(readme.getBytes("UTF-8"));
|
| | |
| | | certBuilder.addExtension(X509Extension.subjectAlternativeName, false, subjectAltName);
|
| | | }
|
| | |
|
| | | ContentSigner signer = new JcaContentSignerBuilder("SHA1WithRSA").setProvider(BC).build(caPrivateKey);
|
| | | ContentSigner signer = new JcaContentSignerBuilder(SIGNING_ALGORITHM).setProvider(BC).build(caPrivateKey);
|
| | |
|
| | | X509Certificate userCert = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certBuilder.build(signer));
|
| | | PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier)pair.getPrivate();
|
| | |
| | |
|
| | | // save certificate after successfully creating the key stores
|
| | | saveCertificate(userCert, certFile);
|
| | | |
| | | // update serial number in metadata object
|
| | | clientMetadata.serialNumber = userCert.getSerialNumber().toString();
|
| | |
|
| | | return userCert;
|
| | | } catch (Throwable t) {
|
| | |
| | | }
|
| | | return false;
|
| | | }
|
| | | |
| | | public static X509Metadata getMetadata(X509Certificate cert) {
|
| | | // manually split DN into OID components
|
| | | // this is instead of parsing with LdapName which:
|
| | | // (1) I don't trust the order of values
|
| | | // (2) it filters out values like EMAILADDRESS
|
| | | String dn = cert.getSubjectDN().getName();
|
| | | Map<String, String> oids = new HashMap<String, String>();
|
| | | for (String kvp : dn.split(",")) {
|
| | | String [] val = kvp.trim().split("=");
|
| | | String oid = val[0].toUpperCase().trim();
|
| | | String data = val[1].trim();
|
| | | oids.put(oid, data);
|
| | | }
|
| | | |
| | | X509Metadata metadata = new X509Metadata(oids.get("CN"), "whocares");
|
| | | metadata.oids.putAll(oids);
|
| | | metadata.serialNumber = cert.getSerialNumber().toString();
|
| | | metadata.notAfter = cert.getNotAfter();
|
| | | metadata.notBefore = cert.getNotBefore();
|
| | | metadata.emailAddress = metadata.getOID("E", null);
|
| | | if (metadata.emailAddress == null) {
|
| | | metadata.emailAddress = metadata.getOID("EMAILADDRESS", null);
|
| | | }
|
| | | return metadata;
|
| | | }
|
| | | }
|
| | |
| | | import org.apache.wicket.protocol.http.WebSession;
|
| | | import org.apache.wicket.protocol.http.request.WebClientInfo;
|
| | |
|
| | | import com.gitblit.Constants.AuthenticationType;
|
| | | import com.gitblit.models.UserModel;
|
| | |
|
| | | public final class GitBlitWebSession extends WebSession {
|
| | |
| | |
|
| | | private AtomicBoolean isForking;
|
| | |
|
| | | public AuthenticationType authenticationType;
|
| | | |
| | | public GitBlitWebSession(Request request) {
|
| | | super(request);
|
| | | isForking = new AtomicBoolean();
|
| | | authenticationType = AuthenticationType.CREDENTIALS;
|
| | | }
|
| | |
|
| | | public void invalidate() {
|
| | |
| | | import java.util.TimeZone;
|
| | | import java.util.regex.Pattern;
|
| | |
|
| | | import javax.servlet.http.Cookie;
|
| | | import javax.servlet.http.HttpServletRequest;
|
| | |
|
| | | import org.apache.wicket.Application;
|
| | |
| | | }
|
| | |
|
| | | private void login() {
|
| | | // try to authenticate by servlet request
|
| | | UserModel user = GitBlit.self().authenticate(((WebRequest) getRequestCycle().getRequest()).getHttpServletRequest());
|
| | | GitBlitWebSession session = GitBlitWebSession.get();
|
| | | if (session.isLoggedIn() && !session.isSessionInvalidated()) {
|
| | | // already have a session
|
| | | return;
|
| | | }
|
| | |
|
| | | if (user == null) {
|
| | | // try to authenticate by cookie
|
| | | Cookie[] cookies = ((WebRequest) getRequestCycle().getRequest()).getCookies();
|
| | | if (GitBlit.self().allowCookieAuthentication() && cookies != null && cookies.length > 0) {
|
| | | // Grab cookie from Browser Session
|
| | | user = GitBlit.self().authenticate(cookies);
|
| | | }
|
| | | }
|
| | | // try to authenticate by servlet request
|
| | | HttpServletRequest httpRequest = ((WebRequest) getRequestCycle().getRequest()).getHttpServletRequest();
|
| | | UserModel user = GitBlit.self().authenticate(httpRequest);
|
| | |
|
| | | // Login the user
|
| | | if (user != null) {
|
| | | // Set the user into the session
|
| | | GitBlitWebSession session = GitBlitWebSession.get();
|
| | | // issue 62: fix session fixation vulnerability
|
| | | session.replaceSession();
|
| | | session.setUser(user);
|
| | |
| | | public UserFragment(String id, String markupId, MarkupContainer markupProvider) {
|
| | | super(id, markupId, markupProvider);
|
| | |
|
| | | if (GitBlitWebSession.get().isLoggedIn()) {
|
| | | // username, logout, and change password
|
| | | add(new Label("username", GitBlitWebSession.get().getUser().getDisplayName() + ":"));
|
| | | add(new LinkPanel("loginLink", null, markupProvider.getString("gb.logout"),
|
| | | LogoutPage.class));
|
| | | GitBlitWebSession session = GitBlitWebSession.get();
|
| | | if (session.isLoggedIn()) { |
| | | UserModel user = session.getUser();
|
| | | boolean editCredentials = GitBlit.self().supportsCredentialChanges();
|
| | | boolean standardLogin = session.authenticationType.isStandard();
|
| | |
|
| | | // username, logout, and change password
|
| | | add(new Label("username", user.getDisplayName() + ":"));
|
| | | add(new LinkPanel("loginLink", null, markupProvider.getString("gb.logout"),
|
| | | LogoutPage.class).setVisible(standardLogin));
|
| | | |
| | | // quick and dirty hack for showing a separator
|
| | | add(new Label("separator", "|").setVisible(editCredentials));
|
| | | add(new Label("separator", "|").setVisible(standardLogin && editCredentials));
|
| | | add(new BookmarkablePageLink<Void>("changePasswordLink",
|
| | | ChangePasswordPage.class).setVisible(editCredentials));
|
| | | } else {
|
| | |
| | | <tr class="hidden-phone"><th><wicket:message key="gb.tree">tree</wicket:message></th>
|
| | | <td><span class="sha1" wicket:id="commitTree">[commit tree]</span>
|
| | | <span class="link">
|
| | | <a wicket:id="treeLink"><wicket:message key="gb.tree"></wicket:message></a> | <a wicket:id="zipLink"><wicket:message key="gb.zip"></wicket:message></a>
|
| | | <a wicket:id="treeLink"><wicket:message key="gb.tree"></wicket:message></a> | <span wicket:id="compressedLinks"></span>
|
| | | </span>
|
| | | </td></tr>
|
| | | <tr class="hidden-phone"><th valign="top"><wicket:message key="gb.parent">parent</wicket:message></th>
|
| | |
| | | import org.apache.wicket.PageParameters;
|
| | | import org.apache.wicket.markup.html.basic.Label;
|
| | | import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
| | | import org.apache.wicket.markup.html.link.ExternalLink;
|
| | | import org.apache.wicket.markup.repeater.Item;
|
| | | import org.apache.wicket.markup.repeater.data.DataView;
|
| | | import org.apache.wicket.markup.repeater.data.ListDataProvider;
|
| | |
| | | import org.eclipse.jgit.revwalk.RevCommit;
|
| | |
|
| | | import com.gitblit.Constants;
|
| | | import com.gitblit.DownloadZipServlet;
|
| | | import com.gitblit.GitBlit;
|
| | | import com.gitblit.Keys;
|
| | | import com.gitblit.models.GitNote;
|
| | | import com.gitblit.models.SubmoduleModel;
|
| | | import com.gitblit.models.PathModel.PathChangeModel;
|
| | | import com.gitblit.models.SubmoduleModel;
|
| | | import com.gitblit.utils.JGitUtils;
|
| | | import com.gitblit.wicket.WicketUtils;
|
| | | import com.gitblit.wicket.panels.CommitHeaderPanel;
|
| | | import com.gitblit.wicket.panels.CommitLegendPanel;
|
| | | import com.gitblit.wicket.panels.CompressedDownloadsPanel;
|
| | | import com.gitblit.wicket.panels.GravatarImage;
|
| | | import com.gitblit.wicket.panels.LinkPanel;
|
| | | import com.gitblit.wicket.panels.RefsPanel;
|
| | |
| | | newCommitParameter()));
|
| | | add(new BookmarkablePageLink<Void>("treeLink", TreePage.class, newCommitParameter()));
|
| | | final String baseUrl = WicketUtils.getGitblitURL(getRequest());
|
| | | add(new ExternalLink("zipLink", DownloadZipServlet.asLink(baseUrl, repositoryName,
|
| | | objectId, null)).setVisible(GitBlit.getBoolean(Keys.web.allowZipDownloads, true)));
|
| | | |
| | | add(new CompressedDownloadsPanel("compressedLinks", baseUrl, repositoryName, objectId, null));
|
| | |
|
| | | // Parent Commits
|
| | | ListDataProvider<String> parentsDp = new ListDataProvider<String>(parents);
|
| | |
| | | boolean canAccess = user.hasBranchPermission(repositoryName,
|
| | | branch.reference.getName());
|
| | | if (!canAccess) {
|
| | | error(getString("gb.accessDeined"), true);
|
| | | error(getString("gb.accessDenied"), true);
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | |
|
| | | <!-- blob nav links -->
|
| | | <div class="page_nav2">
|
| | | <a wicket:id="historyLink"><wicket:message key="gb.history"></wicket:message></a> | <a wicket:id="headLink"><wicket:message key="gb.head"></wicket:message></a> | <a wicket:id="zipLink"><wicket:message key="gb.zip"></wicket:message></a>
|
| | | <a wicket:id="historyLink"><wicket:message key="gb.history"></wicket:message></a> | <a wicket:id="headLink"><wicket:message key="gb.head"></wicket:message></a> | <span wicket:id="compressedLinks"></span>
|
| | | </div>
|
| | |
|
| | | <!-- commit header -->
|
| | |
| | | <!-- submodule links -->
|
| | | <wicket:fragment wicket:id="submoduleLinks">
|
| | | <span class="link">
|
| | | <a wicket:id="view"><wicket:message key="gb.view"></wicket:message></a> | <span class="hidden-phone"><a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | </span><a wicket:id="history"><wicket:message key="gb.history"></wicket:message></a> | <a wicket:id="zip"><wicket:message key="gb.zip"></wicket:message></a>
|
| | | <a wicket:id="view"><wicket:message key="gb.view"></wicket:message></a> | <span class="hidden-phone"><a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | </span><a wicket:id="history"><wicket:message key="gb.history"></wicket:message></a> | <span wicket:id="compressedLinks"></span>
|
| | | </span>
|
| | | </wicket:fragment>
|
| | |
|
| | | <!-- tree links -->
|
| | | <wicket:fragment wicket:id="treeLinks">
|
| | | <span class="link">
|
| | | <span class="hidden-phone"><a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | </span><a wicket:id="history"><wicket:message key="gb.history"></wicket:message></a> | <a wicket:id="zip"><wicket:message key="gb.zip"></wicket:message></a>
|
| | | <span class="hidden-phone"><a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | </span><a wicket:id="history"><wicket:message key="gb.history"></wicket:message></a> | <span wicket:id="compressedLinks"></span>
|
| | | </span>
|
| | | </wicket:fragment>
|
| | |
|
| | |
| | | import org.apache.wicket.PageParameters;
|
| | | import org.apache.wicket.markup.html.basic.Label;
|
| | | import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
| | | import org.apache.wicket.markup.html.link.ExternalLink;
|
| | | import org.apache.wicket.markup.html.panel.Fragment;
|
| | | import org.apache.wicket.markup.repeater.Item;
|
| | | import org.apache.wicket.markup.repeater.data.DataView;
|
| | |
| | | import org.eclipse.jgit.lib.Repository;
|
| | | import org.eclipse.jgit.revwalk.RevCommit;
|
| | |
|
| | | import com.gitblit.DownloadZipServlet;
|
| | | import com.gitblit.GitBlit;
|
| | | import com.gitblit.Keys;
|
| | | import com.gitblit.models.PathModel;
|
| | | import com.gitblit.models.SubmoduleModel;
|
| | | import com.gitblit.utils.ByteFormat;
|
| | | import com.gitblit.utils.JGitUtils;
|
| | | import com.gitblit.wicket.WicketUtils;
|
| | | import com.gitblit.wicket.panels.CommitHeaderPanel;
|
| | | import com.gitblit.wicket.panels.CompressedDownloadsPanel;
|
| | | import com.gitblit.wicket.panels.LinkPanel;
|
| | | import com.gitblit.wicket.panels.PathBreadcrumbsPanel;
|
| | |
|
| | |
| | | WicketUtils.newPathParameter(repositoryName, objectId, path)));
|
| | | add(new BookmarkablePageLink<Void>("headLink", TreePage.class,
|
| | | WicketUtils.newPathParameter(repositoryName, Constants.HEAD, path)));
|
| | | add(new ExternalLink("zipLink", DownloadZipServlet.asLink(getRequest()
|
| | | .getRelativePathPrefixToContextRoot(), repositoryName, objectId, path))
|
| | | .setVisible(GitBlit.getBoolean(Keys.web.allowZipDownloads, true)));
|
| | | add(new CompressedDownloadsPanel("compressedLinks", getRequest()
|
| | | .getRelativePathPrefixToContextRoot(), repositoryName, objectId, path));
|
| | |
|
| | | add(new CommitHeaderPanel("commitHeader", repositoryName, commit));
|
| | |
|
| | |
| | | links.add(new BookmarkablePageLink<Void>("history", HistoryPage.class,
|
| | | WicketUtils.newPathParameter(repositoryName, entry.commitId,
|
| | | entry.path)));
|
| | | links.add(new ExternalLink("zip", DownloadZipServlet.asLink(baseUrl,
|
| | | repositoryName, objectId, entry.path)).setVisible(GitBlit
|
| | | .getBoolean(Keys.web.allowZipDownloads, true)));
|
| | | links.add(new CompressedDownloadsPanel("compressedLinks", baseUrl,
|
| | | repositoryName, objectId, entry.path));
|
| | |
|
| | | item.add(links);
|
| | | } else if (entry.isSubmodule()) {
|
| | | // submodule
|
| | |
| | | links.add(new BookmarkablePageLink<Void>("history", HistoryPage.class,
|
| | | WicketUtils.newPathParameter(submodulePath, submoduleId,
|
| | | "")).setEnabled(hasSubmodule));
|
| | | links.add(new ExternalLink("zip", DownloadZipServlet.asLink(baseUrl,
|
| | | submodulePath, submoduleId, "")).setVisible(GitBlit
|
| | | .getBoolean(Keys.web.allowZipDownloads, true)).setEnabled(hasSubmodule));
|
| | | links.add(new CompressedDownloadsPanel("compressedLinks", baseUrl,
|
| | | submodulePath, submoduleId, "").setEnabled(hasSubmodule));
|
| | | item.add(links);
|
| | | } else {
|
| | | // blob link
|
| | |
| | | import com.gitblit.SyndicationServlet;
|
| | | import com.gitblit.models.RefModel;
|
| | | import com.gitblit.models.RepositoryModel;
|
| | | import com.gitblit.models.UserModel;
|
| | | import com.gitblit.utils.JGitUtils;
|
| | | import com.gitblit.utils.StringUtils;
|
| | | import com.gitblit.wicket.GitBlitWebSession;
|
| | | import com.gitblit.wicket.WicketUtils;
|
| | | import com.gitblit.wicket.pages.BranchesPage;
|
| | | import com.gitblit.wicket.pages.CommitPage;
|
| | |
| | |
|
| | | // branches
|
| | | List<RefModel> branches = new ArrayList<RefModel>();
|
| | | branches.addAll(JGitUtils.getLocalBranches(r, false, maxCount));
|
| | | UserModel user = GitBlitWebSession.get().getUser();
|
| | | if (user == null) {
|
| | | user = UserModel.ANONYMOUS;
|
| | | }
|
| | |
|
| | | List<RefModel> localBranches = JGitUtils.getLocalBranches(r, false, -1);
|
| | | for (RefModel refModel : localBranches) {
|
| | | if (user.hasBranchPermission(model.name, refModel.reference.getName())) {
|
| | | branches.add(refModel);
|
| | | }
|
| | | }
|
| | | if (model.showRemoteBranches) {
|
| | | branches.addAll(JGitUtils.getRemoteBranches(r, false, maxCount));
|
| | | List<RefModel> remoteBranches = JGitUtils.getRemoteBranches(r, false, -1);
|
| | | for (RefModel refModel : remoteBranches) {
|
| | | if (user.hasBranchPermission(model.name, refModel.reference.getName())) {
|
| | | branches.add(refModel);
|
| | | }
|
| | | }
|
| | | }
|
| | | Collections.sort(branches);
|
| | | Collections.reverse(branches);
|
New file |
| | |
| | | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
| | | <html xmlns="http://www.w3.org/1999/xhtml" |
| | | xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" |
| | | xml:lang="en" |
| | | lang="en"> |
| | |
|
| | | <wicket:panel>
|
| | | <span wicket:id="compressedLinks">
|
| | | <span wicket:id="linkSep">|</span><span wicket:id="compressedLink">ref</span>
|
| | | </span> |
| | | </wicket:panel>
|
| | | </html> |
New file |
| | |
| | | /*
|
| | | * Copyright 2012 gitblit.com.
|
| | | *
|
| | | * Licensed under the Apache License, Version 2.0 (the "License");
|
| | | * you may not use this file except in compliance with the License.
|
| | | * You may obtain a copy of the License at
|
| | | *
|
| | | * http://www.apache.org/licenses/LICENSE-2.0
|
| | | *
|
| | | * Unless required by applicable law or agreed to in writing, software
|
| | | * distributed under the License is distributed on an "AS IS" BASIS,
|
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| | | * See the License for the specific language governing permissions and
|
| | | * limitations under the License.
|
| | | */
|
| | | package com.gitblit.wicket.panels;
|
| | |
|
| | | import java.util.List;
|
| | |
|
| | | import org.apache.wicket.Component;
|
| | | import org.apache.wicket.markup.html.basic.Label;
|
| | | import org.apache.wicket.markup.html.panel.Panel;
|
| | | import org.apache.wicket.markup.repeater.Item;
|
| | | import org.apache.wicket.markup.repeater.data.DataView;
|
| | | import org.apache.wicket.markup.repeater.data.ListDataProvider;
|
| | |
|
| | | import com.gitblit.DownloadZipServlet;
|
| | | import com.gitblit.DownloadZipServlet.Format;
|
| | | import com.gitblit.GitBlit;
|
| | | import com.gitblit.Keys;
|
| | |
|
| | | public class CompressedDownloadsPanel extends Panel {
|
| | |
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | | public CompressedDownloadsPanel(String id, final String baseUrl, final String repositoryName, final String objectId, final String path) {
|
| | | super(id);
|
| | | |
| | | List<String> types = GitBlit.getStrings(Keys.web.compressedDownloads);
|
| | | if (types.isEmpty()) {
|
| | | types.add(Format.zip.name());
|
| | | types.add(Format.gz.name());
|
| | | }
|
| | | |
| | | ListDataProvider<String> refsDp = new ListDataProvider<String>(types);
|
| | | DataView<String> refsView = new DataView<String>("compressedLinks", refsDp) {
|
| | | private static final long serialVersionUID = 1L;
|
| | | int counter;
|
| | |
|
| | | @Override
|
| | | protected void onBeforeRender() {
|
| | | super.onBeforeRender();
|
| | | counter = 0;
|
| | | }
|
| | | |
| | | @Override
|
| | | public void populateItem(final Item<String> item) {
|
| | | String compressionType = item.getModelObject();
|
| | | Format format = Format.fromName(compressionType);
|
| | | |
| | | String href = DownloadZipServlet.asLink(baseUrl, repositoryName,
|
| | | objectId, path, format);
|
| | | Component c = new LinkPanel("compressedLink", null, format.name(), href);
|
| | | item.add(c);
|
| | | Label lb = new Label("linkSep", "|");
|
| | | lb.setVisible(counter > 0);
|
| | | lb.setRenderBodyOnly(true);
|
| | | item.add(lb.setEscapeModelStrings(false));
|
| | | item.setRenderBodyOnly(true);
|
| | | counter++;
|
| | | }
|
| | | };
|
| | | add(refsView);
|
| | | |
| | | setVisible(GitBlit.getBoolean(Keys.web.allowZipDownloads, true));
|
| | | }
|
| | | } |
| | |
| | | <td class="icon"><img wicket:id="commitIcon" /></td>
|
| | | <td class="hidden-phone author"><span wicket:id="commitAuthor">[commit author]</span></td>
|
| | | <td class="message"><table class="nestedTable"><tr><td><span style="vertical-align:middle;" wicket:id="commitShortMessage">[commit short message]</span></td><td><div style="text-align:right;" wicket:id="commitRefs">[commit refs]</div></td></tr></table></td>
|
| | | <td class="hidden-phone hidden-tablet"><span class="link" wicket:id="hashLabel">[hash label]</span><span wicket:id="hashLink">[hash link]</span></td>
|
| | | <td class="hidden-phone hidden-tablet rightAlign"><span class="link" wicket:id="hashLabel">[hash label]</span><span wicket:id="hashLink">[hash link]</span></td>
|
| | | <td class="hidden-phone rightAlign">
|
| | | <span wicket:id="historyLinks">[history links]</span>
|
| | | </td>
|
| | |
| | | LinkPanel commitHash = new LinkPanel("hashLink", null, entry.getName().substring(0, hashLen),
|
| | | TreePage.class, WicketUtils.newObjectParameter(
|
| | | repositoryName, entry.getName()));
|
| | | WicketUtils.setCssClass(commitHash, "sha1");
|
| | | WicketUtils.setCssClass(commitHash, "shortsha1");
|
| | | WicketUtils.setHtmlTooltip(commitHash, entry.getName());
|
| | | item.add(commitHash);
|
| | |
|
| | |
| | | <td class="hidden-phone author"><span wicket:id="commitAuthor">[commit author]</span></td>
|
| | | <td class="hidden-phone icon"><img wicket:id="commitIcon" /></td>
|
| | | <td class="message"><table class="nestedTable"><tr><td><span style="vertical-align:middle;" wicket:id="commitShortMessage">[commit short message]</span></td><td><div style="text-align:right;" wicket:id="commitRefs">[commit refs]</div></td></tr></table></td>
|
| | | <td class="hidden-phone hidden-tablet"><span wicket:id="hashLink">[hash link]</span></td>
|
| | | <td class="hidden-phone hidden-tablet rightAlign"><span wicket:id="hashLink">[hash link]</span></td>
|
| | | <td class="hidden-phone hidden-tablet rightAlign">
|
| | | <span class="link">
|
| | | <a wicket:id="diff"><wicket:message key="gb.diff"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a>
|
| | |
| | | LinkPanel commitHash = new LinkPanel("hashLink", null, entry.getName().substring(0, hashLen),
|
| | | CommitPage.class, WicketUtils.newObjectParameter(
|
| | | repositoryName, entry.getName()));
|
| | | WicketUtils.setCssClass(commitHash, "sha1");
|
| | | WicketUtils.setCssClass(commitHash, "shortsha1");
|
| | | WicketUtils.setHtmlTooltip(commitHash, entry.getName());
|
| | | item.add(commitHash);
|
| | |
|
| | |
| | | import com.gitblit.models.PathModel;
|
| | | import com.gitblit.models.PathModel.PathChangeModel;
|
| | | import com.gitblit.models.RefModel;
|
| | | import com.gitblit.utils.CompressionUtils;
|
| | | import com.gitblit.utils.JGitUtils;
|
| | | import com.gitblit.utils.StringUtils;
|
| | |
|
| | |
| | |
|
| | | @Test
|
| | | public void testZip() throws Exception {
|
| | | assertFalse(JGitUtils.zip(null, null, null, null));
|
| | | assertFalse(CompressionUtils.zip(null, null, null, null));
|
| | | Repository repository = GitBlitSuite.getHelloworldRepository();
|
| | | File zipFileA = new File(GitBlitSuite.REPOSITORIES, "helloworld.zip");
|
| | | FileOutputStream fosA = new FileOutputStream(zipFileA);
|
| | | boolean successA = JGitUtils.zip(repository, null, Constants.HEAD, fosA);
|
| | | boolean successA = CompressionUtils.zip(repository, null, Constants.HEAD, fosA);
|
| | | fosA.close();
|
| | |
|
| | | File zipFileB = new File(GitBlitSuite.REPOSITORIES, "helloworld-java.zip");
|
| | | FileOutputStream fosB = new FileOutputStream(zipFileB);
|
| | | boolean successB = JGitUtils.zip(repository, "java.java", Constants.HEAD, fosB);
|
| | | boolean successB = CompressionUtils.zip(repository, "java.java", Constants.HEAD, fosB);
|
| | | fosB.close();
|
| | |
|
| | | repository.close();
|
| | |
| | | File zip = X509Utils.newClientBundle(userMetadata, storeFile, caPassword, log);
|
| | | assertTrue(zip.exists());
|
| | |
|
| | | List<String> expected = Arrays.asList(userMetadata.commonName + ".pem", userMetadata.commonName + ".p12", "README.TXT");
|
| | | List<String> expected = Arrays.asList(
|
| | | userMetadata.commonName + ".pem",
|
| | | userMetadata.commonName + ".p12",
|
| | | userMetadata.commonName + ".cer",
|
| | | "ca.cer",
|
| | | "README.TXT");
|
| | |
|
| | | ZipInputStream zis = new ZipInputStream(new FileInputStream(zip));
|
| | | ZipEntry entry = null;
|