diff --git a/gsa/src/gmp/models/credential.js b/gsa/src/gmp/models/credential.js index 948821a44d..13af869c0b 100644 --- a/gsa/src/gmp/models/credential.js +++ b/gsa/src/gmp/models/credential.js @@ -37,6 +37,8 @@ export const SSH_CREDENTIAL_TYPES = [ USERNAME_SSH_KEY_CREDENTIAL_TYPE, ]; +export const SSH_ELEVATE_CREDENTIAL_TYPES = [USERNAME_PASSWORD_CREDENTIAL_TYPE]; + export const SMB_CREDENTIAL_TYPES = [USERNAME_PASSWORD_CREDENTIAL_TYPE]; export const ESXI_CREDENTIAL_TYPES = [USERNAME_PASSWORD_CREDENTIAL_TYPE]; diff --git a/gsa/src/web/pages/targets/component.js b/gsa/src/web/pages/targets/component.js index 6fcaf621c5..4f6eb1603d 100644 --- a/gsa/src/web/pages/targets/component.js +++ b/gsa/src/web/pages/targets/component.js @@ -54,9 +54,8 @@ class TargetComponent extends React.Component { }; this.openCredentialsDialog = this.openCredentialsDialog.bind(this); - this.handleCloseCredentialsDialog = this.handleCloseCredentialsDialog.bind( - this, - ); + this.handleCloseCredentialsDialog = + this.handleCloseCredentialsDialog.bind(this); this.openPortListDialog = this.openPortListDialog.bind(this); this.handleClosePortListDialog = this.handleClosePortListDialog.bind(this); this.openTargetDialog = this.openTargetDialog.bind(this); @@ -65,14 +64,14 @@ class TargetComponent extends React.Component { this.handleCreateCredential = this.handleCreateCredential.bind(this); this.handleCreatePortList = this.handleCreatePortList.bind(this); this.handlePortListChange = this.handlePortListChange.bind(this); - this.handleEsxiCredentialChange = this.handleEsxiCredentialChange.bind( - this, - ); + this.handleEsxiCredentialChange = + this.handleEsxiCredentialChange.bind(this); this.handleSshCredentialChange = this.handleSshCredentialChange.bind(this); + this.handleSshElevateCredentialChange = + this.handleSshElevateCredentialChange.bind(this); this.handleSmbCredentialChange = this.handleSmbCredentialChange.bind(this); - this.handleSnmpCredentialChange = this.handleSnmpCredentialChange.bind( - this, - ); + this.handleSnmpCredentialChange = + this.handleSnmpCredentialChange.bind(this); } openCredentialsDialog({id_field, types, title}) { @@ -128,6 +127,7 @@ class TargetComponent extends React.Component { smb_credential_id: id_or__(entity.smb_credential), snmp_credential_id: id_or__(entity.snmp_credential), ssh_credential_id: id_or__(entity.ssh_credential), + ssh_elevate_credential_id: id_or__(entity.ssh_elevate_credential_id), }); }); } else { @@ -154,6 +154,7 @@ class TargetComponent extends React.Component { smb_credential_id: undefined, snmp_credential_id: undefined, ssh_credential_id: undefined, + ssh_elevate_credential_id: undefined, target_source: undefined, target_exclude_source: undefined, target_title: _('New Target'), @@ -269,6 +270,10 @@ class TargetComponent extends React.Component { this.setState({ssh_credential_id}); } + handleSshElevateCredentialChange(ssh_elevate_credential_id) { + this.setState({ssh_elevate_credential_id}); + } + handleSnmpCredentialChange(snmp_credential_id) { this.setState({snmp_credential_id}); } @@ -327,6 +332,7 @@ class TargetComponent extends React.Component { smb_credential_id, snmp_credential_id, ssh_credential_id, + ssh_elevate_credential_id, target_source, target_exclude_source, target_title, @@ -377,6 +383,7 @@ class TargetComponent extends React.Component { smb_credential_id={smb_credential_id} snmp_credential_id={snmp_credential_id} ssh_credential_id={ssh_credential_id} + ssh_elevate_credential_id={ssh_elevate_credential_id} target_source={target_source} target_exclude_source={target_exclude_source} title={target_title} @@ -388,6 +395,9 @@ class TargetComponent extends React.Component { onSshCredentialChange={this.handleSshCredentialChange} onEsxiCredentialChange={this.handleEsxiCredentialChange} onSmbCredentialChange={this.handleSmbCredentialChange} + onSshElevateCredentialChange={ + this.handleSshElevateCredentialChange + } onSave={d => { this.handleInteraction(); return save(d).then(() => this.closeTargetDialog()); diff --git a/gsa/src/web/pages/targets/dialog.js b/gsa/src/web/pages/targets/dialog.js index a5bb8118c0..4a446f655b 100644 --- a/gsa/src/web/pages/targets/dialog.js +++ b/gsa/src/web/pages/targets/dialog.js @@ -17,6 +17,8 @@ */ import React from 'react'; +import styled from 'styled-components'; + import {_, _l} from 'gmp/locale/lang'; import {NO_VALUE, YES_VALUE} from 'gmp/parser'; @@ -39,6 +41,8 @@ import NewIcon from 'web/components/icon/newicon'; import Divider from 'web/components/layout/divider'; import Layout from 'web/components/layout/layout'; +import Theme from 'web/utils/theme'; + import { snmp_credential_filter, ssh_credential_filter, @@ -47,6 +51,7 @@ import { SNMP_CREDENTIAL_TYPES, SSH_CREDENTIAL_TYPES, USERNAME_PASSWORD_CREDENTIAL_TYPE, + SSH_ELEVATE_CREDENTIAL_TYPES, } from 'gmp/models/credential'; const DEFAULT_PORT = 22; @@ -89,6 +94,12 @@ const NEW_SSH = { title: _l('Create new SSH credential'), }; +const NEW_SSH_ELEVATE = { + id_field: 'ssh_elevate_credential_id', + types: SSH_ELEVATE_CREDENTIAL_TYPES, + title: _l('Create new credential for root privileges on target system'), // what is a shorter, more explanatory title? +}; + const NEW_SMB = { id_field: 'smb_credential_id', title: _l('Create new SMB credential'), @@ -107,6 +118,10 @@ const NEW_SNMP = { types: SNMP_CREDENTIAL_TYPES, }; +const ElevatePrivilegeText = styled(Layout)` + color: ${Theme.darkRed}; +`; + const TargetDialog = ({ alive_tests = ALIVE_TESTS_DEFAULT, allowSimultaneousIPs = YES_VALUE, @@ -127,6 +142,7 @@ const TargetDialog = ({ smb_credential_id = UNSET_VALUE, snmp_credential_id = UNSET_VALUE, ssh_credential_id = UNSET_VALUE, + ssh_elevate_credential_id = UNSET_VALUE, target_source = 'manual', target_exclude_source = 'manual', title = _('New Target'), @@ -139,6 +155,7 @@ const TargetDialog = ({ onSmbCredentialChange, onEsxiCredentialChange, onSnmpCredentialChange, + onSshElevateCredentialChange, ...initial }) => { const ssh_credentials = credentials.filter(ssh_credential_filter); @@ -170,6 +187,7 @@ const TargetDialog = ({ smb_credential_id, snmp_credential_id, ssh_credential_id, + ssh_elevate_credential_id, }; return ( @@ -342,34 +360,61 @@ const TargetDialog = ({ )} {capabilities.mayOp('get_credentials') && ( - - - + {_('on port')} + + {!in_use && ( + + + + )} + + + {state.ssh_credential_id !== UNSET_VALUE && ( + + + + {_('Elevate privileges')} + +