Project

General

Profile

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

    
25
require_once("globals.inc");
26
require_once("functions.inc");
27
require_once("led.inc");
28

    
29
$notice_path = $g['tmp_path'] . '/notices';
30
global $smtp_authentication_mechanisms;
31
$smtp_authentication_mechanisms = array(
32
	'PLAIN' => 'PLAIN',
33
	'LOGIN' => 'LOGIN');
34
/* Other SMTP Authentication Mechanisms that could be supported.
35
 * Note that MD5 is no longer considered secure.
36
 *	'GSSAPI' => 'GSSAPI ' . gettext("Generic Security Services Application Program Interface")
37
 *	'DIGEST-MD5' => 'DIGEST-MD5 ' . gettext("Digest access authentication")
38
 *	'MD5' => 'MD5'
39
 *	'CRAM-MD5' => 'CRAM-MD5'
40
*/
41

    
42
/****f* notices/file_notice
43
 * NAME
44
 *   file_notice
45
 * INPUTS
46
 *	 $id, $notice, $category, $url, $priority, $local_only
47
 * RESULT
48
 *   Files a notice and kicks off the various alerts, smtp, system log, LED's, etc.
49
 *   If $local_only is true then the notice is not sent to external places (smtp)
50
 ******/
51
function file_notice($id, $notice, $category = "General", $url = "", $priority = 1, $local_only = false) {
52
	/*
53
	 * $category - Category that this notice should be displayed under. This can be arbitrary,
54
	 * 	       but a page must be set to receive this messages for it to be displayed.
55
	 *
56
	 * $priority - A notice's priority. Higher numbers indicate greater severity.
57
	 *	       0 = informational, 1 = warning, 2 = error, etc. This may also be arbitrary,
58
	 */
59
	global $notice_path;
60
	if (!$queue = get_notices()) {
61
		$queue = array();
62
	}
63
	$queuekey = time();
64
	$toqueue = array(
65
				'id'		=> htmlentities($id),
66
				'notice'	=> htmlentities($notice),
67
				'url'		=> htmlentities($url),
68
				'category'	=> htmlentities($category),
69
				'priority'	=> htmlentities($priority),
70
			);
71
	while (isset($queue[$queuekey])) {
72
		$queuekey++;
73
	}
74
	$queue[$queuekey] = $toqueue;
75
	$queueout = fopen($notice_path, "w");
76
	if (!$queueout) {
77
		log_error(sprintf(gettext("Could not open %s for writing"), $notice_path));
78
		return;
79
	}
80
	fwrite($queueout, serialize($queue));
81
	fclose($queueout);
82
	log_error(sprintf(gettext("New alert found: %s"), $notice));
83
	/* soekris */
84
	if (file_exists("/dev/led/error")) {
85
		exec("/bin/echo 1 > /dev/led/error");
86
	}
87
	/* wrap & alix */
88
	led_normalize();
89
	led_morse(1, 'sos');
90
	if (!$local_only) {
91
		notify_all_remote($notice);
92
	}
93
	return $queuekey;
94
}
95

    
96
/****f* notices/get_notices
97
 * NAME
98
 *   get_notices
99
 * INPUTS
100
 *	 $category
101
 * RESULT
102
 *   Returns a specific notices text
103
 ******/
104
function get_notices($category = "all") {
105
	global $g;
106

    
107
	if (file_exists("{$g['tmp_path']}/notices")) {
108
		$queue = unserialize(file_get_contents("{$g['tmp_path']}/notices"));
109
		if (!$queue) {
110
			return false;
111
		}
112
		if ($category != 'all') {
113
			foreach ($queue as $time => $notice) {
114
				if (strtolower($notice['category']) == strtolower($category)) {
115
					$toreturn[$time] = $notice;
116
				}
117
			}
118
			return $toreturn;
119
		} else {
120
			return $queue;
121
		}
122
	} else {
123
		return false;
124
	}
125
}
126

    
127
/****f* notices/close_notice
128
 * NAME
129
 *   close_notice
130
 * INPUTS
131
 *	 $id
132
 * RESULT
133
 *   Removes a notice from the list
134
 ******/
