Project

General

Profile

Download (5.36 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * autoconfigbackup.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2008-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2022 Rubicon Communications, LLC (Netgate)
9
 * All rights reserved.
10
 *
11
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14
 *
15
 * http://www.apache.org/licenses/LICENSE-2.0
16
 *
17
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22
 */
23

    
24
 /*
25
  * This file is called by CRON every few minutes to upload ACB backups to the server.
26
  * This allows the GUI to remain responsive. Backup files are deleted after upload.
27
  */
28
 
29
require_once("filter.inc");
30
require_once("notices.inc");
31

    
32
$lockfile = "/tmp/acb.lock";
33
// Check for 
34
if (file_exists($lockfile)) {
35
    if (time()-filemtime($lockfile) > (60 * 60)) {
36
        // The lock file is more than an hour old. Something probably went wrong
37
        unlink_if_exists($lockfile);
38
        log_error("Stale ACB lock file removed");
39
    } else {
40
       exit();
41
    }
42
}
43

    
44
touch($lockfile);
45

    
46
// Location of backup file pairs
47
$acbuploadpath = $g['acbbackuppath'];
48
// systems we do not allow
49
$badreasons = array("snort", "pfblocker", "minicron", "merged in config");
50
// List any ACB file pairs that have been created
51
$files = glob($acbuploadpath . '*.form');
52

    
53
if (count($files) > 0) {
54
    // Sort them, oldest first
55
    usort($files, function($a, $b) {
56
        return filemtime($a) - filemtime($b);
57
    });
58

    
59
    // Upload them to the server
60
    foreach ($files as $file) {
61
        $basename = basename($file, ".form");
62
        upload($basename);
63
    }
64
}
65

    
66
unlink_if_exists($lockfile);
67

    
68
function upload($basename) {
69
    global $acbuploadpath, $badreasons;
70

    
71
    $upload_url = "https://acb.netgate.com/save";
72

    
73
    if (!is_url_hostname_resolvable($upload_url)) {
74
	$data = " Unable to resolve " . parse_url($upload_url, PHP_URL_HOST) . " ";
75
	acb_error_log($upload_url, $data);
76
	unlink_if_exists($acbuploadpath . $basename . ".data");
77
	unlink_if_exists($acbuploadpath . $basename . ".form");
78
	return;
79
    }
80

    
81
    // Retrieve the data to send
82
    // Retrieve the form data
83
    $formdata = file_get_contents($acbuploadpath . $basename . ".form");
84
    $post_fields = json_decode($formdata, true);
85
    // Add the backup data file
86
    $post_fields['file'] = curl_file_create($acbuploadpath . $basename . ".data", 'image/jpg', 'config.jpg');
87

    
88
    // Ensure there are no backups from systems we do not allow
89
    foreach ($badreasons as $term) {
90
        if (strpos(strtolower($post_fields['reason']), $term) !== false) {
91
            log_error("Skipping ACB backup for " . strtolower($post_fields['reason']) . '.');
92
            unlink_if_exists($acbuploadpath . $basename . ".data");
93
            unlink_if_exists($acbuploadpath . $basename . ".form");
94
            return;
95
        }
96
    }
97

    
98
    // Check configuration into the ESF repo (Copied from /etc/inc/acb.inc)
99
    $curl_session = curl_init();
100

    
101
    curl_setopt($curl_session, CURLOPT_URL, $upload_url);
102
    curl_setopt($curl_session, CURLOPT_POST, count($post_fields));
103
    curl_setopt($curl_session, CURLOPT_POSTFIELDS, $post_fields);
104
    curl_setopt($curl_session, CURLOPT_RETURNTRANSFER, 1);
105
    curl_setopt($curl_session, CURLOPT_SSL_VERIFYPEER, 1);
106
    curl_setopt($curl_session, CURLOPT_CONNECTTIMEOUT, 55);
107
    curl_setopt($curl_session, CURLOPT_TIMEOUT, 30);
108
    curl_setopt($curl_session, CURLOPT_USERAGENT, $g['product_label'] . '/' . rtrim(file_get_contents("/etc/version")));
109
    // Proxy
110
    set_curlproxy($curl_session);
111

    
112
    $data = curl_exec($curl_session);
113
    $httpcode = curl_getinfo($curl_session, CURLINFO_RESPONSE_CODE);
114

    
115
    if (curl_errno($curl_session)) {
116
        $fd = fopen("/tmp/backupdebug.txt", "w");
117
        $acb_curl_error = curl_error($curl_session);
118
        fwrite($fd, $upload_url . "" . $fields_string . "\n\n");
119
        fwrite($fd, $data);
120
        fwrite($fd, $acb_curl_error);
121
        fclose($fd);
122
    } else {
123
        curl_close($curl_session);
124
    }
125

    
126
    // Delete the backup files, whether it worked or not
127
    unlink_if_exists($acbuploadpath . $basename . ".data");
128
    unlink_if_exists($acbuploadpath . $basename . ".form");
129

    
130
    if (strpos(strval($httpcode), '20') === false) {
131
	if (empty($data) && $acb_curl_error) {
132
		$data = $acb_curl_error;
133
	} else {
134
		$data = "Unknown error";
135
	}
136
	acb_error_log($upload_url, $data);
137
    } else {
138
        // Update last pfS backup time
139
        $fd = fopen("/cf/conf/lastpfSbackup.txt", "w");
140
        fwrite($fd, $config['revision']['time']);
141
        fclose($fd);
142
        $notice_text = "End of configuration backup to " . $upload_url . " (success).";
143
        log_error($notice_text);
144
        update_filter_reload_status($notice_text);
145
    }
146
}
147

    
148
function acb_error_log($upload_url, $data) {
149
        $notice_text = sprintf(gettext(
150
            "An error occurred while uploading the encrypted %s configuration to "), $g['product_label']) .
151
            $upload_url . " (" . htmlspecialchars($data) . ")";
152
        log_error($notice_text . " - " . $data);
153
        file_notice("AutoConfigBackup", $notice_text);
154
        update_filter_reload_status($notice_text);
155
}
(1-1/37)