Skip to content
This repository has been archived by the owner on Mar 5, 2021. It is now read-only.

Commit

Permalink
RPM signing feature w/ added license info
Browse files Browse the repository at this point in the history
Signed-off by: Walker Funk <[email protected]>
  • Loading branch information
Walker Funk committed Sep 11, 2019
1 parent 3869c16 commit 132876c
Show file tree
Hide file tree
Showing 20 changed files with 1,139 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Web-ContextPath: /yum
Import-Package: com.google.common.escape;version="18.0.0",
com.google.common.net;version="18.0.0",
com.google.common.io;version="18.0.0",
com.google.common.hash;version="18.0.0",
com.google.gson;version="2.3.1",
javax.servlet;version="3.1.0",
javax.servlet.http;version="3.1.0",
org.apache.commons.compress.archivers.cpio;version="1.9.0",
org.bouncycastle.openpgp;version="1.52.0",
org.eclipse.packagedrone;version="1.0.0",
org.eclipse.packagedrone.repo;version="1.0.0",
org.eclipse.packagedrone.repo.aspect;version="1.0.0",
org.eclipse.packagedrone.repo.aspect.aggregate;version="1.0.0",
org.eclipse.packagedrone.repo.aspect.common.spool;version="1.0.0",
org.eclipse.packagedrone.repo.aspect.extract;version="1.0.0",
org.eclipse.packagedrone.repo.aspect.virtual;version="1.0.0",
org.eclipse.packagedrone.repo.aspect.group;version="1.0.0",
org.eclipse.packagedrone.repo.aspect.recipe;version="1.0.0",
org.eclipse.packagedrone.repo.channel;version="1.0.0",
Expand All @@ -28,6 +32,7 @@ Import-Package: com.google.common.escape;version="18.0.0",
org.eclipse.packagedrone.repo.utils;version="1.0.0",
org.eclipse.packagedrone.repo.web.utils;version="1.0.0",
org.eclipse.packagedrone.repo.xml;version="1.0.0",
org.eclipse.packagedrone.utils;version="1.0.0",
org.eclipse.packagedrone.utils.io;version="1.0.0",
org.eclipse.packagedrone.utils.rpm;version="0.13.0",
org.eclipse.packagedrone.utils.rpm.deps;version="0.13.0",
Expand All @@ -43,7 +48,7 @@ Import-Package: com.google.common.escape;version="18.0.0",
org.osgi.framework;version="1.8.0",
org.osgi.util.tracker;version="1.5.1",
org.slf4j;version="1.7.2"
Service-Component: OSGI-INF/rpm.xml,OSGI-INF/yum.xml,OSGI-INF/groupRpm.xml,OSGI-INF/recipeYum.xml,
Service-Component: OSGI-INF/rpm.xml,OSGI-INF/rpmSign.xml,OSGI-INF/yum.xml,OSGI-INF/groupRpm.xml,OSGI-INF/recipeYum.xml,
OSGI-INF/servlet.xml
Require-Bundle: org.jboss.spec.javax.servlet.jstl.jboss-jstl-api_1.2_spec;bundle-version="1.1.2"
Export-Package: org.eclipse.packagedrone.repo.adapter.rpm;version="1.0.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
drone.aspect.id=rpm.signer
drone.aspect.name=RPM Signer
drone.aspect.description=Sign RPM files
drone.aspect.version=1.0.0
drone.aspect.group.id=rpm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.packagedrone.repo.adapter.rpm.signer">
<implementation class="org.eclipse.packagedrone.repo.adapter.rpm.internal.RpmSignerAspectFactory"/>
<properties entry="OSGI-INF/rpmSign.properties"/>
<service>
<provide interface="org.eclipse.packagedrone.repo.aspect.ChannelAspectFactory"/>
</service>
</scr:component>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*
* Contributors:
* IBH SYSTEMS GmbH - initial API and implementation
* Walker Funk - Trident Systems Inc. - rpm signing components
*******************************************************************************/
package org.eclipse.packagedrone.repo.adapter.rpm;

