Issues (69)

gvmtools/cli.py (1 issue)

Severity
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2018-2021 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
import getpass
20
import logging
21
import sys
22
import time
23
24
from gvm.errors import GvmError
25
from gvm.protocols.latest import Osp
26
from gvm.protocols.gmp import Gmp
27
from gvm.transforms import CheckCommandTransform
28
from gvm.xml import validate_xml_string, pretty_print
29
30
from gvmtools.helper import do_not_run_as_root
31
from gvmtools.parser import (
32
    create_parser,
33
    create_connection,
34
    PROTOCOL_OSP,
35
    PROTOCOL_GMP,
36
)
37
38
logger = logging.getLogger(__name__)
39
40
HELP_TEXT = """
41
    Command line tool to access services via GMP (Greenbone Management Protocol) and OSP (Open Scanner Protocol)
42
43
    Examples:
44
      gvm-cli socket --help
45
      gvm-cli tls --help
46
      gvm-cli ssh --help
47
48
      gvm-cli socket --xml "<get_version/>"
49
      gvm-cli socket --xml "<commands><authenticate><credentials><username>myuser</username><password>mypass</password></credentials></authenticate><get_tasks/></commands>"
50
      gvm-cli socket --gmp-username foo --gmp-password foo < myfile.xml
51
52
    The protocol specifications for GMP and OSP are available at:
53
      https://docs.greenbone.net/index.html#api_documentation"""
54
55
56
def _load_infile(filename=None):
57
    if not filename:
58
        return None
59
60
    with open(filename) as f:
61
        return f.read()
62
63
64
def main():
65
    do_not_run_as_root()
66
67
    parser = create_parser(description=HELP_TEXT, logfilename='gvm-cli.log')
68
69
    parser.add_protocol_argument()
70
71
    parser.add_argument('-X', '--xml', help='XML request to send')
72
    parser.add_argument(
73
        '-r', '--raw', help='Return raw XML', action='store_true', default=False
74
    )
75
    parser.add_argument(
76
        '--pretty',
77
        help='Pretty format the returned xml',
78
        action='store_true',
79
        default=False,
80
    )
81
    parser.add_argument(
82
        '--duration', action='store_true', help='Measure command execution time'
83
    )
84
    parser.add_argument(
85
        'infile', nargs='?', help='File to read XML commands from.'
86
    )
87
88
    args = parser.parse_args()
89
90
    # If timeout value is -1, then the socket has no timeout for this session
91
    if args.timeout == -1:
92
        args.timeout = None
93
94
    if args.xml is not None:
95
        xml = args.xml
96
    else:
97
        try:
98
            xml = _load_infile(args.infile)
99
        except IOError as e:
100
            print(e, file=sys.stderr)
101
            sys.exit(1)
102
103
    # If no command was given, program asks for one
104
    if len(xml) == 0:
105
        xml = input()
106
107
    try:
108
        validate_xml_string(xml)
109
    except GvmError as e:
110
        print(e, file=sys.stderr)
111
        sys.exit(1)
112
113
    connection = create_connection(**vars(args))
114
115
    if args.raw:
116
        transform = None
117
    else:
118
        transform = CheckCommandTransform()
119
120
    if args.protocol == PROTOCOL_OSP:
121
        protocol_class = Osp
122
    else:
123
        protocol_class = Gmp
124
125
    try:
126
        with protocol_class(connection, transform=transform) as protocol:
127
128
            if args.protocol == PROTOCOL_GMP:
129
                # Ask for password if none are given
130
                if args.gmp_username and not args.gmp_password:
131
                    args.gmp_password = getpass.getpass(
132
                        'Enter password for ' + args.gmp_username + ': '
133
                    )
134
135
                if args.gmp_username:
136
                    protocol.authenticate(args.gmp_username, args.gmp_password)
137
138
            if args.duration:
139
                starttime = time.time()
140
141
            result = protocol.send_command(xml)
142
143
            if args.duration:
144
                duration = time.time() - starttime
0 ignored issues
show
The variable starttime does not seem to be defined in case args.duration on line 138 is False. Are you sure this can never be the case?
Loading history...
145
                print('Elapsed time: {} seconds'.format(duration))
146
            elif args.pretty:
147
                pretty_print(result)
148
            else:
149
                print(result)
150
151
    except Exception as e:  # pylint: disable=broad-except
152
        print(e, file=sys.stderr)
153
        sys.exit(1)
154
    sys.exit(0)
155
156
157
if __name__ == '__main__':
158
    main()
159