Skip to content
Closed
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
4 changes: 4 additions & 0 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
<artifactId>cloud-framework-direct-download</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.bettercloud</groupId>
<artifactId>vault-java-driver</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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.cloud.exception;

/**
* @since 4.12.0.0
*/
public class RemoteAccessVpnException extends ManagementServerException {
private static final long serialVersionUID = -5851224796385227880L;

public RemoteAccessVpnException(String message) {
super(message);
}
}
4 changes: 4 additions & 0 deletions api/src/main/java/com/cloud/network/RemoteAccessVpn.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ enum State {

String getIpsecPresharedKey();

String getCaCertificate();

String getLocalIp();

Long getNetworkId();
Expand All @@ -42,4 +44,6 @@ enum State {

@Override
boolean isDisplay();

String getVpnType();
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@
import org.apache.cloudstack.api.command.user.vpn.ListVpnUsersCmd;

import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.RemoteAccessVpnException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.RemoteAccessVpn;
import com.cloud.network.VpnUser;
import com.cloud.user.Account;
import com.cloud.utils.Pair;

public interface RemoteAccessVpnService {
static final String RemoteAccessVpnClientIpRangeCK = "remote.access.vpn.client.iprange";
enum Type {
L2TP, IKEV2
}

RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, Boolean forDisplay) throws NetworkRuleConflictException;
String RemoteAccessVpnTypeConfigKey = "remote.access.vpn.type";
String RemoteAccessVpnClientIpRangeCK = "remote.access.vpn.client.iprange";

RemoteAccessVpn createRemoteAccessVpn(long vpnServerAddressId, String ipRange, boolean openFirewall, Boolean forDisplay)
throws NetworkRuleConflictException, RemoteAccessVpnException;

boolean destroyRemoteAccessVpnForIp(long ipId, Account caller, boolean forceCleanup) throws ResourceUnavailableException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.RemoteAccessVpnException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.IpAddress;
import com.cloud.network.RemoteAccessVpn;
Expand Down Expand Up @@ -156,6 +157,10 @@ public void create() {
s_logger.info("Network rule conflict: " + e.getMessage());
s_logger.trace("Network Rule Conflict: ", e);
throw new ServerApiException(ApiErrorCode.NETWORK_RULE_CONFLICT_ERROR, e.getMessage());
} catch (RemoteAccessVpnException e) {
s_logger.info("Create vpn internal error: " + e.getMessage());
s_logger.trace("Create vpn internal error: ", e);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//Licensed to the Apache Software Foundation (ASF) under one
//or more contributor license agreements. See the NOTICE file
//distributed with this work for additional information
//regarding copyright ownership. The ASF licenses this file
//to you 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 org.apache.cloudstack.api.command.user.vpn;

import javax.inject.Inject;

import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.CertificateResponse;
import org.apache.cloudstack.pki.PkiDetail;
import org.apache.cloudstack.pki.PkiManager;

import com.cloud.domain.Domain;
import com.cloud.exception.RemoteAccessVpnException;
import com.cloud.user.Account;
import com.cloud.user.DomainService;
import com.cloud.utils.exception.CloudRuntimeException;

/**
* @author Khosrow Moossavi
* @since 4.12.0.0
*/
@APICommand(
name = ListRemoteAccessVpnCaCertificatesCmd.APINAME,
description = "Lists the CA public certificate(s) as support by the configured/provided CA plugin",
responseObject = CertificateResponse.class,
requestHasSensitiveInfo = false,
responseHasSensitiveInfo = false,
since = "4.12.0.0",
authorized = {
RoleType.Admin,
RoleType.ResourceAdmin,
RoleType.DomainAdmin,
RoleType.User
}
)
public class ListRemoteAccessVpnCaCertificatesCmd extends BaseCmd {
public static final String APINAME = "listVpnCaCertificate";

@Inject private DomainService domainService;
@Inject private PkiManager pkiManager;

/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////

@Parameter(name = ApiConstants.DOMAIN, type = CommandType.STRING, description = "Name of the CA service provider, otherwise the default configured provider plugin will be used")
private String domain;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////

public String getDomain() {
return domain;
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

@Override
public void execute() {
final PkiDetail certificate;

try {
Domain domain = domainService.getDomain(getDomain());
certificate = pkiManager.getCertificate(domain);
} catch (final RemoteAccessVpnException e) {
throw new CloudRuntimeException("Failed to get CA certificates for given domain");
}

final CertificateResponse certificateResponse = new CertificateResponse("cacertificates");
certificateResponse.setCertificate(certificate.getIssuingCa());
certificateResponse.setResponseName(getCommandName());
setResponseObject(certificateResponse);
}

@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}

@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_TYPE_NORMAL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ public class RemoteAccessVpnResponse extends BaseResponse implements ControlledE
@Param(description = "is vpn for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
private Boolean forDisplay;

@SerializedName(ApiConstants.TYPE)
@Param(description = "the type of remote access vpn implementation")
private String type;

@SerializedName(ApiConstants.CERTIFICATE)
@Param(description = "the client certificate")
private String certificate;

public void setPublicIp(String publicIp) {
this.publicIp = publicIp;
}
Expand Down Expand Up @@ -129,4 +137,12 @@ public void setId(String id) {
public void setForDisplay(Boolean forDisplay) {
this.forDisplay = forDisplay;
}

public void setType(String type) {
this.type = type;
}

public void setCertificate(String certificate) {
this.certificate = certificate;
}
}
74 changes: 74 additions & 0 deletions api/src/main/java/org/apache/cloudstack/pki/PkiDetail.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 org.apache.cloudstack.pki;

/**
* @author Khosrow Moossavi
* @since 4.12.0.0
*/
public class PkiDetail {
private String certificate;
private String issuingCa;
private String privateKey;
private String privateKeyType;
private String serialNumber;

public PkiDetail certificate(final String certificate) {
this.certificate = certificate;
return this;
}

public PkiDetail issuingCa(final String issuingCa) {
this.issuingCa = issuingCa;
return this;
}

public PkiDetail privateKey(final String privateKey) {
this.privateKey = privateKey;
return this;
}

public PkiDetail privateKeyType(final String privateKeyType) {
this.privateKeyType = privateKeyType;
return this;
}

public PkiDetail serialNumber(final String serialNumber) {
this.serialNumber = serialNumber;
return this;
}

public String getCertificate() {
return certificate;
}

public String getIssuingCa() {
return issuingCa;
}

public String getPrivateKey() {
return privateKey;
}

public String getPrivateKeyType() {
return privateKeyType;
}

public String getSerialNumber() {
return serialNumber;
}
}
55 changes: 55 additions & 0 deletions api/src/main/java/org/apache/cloudstack/pki/PkiManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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 org.apache.cloudstack.pki;

import com.cloud.domain.Domain;
import com.cloud.exception.RemoteAccessVpnException;
import com.cloud.utils.net.Ip;

/**
* @author Khosrow Moossavi
* @since 4.12.0.0
*/
public interface PkiManager {
String CREDENTIAL_ISSUING_CA = "credential.issuing.ca";
String CREDENTIAL_SERIAL_NUMBER = "credential.serial.number";
String CREDENTIAL_CERTIFICATE = "credential.certificate";
String CREDENTIAL_PRIVATE_KEY = "credential.private.key";

/**
* Issue a Certificate for specific IP and specific Domain act as the CA
*
* @param domain object to extract name and id to be used to issuing CA
* @param publicIp to be included in the certificate
*
* @return detail about just signed PKI, including issuing CA, certificate, private key and serial number
*
* @throws RemoteAccessVpnException
*/
PkiDetail issueCertificate(Domain domain, Ip publicIp) throws RemoteAccessVpnException;

/**
* Get a Certificate for specific Domain act as the CA
*
* @param domain object to extract its id to be find the issuing CA
*
* @return details about signed PKI, including issuing CA, certificate and serial number
*
* @throws RemoteAccessVpnException
*/
PkiDetail getCertificate(Domain domain) throws RemoteAccessVpnException;
}
Loading