Expand All @@ -18,8 +19,12 @@ public final class Constants

public static final String RPM_ASPECT_ID = "rpm";

public static final String RPM_SIGN_ASPECT_ID = "rpm.signer";

public static final String YUM_ASPECT_ID = "yum";

public static final MetaKey KEY_RSA = new MetaKey ( GROUP_ID, "rsa" );

public static final MetaKey KEY_INFO = new MetaKey ( RPM_ASPECT_ID, "info" );

private Constants ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Contributors:
* IBH SYSTEMS GmbH - initial API and implementation
* Bachmann electronic GmbH - #86 Adding 'release' rpm metadata tag
* Walker Funk - Trident Systems Inc. rpm rsa signature extraction
*******************************************************************************/
package org.eclipse.packagedrone.repo.adapter.rpm.internal;

Expand All @@ -21,6 +22,7 @@
import org.eclipse.packagedrone.repo.adapter.rpm.RpmInformationsJson;
import org.eclipse.packagedrone.repo.aspect.extract.Extractor;
import org.eclipse.packagedrone.utils.rpm.RpmTag;
import org.eclipse.packagedrone.utils.rpm.RpmSignatureTag;
import org.eclipse.packagedrone.utils.rpm.info.RpmInformation;
import org.eclipse.packagedrone.utils.rpm.info.RpmInformations;
import org.eclipse.packagedrone.utils.rpm.parse.RpmInputStream;
Expand Down Expand Up @@ -54,6 +56,12 @@ public void extractMetaData ( final Context context, final Map<String, String> m
metadata.put ( "release", RpmInformations.asString ( in.getPayloadHeader ().getTag ( RpmTag.RELEASE ) ) );

metadata.put ( Constants.KEY_INFO.getKey (), RpmInformationsJson.toJson ( info ) );

String signature = RpmInformations.asArmored ( in.getSignatureHeader ().getTag ( RpmSignatureTag.RSAHEADER ) );
if ( signature != null && signature != "" )
{
metadata.put ( Constants.KEY_RSA.getKey (), signature );
}
}
catch ( final Exception e )
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2019 Trident Systems, Inc.
* This software was developed with U.S government funding in support of the above
* contract. Trident grants unlimited rights to modify, distribute and incorporate
* our contributions to Eclipse Package Drone bound by the overall restrictions from
* the parent Eclipse Public License v1.0 available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Walker Funk - Trident Systems Inc. - initial implementation
*******************************************************************************/
package org.eclipse.packagedrone.repo.adapter.rpm.internal;

import org.eclipse.packagedrone.repo.aspect.ChannelAspect;
import org.eclipse.packagedrone.repo.aspect.ChannelAspectFactory;
import org.eclipse.packagedrone.repo.aspect.virtual.Virtualizer;
import org.eclipse.packagedrone.repo.adapter.rpm.Constants;
import org.eclipse.packagedrone.repo.adapter.rpm.internal.RpmSignerVirtualizer;

