legacy.inc 8.4 KB
Newer Older
1
<?php
Franco Fichtner's avatar
Franco Fichtner committed
2

3
/*
Ad Schellevis's avatar
Ad Schellevis committed
4
    Copyright (C) 2015-2016 Deciso B.V.
5
    Copyright (C) 2004-2010 Scott Ullrich
Ad Schellevis's avatar
Ad Schellevis committed
6 7
    Copyright (C) 2005 Colin Smith
    All rights reserved.
8

Ad Schellevis's avatar
Ad Schellevis committed
9 10
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
11

Ad Schellevis's avatar
Ad Schellevis committed
12 13
    1. Redistributions of source code must retain the above copyright notice,
       this list of conditions and the following disclaimer.
14

Ad Schellevis's avatar
Ad Schellevis committed
15 16 17
    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.
18

Ad Schellevis's avatar
Ad Schellevis committed
19 20 21 22 23 24 25 26 27 28
    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.
29 30 31 32 33 34
*/

/**
 * request functions which may be registered by the xmlrpc system
 * @return array
 */
Ad Schellevis's avatar
Ad Schellevis committed
35
function xmlrpc_publishable_legacy()
36
{
37
    $publish = array('filter_configure_xmlrpc','restore_config_section_xmlrpc','firmware_version_xmlrpc');
38

39
    return $publish;
40 41
}

42 43 44 45 46
/*
 * does_vip_exist($vip): return true or false if a vip is
 * configured.
 */
function does_vip_exist($vip) {
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    global $config;

    if(!$vip) {
        return false;
    }

    switch ($vip['mode']) {
        case "carp":
        case "ipalias":
            /* XXX: Make proper checks? */
            $realif = get_real_interface($vip['interface']);
            if (!does_interface_exist($realif)) {
                return false;
            }
            break;
        case "proxyarp":
            /* XXX: Implement this */
        default:
            return false;
    }

68
    $ifacedata = legacy_getall_interface_addresses($realif);
69 70 71 72 73 74 75
    foreach ($ifacedata as $vipips) {
        if ($vipips == "{$vip['subnet']}/{$vip['subnet_bits']}") {
            return true;
        }
    }

    return false;
76 77
}

78
/**
79
 * merge attributes from source array to destination
80
 * updates leaves and overwrites sequenced arrays (container types).
81 82
 * @param array $cnf_source source data
 * @param array $cnf_dest target
83
 */
84
function merge_config_attributes(&$cnf_source, &$cnf_dest)
85
{
86 87
   foreach ($cnf_source as $cnf_key => &$cnf_value) {
       if (is_array($cnf_value)) {
88 89 90 91
           if (!isset($cnf_dest[$cnf_key]) || !is_array($cnf_dest[$cnf_key]) || // new
                (count($cnf_dest[$cnf_key]) > 0 && isset($cnf_dest[$cnf_key][0])) || // sequenced item
                (count($cnf_dest[$cnf_key]) > 0 && isset($cnf_dest[$cnf_key]['@attributes']['uuid'])) // mvc array
                ) {
92
               // (re)set destination array when new or containing a sequenced list of items
93 94 95 96 97 98 99
               $cnf_dest[$cnf_key] = array();
           }
           merge_config_attributes($cnf_value, $cnf_dest[$cnf_key]);
       } else {
           $cnf_dest[$cnf_key] = $cnf_value;
       }
   }
100 101 102 103
}

/**
 * retrieve firmware version
104
 * @return array
105 106 107
 */
function firmware_version_xmlrpc()
{
108
    global $config;
109

110 111 112 113 114 115 116
    return array(
      'kernel' => array('version' => file_get_contents('/usr/local/opnsense/version/opnsense-update.kernel')),
      'base' => array('version' => file_get_contents('/usr/local/opnsense/version/opnsense-update.base')),
      'firmware' => array('version' => file_get_contents('/usr/local/opnsense/version/opnsense')),
      'config_version' => $config['version'],
    );
}
117 118 119 120 121 122 123

/**
 * filter reconfigure
 * @return mixed
 */
function filter_configure_xmlrpc()
{
124
    global $config;
Franco Fichtner's avatar
Franco Fichtner committed
125

126
    require_once("filter.inc");
Ad Schellevis's avatar
Ad Schellevis committed
127
    require_once("system.inc");
Franco Fichtner's avatar
Franco Fichtner committed
128
    require_once("util.inc");
129
    require_once("interfaces.inc");
130 131
    require_once("openvpn.inc");
    require_once("services.inc");
132
    require_once("rrd.inc");
133 134 135 136

    filter_configure();
    system_routing_configure();
    setup_gateways_monitor();
137
    system_hosts_generate();
138
    local_sync_accounts();
139
    dnsmasq_configure_do();
Franco Fichtner's avatar
Franco Fichtner committed
140
    unbound_configure_do();
141 142
    services_dhcpd_configure();
    openvpn_resync_all();
143

144
    plugins_configure('remote');
145

146 147 148
    return true;
}