135
function close_notice($id) {
136
	global $notice_path;
137
	require_once("util.inc");
138
	/* soekris */
139
	if (file_exists("/dev/led/error")) {
140
		exec("/bin/echo 0 > /dev/led/error");
141
	}
142
	/* wrap & alix */
143
	led_normalize();
144
	$ids = array();
145
	if (!$notices = get_notices()) {
146
		return;
147
	}
148
	if ($id == "all") {
149
		unlink_if_exists($notice_path);
150
		return;
151
	}
152
	foreach (array_keys($notices) as $time) {
153
		if ($id == $time) {
154
			unset($notices[$id]);
155
			break;
156
		}
157
	}
158
	foreach ($notices as $key => $notice) {
159
		$ids[$key] = $notice['id'];
160
	}
161
	foreach ($ids as $time => $tocheck) {
162
		if ($id == $tocheck) {
163
			unset($notices[$time]);
164
			break;
165
		}
166
	}
167
	if (count($notices) != 0) {
168
		$queueout = fopen($notice_path, "w");
169
		fwrite($queueout, serialize($notices));
170
		fclose($queueout);
171
	} else {
172
		unlink_if_exists($notice_path);
173
	}
174

    
175
	return;
176
}
177

    
178
/****f* notices/dump_xml_notices
179
 * NAME
180
 *   dump_xml_notices
181
 * INPUTS
182
 *	 NONE
183
 * RESULT
184
 *   Outputs notices in XML formatted text
185
 ******/
186
function dump_xml_notices() {
187
	if (file_exists("/cf/conf/use_xmlreader")) {
188
		require_once("xmlreader.inc");
189
	} else {
190
		require_once("xmlparse.inc");
191
	}
192
	global $notice_path, $listtags;
193
	$listtags[] = 'notice';
194
	if (!$notices = get_notices()) {
195
		return;
196
	}
197
	foreach ($notices as $time => $notice) {
198
		$notice['time'] = $time;
199
		$toput['notice'][] = $notice;
200
	}
201
	$xml = dump_xml_config($toput, 'notices');
202
	return $xml;
203
}
204

    
205
/****f* notices/are_notices_pending
206
 * NAME
207
 *   are_notices_pending
208
 * INPUTS
209
 *	 $category to check
210
 * RESULT
211
 *   returns true if notices are pending, false if they are not
212
 ******/
213
function are_notices_pending($category = "all") {
214
	global $notice_path;
215
	if (file_exists($notice_path)) {
216
		return true;
217
	}
218
	return false;
219
}
220

    
221
function notices_sendqueue() {
222
	global $g;
223
	$nothing_done_count = 0;
224
	$messagequeue = array();
225

    
226
	while(true) {
227
		$notifyqueue_lck = lock("notifyqueue", LOCK_EX);
228
		$nothing_done_count++;
229
		$smptcount = 0;
230
		$messages = array();
231
		if (file_exists("{$g['vardb_path']}/notifyqueue.messages")) {
232
			$messages = unserialize(file_get_contents("{$g['vardb_path']}/notifyqueue.messages"));
233
			$messagequeue = $messages;
234
			$messages['mails']['item'] = array(); // clear all items to be send
235
			file_put_contents("{$g['vardb_path']}/notifyqueue.messages", serialize($messages));
236
			unset($messages);
237
		}
238
		// clear lock before trying to send messages, so new one's can be added
239
		unlock($notifyqueue_lck);
240

    
241
		if (is_array($messagequeue['mails']['item'])) {
242
			$smtpmessage = "";
243
			foreach($messagequeue['mails']['item'] as $mail) {
244
				switch ($mail['type']) {
245
					case 'mail':
246
						$smptcount++;
247
						$smtpmessage .= "\r\n" . date("G:i:s",$mail['time']) . " " . $mail['msg'];
248
						break;
249
					default:
250
						break;
251
				}
252
			}
253
			if (!empty($smtpmessage)) {
254
				$smtpmessageheader = sprintf(gettext("Notifications in this message: %s"), $smptcount);
255
				$smtpmessageheader .= "\n" . str_repeat('=', strlen($smtpmessageheader)) . "\n";
256
				$nothing_done_count = 0;
257
				notify_via_smtp($smtpmessageheader . $smtpmessage, true);
258
			}
259
		}
260
		if ($nothing_done_count > 6) {
261
			break;
262
		} else {
263
			sleep(10);
264
		}
265
	}
266
}
267

    
268
function notify_via_queue_add($message, $type='mail') {
269
	global $g;
270
	$mail = array();
271
	$mail['time'] = time();
272
	$mail['type'] = $type;
273
	$mail['msg'] = $message;
274
	$notifyqueue_lck = lock("notifyqueue", LOCK_EX);
275
	$messages = array();
276
	if (file_exists("{$g['vardb_path']}/notifyqueue.messages")) {
277
		$messages = unserialize(file_get_contents("{$g['vardb_path']}/notifyqueue.messages"));
278
	}
279
	if(is_array($messages)) {
280
		$messages['mails']['item'][] = $mail;
281
		file_put_contents("{$g['vardb_path']}/notifyqueue.messages", serialize($messages));
282
	}
283
	unset($messages);
284

    
285
	mwexec_bg('/usr/local/bin/notify_monitor.php');
286
	unlock($notifyqueue_lck);
287
}
288

    
289
/****f* notices/notify_via_smtp
290
 * NAME
291
 *   notify_via_smtp
292
 * INPUTS
293
 *	 notification string to send as an email
294
 * RESULT
295
 *   returns true if message was sent
296
 ******/
