Issues (2963)

addhost.php (3 issues)

Labels
1
#!/usr/bin/env php
2
<?php
3
4
/**
5
 * LibreNMS
6
 *
7
 *   This file is part of LibreNMS.
8
 *
9
 * @copyright  (C) 2006 - 2012 Adam Armstrong
10
 */
11
12
use LibreNMS\Config;
0 ignored issues
show
This use statement conflicts with another class in this namespace, Config. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
13
use LibreNMS\Exceptions\HostUnreachableException;
14
15
$init_modules = [];
16
require __DIR__ . '/includes/init.php';
17
18
$options = getopt('Pbg:p:f::');
19
20
if (isset($options['g']) && $options['g'] >= 0) {
21
    $cmd = array_shift($argv);
22
    array_shift($argv);
23
    array_shift($argv);
24
    array_unshift($argv, $cmd);
25
    $poller_group = $options['g'];
26
} elseif (Config::get('distributed_poller') === true) {
27
    $poller_group = Config::get('default_poller_group');
28
} else {
29
    $poller_group = 0;
30
}
31
32
if (isset($options['f']) && $options['f'] == 0) {
33
    $cmd = array_shift($argv);
34
    array_shift($argv);
35
    array_unshift($argv, $cmd);
36
    $force_add = true;
37
} else {
38
    $force_add = false;
39
}
40
41
$port_assoc_mode = Config::get('default_port_association_mode');
42
$valid_assoc_modes = get_port_assoc_modes();
43
if (isset($options['p'])) {
44
    $port_assoc_mode = $options['p'];
45
    if (! in_array($port_assoc_mode, $valid_assoc_modes)) {
46
        echo "Invalid port association mode '" . $port_assoc_mode . "'\n";
47
        echo 'Valid modes: ' . join(', ', $valid_assoc_modes) . "\n";
48
        exit(1);
49
    }
50
51
    $cmd = array_shift($argv);
52
    array_shift($argv);
53
    array_shift($argv);
54
    array_unshift($argv, $cmd);
55
}
56
57
if (isset($options['P'])) {
58
    $cmd = array_shift($argv);
59
    array_shift($argv);
60
    array_unshift($argv, $cmd);
61
}
62
63
if (isset($options['b'])) {
64
    $cmd = array_shift($argv);
65
    array_shift($argv);
66
    array_unshift($argv, $cmd);
67
}
68
69
$transports_regex = implode('|', Config::get('snmp.transports'));
0 ignored issues
show
It seems like LibreNMS\Config::get('snmp.transports') can also be of type null; however, parameter $pieces of implode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
$transports_regex = implode('|', /** @scrutinizer ignore-type */ Config::get('snmp.transports'));
Loading history...
70
if (! empty($argv[1])) {
71
    $host = strtolower($argv[1]);
72
    $community = $argv[2];
73
    $snmpver = strtolower($argv[3]);
74
75
    $port = 161;
76
    $transport = 'udp';
77
78
    $additional = [];
79
    if (isset($options['b'])) {
80
        $additional = [
81
            'ping_fallback' => 1,
82
        ];
83
    }
84
    if (isset($options['P'])) {
85
        $community = '';
86
        $snmpver = 'v2c';
87
        $additional = [
88
            'snmp_disable' => 1,
89
            'os'           => $argv[2] ? $argv[2] : 'ping',
90
            'hardware'     => $argv[3] ? $argv[3] : '',
91
        ];
92
    } elseif ($snmpver === 'v3') {
93
        $seclevel = $community;
94
95
        // These values are the same as in defaults.inc.php
96
        $v3 = [
97
            'authlevel'  => 'noAuthNoPriv',
98
            'authname'   => 'root',
99
            'authpass'   => '',
100
            'authalgo'   => 'MD5',
101
            'cryptopass' => '',
102
            'cryptoalgo' => 'AES',
103
        ];
104
105
        // v3
106
        if ($seclevel === 'nanp' or $seclevel === 'any' or $seclevel === 'noAuthNoPriv') {
107
            $v3['authlevel'] = 'noAuthNoPriv';
108
            $v3args = array_slice($argv, 4);
109
110
            while ($arg = array_shift($v3args)) {
111
                // parse all remaining args
112
                if (is_numeric($arg)) {
113
                    $port = $arg;
114
                } elseif (preg_match('/^(' . $transports_regex . ')$/', $arg)) {
115
                    $transport = $arg;
116
                } else {
117
                    // should add a sanity check of chars allowed in user
118
                    $user = $arg;
119
                }
120
            }
121
122
            if ($seclevel === 'nanp') {
123
                $v3_config = Config::get('snmp.v3');
124
                array_unshift($v3_config, $v3);
0 ignored issues
show
It seems like $v3_config can also be of type null; however, parameter $array of array_unshift() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

124
                array_unshift(/** @scrutinizer ignore-type */ $v3_config, $v3);
Loading history...
125
                Config::set('snmp.v3', $v3_config);
126
            }
127
        } elseif ($seclevel === 'anp' or $seclevel === 'authNoPriv') {
128
            $v3['authlevel'] = 'authNoPriv';
129
            $v3args = array_slice($argv, 4);
130
            $v3['authname'] = array_shift($v3args);
131
            $v3['authpass'] = array_shift($v3args);
132
133
            while ($arg = array_shift($v3args)) {
134
                // parse all remaining args
135
                if (is_numeric($arg)) {
136
                    $port = $arg;
137
                } elseif (preg_match('/^(' . $transports_regex . ')$/i', $arg)) {
138
                    $transport = $arg;
139
                } elseif (preg_match('/^(sha|md5)$/i', $arg)) {
140
                    $v3['authalgo'] = $arg;
141
                } else {
142
                    echo 'Invalid argument: ' . $arg . "\n";
143
                    exit(1);
144
                }
145
            }
146
147
            $v3_config = Config::get('snmp.v3');
148
            array_unshift($v3_config, $v3);
149
            Config::set('snmp.v3', $v3_config);
150
        } elseif ($seclevel === 'ap' or $seclevel === 'authPriv') {
151
            $v3['authlevel'] = 'authPriv';
152
            $v3args = array_slice($argv, 4);
153
            $v3['authname'] = array_shift($v3args);
154
            $v3['authpass'] = array_shift($v3args);
155
            $v3['cryptopass'] = array_shift($v3args);
156
157
            while ($arg = array_shift($v3args)) {
158
                // parse all remaining args
159
                if (is_numeric($arg)) {
160
                    $port = $arg;
161
                } elseif (preg_match('/^(' . $transports_regex . ')$/i', $arg)) {
162
                    $transport = $arg;
163
                } elseif (preg_match('/^(sha|md5)$/i', $arg)) {
164
                    $v3['authalgo'] = $arg;
165
                } elseif (preg_match('/^(aes|des)$/i', $arg)) {
166
                    $v3['cryptoalgo'] = $arg;
167
                } else {
168
                    echo 'Invalid argument: ' . $arg . "\n";
169
                    exit(1);
170
                }
171
            }//end while
172
173
            $v3_config = Config::get('snmp.v3');
174
            array_unshift($v3_config, $v3);
175
            Config::set('snmp.v3', $v3_config);
176
        }
177
    } else {
178
        // v2c or v1
179
        $v2args = array_slice($argv, 2);
180
181
        while ($arg = array_shift($v2args)) {
182
            // parse all remaining args
183
            if (is_numeric($arg)) {
184
                $port = $arg;
185
            } elseif (preg_match('/(' . $transports_regex . ')/i', $arg)) {
186
                $transport = $arg;
187
            } elseif (preg_match('/^(v1|v2c)$/i', $arg)) {
188
                $snmpver = $arg;
189
            }
190
        }
191
192
        if ($community) {
193
            $comm_config = Config::get('snmp.community');
194
            array_unshift($comm_config, $community);
195
            Config::set('snmp.community', $comm_config);
196
        }
197
    }//end if
198
199
    try {
200
        $device_id = addHost($host, $snmpver, $port, $transport, $poller_group, $force_add, $port_assoc_mode, $additional);
201
        $device = device_by_id_cache($device_id);
202
        echo "Added device {$device['hostname']} ($device_id)\n";
203
        exit(0);
204
    } catch (HostUnreachableException $e) {
205
        print_error($e->getMessage());
206
        foreach ($e->getReasons() as $reason) {
207
            echo "  $reason\n";
208
        }
209
        exit(2);
210
    } catch (Exception $e) {
211
        print_error($e->getMessage());
212
        exit(3);
213
    }
214
} else {
215
    c_echo(
216
        "\n" . Config::get('project_name') . ' Add Host Tool
217
218
    Usage (SNMPv1/2c)    : ./addhost.php [-g <poller group>] [-f] [-b] [-p <port assoc mode>] <%Whostname or IP%n> [community] [v1|v2c] [port] [' . $transports_regex . ']
219
    Usage (SNMPv3)       :
220
        Config Defaults  : ./addhost.php [-g <poller group>] [-f] [-b] [-p <port assoc mode>] <%Whostname or IP%n> any v3 [user] [port] [' . $transports_regex . ']
221
        No Auth, No Priv : ./addhost.php [-g <poller group>] [-f] [-b] [-p <port assoc mode>] <%Whostname or IP%n> nanp v3 [user] [port] [' . $transports_regex . ']
222
        Auth, No Priv    : ./addhost.php [-g <poller group>] [-f] [-b] [-p <port assoc mode>] <%Whostname or IP%n> anp v3 <user> <password> [md5|sha] [port] [' . $transports_regex . ']
223
        Auth,    Priv    : ./addhost.php [-g <poller group>] [-f] [-b] [-p <port assoc mode>] <%Whostname or IP%n> ap v3 <user> <password> <enckey> [md5|sha] [aes|des] [port] [' . $transports_regex . ']
224
    Usage (ICMP only)    : ./addhost.php [-g <poller group>] [-f] -P <%Whostname or IP%n> [os] [hardware]
225
226
    -g <poller group> allows you to add a device to be pinned to a specific poller when using distributed polling. X can be any number associated with a poller group
227
    -f forces the device to be added by skipping the icmp and snmp check against the host.
228
    -p <port assoc mode> allow you to set a port association mode for this device. By default ports are associated by \'ifIndex\'.
229
        For Linux/Unix based devices \'ifName\' or \'ifDescr\' might be useful for a stable iface mapping.
230
        The default for this installation is \'' . Config::get('default_port_association_mode') . '\'
231
        Valid port assoc modes are: ' . join(', ', $valid_assoc_modes) . '
232
    -b Add the host with SNMP if it replies to it, otherwise only ICMP.
233
    -P Add the host with only ICMP, no SNMP or OS discovery.
234
235
    %rRemember to run discovery for the host afterwards.%n
236
'
237
    );
238
    exit(1);
239
}
240