public class RpmSignerAspectFactory implements ChannelAspectFactory
{

@Override
public ChannelAspect createAspect ()
{
return new ChannelAspect () {

@Override
public String getId ()
{
return Constants.RPM_SIGN_ASPECT_ID;
}

@Override
public Virtualizer getArtifactVirtualizer ()
{
return new RpmSignerVirtualizer ();
}
};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*******************************************************************************
* Copyright (c) 2019 Trident Systems, Inc.
* This software was developed with U.S government funding in support of the above
* contract. Trident grants unlimited rights to modify, distribute and incorporate
* our contributions to Eclipse Package Drone bound by the overall restrictions from
* the parent Eclipse Public License v1.0 available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Walker Funk - Trident Systems Inc. - initial implementation
*******************************************************************************/
package org.eclipse.packagedrone.repo.adapter.rpm.internal;

import java.io.DataInputStream;
import java.io.BufferedInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;

import org.eclipse.packagedrone.repo.MetaKey;
import org.eclipse.packagedrone.repo.utils.HashHelper;
import org.eclipse.packagedrone.repo.signing.SigningService;
import org.eclipse.packagedrone.repo.aspect.virtual.Virtualizer;
import org.eclipse.packagedrone.repo.channel.ArtifactInformation;
import org.eclipse.packagedrone.repo.adapter.rpm.Constants;
import org.eclipse.packagedrone.repo.adapter.rpm.yum.internal.YumChannelAggregator;
import org.eclipse.packagedrone.utils.Exceptions;
import org.eclipse.packagedrone.utils.rpm.parse.RpmParserStream;

import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import com.google.common.io.ByteStreams;
import com.google.common.hash.Hashing;
import com.google.common.hash.HashCode;
import com.google.common.hash.HashFunction;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RpmSignerVirtualizer implements Virtualizer
{
private final static Logger logger = LoggerFactory.getLogger ( RpmSignerVirtualizer.class );

private static final MetaKey KEY_SIGNING_ID = new MetaKey ( "yum", "signingServiceId" );

private final BundleContext bundleContext = FrameworkUtil.getBundle ( YumChannelAggregator.class ).getBundleContext ();

@Override
public void virtualize ( final Context context )
{
Exceptions.wrapException ( () -> processVirtualize ( context ) );
}

private void processVirtualize ( final Context context ) throws Exception
{
final Path path = context.getFile ();
final ArtifactInformation art = context.getArtifactInformation ();
final String name = art.getName ();
Map<MetaKey, String> metaData = new HashMap<> ( art.getMetaData () );

if ( metaData.containsKey ( Constants.KEY_RSA ) )
{
return;
}

final String signingServiceId = context.getProvidedChannelMetaData ().get ( KEY_SIGNING_ID );
ServiceReference<SigningService> ssref = null;
SigningService signingService = null;

if ( signingServiceId != null && !signingServiceId.isEmpty () )
{
final Collection<ServiceReference<SigningService>> services = bundleContext.getServiceReferences ( SigningService.class, String.format( "(%s=%s)", org.osgi.framework.Constants.SERVICE_PID, signingServiceId ) );

if ( services == null || services.isEmpty () )
{
throw new IllegalStateException ( String.format ( "Unable to find configured signing service: %s", signingServiceId ) );
}

ssref = services.iterator ().next ();
signingService = bundleContext.getService ( ssref );

try ( RpmParserStream preIn = new RpmParserStream ( new BufferedInputStream ( Files.newInputStream ( path, StandardOpenOption.READ ) ) ); )
{
signingService.signRpm ( path, preIn );

Map<String, HashFunction> functions = new HashMap<> ();

functions.put ( "md5", Hashing.md5 () );
functions.put ( "sha1", Hashing.sha1 () );
functions.put ( "sha256", Hashing.sha256 () );
functions.put ( "sha512", Hashing.sha512 () );

final Map<String, HashCode> result = HashHelper.createChecksums ( path, functions );
for ( final Map.Entry<String, HashCode> entry : result.entrySet () )
{
metaData.replace ( new MetaKey ("hasher", entry.getKey () ), entry.getValue ().toString () );
}

DataInputStream postIn = new DataInputStream ( Files.newInputStream( path, StandardOpenOption.READ ) );
context.createVirtualArtifact ( name, out -> ByteStreams.copy ( postIn, out ), metaData );
}
catch ( final Exception e )
{
logger.debug ( "Failed to sign RPM", e );
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*
* Contributors:
* IBH SYSTEMS GmbH - initial API and implementation
* Walker Funk - Trident Systems Inc. - limit repo to only signed rpms when signing enabled
*******************************************************************************/
package org.eclipse.packagedrone.repo.adapter.rpm.yum.internal;

Expand Down Expand Up @@ -46,6 +47,8 @@ public class YumChannelAggregator implements ChannelAggregator

private final XmlToolsFactory xml;

private boolean isSigning = false;

public YumChannelAggregator ( final XmlToolsFactory xml )
{
this.xml = xml;
Expand All @@ -69,6 +72,7 @@ public Map<String, String> aggregateMetaData ( final AggregationContext context

ssref = services.iterator ().next ();
signingService = this.context.getService ( ssref );
this.isSigning = true;
}

try
Expand All @@ -88,20 +92,22 @@ public Map<String, String> aggregateMetaData ( final AggregationContext context
creator.process ( repoContext -> {
for ( final ArtifactInformation art : context.getArtifacts () )
{
final RpmInformation info = RpmInformationsJson.fromJson ( art.getMetaData ().get ( Constants.KEY_INFO ) );

if ( info == null )
if ( ( this.isSigning && art.getMetaData ().containsKey ( Constants.KEY_RSA ) ) || !this.isSigning )
{
continue;
}
final RpmInformation info = RpmInformationsJson.fromJson(art.getMetaData().get(Constants.KEY_INFO));

final String sha1 = art.getMetaData ().get ( KEY_SHA1 );
final Map<HashAlgorithm, String> checksums = Collections.singletonMap ( HashAlgorithm.SHA1, sha1 );
if (info == null) {
continue;
}

final String location = String.format ( "pool/%s/%s", art.getId (), art.getName () );
final RepositoryCreator.FileInformation file = new RepositoryCreator.FileInformation ( art.getCreationInstant (), art.getSize (), location );
final String sha1 = art.getMetaData().get(KEY_SHA1);
final Map<HashAlgorithm, String> checksums = Collections.singletonMap(HashAlgorithm.SHA1, sha1);

repoContext.addPackage ( file, info, checksums, HashAlgorithm.SHA1 );
final String location = String.format("pool/%s/%s", art.getId(), art.getName());
final RepositoryCreator.FileInformation file = new RepositoryCreator.FileInformation(art.getCreationInstant(), art.getSize(), location);

repoContext.addPackage(file, info, checksums, HashAlgorithm.SHA1);
}
}
} );

Expand Down Expand Up @@ -134,4 +140,4 @@ private DefaultXmlContext makeXmlContext ()
final DefaultXmlContext xmlCtx = new DefaultXmlContext ( dbf, this.xml.newTransformerFactory () );
return xmlCtx;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class YumRecipe implements Recipe
@Override
public LinkTarget setup ( final String channelId, final AspectableChannel channel )
{
channel.addAspects ( true, "rpm", "yum" );
channel.addAspects ( true, "rpm", "yum", "rpm.signer" );
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*
* Contributors:
* IBH SYSTEMS GmbH - initial API and implementation
* Walker Funk - Trident Systems Inc. - added system call to clear function to delete empty directories
*******************************************************************************/
package org.eclipse.packagedrone.repo.channel.apm;

Expand All @@ -30,6 +31,7 @@
import java.util.UUID;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.lang.Runtime;

import org.eclipse.packagedrone.repo.MetaKey;
import org.eclipse.packagedrone.repo.channel.ArtifactInformation;
Expand Down Expand Up @@ -822,6 +824,16 @@ public void clear ()

this.state.setNumberOfArtifacts ( 0L );
this.state.setNumberOfBytes ( 0L );

final String cmd = "rm -rf " + System.getProperty ( "drone.storage.base" ) + "/channels/" + this.channelId + "/blobs/data/*";
try
{
Process p = Runtime.getRuntime().exec( new String[] {"sh", "-c", cmd} );
}
catch ( Exception e )
{
throw new RuntimeException ( "Could not remove channel " + this.channelId + " data directories" );
}
}

@Override
Expand Down
Loading

0 comments on commit 132876c

Please sign in to comment.