Project

General

Profile

Download (11.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/****h* pfSense/notices
3
 * NAME
4
 *   notices.inc - pfSense notice utilities
5
 * DESCRIPTION
6
 *   This include contains the pfSense notice facilities.
7
 * HISTORY
8
 *   $Id$
9
 ******
10
 *
11
 * Copyright (C) 2009 Scott Ullrich (sullrich@gmail.com)
12
 * Copyright (C) 2005 Colin Smith (ethethlay@gmail.com)
13
 * All rights reserved.
14
 * Redistribution and use in source and binary forms, with or without
15
 * modification, are permitted provided that the following conditions are met:
16
 *
17
 * 1. Redistributions of source code must retain the above copyright notice,
18
 * this list of conditions and the following disclaimer.
19
 *
20
 * 2. Redistributions in binary form must reproduce the above copyright
21
 * notice, this list of conditions and the following disclaimer in the
22
 * documentation and/or other materials provided with the distribution.
23
 *
24
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
 * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
 * POSSIBILITY OF SUCH DAMAGE.
34
 *
35
 */
36

    
37
/*
38
	pfSense_BUILDER_BINARIES:	/bin/echo
39
	pfSense_MODULE:	notifications
40
*/
41

    
42
require_once("globals.inc");
43
require_once("led.inc");
44

    
45
$notice_path = $g['tmp_path'] . '/notices';
46
$smtp_authentication_mechanisms = array(
47
	'PLAIN' => 'PLAIN',
48
	'LOGIN' => 'LOGIN');
49
/* Other SMTP Authentication Mechanisms that could be supported.
50
 * Note that MD5 is no longer considered secure.
51
 *	'GSSAPI' => 'GSSAPI ' . gettext("Generic Security Services Application Program Interface")
52
 *	'DIGEST-MD5' => 'DIGEST-MD5 ' . gettext("Digest access authentication")
53
 *	'MD5' => 'MD5'
54
 *	'CRAM-MD5' => 'CRAM-MD5'
55
*/
56

    
57
/****f* notices/file_notice
58
 * NAME
59
 *   file_notice
60
 * INPUTS
61
 *	 $id, $notice, $category, $url, $priority
62
 * RESULT
63
 *   Files a notice and kicks off the various alerts, smtp, growl, system log, LED's, etc.
64
 ******/
65
function file_notice($id, $notice, $category = "General", $url = "", $priority = 1) {
66
	/*
67
	 * $category - Category that this notice should be displayed under. This can be arbitrary,
68
	 * 	       but a page must be set to receive this messages for it to be displayed.
69
	 *
70
	 * $priority - A notice's priority. Higher numbers indicate greater severity.
71
	 *	       0 = informational, 1 = warning, 2 = error, etc. This may also be arbitrary,
72
	 */
73
	global $notice_path;
74
	if(!$queue = get_notices()) $queue = array();
75
	$queuekey = time();
76
	$toqueue = array(
77
				'id'		=> $id,
78
				'notice'	=> $notice,
79
				'url'		=> $url,
80
				'category'	=> $category,
81
				'priority'	=> $priority,
82
			);
83
	$queue[$queuekey] = $toqueue;
84
	$queueout = fopen($notice_path, "w");
85
	if(!$queueout) {
86
		log_error(printf(gettext("Could not open %s for writing"), $notice_path));
87
		return;
88
	}
89
	fwrite($queueout, serialize($queue));
90
	fclose($queueout);
91
	log_error("New alert found: $notice");
92
	/* soekris */
93
	if(file_exists("/dev/led/error"))
94
		exec("/bin/echo 1 > /dev/led/error");
95
	/* wrap & alix */
96
	led_normalize();
97
	led_morse(1, 'sos');
98
	notify_via_growl($notice);
99
	notify_via_smtp($notice);
100
	return $queuekey;
101
}
102

    
103
/****f* notices/get_notices
104
 * NAME
105
 *   get_notices
106
 * INPUTS
107
 *	 $category
108
 * RESULT
109
 *   Returns a specific notices text
110
 ******/
111
function get_notices($category = "all") {
112
	global $g;
113

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

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

    
176
	return;
177
}
178

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

    
203
/****f* notices/print_notices
204
 * NAME
205
 *   print_notices
206
 * INPUTS
207
 *	 $notices, $category
208
 * RESULT
209
 *   prints notices to the GUI
210
 ******/
211
function print_notices($notices, $category = "all") {
212
	foreach($notices as $notice) {
213
		if($category != "all") {
214
			if(in_array($notice['category'], $category)) $categories[] = $notice['category'];
215
		} else {
216
			$categories[] = $notice['category'];
217
		}
218
	}
219
	$categories = array_unique($categories);
220
	sort($categories);
221
	foreach($categories as $category) {
222
		$toreturn .= "<ul><li>{$category}<ul>";
223
		foreach($notices as $notice) {
224
			if(strtolower($notice['category']) == strtolower($category)) {
225
				if($notice['id'] != "") {
226
					if($notice['url'] != "") {
227
						$toreturn .= "<li><a href={$notice['url']}>{$notice['id']}</a> - {$notice['notice']}</li>";
228
					} else {
229
						$toreturn .= "<li>{$notice['id']} - {$notice['notice']}</li>";
230
					}
231
				}
232
			}
233
		}
234
		$toreturn .= "</ul></li></ul>";
235
	}
236
	return $toreturn;
237
}
238

    
239
/****f* notices/print_notice_box
240
 * NAME
241
 *   print_notice_box
242
 * INPUTS
243
 *	 $category
244
 * RESULT
245
 *   prints an info box to the GUI
246
 ******/
247
function print_notice_box($category = "all") {
248
	$notices = get_notices();
249
	if(!$notices) return;
250
	print_info_box_np(print_notices($notices, $category));
251
	return;
252
}
253

    
254
/****f* notices/are_notices_pending
255
 * NAME
256
 *   are_notices_pending
257
 * INPUTS
258
 *	 $category to check
259
 * RESULT
260
 *   returns true if notices are pending, false if they are not
261
 ******/
262
function are_notices_pending($category = "all") {
263
	global $notice_path;
264
	if(file_exists($notice_path)) {
265
		return true;
266
	}
267
	return false;
268
}
269

    
270
/****f* notices/notify_via_smtp
271
 * NAME
272
 *   notify_via_smtp
273
 * INPUTS
274
 *	 notification string to send as an email
275
 * RESULT
276
 *   returns true if message was sent
277
 ******/
278
function notify_via_smtp($message, $force = false) {
279
	global $config, $g;
280
	if(platform_booting())
281
		return;
282

    
283
	if(isset($config['notifications']['smtp']['disable']) && !$force)
284
		return;
285

    
286
	/* Do NOT send the same message twice */
287
	if(file_exists("/var/db/notices_lastmsg.txt")) {
288
		$lastmsg = trim(file_get_contents("/var/db/notices_lastmsg.txt"));
289
		if($lastmsg == $message)
290
			return;
291
	}
292

    
293
	/* Store last message sent to avoid spamming */
294
	$fd = fopen("/var/db/notices_lastmsg.txt", "w");
295
	fwrite($fd, $message);
296
	fclose($fd);
297

    
298
	send_smtp_message($message, "{$config['system']['hostname']}.{$config['system']['domain']} - Notification", $force);
299
	return;
300
}
301

    
302
function send_smtp_message($message, $subject = "(no subject)", $force = false) {
303
	global $config, $g;
304
	require_once("sasl.inc");
305
	require_once("smtp.inc");
306

    
307
	if(isset($config['notifications']['smtp']['disable']) && !$force)
308
		return;
309

    
310
	if(!$config['notifications']['smtp']['ipaddress'])
311
		return;
312

    
313
	if(!$config['notifications']['smtp']['notifyemailaddress'])
314
		return;
315

    
316
	$smtp = new smtp_class;
317

    
318
	$from = "pfsense@{$config['system']['hostname']}.{$config['system']['domain']}";
319
	$to = $config['notifications']['smtp']['notifyemailaddress'];
320

    
321
	$smtp->host_name = $config['notifications']['smtp']['ipaddress'];
322
	$smtp->host_port = empty($config['notifications']['smtp']['port']) ? 25 : $config['notifications']['smtp']['port'];
323

    
324
	$smtp->direct_delivery = 0;
325
	$smtp->ssl = (isset($config['notifications']['smtp']['ssl'])) ? 1 : 0;
326
	$smtp->tls = (isset($config['notifications']['smtp']['tls'])) ? 1 : 0;
327
	$smtp->debug = 0;
328
	$smtp->html_debug = 0;
329
	$smtp->localhost=$config['system']['hostname'].".".$config['system']['domain'];
330
	
331
	if($config['notifications']['smtp']['fromaddress'])
332
		$from = $config['notifications']['smtp']['fromaddress'];
333
	
334
	// Use SMTP Auth if fields are filled out
335
	if($config['notifications']['smtp']['username'] && 
336
	   $config['notifications']['smtp']['password']) {
337
		if (isset($config['notifications']['smtp']['authentication_mechanism'])) {
338
			$smtp->authentication_mechanism = $config['notifications']['smtp']['authentication_mechanism'];
339
		} else {
340
			$smtp->authentication_mechanism = "PLAIN";
341
		}
342
		$smtp->user = $config['notifications']['smtp']['username'];
343
		$smtp->password = $config['notifications']['smtp']['password'];
344
	}
345

    
346
	$headers = array(
347
		"From: {$from}",
348
		"To: {$to}",
349
		"Subject: {$subject}",
350
		"Date: ".date("r")
351
	);
352

    
353
	if($smtp->SendMessage($from, preg_split('/\s*,\s*/', trim($to)), $headers, $message)) {
354
		log_error(sprintf(gettext("Message sent to %s OK"), $to));
355
		return;
356
	} else {
357
		log_error(sprintf(gettext('Could not send the message to %1$s -- Error: %2$s'), $to, $smtp->error));
358
		return(sprintf(gettext('Could not send the message to %1$s -- Error: %2$s'), $to, $smtp->error));
359
	}
360
}
361

    
362
/****f* notices/notify_via_growl
363
 * NAME
364
 *   notify_via_growl
365
 * INPUTS
366
 *	 notification string to send
367
 * RESULT
368
 *   returns true if message was sent
369
 ******/
370
function notify_via_growl($message, $force=false) {
371
	require_once("growl.class");
372
	global $config,$g;
373

    
374
	if (isset($config['notifications']['growl']['disable']) && !$force)
375
		return;
376

    
377
	/* Do NOT send the same message twice */
378
	if(file_exists("/var/db/growlnotices_lastmsg.txt")) {
379
		$lastmsg = trim(file_get_contents("/var/db/growlnotices_lastmsg.txt"));
380
		if($lastmsg == $message)
381
			return;
382
	}
383

    
384
	$hostname = $config['system']['hostname'] . "." . $config['system']['domain'];
385
	$growl_ip = $config['notifications']['growl']['ipaddress'];
386
	$growl_password = $config['notifications']['growl']['password'];
387
	$growl_name = $config['notifications']['growl']['name'];
388
	$growl_notification = $config['notifications']['growl']['notification_name'];
389
	
390
	if(!empty($growl_ip)) {
391
		$growl = new Growl($growl_ip, $growl_password, $growl_name);
392
		$growl->notify("{$growl_notification}", gettext(sprintf("%s (%s) - Notification", $g['product_name'], $hostname)), "{$message}");
393
	}
394

    
395
	/* Store last message sent to avoid spamming */
396
	$fd = fopen("/var/db/growlnotices_lastmsg.txt", "w");
397
	fwrite($fd, $message);
398
	fclose($fd);
399
}
400

    
401
/****f* notices/register_via_growl
402
 * NAME
403
 *   register_via_growl
404
 * INPUTS
405
 *	 none
406
 * RESULT
407
 *   none
408
 ******/
409
function register_via_growl() {
410
	require_once("growl.class");
411
	global $config;
412
	$growl_ip = $config['notifications']['growl']['ipaddress'];
413
	$growl_password = $config['notifications']['growl']['password'];
414
	$growl_name = $config['notifications']['growl']['name'];
415
	$growl_notification = $config['notifications']['growl']['notification_name'];
416
	
417
	if($growl_ip) {
418
	  $growl = new Growl($growl_ip, $growl_password, $growl_name);
419
		$growl->addNotification($growl_notification);
420
		$growl->register();
421
	}
422
}
423

    
424
/* Notify via remote methods only - not via GUI. */
425
function notify_all_remote($msg) {
426
	notify_via_smtp($msg);
427
	notify_via_growl($msg);
428
}
429

    
430
?>
(34-34/68)