From commits-return-70614-archive-asf-public=cust-asf.ponee.io@cloudstack.apache.org Wed Jan 10 12:15:11 2018 Return-Path: X-Original-To: archive-asf-public@eu.ponee.io Delivered-To: archive-asf-public@eu.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by mx-eu-01.ponee.io (Postfix) with ESMTP id C926D18072F for ; Wed, 10 Jan 2018 12:15:11 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id B96D5160C23; Wed, 10 Jan 2018 11:15:11 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id D8B1C160C2E for ; Wed, 10 Jan 2018 12:15:10 +0100 (CET) Received: (qmail 64033 invoked by uid 500); 10 Jan 2018 11:15:10 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 64021 invoked by uid 99); 10 Jan 2018 11:15:10 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 10 Jan 2018 11:15:10 +0000 From: GitBox To: commits@cloudstack.apache.org Subject: [GitHub] DaanHoogland closed pull request #2357: CLOUDSTACK-10182 Restrict volumes and templates download per user for security purposes Message-ID: <151558290947.12135.17736856183759651040.gitbox@gitbox.apache.org> DaanHoogland closed pull request #2357: CLOUDSTACK-10182 Restrict volumes and templates download per user for security purposes URL: https://github.com/apache/cloudstack/pull/2357 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java b/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java index 9c526563d44..c82c291e9c2 100644 --- a/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java @@ -59,6 +59,7 @@ public void execute() { response.setKVMSnapshotEnabled((Boolean)capabilities.get("KVMSnapshotEnabled")); response.setAllowUserViewDestroyedVM((Boolean)capabilities.get("allowUserViewDestroyedVM")); response.setAllowUserExpungeRecoverVM((Boolean)capabilities.get("allowUserExpungeRecoverVM")); + response.setAllowVolumeExtraction((Boolean)capabilities.get("allowVolumeExtraction")); if (capabilities.containsKey("apiLimitInterval")) { response.setApiLimitInterval((Integer)capabilities.get("apiLimitInterval")); } diff --git a/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java b/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java index bcdad468fac..5dcf22e5875 100644 --- a/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java +++ b/api/src/org/apache/cloudstack/api/response/CapabilitiesResponse.java @@ -84,6 +84,10 @@ @Param(description = "true if the user can recover and expunge virtualmachines, false otherwise", since = "4.6.0") private boolean allowUserExpungeRecoverVM; + @SerializedName("allowvolumeextraction") + @Param(description = "If false, users will not be able to extract volumes and templates") + private boolean allowVolumeExtraction; + public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) { this.securityGroupsEnabled = securityGroupsEnabled; } @@ -143,4 +147,8 @@ public void setAllowUserViewDestroyedVM(boolean allowUserViewDestroyedVM) { public void setAllowUserExpungeRecoverVM(boolean allowUserExpungeRecoverVM) { this.allowUserExpungeRecoverVM = allowUserExpungeRecoverVM; } + + public void setAllowVolumeExtraction(boolean allowVolumeExtraction) { + this.allowVolumeExtraction = allowVolumeExtraction; + } } \ No newline at end of file diff --git a/engine/components-api/src/com/cloud/template/TemplateManager.java b/engine/components-api/src/com/cloud/template/TemplateManager.java index 68c3b585692..38f6fedd0f4 100644 --- a/engine/components-api/src/com/cloud/template/TemplateManager.java +++ b/engine/components-api/src/com/cloud/template/TemplateManager.java @@ -39,6 +39,7 @@ public interface TemplateManager { static final String AllowPublicUserTemplatesCK = "allow.public.user.templates"; static final String TemplatePreloaderPoolSizeCK = "template.preloader.pool.size"; + static final String AllowVolumeExtractionCK = "allow.volume.extraction"; static final ConfigKey AllowPublicUserTemplates = new ConfigKey("Advanced", Boolean.class, AllowPublicUserTemplatesCK, "true", "If false, users will not be able to create public templates.", true, ConfigKey.Scope.Account); @@ -46,6 +47,8 @@ static final ConfigKey TemplatePreloaderPoolSize = new ConfigKey("Advanced", Integer.class, TemplatePreloaderPoolSizeCK, "8", "Size of the TemplateManager threadpool", false, ConfigKey.Scope.Global); + static final ConfigKey AllowVolumeExtraction = new ConfigKey("Advanced", Boolean.class, AllowVolumeExtractionCK, "true", + "If false, users will not be able to extract volumes and templates", true, ConfigKey.Scope.Account); /** diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index da987ca1330..20f7fdcf708 100644 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -3370,6 +3370,7 @@ private String signRequest(final String request, final String key) { boolean securityGroupsEnabled = false; boolean elasticLoadBalancerEnabled = false; boolean KVMSnapshotEnabled = false; + boolean allowVolumeExtraction = false; String supportELB = "false"; final List networks = _networkDao.listSecurityGroupEnabledNetworks(); if (networks != null && !networks.isEmpty()) { @@ -3388,6 +3389,9 @@ private String signRequest(final String request, final String key) { final long diskOffMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value(); KVMSnapshotEnabled = Boolean.parseBoolean(_configDao.getValue("KVM.snapshot.enabled")); + Account account = CallContext.current().getCallingAccount(); + allowVolumeExtraction = TemplateManager.AllowVolumeExtraction.valueIn(account.getId()); + final boolean userPublicTemplateEnabled = TemplateManager.AllowPublicUserTemplates.valueIn(caller.getId()); // add some parameters UI needs to handle API throttling @@ -3417,6 +3421,7 @@ private String signRequest(final String request, final String key) { capabilities.put("KVMSnapshotEnabled", KVMSnapshotEnabled); capabilities.put("allowUserViewDestroyedVM", allowUserViewDestroyedVM); capabilities.put("allowUserExpungeRecoverVM", allowUserExpungeRecoverVM); + capabilities.put("allowVolumeExtraction", allowVolumeExtraction); if (apiLimitEnabled) { capabilities.put("apiLimitInterval", apiLimitInterval); capabilities.put("apiLimitMax", apiLimitMax); diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 37b72a68d14..0c4eff7f6d2 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -2279,6 +2279,12 @@ public String extractVolume(ExtractVolumeCmd cmd) { throw new PermissionDeniedException("Extraction has been disabled by admin"); } + boolean VolumeExtractionEnabled = TemplateManager.AllowVolumeExtraction.valueIn(account.getId()); + //AccountDetailVO accountDetailVO = _accountDetailsDao.findDetail(account.getId(), "allow.volume.extraction"); + if (!VolumeExtractionEnabled) { + throw new PermissionDeniedException("Extraction has been disabled in user properties"); + } + VolumeVO volume = _volsDao.findById(volumeId); if (volume == null) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with specified volumeId"); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index f6494c3b77e..9a3cb7ec417 100644 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -2095,7 +2095,7 @@ public String getConfigComponentName() { @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {AllowPublicUserTemplates, TemplatePreloaderPoolSize}; + return new ConfigKey[] {AllowPublicUserTemplates, TemplatePreloaderPoolSize, AllowVolumeExtraction}; } public List getTemplateAdapters() { diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index 119013326fb..bf948255886 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -149,6 +149,7 @@ g_allowUserExpungeRecoverVm = json.listcapabilitiesresponse.capability.allowuserexpungerecovervm; g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects; + g_allowvolumeextraction = json.listcapabilitiesresponse.capability.allowvolumeextraction; g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion; @@ -302,6 +303,7 @@ } g_allowUserExpungeRecoverVm = json.listcapabilitiesresponse.capability.allowuserexpungerecovervm; g_userProjectsEnabled = json.listcapabilitiesresponse.capability.allowusercreateprojects; + g_allowvolumeextraction = json.listcapabilitiesresponse.capability.allowvolumeextraction; g_cloudstackversion = json.listcapabilitiesresponse.capability.cloudstackversion; @@ -360,6 +362,7 @@ g_kvmsnapshotenabled = null; g_regionsecondaryenabled = null; g_loginCmdText = null; + g_allowvolumeextraction = null; // Remove any cookies var cookies = document.cookie.split(";"); @@ -396,6 +399,7 @@ g_kvmsnapshotenabled = null; g_regionsecondaryenabled = null; g_loginCmdText = null; + g_allowvolumeextraction = null; // Remove any cookies var cookies = document.cookie.split(";"); diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index 655aee9fb93..37af41d7eff 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -35,6 +35,7 @@ var g_cloudstackversion = null; var g_queryAsyncJobResultInterval = 3000; var g_idpList = null; var g_appendIdpDomain = false; +var g_allowvolumeextraction = true; //keyboard keycode var keycode_Enter = 13; diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index 9c017b1025b..14f13bff633 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -2767,7 +2767,7 @@ } if (jsonObj.state != "Allocated") { - if ((jsonObj.vmstate == "Stopped" || jsonObj.virtualmachineid == null) && jsonObj.state == "Ready") { + if ((jsonObj.vmstate == "Stopped" || jsonObj.virtualmachineid == null) && jsonObj.state == "Ready" && g_allowvolumeextraction == true) { allowedActions.push("downloadVolume"); } } diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js index 1ab1b9b09dd..da816755bd3 100755 --- a/ui/scripts/templates.js +++ b/ui/scripts/templates.js @@ -2959,7 +2959,7 @@ // "Download Template" if (((isAdmin() == false && !(jsonObj.domainid == g_domainid && jsonObj.account == g_account) && !(jsonObj.domainid == g_domainid && cloudStack.context.projects && jsonObj.projectid == cloudStack.context.projects[0].id))) //if neither root-admin, nor the same account, nor the same project - || (jsonObj.isready == false) || jsonObj.templatetype == "SYSTEM") { + || (jsonObj.isready == false) || jsonObj.templatetype == "SYSTEM" || g_allowvolumeextraction == false) { //do nothing } else { allowedActions.push("downloadTemplate"); ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: users@infra.apache.org With regards, Apache Git Services