Project

General

Profile

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

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

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

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

    
201
	return;
202
}
203

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

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

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

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

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

    
316
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
317
		return;
318
	}
319

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

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

    
333
	send_smtp_message($message, "{$config['system']['hostname']}.{$config['system']['domain']} - Notification", $force);
334
	return;
335
}
336

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

    
342
	if (isset($config['notifications']['smtp']['disable']) && !$force) {
343
		return;
344
	}
345

    
346
	if (!$config['notifications']['smtp']['ipaddress']) {
347
		return;
348
	}
349

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

    
354
	$smtp = new smtp_class;
355

    
356
	$from = "pfsense@{$config['system']['hostname']}.{$config['system']['domain']}";
357
	$to = $config['notifications']['smtp']['notifyemailaddress'];
358

    
359
	$smtp->host_name = $config['notifications']['smtp']['ipaddress'];
360
	$smtp->host_port = empty($config['notifications']['smtp']['port']) ? 25 : $config['notifications']['smtp']['port'];
361

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

    
369
	if ($config['notifications']['smtp']['fromaddress']) {
370
		$from = $config['notifications']['smtp']['fromaddress'];
371
	}
372

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

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

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

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

    
413
	if (isset($config['notifications']['growl']['disable']) && !$force) {
414
		return;
415
	}
416

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

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

    
431
	if (!empty($growl_ip) && (is_ipaddr($growl_ip) || dns_get_record($growl_ip, DNS_A) || dns_get_record($growl_ip, DNS_AAAA))) {
432
		$growl = new Growl($growl_ip, $growl_password, $growl_name);
433
		$growl->notify("{$growl_notification}", gettext(sprintf("%s (%s) - Notification", $g['product_name'], $hostname)), "{$message}");
434
	}
435

    
436
	/* Store last message sent to avoid spamming */
437
	$fd = fopen("/var/db/growlnotices_lastmsg.txt", "w");
438
	fwrite($fd, $message);
439
	fclose($fd);
440
}
441

    
442
/****f* notices/register_via_growl
443
 * NAME
444
 *   register_via_growl
445
 * INPUTS
446
 *	 none
447
 * RESULT
448
 *   none
449
 ******/
450
function register_via_growl() {
451
	require_once("growl.class");
452
	global $config;
453
	$growl_ip = $config['notifications']['growl']['ipaddress'];
454
	$growl_password = $config['notifications']['growl']['password'];
455
	$growl_name = $config['notifications']['growl']['name'];
456
	$growl_notification = $config['notifications']['growl']['notification_name'];
457

    
458
	if ($growl_ip) {
459
		$growl = new Growl($growl_ip, $growl_password, $growl_name);
460
		$growl->addNotification($growl_notification);
461
		$growl->register();
462
	}
463
}
464

    
465
/* Notify via remote methods only - not via GUI. */
466
function notify_all_remote($msg) {
467
	notify_via_smtp($msg);
468
	notify_via_growl($msg);
469
}
470

    
471
?>
(33-33/65)