Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,17 @@ FullResponse JoinSps(ISafeguardSessionsConnection spsConnection, String certific
*/
ISafeguardEventListener getPersistentEventListener() throws ObjectDisposedException, SafeguardForJavaException;

/**
* Returns a Safeguard API connection tailored to work with the Safeguard management service
* service. To invoke methods on the Management service, call this method first and use the
* returned ISafeguardConnection. Applicable options such as SSL validation will be inherited
* from the original ISafeguardConnection.
*
* @param networkAddress Network address.
* @return Reusable Safeguard API connection.
*/
ISafeguardConnection GetManagementServiceConnection(String networkAddress);

/**
* Call Safeguard API to invalidate current access token and clear its value from
* the connection. In order to continue using the connection you will need to call
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ public String invokeMethodCsv(Service service, Method method, String relativeUrl
public SafeguardEventListener getEventListener() throws ObjectDisposedException, ArgumentException {
return _connection.getEventListener();
}

@Override
public ISafeguardConnection GetManagementServiceConnection(String networkAddress) {
return _connection.GetManagementServiceConnection(networkAddress);
}

@Override
public ISafeguardEventListener getPersistentEventListener() throws ObjectDisposedException, SafeguardForJavaException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ public ISafeguardEventListener getPersistentEventListener()
throw new SafeguardForJavaException("Unable to create persistent event listener from " + this.authenticationMechanism.getClass().getName());
}

@Override
public ISafeguardConnection GetManagementServiceConnection(String networkAddress) {
return new SafeguardManagementServiceConnection(authenticationMechanism, networkAddress);
}

@Override
public void logOut() throws ObjectDisposedException {

Expand Down Expand Up @@ -238,7 +243,7 @@ static void logResponseDetails(FullResponse fullResponse)
Logger.getLogger(SafeguardConnection.class.getName()).log(Level.FINEST, " Body size: {0}", msg);
}

RestClient getClientForService(Service service) throws SafeguardForJavaException {
protected RestClient getClientForService(Service service) throws SafeguardForJavaException {
switch (service) {
case Core:
return coreClient;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.oneidentity.safeguard.safeguardjava;

import com.oneidentity.safeguard.safeguardjava.authentication.IAuthenticationMechanism;
import com.oneidentity.safeguard.safeguardjava.authentication.ManagementServiceAuthenticator;
import com.oneidentity.safeguard.safeguardjava.data.FullResponse;
import com.oneidentity.safeguard.safeguardjava.data.Service;
import com.oneidentity.safeguard.safeguardjava.event.ISafeguardEventListener;
import com.oneidentity.safeguard.safeguardjava.exceptions.SafeguardForJavaException;
import com.oneidentity.safeguard.safeguardjava.restclient.RestClient;

class SafeguardManagementServiceConnection extends SafeguardConnection {

private final IAuthenticationMechanism authenticationMechanism;

private final RestClient managementClient;

public SafeguardManagementServiceConnection(IAuthenticationMechanism parentAuthenticationMechanism, String networkAddress) {

super(parentAuthenticationMechanism);
authenticationMechanism = new ManagementServiceAuthenticator(parentAuthenticationMechanism, networkAddress);

String safeguardManagementUrl = String.format("https://%s/service/management/v%d",
this.authenticationMechanism.getNetworkAddress(), this.authenticationMechanism.getApiVersion());
managementClient = new RestClient(safeguardManagementUrl, authenticationMechanism.isIgnoreSsl(), authenticationMechanism.getValidationCallback());
}

public FullResponse JoinSps(ISafeguardSessionsConnection spsConnection, String certificateChain, String sppAddress)
throws SafeguardForJavaException {
throw new SafeguardForJavaException("Management connection cannot be used to join SPS.");
}

public ISafeguardEventListener GetEventListener() throws SafeguardForJavaException {
throw new SafeguardForJavaException("Management connection does not support event listeners.");
}

public ISafeguardEventListener GetPersistentEventListener() throws SafeguardForJavaException {
throw new SafeguardForJavaException("Management connection does not support event listeners.");
}

@Override
protected RestClient getClientForService(Service service) throws SafeguardForJavaException {

if (service == Service.Management) {
return managementClient;
}
throw new SafeguardForJavaException(String.format("%s service cannot be invoked with a management connection.", service.name()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected char[] getRstsTokenInternal() throws SafeguardForJavaException {

@Override
public boolean hasAccessToken() {
return true;
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.oneidentity.safeguard.safeguardjava.authentication;

import com.oneidentity.safeguard.safeguardjava.exceptions.ObjectDisposedException;
import com.oneidentity.safeguard.safeguardjava.exceptions.SafeguardForJavaException;
import javax.net.ssl.HostnameVerifier;

public class ManagementServiceAuthenticator implements IAuthenticationMechanism {

private boolean disposed;

private final String networkAddress;
private final int apiVersion;
private final boolean ignoreSsl;
private final HostnameVerifier validationCallback;


public ManagementServiceAuthenticator(IAuthenticationMechanism parentAuthenticationMechanism, String networkAddress) {
this.apiVersion = parentAuthenticationMechanism.getApiVersion();
this.ignoreSsl = parentAuthenticationMechanism.isIgnoreSsl();
this.validationCallback = parentAuthenticationMechanism.getValidationCallback();
this.networkAddress = networkAddress;
}

@Override
public String getId() {
return "Management";
}

@Override
public String getNetworkAddress() {
return networkAddress;
}

@Override
public int getApiVersion() {
return apiVersion;
}

@Override
public boolean isIgnoreSsl() {
return ignoreSsl;
}

@Override
public HostnameVerifier getValidationCallback() {
return validationCallback;
}

@Override
public boolean isAnonymous() {
return true;
}

@Override
public boolean hasAccessToken() {
return false;
}

@Override
public void clearAccessToken() {
// There is no access token for anonymous auth
}

@Override
public char[] getAccessToken() throws ObjectDisposedException {
return null;
}

@Override
public int getAccessTokenLifetimeRemaining() throws ObjectDisposedException, SafeguardForJavaException {
return 0;
}

@Override
public void refreshAccessToken() throws ObjectDisposedException, SafeguardForJavaException {
throw new SafeguardForJavaException("Anonymous connection cannot be used to get an API access token, Error: Unsupported operation");
}

@Override
public String resolveProviderToScope(String provider) throws SafeguardForJavaException {
throw new SafeguardForJavaException("Anonymous connection does not require a provider, Error: Unsupported operation");
}

@Override
public Object cloneObject() throws SafeguardForJavaException {
throw new SafeguardForJavaException("Anonymous authenticators are not cloneable");
}

@Override
public void dispose() {
disposed = true;
}

@Override
protected void finalize() throws Throwable {
try {
} finally {
disposed = true;
super.finalize();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,12 @@ public enum Service {
/**
* The a2a service contains application integration Safeguard operations. It is called via the Safeguard.A2A class.
*/
A2A
A2A,

/**
* The Management service contains unauthenticated endpoints for disaster-recovery and support operations. On hardware
* it is bound to the MGMT network interface. For on-prem VM it is unavailable except through the Kiosk app. On cloud
* VM it is listening on port 9337 and should be firewalled appropriately to restrict access.
*/
Management
}
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ public CloseableHttpResponse execPUT(String path, Map<String, String> queryParam
RequestBuilder rb = prepareRequest(RequestBuilder.put(getBaseURI(path)), queryParams, headers, timeout);

try {
rb.setEntity(new StringEntity(requestEntity.toJson()));
String body = requestEntity.toJson();
rb.setEntity(new StringEntity(body == null ? "{}" : body));
CloseableHttpResponse r = client.execute(rb.build());
return r;
} catch (Exception ex) {
Expand All @@ -273,7 +274,8 @@ public CloseableHttpResponse execPOST(String path, Map<String, String> queryPara
RequestBuilder rb = prepareRequest(RequestBuilder.post(getBaseURI(path)), queryParams, headers, timeout);

try {
rb.setEntity(new StringEntity(requestEntity.toJson()));
String body = requestEntity.toJson();
rb.setEntity(new StringEntity(body == null ? "{}" : body));
CloseableHttpResponse r = client.execute(rb.build());
return r;
} catch (Exception ex) {
Expand All @@ -290,7 +292,8 @@ public CloseableHttpResponse execPOST(String path, Map<String, String> queryPara
RequestBuilder rb = prepareRequest(RequestBuilder.post(getBaseURI(path)), queryParams, headers, timeout);

try {
rb.setEntity(new StringEntity(requestEntity.toJson()));
String body = requestEntity.toJson();
rb.setEntity(new StringEntity(body == null ? "{}" : body));
CloseableHttpResponse r = certClient.execute(rb.build());
return r;
} catch (IOException ex) {
Expand Down
2 changes: 1 addition & 1 deletion tests/safeguardjavaclient/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<dependency>
<groupId>com.oneidentity.safeguard</groupId>
<artifactId>safeguardjava</artifactId>
<version>6.11.0-SNAPSHOT</version>
<version>6.12.0-SNAPSHOT</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ public static void main(String[] args) {
case 23:
tests.safeguardSessionsApi(sessionConnection);
break;
case 24:
tests.safeguardTestManagementConnection(connection);
break;
case 25:
tests.safeguardTestAnonymousConnection(connection);
break;
default:
done = true;
break;
Expand Down Expand Up @@ -135,6 +141,8 @@ private static Integer displayMenu() {
System.out.println ("\t21. Test Upload Backup File");
System.out.println ("\t22. Test SPS Connection");
System.out.println ("\t23. Test SPS API");
System.out.println ("\t24. Test Management Interface API");
System.out.println ("\t25. Test Anonymous Connection");

System.out.println ("\t99. Exit");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,22 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;

public class SafeguardTests {

public SafeguardTests() {
}

private void logResponseDetails(FullResponse fullResponse)
{
System.out.println(String.format("\t\tReponse status code: %d", fullResponse.getStatusCode()));
String msg = fullResponse.getHeaders() == null ? "None" : fullResponse.getHeaders().stream().map(header -> header.getName() + "=" + header.getValue()).collect(Collectors.joining(", ", "{", "}"));
System.out.println(String.format("\t\tResponse headers: %s", msg));
msg = (fullResponse.getBody() == null) || (fullResponse.getBody().trim().length() == 0) ? "No-Content" : fullResponse.getBody();
System.out.println(String.format("\t\tBody: %s", msg));
}

public ISafeguardConnection safeguardConnectByUserPassword() {

String address = readLine("SPP address: ", null);
Expand Down Expand Up @@ -195,15 +205,21 @@ public void safeguardTestConnection(ISafeguardConnection connection) {

FullResponse fullResponse = connection.invokeMethodFull(Service.Core, Method.Get, "Users", null, null, null, null);
System.out.println(String.format("\t\\Users full response:"));
System.out.println(fullResponse.toString());
logResponseDetails(fullResponse);

fullResponse = connection.invokeMethodFull(Service.Core, Method.Post, "Events/FireTestEvent", null, null, null, null);
System.out.println(String.format("\t\\FireTestEvent response:"));
logResponseDetails(fullResponse);

response = connection.invokeMethod(Service.Notification, Method.Get, "Status", null, null, null, null);
fullResponse = connection.invokeMethodFull(Service.Notification, Method.Get, "Status", null, null, null, null);
System.out.println(String.format("\t\\Appliance status:"));
System.out.println(response);
logResponseDetails(fullResponse);

} catch (ObjectDisposedException | SafeguardForJavaException ex) {
System.out.println("\t[ERROR]Test connection failed: " + ex.getMessage());
} catch (Exception ex) {
fullResponse = connection.invokeMethodFull(Service.Appliance, Method.Get, "NetworkInterfaces", null, null, null, null);
System.out.println(String.format("\t\\NetworkInterfaces response:"));
logResponseDetails(fullResponse);

} catch (ArgumentException | ObjectDisposedException | SafeguardForJavaException ex) {
System.out.println("\t[ERROR]Test connection failed: " + ex.getMessage());
}
}
Expand Down Expand Up @@ -586,13 +602,50 @@ void safeguardSessionsApi(ISafeguardSessionsConnection connection) {
try {
FullResponse fullResponse = connection.InvokeMethodFull(Method.Get, "firmware", null);
System.out.println(String.format("\t\\Users full response:"));
System.out.println(fullResponse.getBody());
logResponseDetails(fullResponse);

} catch (ObjectDisposedException | SafeguardForJavaException ex) {
System.out.println("\t[ERROR]Test connection failed: " + ex.getMessage());
} catch (Exception ex) {
} catch (ArgumentException | ObjectDisposedException | SafeguardForJavaException ex) {
System.out.println("\t[ERROR]Test connection failed: " + ex.getMessage());
}
}

void safeguardTestManagementConnection(ISafeguardConnection connection) {
if (connection == null) {
System.out.println(String.format("Safeguard not connected. This test requires an annonymous connection."));
return;
}

String address = readLine("SPP address(management service): ", null);

try {
ISafeguardConnection managementConnection = connection.GetManagementServiceConnection(address);
FullResponse response = managementConnection.invokeMethodFull(Service.Management, Method.Get, "ApplianceInformation", null, null, null, null);
System.out.println(String.format("\t\\ApplianceInformation response:"));
logResponseDetails(response);
} catch (ArgumentException | ObjectDisposedException | SafeguardForJavaException ex) {
System.out.println("\t[ERROR]Test management connection failed: " + ex.getMessage());
}

}

public void safeguardTestAnonymousConnection(ISafeguardConnection connection) {

if (connection == null) {
System.out.println(String.format("Safeguard not connected"));
return;
}

try {
int remaining = connection.getAccessTokenLifetimeRemaining();
System.out.println(String.format("\tTime remaining: %d", remaining));

FullResponse fullResponse = connection.invokeMethodFull(Service.Notification, Method.Get, "Status", null, null, null, null);
System.out.println(String.format("\t\\Appliance status:"));
logResponseDetails(fullResponse);

} catch (ArgumentException | ObjectDisposedException | SafeguardForJavaException ex) {
System.out.println("\t[ERROR]Test connection failed: " + ex.getMessage());
}
}

}