149 150 151 152 153 154 155 156
/**
 * restore config section
 * @param $new_config
 * @return bool
 */
function restore_config_section_xmlrpc($new_config)
{
    global $config;
157

158
    require_once("interfaces.inc");
159
    require_once("filter.inc");
160
    require_once("ipsec.inc");
161

162
    // save old config
163 164
    $old_config = $config;

165 166 167 168
    // Some sections should just be copied and not merged, namely if there's a risk of attributes being removed
    // without being seen by the remote remote (backup) side.
    // (ipsec, openvpn, nat can probably moved out later by specifying a better path to the attribute)
    $sync_full = array('ipsec', 'wol', 'dnsmasq', 'load_balancer', 'openvpn', 'nat', 'dhcpd', 'dhcpv6');
169 170 171 172 173 174 175 176 177 178 179
    $sync_full_done = array();
    foreach ($sync_full as $syncfull) {
        if (isset($new_config[$syncfull])) {
            $config[$syncfull] = $new_config[$syncfull];
            unset($new_config[$syncfull]);
            $sync_full_done[] = $syncfull;
        }
    }

    $vipbackup = array();
    $oldvips = array();
180
    if (isset($new_config['virtualip']['vip']) && isset($config['virtualip']['vip'])) {
181 182
        foreach ($config['virtualip']['vip'] as $vipindex => $vip) {
            if ($vip['mode'] == "carp") {
183 184 185
                // rc.filter_synchronize only sends carp vips, keep the rest like it was
                $oldvips["{$vip['interface']}_vip{$vip['vhid']}"] = $vip ;
            } else {
186
                $vipbackup[] = $vip;
187 188 189 190
            }
        }
    }

191 192
    // merge config attributes.
    merge_config_attributes($new_config, $config);
193

194
    if (count($vipbackup) > 0) {
195
        // if $new_config contained VIPS and the old config contained non carp vips, prepend original vips
196 197 198 199 200 201 202
        foreach ($vipbackup as $vip) {
            array_unshift($config['virtualip']['vip'], $vip);
        }
    }

    /* Log what happened */
    $mergedkeys = implode(",", array_merge(array_keys($new_config), $sync_full_done));
203
    write_config(sprintf('Merged %s config sections from XMLRPC client.', $mergedkeys));
204 205

    /*
206
     * Handle virtual ips
207
     */
208
    if (isset($new_config['virtualip']['vip'])) {
209 210
        $carp_setuped = false;
        $anyproxyarp = false;
211 212 213
        if (isset($config['virtualip']['vip'])) {
          foreach ($config['virtualip']['vip'] as $vip) {
              if ($vip['mode'] == "carp" && isset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"])) {
214 215 216 217 218
                  $is_changed = false;
                  foreach (array('password', 'advskew', 'subnet', 'subnet_bits', 'advbase') as $chk_key) {
                      if ($oldvips["{$vip['interface']}_vip{$vip['vhid']}"][$chk_key] != $vip[$chk_key]) {
                          $is_changed = true;
                          break;
219 220
                      }
                  }
221 222
                  if (!$is_changed) {
                      unset($oldvips["{$vip['interface']}_vip{$vip['vhid']}"]);
223 224 225 226 227 228 229 230 231 232 233 234 235 236
                      if (does_vip_exist($vip)) {
                          continue; // Skip reconfiguring this vips since nothing has changed.
                      }
                  }
              }

              switch ($vip['mode']) {
                  case "proxyarp":
                      $anyproxyarp = true;
                      break;
                  case "ipalias":
                      interface_ipalias_configure($vip);
                      break;
                  case "carp":
237
                      $carp_setuped = true;
238 239 240 241
                      interface_carp_configure($vip);
                      break;
              }
          }
242
        }
243 244 245 246 247 248

        // remove old (carp) virtual ip's
        foreach ($oldvips as $oldvip) {
            interface_vip_bring_down($oldvip);
        }

249 250 251 252 253 254 255 256 257 258 259
        if ($carp_setuped) {
            interfaces_carp_setup();
        }

        if ($anyproxyarp) {
            interface_proxyarp_configure();
        }

    }

    if (isset($old_config['ipsec']['enable']) !== isset($config['ipsec']['enable'])) {
260
        ipsec_configure();
261 262 263 264 265 266
    }

    unset($old_config);

    return true;
}