297
function notify_via_smtp($message, $force = false) {
298
	global $config, $g;
299
	if (platform_booting()) {
300
		return;
301
	}
302

    
303
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
304
		return;
305
	}
306

    
307
	/* Do NOT send the same message twice, except if $force is true */
308
	if (!$force && file_exists("/var/db/notices_lastmsg.txt")) {
309
		$lastmsg = trim(file_get_contents("/var/db/notices_lastmsg.txt"));
310
		if ($lastmsg == $message) {
311
			return;
312
		}
313
	}
314

    
315
	/* Store last message sent to avoid spamming */
316
	@file_put_contents("/var/db/notices_lastmsg.txt", $message);
317
	if (!$force) {
318
		notify_via_queue_add($message, 'mail');
319
		$ret = true;
320
	} else {
321
		$ret = send_smtp_message($message, "{$config['system']['hostname']}.{$config['system']['domain']} - Notification", $force);
322
	}
323

    
324
	return $ret;
325
}
326

    
327
function send_smtp_message($message, $subject = "(no subject)", $force = false) {
328
	global $config, $g;
329
	require_once("Mail.php");
330

    
331
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
332
		return;
333
	}
334

    
335
	if (!$config['notifications']['smtp']['ipaddress']) {
336
		return;
337
	}
338

    
339
	if (!$config['notifications']['smtp']['notifyemailaddress']) {
340
		return;
341
	}
342

    
343
	$to = $config['notifications']['smtp']['notifyemailaddress'];
344

    
345
	if (empty($config['notifications']['smtp']['username']) ||
346
	    empty($config['notifications']['smtp']['password'])) {
347
		$auth = false;
348
		$username = '';
349
		$password = '';
350
	} else {
351
		$auth = isset($config['notifications']['smtp']['authentication_mechanism'])
352
		    ? $config['notifications']['smtp']['authentication_mechanism']
353
		    : 'PLAIN';
354
		$username = $config['notifications']['smtp']['username'];
355
		$password = $config['notifications']['smtp']['password'];
356
	}
357

    
358
	$params = array(
359
		'host' => (isset($config['notifications']['smtp']['ssl'])
360
		    ? 'ssl://'
361
		    : '')
362
		    . $config['notifications']['smtp']['ipaddress'],
363
		'port' => empty($config['notifications']['smtp']['port'])
364
		    ? 25
365
		    : $config['notifications']['smtp']['port'],
366
		'auth' => $auth,
367
		'username' => $username,
368
		'password' => $password,
369
		'localhost' => $config['system']['hostname'] . "." .
370
		    $config['system']['domain'],
371
		'timeout' => !empty($config['notifications']['smtp']['timeout'])
372
		    ? $config['notifications']['smtp']['timeout']
373
		    : 20,
374
		'debug' => false,
375
		'persist' => false
376
	);
377

    
378
	if ($config['notifications']['smtp']['sslvalidate'] == "disabled") {
379
		$params['socket_options'] = array('ssl' => array('verify_peer_name' => false));
380
	}
381

    
382
	if ($config['notifications']['smtp']['fromaddress']) {
383
		$from = $config['notifications']['smtp']['fromaddress'];
384
	} else {
385
		$from = "pfsense@{$config['system']['hostname']}.{$config['system']['domain']}";
386
	}
387

    
388
	$headers = array(
389
		"From"    => $from,
390
		"To"      => $to,
391
		"Subject" => $subject,
392
		"Date"    => date("r")
393
	);
394

    
395
	$smtp =& Mail::factory('smtp', $params);
396
	$mail = $smtp->send($to, $headers, $message);
397

    
398
	if (PEAR::isError($mail)) {
399
		$err_msg = sprintf(gettext(
400
		    'Could not send the message to %1$s -- Error: %2$s'),
401
		    $to, $mail->getMessage());
402
		log_error($err_msg);
403
		return($err_msg);
404
	}
405

    
406
	log_error(sprintf(gettext("Message sent to %s OK"), $to));
407
	return;
408
}
409

    
410
/* Notify via remote methods only - not via GUI. */
411
function notify_all_remote($msg) {
412
	notify_via_smtp($msg);
413
}
414

    
415
?>
(30-30/60)