Project

General

Profile

Download (13.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-2016 Electric Sheep Fencing, LLC.
8
	All rights reserved.
9

    
10
	Redistribution and use in source and binary forms, with or without
11
	modification, are permitted provided that the following conditions are met:
12

    
13
	1. Redistributions of source code must retain the above copyright notice,
14
	   this list of conditions and the following disclaimer.
15

    
16
	2. Redistributions in binary form must reproduce the above copyright
17
	   notice, this list of conditions and the following disclaimer in
18
	   the documentation and/or other materials provided with the
19
	   distribution.
20

    
21
	3. All advertising materials mentioning features or use of this software
22
	   must display the following acknowledgment:
23
	   "This product includes software developed by the pfSense Project
24
	   for use in the pfSense® software distribution. (http://www.pfsense.org/).
25

    
26
	4. The names "pfSense" and "pfSense Project" must not be used to
27
	   endorse or promote products derived from this software without
28
	   prior written permission. For written permission, please contact
29
	   coreteam@pfsense.org.
30

    
31
	5. Products derived from this software may not be called "pfSense"
32
	   nor may "pfSense" appear in their names without prior written
33
	   permission of the Electric Sheep Fencing, LLC.
34

    
35
	6. Redistributions of any form whatsoever must retain the following
36
	   acknowledgment:
37

    
38
	"This product includes software developed by the pfSense Project
39
	for use in the pfSense software distribution (http://www.pfsense.org/).
40

    
41
	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
42
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44
	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
45
	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52
	OF THE POSSIBILITY OF SUCH DAMAGE.
53
 */
54

    
55
require_once("globals.inc");
56
require_once("led.inc");
57

    
58
$notice_path = $g['tmp_path'] . '/notices';
59
$smtp_authentication_mechanisms = array(
60
	'PLAIN' => 'PLAIN',
61
	'LOGIN' => 'LOGIN');
62
/* Other SMTP Authentication Mechanisms that could be supported.
63
 * Note that MD5 is no longer considered secure.
64
 *	'GSSAPI' => 'GSSAPI ' . gettext("Generic Security Services Application Program Interface")
65
 *	'DIGEST-MD5' => 'DIGEST-MD5 ' . gettext("Digest access authentication")
66
 *	'MD5' => 'MD5'
67
 *	'CRAM-MD5' => 'CRAM-MD5'
68
*/
69

    
70
/****f* notices/file_notice
71
 * NAME
72
 *   file_notice
73
 * INPUTS
74
 *	 $id, $notice, $category, $url, $priority, $local_only
75
 * RESULT
76
 *   Files a notice and kicks off the various alerts, smtp, growl, system log, LED's, etc.
77
 *   If $local_only is true then the notice is not sent to external places (smtp, growl)
78
 ******/
79
function file_notice($id, $notice, $category = "General", $url = "", $priority = 1, $local_only = false) {
80
	/*
81
	 * $category - Category that this notice should be displayed under. This can be arbitrary,
82
	 * 	       but a page must be set to receive this messages for it to be displayed.
83
	 *
84
	 * $priority - A notice's priority. Higher numbers indicate greater severity.
85
	 *	       0 = informational, 1 = warning, 2 = error, etc. This may also be arbitrary,
86
	 */
87
	global $notice_path;
88
	if (!$queue = get_notices()) {
89
		$queue = array();
90
	}
91
	$queuekey = time();
92
	$toqueue = array(
93
				'id'		=> htmlentities($id),
94
				'notice'	=> htmlentities($notice),
95
				'url'		=> htmlentities($url),
96
				'category'	=> htmlentities($category),
97
				'priority'	=> htmlentities($priority),
98
			);
99
	while (isset($queue[$queuekey])) {
100
		$queuekey++;
101
	}
102
	$queue[$queuekey] = $toqueue;
103
	$queueout = fopen($notice_path, "w");
104
	if (!$queueout) {
105
		log_error(sprintf(gettext("Could not open %s for writing"), $notice_path));
106
		return;
107
	}
108
	fwrite($queueout, serialize($queue));
109
	fclose($queueout);
110
	log_error(sprintf(gettext("New alert found: %s"), $notice));
111
	/* soekris */
112
	if (file_exists("/dev/led/error")) {
113
		exec("/bin/echo 1 > /dev/led/error");
114
	}
115
	/* wrap & alix */
116
	led_normalize();
117
	led_morse(1, 'sos');
118
	if (!$local_only) {
119
		notify_via_growl($notice);
120
		notify_via_smtp($notice);
121
	}
122
	return $queuekey;
123
}
124

    
125
/****f* notices/get_notices
126
 * NAME
127
 *   get_notices
128
 * INPUTS
129
 *	 $category
130
 * RESULT
131
 *   Returns a specific notices text
132
 ******/
133
function get_notices($category = "all") {
134
	global $g;
135

    
136
	if (file_exists("{$g['tmp_path']}/notices")) {
137
		$queue = unserialize(file_get_contents("{$g['tmp_path']}/notices"));
138
		if (!$queue) {
139
			return false;
140
		}
141
		if ($category != 'all') {
142
			foreach ($queue as $time => $notice) {
143
				if (strtolower($notice['category']) == strtolower($category)) {
144
					$toreturn[$time] = $notice;
145
				}
146
			}
147
			return $toreturn;
148
		} else {
149
			return $queue;
150
		}
151
	} else {
152
		return false;
153
	}
154
}
155

    
156
/****f* notices/close_notice
157
 * NAME
158
 *   close_notice
159
 * INPUTS
160
 *	 $id
161
 * RESULT
162
 *   Removes a notice from the list
163
 ******/
164
function close_notice($id) {
165
	global $notice_path;
166
	require_once("util.inc");
167
	/* soekris */
168
	if (file_exists("/dev/led/error")) {
169
		exec("/bin/echo 0 > /dev/led/error");
170
	}
171
	/* wrap & alix */
172
	led_normalize();
173
	$ids = array();
174
	if (!$notices = get_notices()) {
175
		return;
176
	}
177
	if ($id == "all") {
178
		unlink_if_exists($notice_path);
179
		return;
180
	}
181
	foreach (array_keys($notices) as $time) {
182
		if ($id == $time) {
183
			unset($notices[$id]);
184
			break;
185
		}
186
	}
187
	foreach ($notices as $key => $notice) {
188
		$ids[$key] = $notice['id'];
189
	}
190
	foreach ($ids as $time => $tocheck) {
191
		if ($id == $tocheck) {
192
			unset($notices[$time]);
193
			break;
194
		}
195
	}
196
	if (count($notices) != 0) {
197
		$queueout = fopen($notice_path, "w");
198
		fwrite($queueout, serialize($notices));
199
		fclose($queueout);
200
	} else {
201
		unlink_if_exists($notice_path);
202
	}
203

    
204
	return;
205
}
206

    
207
/****f* notices/dump_xml_notices
208
 * NAME
209
 *   dump_xml_notices
210
 * INPUTS
211
 *	 NONE
212
 * RESULT
213
 *   Outputs notices in XML formatted text
214
 ******/
215
function dump_xml_notices() {
216
	if (file_exists("/cf/conf/use_xmlreader")) {
217
		require_once("xmlreader.inc");
218
	} else {
219
		require_once("xmlparse.inc");
220
	}
221
	global $notice_path, $listtags;
222
	$listtags[] = 'notice';
223
	if (!$notices = get_notices()) {
224
		return;
225
	}
226
	foreach ($notices as $time => $notice) {
227
		$notice['time'] = $time;
228
		$toput['notice'][] = $notice;
229
	}
230
	$xml = dump_xml_config($toput, 'notices');
231
	return $xml;
232
}
233

    
234
/****f* notices/print_notices
235
 * NAME
236
 *   print_notices
237
 * INPUTS
238
 *	 $notices, $category
239
 * RESULT
240
 *   prints notices to the GUI
241
 ******/
242
function print_notices($notices, $category = "all") {
243
	foreach ($notices as $notice) {
244
		if ($category != "all") {
245
			if (in_array($notice['category'], $category)) {
246
				$categories[] = $notice['category'];
247
			}
248
		} else {
249
			$categories[] = $notice['category'];
250
		}
251
	}
252
	$categories = array_unique($categories);
253
	sort($categories);
254
	foreach ($categories as $category) {
255
		$toreturn .= "<ul><li>{$category}<ul>";
256
		foreach ($notices as $notice) {
257
			if (strtolower($notice['category']) == strtolower($category)) {
258
				if ($notice['id'] != "") {
259
					if ($notice['url'] != "") {
260
						$toreturn .= "<li><a href={$notice['url']}>{$notice['id']}</a> - {$notice['notice']}</li>";
261
					} else {
262
						$toreturn .= "<li>{$notice['id']} - {$notice['notice']}</li>";
263
					}
264
				}
265
			}
266
		}
267
		$toreturn .= "</ul></li></ul>";
268
	}
269
	return $toreturn;
270
}
271

    
272
/****f* notices/print_notice_box
273
 * NAME
274
 *   print_notice_box
275
 * INPUTS
276
 *	 $category
277
 * RESULT
278
 *   prints an info box to the GUI
279
 ******/
280
function print_notice_box($category = "all") {
281
	$notices = get_notices();
282
	if (!$notices) {
283
		return;
284
	}
285
	print_info_box(print_notices($notices, $category));
286
	return;
287
}
288

    
289
/****f* notices/are_notices_pending
290
 * NAME
291
 *   are_notices_pending
292
 * INPUTS
293
 *	 $category to check
294
 * RESULT
295
 *   returns true if notices are pending, false if they are not
296
 ******/
297
function are_notices_pending($category = "all") {
298
	global $notice_path;
299
	if (file_exists($notice_path)) {
300
		return true;
301
	}
302
	return false;
303
}
304

    
305
/****f* notices/notify_via_smtp
306
 * NAME
307
 *   notify_via_smtp
308
 * INPUTS
309
 *	 notification string to send as an email
310
 * RESULT
311
 *   returns true if message was sent
312
 ******/
313
function notify_via_smtp($message, $force = false) {
314
	global $config, $g;
315
	if (platform_booting()) {
316
		return;
317
	}
318

    
319
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
320
		return;
321
	}
322

    
323
	/* Do NOT send the same message twice, except if $force is true */
324
	if (!$force && file_exists("/var/db/notices_lastmsg.txt")) {
325
		$lastmsg = trim(file_get_contents("/var/db/notices_lastmsg.txt"));
326
		if ($lastmsg == $message) {
327
			return;
328
		}
329
	}
330

    
331
	/* Store last message sent to avoid spamming */
332
	$fd = fopen("/var/db/notices_lastmsg.txt", "w");
333
	fwrite($fd, $message);
334
	fclose($fd);
335

    
336
	send_smtp_message($message, "{$config['system']['hostname']}.{$config['system']['domain']} - Notification", $force);
337
	return;
338
}
339

    
340
function send_smtp_message($message, $subject = "(no subject)", $force = false) {
341
	global $config, $g;
342
	require_once("sasl.inc");
343
	require_once("smtp.inc");
344

    
345
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
346
		return;
347
	}
348

    
349
	if (!$config['notifications']['smtp']['ipaddress']) {
350
		return;
351
	}
352

    
353
	if (!$config['notifications']['smtp']['notifyemailaddress']) {
354
		return;
355
	}
356

    
357
	$smtp = new smtp_class;
358

    
359
	$from = "pfsense@{$config['system']['hostname']}.{$config['system']['domain']}";
360
	$to = $config['notifications']['smtp']['notifyemailaddress'];
361

    
362
	$smtp->host_name = $config['notifications']['smtp']['ipaddress'];
363
	$smtp->host_port = empty($config['notifications']['smtp']['port']) ? 25 : $config['notifications']['smtp']['port'];
364

    
365
	$smtp->direct_delivery = 0;
366
	$smtp->ssl = (isset($config['notifications']['smtp']['ssl'])) ? 1 : 0;
367
	$smtp->start_tls = (isset($config['notifications']['smtp']['tls'])) ? 1 : 0;
368
	$smtp->debug = 0;
369
	$smtp->html_debug = 0;
370
	$smtp->localhost = $config['system']['hostname'] . "." . $config['system']['domain'];
371

    
372
	if ($config['notifications']['smtp']['fromaddress']) {
373
		$from = $config['notifications']['smtp']['fromaddress'];
374
	}
375

    
376
	// Use SMTP Auth if fields are filled out
377
	if ($config['notifications']['smtp']['username'] &&
378
	    $config['notifications']['smtp']['password']) {
379
		if (isset($config['notifications']['smtp']['authentication_mechanism'])) {
380
			$smtp->authentication_mechanism = $config['notifications']['smtp']['authentication_mechanism'];
381
		} else {
382
			$smtp->authentication_mechanism = "PLAIN";
383
		}
384
		$smtp->user = $config['notifications']['smtp']['username'];
385
		$smtp->password = $config['notifications']['smtp']['password'];
386
	}
387

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

    
395
	if ($smtp->SendMessage($from, preg_split('/\s*,\s*/', trim($to)), $headers, $message)) {
396
		log_error(sprintf(gettext("Message sent to %s OK"), $to));
397
		return;
398
	} else {
399
		log_error(sprintf(gettext('Could not send the message to %1$s -- Error: %2$s'), $to, $smtp->error));
400
		return(sprintf(gettext('Could not send the message to %1$s -- Error: %2$s'), $to, $smtp->error));
401
	}
402
}
403

    
404
/****f* notices/notify_via_growl
405
 * NAME
406
 *   notify_via_growl
407
 * INPUTS
408
 *	 notification string to send
409
 * RESULT
410
 *   returns true if message was sent
411
 ******/
412
function notify_via_growl($message, $force=false) {
413
	require_once("growl.class");
414
	global $config, $g;
415

    
416
	if (isset($config['notifications']['growl']['disable']) && !$force) {
417
		return;
418
	}
419

    
420
	/* Do NOT send the same message twice */
421
	if (file_exists("/var/db/growlnotices_lastmsg.txt")) {
422
		$lastmsg = trim(file_get_contents("/var/db/growlnotices_lastmsg.txt"));
423
		if ($lastmsg == $message) {
424
			return;
425
		}
426
	}
427

    
428
	$hostname = $config['system']['hostname'] . "." . $config['system']['domain'];
429
	$growl_ip = $config['notifications']['growl']['ipaddress'];
430
	$growl_password = $config['notifications']['growl']['password'];
431
	$growl_name = $config['notifications']['growl']['name'];
432
	$growl_notification = $config['notifications']['growl']['notification_name'];
433

    
434
	if (!empty($growl_ip)) {
435
		if (is_ipaddr($growl_ip) || dns_check_record($growl_ip, A) || dns_check_record($growl_ip, AAAA)) {
436
			$growl = new Growl($growl_ip, $growl_password, $growl_name);
437
			$growl->notify("{$growl_notification}", gettext(sprintf("%s (%s) - Notification", $g['product_name'], $hostname)), "{$message}");
438
		} else {
439
			// file_notice to local only to prevent file_notice from calling back to growl in a loop
440
			file_notice("growl", gettext("Growl IP Address is invalid. Check the setting in System Advanced Notifications."), "General", "", 1, true);
441
		}
442
	}
443

    
444
	/* Store last message sent to avoid spamming */
445
	$fd = fopen("/var/db/growlnotices_lastmsg.txt", "w");
446
	fwrite($fd, $message);
447
	fclose($fd);
448
}
449

    
450
/****f* notices/register_via_growl
451
 * NAME
452
 *   register_via_growl
453
 * INPUTS
454
 *	 none
455
 * RESULT
456
 *   none
457
 ******/
458
function register_via_growl() {
459
	require_once("growl.class");
460
	global $config;
461
	$growl_ip = $config['notifications']['growl']['ipaddress'];
462
	$growl_password = $config['notifications']['growl']['password'];
463
	$growl_name = $config['notifications']['growl']['name'];
464
	$growl_notification = $config['notifications']['growl']['notification_name'];
465

    
466
	if (!empty($growl_ip)) {
467
		if (is_ipaddr($growl_ip) || dns_check_record($growl_ip, A) || dns_check_record($growl_ip, AAAA)) {
468
			$growl = new Growl($growl_ip, $growl_password, $growl_name);
469
			$growl->addNotification($growl_notification);
470
			$growl->register();
471
		} else {
472
			// file_notice to local only to prevent file_notice from calling back to growl in a loop
473
			file_notice("growl", gettext("Growl IP Address is invalid. Check the setting in System Advanced Notifications."), "General", "", 1, true);
474
		}
475
	}
476
}
477

    
478
/* Notify via remote methods only - not via GUI. */
479
function notify_all_remote($msg) {
480
	notify_via_smtp($msg);
481
	notify_via_growl($msg);
482
}
483

    
484
?>
(33-33/65)