File.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <?php
  2. /**
  3. * PHPIDS
  4. *
  5. * Requirements: PHP5, SimpleXML
  6. *
  7. * Copyright (c) 2008 PHPIDS group (http://php-ids.org)
  8. *
  9. * PHPIDS is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation, version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * PHPIDS is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with PHPIDS. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. * PHP version 5.1.6+
  23. *
  24. * @category Security
  25. * @package PHPIDS
  26. * @author Mario Heiderich <mario.heiderich@gmail.com>
  27. * @author Christian Matthies <ch0012@gmail.com>
  28. * @author Lars Strojny <lars@strojny.net>
  29. * @license http://www.gnu.org/licenses/lgpl.html LGPL
  30. * @link http://php-ids.org/
  31. */
  32. require_once 'IDS/Log/Interface.php';
  33. /**
  34. * File logging wrapper
  35. *
  36. * The file wrapper is designed to store data into a flatfile. It implements the
  37. * singleton pattern.
  38. *
  39. * @category Security
  40. * @package PHPIDS
  41. * @author Christian Matthies <ch0012@gmail.com>
  42. * @author Mario Heiderich <mario.heiderich@gmail.com>
  43. * @author Lars Strojny <lars@strojny.net>
  44. * @copyright 2007-2009 The PHPIDS Group
  45. * @license http://www.gnu.org/licenses/lgpl.html LGPL
  46. * @version Release: $Id:File.php 517 2007-09-15 15:04:13Z mario $
  47. * @link http://php-ids.org/
  48. */
  49. class IDS_Log_File implements IDS_Log_Interface
  50. {
  51. /**
  52. * Path to the log file
  53. *
  54. * @var string
  55. */
  56. private $logfile = null;
  57. /**
  58. * Instance container
  59. *
  60. * Due to the singleton pattern this class allows to initiate only one
  61. * instance for each file.
  62. *
  63. * @var array
  64. */
  65. private static $instances = array();
  66. /**
  67. * Holds current remote address
  68. *
  69. * @var string
  70. */
  71. private $ip = 'local/unknown';
  72. /**
  73. * Constructor
  74. *
  75. * @param string $logfile path to the log file
  76. *
  77. * @return void
  78. */
  79. protected function __construct($logfile)
  80. {
  81. // determine correct IP address
  82. if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  83. $this->ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  84. } else {
  85. $this->ip = $_SERVER['REMOTE_ADDR'];
  86. }
  87. $this->logfile = $logfile;
  88. }
  89. /**
  90. * Returns an instance of this class
  91. *
  92. * This method allows the passed argument to be either an instance of
  93. * IDS_Init or a path to a log file. Due to the singleton pattern only one
  94. * instance for each file can be initiated.
  95. *
  96. * @param mixed $config IDS_Init or path to a file
  97. * @param string $classname the class name to use
  98. *
  99. * @return object $this
  100. */
  101. public static function getInstance($config, $classname = 'IDS_Log_File')
  102. {
  103. if ($config instanceof IDS_Init) {
  104. $logfile = $config->getBasePath() . $config->config['Logging']['path'];
  105. } elseif (is_string($config)) {
  106. $logfile = $config;
  107. }
  108. if (!isset(self::$instances[$logfile])) {
  109. self::$instances[$logfile] = new $classname($logfile);
  110. }
  111. return self::$instances[$logfile];
  112. }
  113. /**
  114. * Permitting to clone this object
  115. *
  116. * For the sake of correctness of a singleton pattern, this is necessary
  117. *
  118. * @return void
  119. */
  120. private function __clone()
  121. {
  122. }
  123. /**
  124. * Prepares data
  125. *
  126. * Converts given data into a format that can be stored into a file.
  127. * You might edit this method to your requirements.
  128. *
  129. * @param mixed $data incoming report data
  130. *
  131. * @return string
  132. */
  133. protected function prepareData($data)
  134. {
  135. $format = '"%s",%s,%d,"%s","%s","%s","%s"';
  136. $attackedParameters = '';
  137. foreach ($data as $event) {
  138. $attackedParameters .= $event->getName() . '=' .
  139. rawurlencode($event->getValue()) . ' ';
  140. }
  141. $dataString = sprintf($format,
  142. $this->ip,
  143. date('c'),
  144. $data->getImpact(),
  145. join(' ', $data->getTags()),
  146. trim($attackedParameters),
  147. urlencode($_SERVER['REQUEST_URI']),
  148. $_SERVER['SERVER_ADDR']);
  149. return $dataString;
  150. }
  151. /**
  152. * Stores given data into a file
  153. *
  154. * @param object $data IDS_Report
  155. *
  156. * @throws Exception if the logfile isn't writeable
  157. * @return boolean
  158. */
  159. public function execute(IDS_Report $data)
  160. {
  161. /*
  162. * In case the data has been modified before it might be necessary
  163. * to convert it to string since we can't store array or object
  164. * into a file
  165. */
  166. $data = $this->prepareData($data);
  167. if (is_string($data)) {
  168. if (file_exists($this->logfile)) {
  169. $data = trim($data);
  170. if (!empty($data)) {
  171. if (is_writable($this->logfile)) {
  172. $handle = fopen($this->logfile, 'a');
  173. fwrite($handle, trim($data) . "\n");
  174. fclose($handle);
  175. } else {
  176. throw new Exception(
  177. 'Please make sure that ' . $this->logfile .
  178. ' is writeable.'
  179. );
  180. }
  181. }
  182. } else {
  183. throw new Exception(
  184. 'Given file does not exist. Please make sure the
  185. logfile is present in the given directory.'
  186. );
  187. }
  188. } else {
  189. throw new Exception(
  190. 'Please make sure that data returned by
  191. IDS_Log_File::prepareData() is a string.'
  192. );
  193. }
  194. return true;
  195. }
  196. }
  197. /**
  198. * Local variables:
  199. * tab-width: 4
  200. * c-basic-offset: 4
  201. * End:
  202. * vim600: sw=4 ts=4 expandtab
  203. */