diff options
author | Mickael Istria | 2021-11-04 10:38:54 +0000 |
---|---|---|
committer | Mickael Istria | 2021-11-04 16:16:26 +0000 |
commit | 0dd75d1e5ac5b4ebc498efe5a02ae85e85c98d51 (patch) | |
tree | 4251d13fb07e1cf96efbd17a07ce522891a9109f | |
parent | 80ecce3078ec0e9d64f2eab13d705aff2ffebe96 (diff) | |
download | rt.equinox.p2-R4_22_maintenance.tar.gz rt.equinox.p2-R4_22_maintenance.tar.xz rt.equinox.p2-R4_22_maintenance.zip |
Bug 577028 - A preference page to review and manage trusted PGP keysS4_22_0_RC2S4_22_0_RC1S4_22_0_M3R4_22I20211124-1800I20211124-0600I20211123-1800I20211123-0750I20211123-0600I20211122-1800I20211122-0820I20211121-1800I20211121-0600I20211120-1800I20211120-0600I20211119-1800I20211117-1830I20211117-0920I20211117-0600I20211116-1800I20211116-0600I20211116-0000I20211115-0600I20211114-1800I20211114-0600I20211113-1800I20211113-0600I20211112-2030I20211111-0910I20211110-1800I20211110-0750I20211110-0600I20211109-1800I20211109-0840I20211109-0720I20211108-1800I20211108-0620I20211107-1800I20211107-0600I20211106-1800I20211106-0600I20211105-1800I20211104-1800R4_22_maintenance
Change-Id: Ib162e202f4b92888cca8d6e9c30d012b993a1bb0
Reviewed-on: https://git.eclipse.org/r/c/equinox/rt.equinox.p2/+/187303
Tested-by: Equinox Bot <equinox-bot@eclipse.org>
Reviewed-by: Mickael Istria <mistria@redhat.com>
9 files changed, 178 insertions, 6 deletions
diff --git a/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF index 72d1dac18..439758603 100644 --- a/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF @@ -14,7 +14,7 @@ Export-Package: org.eclipse.equinox.internal.p2.engine; org.eclipse.equinox.p2.ui.sdk.scheduler, org.eclipse.pde.build, org.eclipse.equinox.p2.director.app", - org.eclipse.equinox.internal.p2.engine.phases;x-friends:="org.eclipse.equinox.p2.director.app,org.eclipse.equinox.p2.repository.tools,org.eclipse.equinox.p2.ui.sdk.scheduler,org.eclipse.equinox.p2.touchpoint.eclipse", + org.eclipse.equinox.internal.p2.engine.phases;x-friends:="org.eclipse.equinox.p2.director.app,org.eclipse.equinox.p2.repository.tools,org.eclipse.equinox.p2.ui.sdk,org.eclipse.equinox.p2.ui.sdk.scheduler,org.eclipse.equinox.p2.touchpoint.eclipse", org.eclipse.equinox.p2.engine;version="2.2.0", org.eclipse.equinox.p2.engine.query;version="2.0.0", org.eclipse.equinox.p2.engine.spi;version="2.0.0" diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java index 511f3e5f6..12c3fd3d2 100644 --- a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java +++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/p2/engine/phases/CertificateChecker.java @@ -114,7 +114,7 @@ public class CertificateChecker { Collection<PGPSignature> signatures = PGPSignatureVerifier.getSignatures(artifact.getKey()); if (!signatures.isEmpty()) { if (trustedKeys == null) { - trustedKeys = buildTrustore(); + trustedKeys = buildPGPTrustore(); } if (trustedKeysIds.isEmpty() && !trustedKeys.isEmpty()) { trustedKeysIds.addAll(trustedKeys.stream() @@ -286,7 +286,7 @@ public class CertificateChecker { artifacts.putAll(toAdd); } - private Set<PGPPublicKey> buildTrustore() { + public Set<PGPPublicKey> buildPGPTrustore() { IProfile profile = agent.getService(IProfileRegistry.class).getProfile(IProfileRegistry.SELF); Set<PGPPublicKey> store = new HashSet<>( PGPSignatureVerifier.readPublicKeys(profile.getProperty(TRUSTED_KEY_STORE_PROPERTY))); diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF index 6929404c6..cc9e868d8 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %bundleName Bundle-SymbolicName: org.eclipse.equinox.p2.ui.sdk;singleton:=true -Bundle-Version: 1.2.1.qualifier +Bundle-Version: 1.2.2.qualifier Bundle-Activator: org.eclipse.equinox.internal.p2.ui.sdk.ProvSDKUIActivator Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -12,8 +12,11 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.6.0", org.eclipse.core.runtime, org.eclipse.equinox.p2.ui;bundle-version="2.6.0" Import-Package: javax.xml.parsers, + org.bouncycastle.bcpg;version="1.69.0", + org.bouncycastle.openpgp;version="1.69.0", org.eclipse.compare;resolution:=optional, org.eclipse.compare.structuremergeviewer;resolution:=optional, + org.eclipse.equinox.internal.p2.engine.phases, org.eclipse.equinox.p2.core;version="[2.0.0,3.0.0)", org.eclipse.equinox.p2.engine;version="[2.0.0,3.0.0)", org.eclipse.equinox.p2.engine.query;version="[2.0.0,3.0.0)", diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.properties b/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.properties index 672cb238d..372fe98ce 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.properties +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.properties @@ -28,5 +28,7 @@ provisioningPrefPage = Install/Update sitesPrefPage = Available Software Sites installedSoftwarePage = Installed Software installHistoryPage = Installation History +trustPrefPage = Trust preferenceKeywords.general=automatic update schedule remove download site software uninstall install import bundle +preferenceKeywords.trust=trust security keys pgp gpg preferences=Update and Install Preferences diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml b/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml index 249d78378..69e973118 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/plugin.xml @@ -22,6 +22,14 @@ <keywordReference id="org.eclipse.equinox.p2.ui.sdk.updates.general"/> </page> + <page + name="%trustPrefPage" + category="org.eclipse.equinox.internal.p2.ui.sdk.ProvisioningPreferencePage" + class="org.eclipse.equinox.internal.p2.ui.sdk.TrustPreferencePage" + id="org.eclipse.equinox.internal.p2.ui.sdk.TrustPreferencePage"> + <keywordReference id="org.eclipse.equinox.p2.ui.sdk.updates.trust"/> + </page> + </extension> <extension @@ -29,6 +37,10 @@ <keyword label="%preferenceKeywords.general" id="org.eclipse.equinox.p2.ui.sdk.updates.general"/> + <keyword + id="org.eclipse.equinox.p2.ui.sdk.updates.trust" + label="%preferenceKeywords.trust"> + </keyword> </extension> diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml b/bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml index a1a7b1f62..0cc56b3b9 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/pom.xml @@ -9,6 +9,6 @@ </parent> <groupId>org.eclipse.equinox</groupId> <artifactId>org.eclipse.equinox.p2.ui.sdk</artifactId> - <version>1.2.1-SNAPSHOT</version> + <version>1.2.2-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java index e985ebb74..4c73980f4 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/ProvSDKMessages.java @@ -50,5 +50,11 @@ public class ProvSDKMessages extends NLS { public static String UpdateHandler_ProgressTaskName; public static String RemediationOperation_ResolveJobName; public static String RemediationOperation_ResolveJobTask; + public static String TrustPreferencePage_title; + public static String TrustPreferencePage_export; + public static String TrustPreferencePage_idColumn; + public static String TrustPreferencePage_userColumn; + public static String TrustPreferencePage_fileExportTitle; + public static String TrustPreferencePage_pgpIntro; } diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/TrustPreferencePage.java b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/TrustPreferencePage.java new file mode 100644 index 000000000..4b4c2439c --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/TrustPreferencePage.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2021 Red Hat Inc. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.ui.sdk; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.internal.p2.engine.phases.CertificateChecker; +import org.eclipse.equinox.internal.p2.ui.ProvUIActivator; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +public class TrustPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + public TrustPreferencePage() { + super(ProvSDKMessages.TrustPreferencePage_title); + } + + @Override + public void init(IWorkbench workbench) { + // nothing to do + } + + @Override + protected Control createContents(Composite parent) { + Composite res = new Composite(parent, SWT.NONE); + + Label pgpLabel = new Label(res, SWT.WRAP); + pgpLabel.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 2, 1)); + pgpLabel.setText(ProvSDKMessages.TrustPreferencePage_pgpIntro); + + res.setLayout(new GridLayout(2, false)); + TableViewer viewer = new TableViewer(res); + viewer.getTable().setHeaderVisible(true); + viewer.setContentProvider(new ArrayContentProvider()); + TableViewerColumn idColumn = new TableViewerColumn(viewer, SWT.NONE); + idColumn.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + return Long.toHexString(((PGPPublicKey) element).getKeyID()).toUpperCase(); + } + }); + idColumn.getColumn().setWidth(16 * 10); // number of chars in a key Id * some heuristic of width + idColumn.getColumn().setText(ProvSDKMessages.TrustPreferencePage_idColumn); + TableViewerColumn userColumn = new TableViewerColumn(viewer, SWT.NONE); + userColumn.setLabelProvider(new ColumnLabelProvider() { + @Override + public String getText(Object element) { + List<String> userIds = new ArrayList<>(); + ((PGPPublicKey) element).getUserIDs().forEachRemaining(userIds::add); + return String.join(",", userIds); //$NON-NLS-1$ + } + }); + userColumn.getColumn().setWidth(400); + userColumn.getColumn().setText(ProvSDKMessages.TrustPreferencePage_userColumn); + viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + viewer.setInput( + new CertificateChecker(ProvSDKUIActivator.getDefault().getProvisioningAgent()).buildPGPTrustore()); + Composite buttonComposite = createVerticalButtonBar(res); + buttonComposite.setLayoutData(new GridData(SWT.DEFAULT, SWT.BEGINNING, false, false)); + Button exportButton = new Button(buttonComposite, SWT.PUSH); + exportButton.setText(ProvSDKMessages.TrustPreferencePage_export); + setVerticalButtonLayoutData(exportButton); + exportButton.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> { + ISelection sel = viewer.getSelection(); + if (!(sel instanceof IStructuredSelection)) { + return; + } + Object o = ((IStructuredSelection)sel).getFirstElement(); + if (!(o instanceof PGPPublicKey)) { + return; + } + PGPPublicKey key = (PGPPublicKey)o; + FileDialog dialog = new FileDialog(getShell(), SWT.SAVE); + dialog.setText(ProvSDKMessages.TrustPreferencePage_fileExportTitle); + dialog.setFilterExtensions(new String[] { "*.asc" }); //$NON-NLS-1$ + dialog.setFileName(Long.toHexString(key.getKeyID()).toUpperCase() + ".asc"); //$NON-NLS-1$ + String path = dialog.open(); + if (path == null) { + return; + } + File destinationFile = new File(path); + try (OutputStream output = new ArmoredOutputStream(new FileOutputStream(destinationFile))) { + output.write(key.getEncoded()); + } catch (IOException ex) { + ProvSDKUIActivator.getDefault().getLog() + .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, ex.getMessage(), ex)); + } + })); + viewer.addPostSelectionChangedListener(e -> exportButton.setEnabled(!e.getSelection().isEmpty())); + exportButton.setEnabled(!viewer.getSelection().isEmpty()); + return res; + } + + private Composite createVerticalButtonBar(Composite parent) { + // Create composite. + Composite composite = new Composite(parent, SWT.NONE); + initializeDialogUnits(composite); + + // create a layout with spacing and margins appropriate for the font + // size. + GridLayout layout = new GridLayout(); + layout.numColumns = 1; + layout.marginWidth = 5; + layout.marginHeight = 0; + layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); + layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); + composite.setLayout(layout); + + return composite; + } + + private GridData setVerticalButtonLayoutData(Button button) { + GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); + Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + data.widthHint = Math.max(widthHint, minSize.x); + button.setLayoutData(data); + return data; + } +} diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties index e91eb07b5..4e79e3211 100644 --- a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties +++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/messages.properties @@ -34,4 +34,11 @@ UpdateHandler_NoSitesMessage=There are no update sites to search. Do you wish to UpdateHandler_NoSitesTitle=No Updates Found UpdateHandler_ProgressTaskName=Checking for updates... RemediationOperation_ResolveJobName=Searching alternate solutions... -RemediationOperation_ResolveJobTask=Some items cannot be at the highest version. Searching for the highest common denominator ...
\ No newline at end of file +RemediationOperation_ResolveJobTask=Some items cannot be at the highest version. Searching for the highest common denominator ... +TrustPreferencePage_title=Trust +TrustPreferencePage_export=E&xport... +TrustPreferencePage_idColumn=Id +TrustPreferencePage_userColumn=User +TrustPreferencePage_fileExportTitle=Export PGP public key +TrustPreferencePage_pgpIntro=The following PGP public keys are considered as trusted.\n\ +Artifacts that are signed and verified by one of those keys will be trusted and installed without further trust confirmation request.
\ No newline at end of file |