Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISSv3 - Add API to register a peripheral/hub #9611

Merged
merged 11 commits into from
Jan 20, 2025
2 changes: 1 addition & 1 deletion java/buildconf/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
^/\*$
(^ \* Copyright \(c\) (20([0123]\d|20)--)?20(1\d|2[01234]) (Red Hat, Inc.|SUSE LLC)$)+
(^ \* Copyright \(c\) (20([0123]\d|20)--)?20(1\d|2[012345]) (Red Hat, Inc.|SUSE LLC)$)+
^ \*$
^ \* This software is licensed to you under the GNU General Public License,$
^ \* version 2 \(GPLv2\). There is NO WARRANTY for this software, express or$
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018--2024 SUSE LLC
* Copyright (c) 2018--2025 SUSE LLC
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
Expand Down Expand Up @@ -31,6 +31,7 @@
import com.redhat.rhn.domain.contentmgmt.SoftwareProjectSource;
import com.redhat.rhn.domain.credentials.BaseCredentials;
import com.redhat.rhn.domain.credentials.CloudRMTCredentials;
import com.redhat.rhn.domain.credentials.HubSCCCredentials;
import com.redhat.rhn.domain.credentials.RHUICredentials;
import com.redhat.rhn.domain.credentials.RegistryCredentials;
import com.redhat.rhn.domain.credentials.ReportDBCredentials;
Expand Down Expand Up @@ -194,6 +195,7 @@ private AnnotationRegistry() {
RHUICredentials.class,
SCCCredentials.class,
VHMCredentials.class,
HubSCCCredentials.class,
ChannelSyncFlag.class,
ServerCoCoAttestationConfig.class,
ServerCoCoAttestationReport.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
/*
* Copyright (c) 2015 SUSE LLC
* Copyright (c) 2015--2024 SUSE LLC
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.rhn.common.util.http;

Expand All @@ -34,6 +30,8 @@
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.ProxyAuthenticationStrategy;
Expand All @@ -49,9 +47,11 @@
import java.net.URI;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.net.ssl.SSLContext;
Expand Down Expand Up @@ -101,14 +101,41 @@ public class HttpClientAdapter {

/** The credentials provider. */
private final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

/**
* The cookie store
*/
private BasicCookieStore cookieStore;

/**
* Initialize an {@link HttpClient} for performing requests. Proxy settings will
* be read from the configuration and applied transparently.
* be read from the configuration and applied transparently. The cookies will not be supported.
*/
public HttpClientAdapter() {
this(List.of(), false);
}

/**
* Initialize an {@link HttpClient} for performing requests. Proxy settings will
* be read from the configuration and applied transparently. The cookies will not be supported.
*
* @param additionalCertificates a list of additional certificate to consider when establishing the connection
*/
public HttpClientAdapter(List<Certificate> additionalCertificates) {
this(additionalCertificates, false);
}

/**
* Initialize an {@link HttpClient} for performing requests. Proxy settings will
* be read from the configuration and applied transparently.
*
* @param allowCookies true, to allow and use cookies.
* @param additionalCertificates a list of additional certificate to consider when establishing the connection
*/
public HttpClientAdapter(List<Certificate> additionalCertificates, boolean allowCookies) {
Optional<SSLConnectionSocketFactory> sslSocketFactory = Optional.empty();
try {
SSLContext sslContext = buildSslSocketContext();
SSLContext sslContext = buildSslSocketContext(additionalCertificates);
List<String> supportedProtocols = Arrays.asList(sslContext.getSupportedSSLParameters().getProtocols());
List<String> wantedProtocols = Arrays.asList("TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3");
wantedProtocols.retainAll(supportedProtocols);
Expand All @@ -129,7 +156,7 @@ public HttpClientAdapter() {
Builder requestConfigBuilder = RequestConfig.custom()
.setConnectTimeout(HttpClientAdapter.getHTTPConnectionTimeout(5))
.setSocketTimeout(HttpClientAdapter.getHTTPSocketTimeout(5 * 60))
.setCookieSpec(CookieSpecs.IGNORE_COOKIES);
.setCookieSpec(allowCookies ? CookieSpecs.STANDARD : CookieSpecs.IGNORE_COOKIES);

// Store the proxy settings
String proxyHostname = ConfigDefaults.get().getProxyHost();
Expand Down Expand Up @@ -170,22 +197,36 @@ public HttpClientAdapter() {
requestConfig = requestConfigBuilder.build();
clientBuilder.setMaxConnPerRoute(Config.get().getInt(MAX_CONNCECTIONS, 1));
clientBuilder.setMaxConnTotal(Config.get().getInt(MAX_CONNCECTIONS, 1));
if (allowCookies) {
cookieStore = new BasicCookieStore();
clientBuilder.setDefaultCookieStore(cookieStore);
}

httpClient = clientBuilder.build();
}

private SSLContext buildSslSocketContext() throws NoSuchAlgorithmException {
private SSLContext buildSslSocketContext(List<Certificate> additionalCertificates) throws NoSuchAlgorithmException {

LOG.info("Started checking for certificates and if it finds the certificates will be loaded...");

String keyStoreLoc = System.getProperty("javax.net.ssl.trustStore",
System.getProperty("java.home") + "/lib/security/cacerts");
String defaultLocation = System.getProperty("java.home") + "/lib/security/cacerts";
String keyStoreLoc = System.getProperty("javax.net.ssl.trustStore", defaultLocation);

SSLContext context;

try (InputStream in = new FileInputStream(keyStoreLoc)) {
// Create a KeyStore containing our trusted CAs
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(in, null);

// Add any additional certificate to the store, if specified
if (!additionalCertificates.isEmpty()) {
int customCert = 0;
for (Certificate certificate : additionalCertificates) {
keystore.setCertificateEntry("additional_certificate_" + customCert++, certificate);
}
}

// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
Expand Down Expand Up @@ -327,6 +368,25 @@ public HttpResponse executeRequest(HttpRequestBase request, String username,
return executeRequest(request, ignoreNoProxy);
}

/**
* Set the value of a cookie
* @param cookie the cookie
*/
public void setCookie(Cookie cookie) {
cookieStore.addCookie(cookie);
}

/**
* Retrieves the cookies with the specified name from the cookie store.
* @param name the name of the cookie to retrieve
* @return the cookie with a matching name.
*/
public List<Cookie> getCookies(String name) {
return cookieStore.getCookies().stream()
.filter(cookie -> Objects.equals(name, cookie.getName()))
.toList();
}

/**
* Check for a given {@link URI} if a proxy should be used or not.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
/*
* Copyright (c) 2012 SUSE LLC
* Copyright (c) 2012--2025 SUSE LLC
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/

package com.redhat.rhn.domain.credentials;
Expand Down Expand Up @@ -92,6 +88,17 @@ public static SCCCredentials createSCCCredentials(String username, String passwo
return new SCCCredentials(username, password);
}

/**
* Helper method for creating new Hub SCC {@link Credentials}
* @param username the username
* @param password the password that will be BASE64 encoded
* @param fqdn the FQDN of the peripheral server that will use this credentials
* @return new credential with type SCC
*/
public static HubSCCCredentials createHubSCCCredentials(String username, String password, String fqdn) {
return new HubSCCCredentials(username, password, fqdn);
}

/**
* Helper method for creating new Virtual Host Manager {@link Credentials}
* @param username the username
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
/*
* Copyright (c) 2012 SUSE LLC
* Copyright (c) 2012--2025 SUSE LLC
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.rhn.domain.credentials;

Expand All @@ -25,7 +21,8 @@ public enum CredentialsType {
REGISTRY(Label.REGISTRY),
CLOUD_RMT(Label.CLOUD_RMT),
REPORT_DATABASE(Label.REPORT_DATABASE),
RHUI(Label.RHUI);
RHUI(Label.RHUI),
HUB_SCC(Label.HUB_SCC);

private final String label;

Expand Down Expand Up @@ -58,6 +55,7 @@ public static class Label {
public static final String CLOUD_RMT = "cloudrmt";
public static final String REPORT_DATABASE = "reportcreds";
public static final String RHUI = "rhui";
public static final String HUB_SCC = "hub_scc";

private Label() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2025 SUSE LLC
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*/

package com.redhat.rhn.domain.credentials;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Transient;

@Entity
@DiscriminatorValue(CredentialsType.Label.HUB_SCC)
public class HubSCCCredentials extends PasswordBasedCredentials {

private String peripheralUrl;

// No args constructor for hibernate
protected HubSCCCredentials() {
}

// Default constructor filling the mandatory fields to be used in the CredentialFactory
protected HubSCCCredentials(String usernameIn, String passwordIn, String peripheralUrlIn) {
setUsername(usernameIn);
setPassword(passwordIn);
this.peripheralUrl = peripheralUrlIn;
}

@Override
@Transient
public CredentialsType getType() {
return CredentialsType.HUB_SCC;
}

@Column(name = "url")
public String getPeripheralUrl() {
return peripheralUrl;
}

public void setPeripheralUrl(String peripheralUrlIn) {
this.peripheralUrl = peripheralUrlIn;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}

if (!(o instanceof HubSCCCredentials that)) {
return false;
}

return new EqualsBuilder()
.appendSuper(super.equals(o))
.append(getPeripheralUrl(), that.getPeripheralUrl())
.isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.appendSuper(super.hashCode())
.append(getPeripheralUrl())
.toHashCode();
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("id", getId())
.append("type", CredentialsType.HUB_SCC)
.append("user", getUser())
.append("username", getUsername())
.append("url", getPeripheralUrl())
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 SUSE LLC
* Copyright (c) 2024--2025 SUSE LLC
* Copyright (c) 2009--2010 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
Expand Down Expand Up @@ -96,7 +96,7 @@
import com.suse.manager.webui.controllers.bootstrap.SSHMinionBootstrapper;
import com.suse.manager.webui.services.iface.SaltApi;
import com.suse.manager.xmlrpc.admin.AdminPaygHandler;
import com.suse.manager.xmlrpc.iss.SyncHandler;
import com.suse.manager.xmlrpc.iss.IssHandler;
import com.suse.manager.xmlrpc.maintenance.MaintenanceHandler;

import java.util.HashMap;
Expand Down Expand Up @@ -211,7 +211,7 @@ public static HandlerFactory getDefaultHandlerFactory() {
factory.addHandler("saltkey", new SaltKeyHandler(saltKeyUtils));
factory.addHandler("schedule", new ScheduleHandler());
factory.addHandler("subscriptionmatching.pinnedsubscription", new PinnedSubscriptionHandler());
factory.addHandler("sync.iss", new SyncHandler());
factory.addHandler("sync.iss", new IssHandler());
factory.addHandler("sync.master", new MasterHandler());
factory.addHandler("sync.slave", new SlaveHandler());
factory.addHandler("sync.content", new ContentSyncHandler());
Expand Down
Loading
Loading