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

Scanner details #86

Merged
merged 9 commits into from
Nov 14, 2017
3 changes: 3 additions & 0 deletions ng/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,9 @@ set (NG_JS_SRC_FILES
${NG_SRC_DIR}/src/web/pages/scanconfigs/nvtpreference.js
${NG_SRC_DIR}/src/web/pages/scanconfigs/row.js
${NG_SRC_DIR}/src/web/pages/scanconfigs/trend.js
${NG_SRC_DIR}/src/web/pages/scanners/component.js
${NG_SRC_DIR}/src/web/pages/scanners/details.js
${NG_SRC_DIR}/src/web/pages/scanners/detailspage.js
${NG_SRC_DIR}/src/web/pages/scanners/dialog.js
${NG_SRC_DIR}/src/web/pages/scanners/listpage.js
${NG_SRC_DIR}/src/web/pages/scanners/row.js
Expand Down
1 change: 1 addition & 0 deletions ng/src/gmp/models/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,7 @@ export const PORTLISTS_FILTER_FILTER = Filter.fromString('type=port_list');
export const REPORTS_FILTER_FILTER = Filter.fromString('type=report');
export const RESULTS_FILTER_FILTER = Filter.fromString('type=result');
export const ROLES_FILTER_FILTER = Filter.fromString('type=role');
export const SCANNERS_FILTER_FILTER = Filter.fromString('type=scanner');
export const TARGETS_FILTER_FILTER = Filter.fromString('type=target');
export const TASKS_FILTER_FILTER = Filter.fromString('type=task');
export const VULNS_FILTER_FILTER = Filter.fromString('type=vuln');
Expand Down
65 changes: 61 additions & 4 deletions ng/src/gmp/models/scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import moment from 'moment';

import _ from '../locale.js';
import {is_defined, is_empty, is_string} from '../utils.js';
import {parse_int} from '../parser.js';
import {is_defined, is_empty, is_string, map} from '../utils.js';
import {parse_int, parse_yesno} from '../parser.js';

import Model from '../model.js';

Expand All @@ -39,6 +39,10 @@ export const SLAVE_SCANNER_TYPE = 4;
export const OPENVAS_DEFAULT_SCANNER_ID =
'08b69003-5fc2-4037-a479-93b440211c73';

export const PARAM_TYPE_OVALDEF_FILE = 'osp_ovaldef_file';
export const PARAM_TYPE_SELECTION = 'osp_selection';
export const PARAM_TYPE_BOOLEAN = 'osp_boolean';

export function scanner_type_name(scanner_type) {
scanner_type = parse_int(scanner_type);
if (scanner_type === OSP_SCANNER_TYPE) {
Expand All @@ -56,13 +60,28 @@ export function scanner_type_name(scanner_type) {
return _('Unknown type ({{type}})', {type: scanner_type});
}

const parse_scanner_info = (info = {}) => {
const data = {};

if (!is_empty(info.name)) {
data.name = info.name;
}
if (!is_empty(info.version)) {
data.version = info.version;
}

return data;
};

class Scanner extends Model {

static entity_type = 'scanner';

parseProperties(elem) {
let ret = super.parseProperties(elem);
const ret = super.parseProperties(elem);

ret.scanner_type = parse_int(elem.type);

ret.credential = is_defined(ret.credential) &&
!is_empty(ret.credential._id) ? new Credential(ret.credential) :
undefined;
Expand All @@ -87,7 +106,45 @@ class Scanner extends Model {
}
}

// TODO parse tasks and configs
if (is_defined(ret.tasks)) {
ret.tasks = map(ret.tasks.task, task => new Model(task, 'task'));
}
else {
ret.tasks = [];
}

if (is_empty(ret.configs)) {
ret.configs = [];
}
else {
ret.configs = map(ret.configs.config,
config => new Model(config, 'config'));
}

if (is_defined(ret.info)) {
const {scanner, daemon, description, params, protocol} = ret.info;

ret.info.scanner = parse_scanner_info(scanner);
ret.info.daemon = parse_scanner_info(daemon);
ret.info.protocol = parse_scanner_info(protocol);

if (is_empty(description)) {
delete ret.info.description;
}
if (is_empty(params)) {
delete ret.info.params;
}
else {
ret.info.params = map(ret.info.params.param, param => ({
name: param.name,
description: param.description,
param_type: param.type,
mandatory: parse_yesno(param.mandatory),
default: param.default,
}));
}
}

return ret;
}

Expand Down
5 changes: 5 additions & 0 deletions ng/src/web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import RolesPage from './pages/roles/listpage.js';
import RoleDetailsPage from './pages/roles/detailspage.js';
import ScanConfigsPage from './pages/scanconfigs/listpage.js';
import ScannersPage from './pages/scanners/listpage.js';
import ScannerDetailsPage from './pages/scanners/detailspage.js';
import SchedulesPage from './pages/schedules/listpage.js';
import ScheduleDetailsPage from './pages/schedules/detailspage.js';
import TagsPage from './pages/tags/listpage.js';
Expand Down Expand Up @@ -414,6 +415,10 @@ ReactDOM.render(
path="schedule/:id"
component={ScheduleDetailsPage}
/>
<Route
path="scanner/:id"
component={ScannerDetailsPage}
/>
<Route
path="reportformat/:id"
component={ReportFormatDetailsPage}
Expand Down
207 changes: 207 additions & 0 deletions ng/src/web/pages/scanners/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/* Greenbone Security Assistant
*
* Authors:
* Björn Ricks <[email protected]>
*
* Copyright:
* Copyright (C) 2017 Greenbone Networks GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
import React from 'react';

import _ from 'gmp/locale.js';
import {is_defined, shorten, select_save_id} from 'gmp/utils.js';

import {
SLAVE_SCANNER_TYPE,
} from 'gmp/models/scanner.js';

import {
CLIENT_CERTIFICATE_CREDENTIAL_TYPE,
USERNAME_PASSWORD_CREDENTIAL_TYPE,
} from 'gmp/models/credential.js';

import PropTypes from '../../utils/proptypes.js';
import withGmp from '../../utils/withGmp.js';

import Wrapper from '../../components/layout/wrapper.js';

import EntityComponent from '../../entity/component.js';

import CredentialDialog from '../credentials/dialog.js';

import ScannerDialog from './dialog.js';

class ScannerComponent extends React.Component {

constructor(...args) {
super(...args);

this.openCredentialDialog = this.openCredentialDialog.bind(this);
this.openScannerDialog = this.openScannerDialog.bind(this);
this.handleCreateCredential = this.handleCreateCredential.bind(this);
this.handleVerifyScanner = this.handleVerifyScanner.bind(this);
}

openScannerDialog(scanner) {
const {gmp} = this.props;

if (is_defined(scanner)) {
gmp.scanner.get(scanner).then(response => {
scanner = response.data;
const state = {
comment: scanner.comment,
id: scanner.id,
name: scanner.name,
type: scanner.scanner_type,
host: scanner.host,
port: scanner.port,
ca_pub: is_defined(scanner.ca_pub) ?
scanner.ca_pub.certificate : undefined,
scanner,
which_cert: is_defined(scanner.ca_pub) ? 'existing' : 'default',
};
this.scanner_dialog.show(state, {
title: _('Edit scanner {{name}}', {name: shorten(scanner.name)}),
});
});
}
else {
this.scanner_dialog.show({});
}

gmp.credentials.getAll().then(credentials => {
this.credentials = credentials;
const credential_id = is_defined(scanner) &&
is_defined(scanner.credential) ? scanner.credential.id : undefined;
this.scanner_dialog.setValues({
credentials,
credential_id: select_save_id(credentials, credential_id),
});
});
}

openCredentialDialog(type) {
const base = type === SLAVE_SCANNER_TYPE ?
USERNAME_PASSWORD_CREDENTIAL_TYPE :
CLIENT_CERTIFICATE_CREDENTIAL_TYPE;
this.credential_dialog.show({types: [base], base});
}

handleVerifyScanner(scanner) {
const {gmp, onVerified, onVerifyError} = this.props;

return gmp.scanner.verify(scanner).then(onVerified, response => {
const message = is_defined(response.root) &&
is_defined(response.root.get_scanner) &&
is_defined(response.root.get_scanner.verify_scanner_response) ?
response.root.get_scanner.verify_scanner_response._status_text :
_('Unkown Error');

if (is_defined(onVerifyError)) {
onVerifyError(new Error(message));
}
});
}

handleCreateCredential(data) {
const {gmp} = this.props;
return gmp.credential.create(data).then(response => {
const {credentials} = this;
const credential = response.data;
credentials.push(credential);
this.scanner_dialog.setValues({
credentials,
credential_id: credential.id,
});
});
}

render() {
const {
children,
onCloned,
onCloneError,
onCreated,
onCreateError,
onDeleted,
onDeleteError,
onDownloaded,
onDownloadError,
onSaved,
onSaveError,
} = this.props;
return (
<EntityComponent
name="scanner"
onCreated={onCreated}
onCreateError={onCreateError}
onCloned={onCloned}
onCloneError={onCloneError}
onDeleted={onDeleted}
onDeleteError={onDeleteError}
onDownloaded={onDownloaded}
onDownloadError={onDownloadError}
onSaved={onSaved}
onSaveError={onSaveError}
>
{({
save,
...other
}) => (
<Wrapper>
{children({
...other,
create: this.openScannerDialog,
edit: this.openScannerDialog,
verify: this.handleVerifyScanner,
})}
<ScannerDialog
ref={ref => this.scanner_dialog = ref}
onNewCredentialClick={this.openCredentialDialog}
onSave={save}
/>
<CredentialDialog
ref={ref => this.credentials_dialog = ref}
onSave={this.handleCreateCredential}
/>
</Wrapper>
)}
</EntityComponent>
);
}
}

ScannerComponent.propTypes = {
children: PropTypes.func.isRequired,
gmp: PropTypes.gmp.isRequired,
onCloneError: PropTypes.func,
onCloned: PropTypes.func,
onCreateError: PropTypes.func,
onCreated: PropTypes.func,
onDeleteError: PropTypes.func,
onDeleted: PropTypes.func,
onDownloadError: PropTypes.func,
onDownloaded: PropTypes.func,
onSaveError: PropTypes.func,
onSaved: PropTypes.func,
onVerified: PropTypes.func,
onVerifyError: PropTypes.func,
};

export default withGmp(ScannerComponent);

// vim: set ts=2 sw=2 tw=80:
Loading