falon /
RBL
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | ini_set('error_log', 'syslog'); |
||
| 4 | |||
| 5 | function username() { |
||
| 6 | if (isset ($_SERVER['REMOTE_USER'])) $user = $_SERVER['REMOTE_USER']; |
||
| 7 | else if (isset ($_SERVER['USER'])) $user = $_SERVER['USER']; |
||
| 8 | else $user='unknown'; |
||
| 9 | return $user; |
||
| 10 | } |
||
| 11 | |||
| 12 | function checkSSL() { |
||
| 13 | if ( empty( $_SERVER['HTTPS'] ) ) |
||
| 14 | printf ('<div id="content">Ehi sysadmin! Your site is not secure. Please enable SSL on your server and configure a redirect, such as' . |
||
| 15 | '<pre>' . |
||
| 16 | htmlspecialchars('<VirtualHost *:80>' . "\n" . |
||
| 17 | ' ServerName %s' . "\n" . |
||
| 18 | ' Redirect permanent / https://%s/' . "\n" . |
||
| 19 | '</VirtualHost>') . |
||
| 20 | '</pre></div>', gethostname(), gethostname()); |
||
| 21 | } |
||
| 22 | |||
| 23 | function myConnect($host, $user, $pass, $db, $port, $tablelist, $typedesc, $loguser) { |
||
| 24 | $db = ( $tablelist["$typedesc"]['milter'] ) ? $tablelist["$typedesc"]['name'] : $db; |
||
| 25 | $mysqli = new mysqli($host, $user, $pass, $db, $port); |
||
| 26 | if ($mysqli->connect_error) { |
||
| 27 | syslog (LOG_EMERG, $loguser.': Connect Error to DB <'.$db.'> (' . $mysqli->connect_errno . ') ' |
||
| 28 | . $mysqli->connect_error); |
||
| 29 | return FALSE; |
||
| 30 | } |
||
| 31 | syslog(LOG_INFO, $loguser.': Successfully MySQL connected at DB <'.$db.'> to ' . $mysqli->host_info) ; |
||
| 32 | return $mysqli; |
||
| 33 | } |
||
| 34 | |||
| 35 | function addtolist ($myconn,$user,$value,$tabledesc,$expUnit,$expQ,$myreason,&$err) { |
||
| 36 | // See MySQL manual for $expQ and $expUnit at |
||
| 37 | // https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_timestampadd |
||
| 38 | |||
| 39 | $result=FALSE; |
||
| 40 | $sub=array(); |
||
| 41 | $type = $tabledesc['field']; |
||
| 42 | $milt = $tabledesc['milter']; |
||
| 43 | $table = ($milt) ? milterTable($type) : $tabledesc['name']; |
||
| 44 | |||
| 45 | switch ($type) { |
||
| 46 | case 'ip': |
||
| 47 | $query= sprintf("INSERT INTO `$table` ( |
||
| 48 | `$type` , |
||
| 49 | `date` , |
||
| 50 | `exp` , |
||
| 51 | `active` , |
||
| 52 | `user` , |
||
| 53 | `reason` |
||
| 54 | ) |
||
| 55 | VALUES ( |
||
| 56 | INET_ATON( '%s' ) , |
||
| 57 | CURRENT_TIMESTAMP , TIMESTAMPADD(%s,%d,CURRENT_TIMESTAMP), '1', '%s', '%s' |
||
| 58 | )" ,$value,$expUnit,$expQ,$user,$myreason); |
||
| 59 | break; |
||
| 60 | |||
| 61 | case 'network': |
||
| 62 | if (!$milt) { |
||
| 63 | if ( netOverlap($myconn, $tabledesc, $value, $overlappedNet, $user) ) { |
||
| 64 | $err = "<$value> overlaps the existing network <$overlappedNet>"; |
||
| 65 | return FALSE; |
||
| 66 | } |
||
| 67 | } |
||
| 68 | list($sub['net'],$sub['mask'])=explode('/',$value); |
||
| 69 | $query= sprintf("INSERT INTO `$table` ( |
||
| 70 | `$type` , |
||
| 71 | `netmask`, |
||
| 72 | `date` , |
||
| 73 | `exp` , |
||
| 74 | `active` , |
||
| 75 | `user` , |
||
| 76 | `reason` |
||
| 77 | ) |
||
| 78 | VALUES ( |
||
| 79 | INET_ATON( '%s' ) , INET_ATON( '%s' ) , |
||
| 80 | CURRENT_TIMESTAMP , TIMESTAMPADD(%s,%d,CURRENT_TIMESTAMP), '1', '%s', '%s' |
||
| 81 | )" ,$sub['net'],$sub['mask'],$expUnit,$expQ,$user,$myreason); |
||
| 82 | break; |
||
| 83 | |||
| 84 | default: |
||
| 85 | $query= sprintf("INSERT INTO `$table` ( |
||
| 86 | `$type` , |
||
| 87 | `date` , |
||
| 88 | `exp` , |
||
| 89 | `active` , |
||
| 90 | `user` , |
||
| 91 | `reason` |
||
| 92 | ) |
||
| 93 | VALUES ( |
||
| 94 | '%s' , |
||
| 95 | CURRENT_TIMESTAMP , TIMESTAMPADD(%s,%d,CURRENT_TIMESTAMP), '1', '%s', '%s' |
||
| 96 | )" ,$value,$expUnit,$expQ,$user,$myreason); |
||
| 97 | } |
||
| 98 | |||
| 99 | View Code Duplication | if ($myconn->query($query) === TRUE) { |
|
| 100 | syslog(LOG_INFO, "$user: $type <$value> successfully listed on <$table> for $expQ $expUnit."); |
||
| 101 | $result=TRUE; |
||
| 102 | } |
||
| 103 | else syslog(LOG_ERR, "$user: Error: ".$myconn->error); |
||
| 104 | return $result; |
||
| 105 | } |
||
| 106 | |||
| 107 | function relist ($myconn,$user,$value,$type,$table,$expUnit,$expQ,$myreason, $exptime = 0) { |
||
| 108 | |||
| 109 | $result=FALSE; |
||
| 110 | if ( $exptime ) { /* Entry already listed */ |
||
| 111 | $nlist = '`nlist`'; |
||
| 112 | $exptime = sprintf('\'%s\'', $exptime); /* Eh MySQL... an hour lost to notice this */ |
||
| 113 | } |
||
| 114 | else { |
||
| 115 | $exptime = 'CURRENT_TIMESTAMP'; |
||
| 116 | $nlist = '`nlist` + 1'; |
||
| 117 | } |
||
| 118 | |||
| 119 | switch ($type) { |
||
| 120 | View Code Duplication | case 'ip': |
|
|
0 ignored issues
–
show
|
|||
| 121 | $query= sprintf("UPDATE `$table` SET |
||
| 122 | `active` = '1', |
||
| 123 | `user` = '%s', |
||
| 124 | `exp` = TIMESTAMPADD(%s,%d,%s), |
||
| 125 | `nlist` = %s, |
||
| 126 | `reason` = '%s' |
||
| 127 | WHERE `$table`.`$type` = INET_ATON('%s') LIMIT 1" ,$user,$expUnit,$expQ,$exptime,$nlist,$myreason,$value); |
||
| 128 | break; |
||
| 129 | case 'network': |
||
| 130 | list($sub['net'],$sub['mask'])=explode('/',$value); |
||
| 131 | $query= sprintf("UPDATE `$table` SET |
||
| 132 | `active` = '1', |
||
| 133 | `user` = '%s', |
||
| 134 | `exp` = TIMESTAMPADD(%s,%d,%s), |
||
| 135 | `nlist` = %s, |
||
| 136 | `reason` = '%s' |
||
| 137 | WHERE (`$table`.`$type` = INET_ATON('%s') AND `$table`.`netmask` = INET_ATON('%s')) LIMIT 1" ,$user,$expUnit,$expQ,$exptime,$nlist,$myreason,$sub['net'],$sub['mask']); |
||
|
0 ignored issues
–
show
|
|||
| 138 | break; |
||
| 139 | View Code Duplication | default: |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 140 | $query= sprintf("UPDATE `$table` SET |
||
| 141 | `active` = '1', |
||
| 142 | `user` = '%s', |
||
| 143 | `exp` = TIMESTAMPADD(%s,%d,%s), |
||
| 144 | `nlist` = %s, |
||
| 145 | `reason` = '%s' |
||
| 146 | WHERE `$table`.`$type` = '%s' LIMIT 1" ,$user,$expUnit,$expQ,$exptime,$nlist,$myreason,$value); |
||
| 147 | } |
||
| 148 | |||
| 149 | View Code Duplication | if ($myconn->query($query) === TRUE) { |
|
| 150 | syslog(LOG_INFO, "$user: relist $type <$value> on <$table> for $expQ $expUnit from $exptime."); |
||
| 151 | $result=TRUE; |
||
| 152 | } |
||
| 153 | else syslog (LOG_ERR, "$user: Error: ". $myconn->error); |
||
| 154 | return $result; |
||
| 155 | } |
||
| 156 | |||
| 157 | function remove ($myconn,$user,$value,$type,$table) { |
||
| 158 | |||
| 159 | switch ($type) { |
||
| 160 | case 'ip': |
||
| 161 | $query = sprintf("DELETE FROM `$table` WHERE |
||
| 162 | `$table`.`$type` = INET_ATON('%s') LIMIT 1", $value); |
||
| 163 | break; |
||
| 164 | View Code Duplication | case 'network': |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 165 | list($sub['net'],$sub['mask'])=explode('/',$value); |
||
| 166 | $query = sprintf("DELETE FROM `$table` WHERE |
||
| 167 | `$table`.`$type` = INET_ATON('%s') AND `$table`.`netmask` = INET_ATON('%s') LIMIT 1", |
||
| 168 | $sub['net'],$sub['mask']); |
||
|
0 ignored issues
–
show
|
|||
| 169 | break; |
||
| 170 | default: |
||
| 171 | $query = sprintf("DELETE FROM `$table` WHERE |
||
| 172 | `$table`.`$type` = %s LIMIT 1", $value); |
||
| 173 | } |
||
| 174 | |||
| 175 | |||
| 176 | if ($return=$myconn->query($query) === TRUE) |
||
| 177 | syslog(LOG_INFO, "$user: permanently DELETED $type <$value> from <$table>."); |
||
| 178 | else syslog(LOG_ERR, "$user: Error: ". $myconn->error); |
||
| 179 | |||
| 180 | return $return; |
||
| 181 | } |
||
| 182 | |||
| 183 | |||
| 184 | function changestatus ($myconn,$user,$value,$status,$type,$table) { |
||
| 185 | |||
| 186 | switch ($type) { |
||
| 187 | case 'ip': |
||
| 188 | $query= sprintf("UPDATE `$table` SET `active` = '$status', `user` = '%s' WHERE `$table`.`$type` = INET_ATON('%s') LIMIT 1" ,$user, $value); |
||
| 189 | break; |
||
| 190 | View Code Duplication | case 'network': |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 191 | list($sub['net'],$sub['mask'])=explode('/',$value); |
||
| 192 | $query= sprintf("UPDATE `$table` SET `active` = '$status', `user` = '%s' WHERE (`$table`.`$type` = INET_ATON('%s') AND `$table`.`netmask` = INET_ATON('%s')) LIMIT 1" ,$user, $sub['net'],$sub['mask']); |
||
|
0 ignored issues
–
show
|
|||
| 193 | break; |
||
| 194 | default: |
||
| 195 | $query= sprintf("UPDATE `$table` SET `active` = '$status', `user` = '%s' WHERE `$table`.`$type` = '%s' LIMIT 1" ,$user, $value); |
||
| 196 | } |
||
| 197 | |||
| 198 | if ($return=$myconn->query($query) === TRUE) { |
||
| 199 | syslog(LOG_INFO, "$user: change status of $type <$value>. The status is now <$status>"); |
||
| 200 | } |
||
| 201 | else syslog(LOG_ERR, "$user: Error: ". $myconn->error); |
||
| 202 | return $return; |
||
| 203 | } |
||
| 204 | |||
| 205 | |||
| 206 | function expire ($myconn,$user,$tables,$expireTime) { |
||
| 207 | $return=TRUE; |
||
| 208 | $log=array(); |
||
| 209 | $desc = array_keys($tables); |
||
| 210 | foreach ($desc as $tdesc) { |
||
| 211 | /* QUERY */ |
||
| 212 | $query = 'DELETE FROM `'.$tables["$tdesc"]['name']."` WHERE `exp` < DATE_SUB( NOW(), INTERVAL $expireTime YEAR);"; |
||
| 213 | $query .= 'DELETE FROM `'.$tables["$tdesc"]['name']."` WHERE `datemod` < DATE_SUB( NOW(), INTERVAL $expireTime YEAR) AND `active` = 0"; |
||
| 214 | /* END OF QUERY */ |
||
| 215 | $log[0] = 'expired for'; |
||
| 216 | $log[1] = 'disabled for'; |
||
| 217 | if ($myconn->multi_query($query)) { |
||
| 218 | $j = 0; |
||
| 219 | do { |
||
| 220 | $numdel = $myconn->affected_rows; |
||
| 221 | syslog(LOG_INFO, "Expire job - <$user> Permanently DELETED $numdel records ".$log[$j]." $expireTime YEARS from <".$tables["$tdesc"]['name'].'>.'); |
||
| 222 | $j++; |
||
| 223 | |||
| 224 | } while ($myconn->next_result()); |
||
| 225 | } |
||
| 226 | else { |
||
| 227 | syslog(LOG_ERR, "Expire job - Error: ". $myconn->error); |
||
| 228 | $return = FALSE; |
||
| 229 | } |
||
| 230 | } |
||
| 231 | if ( !($return) ) syslog(LOG_EMERG, 'End of Expire job with error. See above logs. SQL Connection terminated'); |
||
| 232 | else syslog(LOG_INFO, 'Successfully End of Expire job. SQL Connection successfully terminated.'); |
||
| 233 | return $return; |
||
| 234 | } |
||
| 235 | |||
| 236 | |||
| 237 | function isListed($row) { |
||
| 238 | |||
| 239 | $exp=new DateTime($row['exp']); |
||
| 240 | $now=new DateTime('NOW'); |
||
| 241 | if (($exp > $now) and ($row['active'])) return true; |
||
| 242 | else return false; |
||
| 243 | |||
| 244 | } |
||
| 245 | |||
| 246 | |||
| 247 | function askMilter($myconn,$id,$obj,$typedesc,$miltId,$value,$user,$adm) { |
||
| 248 | $milts = readMiltName($myconn,$user); |
||
| 249 | $size = count($milts); |
||
| 250 | if (in_array($user,array_keys($adm))) { |
||
| 251 | $button = <<<END |
||
| 252 | <form style="margin:0; display:inline;" name="Milter$id" enctype="text/plain" method="post" target="_self" action="changeMilter.php" onSubmit="xmlhttpPost('changeMilter.php', 'Milter$id', 'id$id', '<img src=\'/include/pleasewait.gif\'>'); return false;" /> |
||
| 253 | <input name="object" type="hidden" value="$obj" /><input name="oldvalues" type="hidden" value="$value" /> |
||
| 254 | <input name="type" type="hidden" value="$typedesc" /> |
||
| 255 | <input name="user" type="hidden" value="$user" /> |
||
| 256 | <input name="miltId" type="hidden" value="$miltId" /> |
||
| 257 | <div class="noscroll"> |
||
| 258 | <select class="input_text" name="newvalues[]" multiple size="$size"> |
||
| 259 | END; |
||
| 260 | $activeMilts = explode(',',$value); |
||
| 261 | foreach ( $milts as $milter ) { |
||
|
0 ignored issues
–
show
The expression
$milts of type false|array is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
Loading history...
|
|||
| 262 | if ( in_array($milter, $activeMilts) ) |
||
| 263 | $selected= 'selected'; |
||
| 264 | else |
||
| 265 | $selected= NULL; |
||
| 266 | $button .= sprintf('<option value="%s" %s>%s</option>', $milter, $selected, $milter); |
||
| 267 | } |
||
| 268 | $button .= '</select></div><input class="button" name="Change" type="submit" value="Change" /></form>'; |
||
| 269 | return $button; |
||
| 270 | } |
||
| 271 | return $value; |
||
| 272 | |||
| 273 | |||
| 274 | } |
||
| 275 | |||
| 276 | |||
| 277 | function ask($myconn,$id,$what,$alltables,$typedesc,$value,$lock,$user,$adm) { |
||
| 278 | |||
| 279 | $whynot=NULL; |
||
| 280 | switch ($what) { |
||
| 281 | case 'Ok': |
||
| 282 | if ($lock) return NULL; |
||
| 283 | if (in_array($user,array_keys($adm))) |
||
| 284 | if ( consistentListing($myconn,$alltables,$typedesc,$value,$whynot) ) return require('relistButton.php'); |
||
| 285 | return htmlspecialchars($whynot); |
||
| 286 | case 'Listed': |
||
| 287 | case 'WhiteListed': |
||
| 288 | return require('delistButton.php'); |
||
| 289 | } |
||
| 290 | } |
||
| 291 | |||
| 292 | |||
| 293 | function consistentListing($myconn,$alltables,$typed,$value,&$warn) { |
||
| 294 | /* Check if there are no pending mislisting */ |
||
| 295 | $warn = NULL; |
||
| 296 | if (! isset($alltables["$typed"]['depend']) ) return TRUE; |
||
| 297 | foreach ($alltables["$typed"]['depend'] as $listdep) { |
||
| 298 | if ($alltables["$typed"]['field'] != $alltables["$listdep"]['field'] ) { |
||
| 299 | $warn = "Config ERROR: <$typed> and <$listdep> are of different types! I can't check consistency!"; |
||
| 300 | return FALSE; |
||
| 301 | } |
||
| 302 | $entry = searchentry($myconn,$value,$alltables["$listdep"]); |
||
| 303 | if ( $entry->num_rows ) { |
||
| 304 | if ( $entry->num_rows == 1 ) { |
||
| 305 | $riga = $entry->fetch_array(MYSQLI_ASSOC); |
||
| 306 | if (isListed($riga)) { |
||
| 307 | $warn = "<$value> is already present in <$listdep> list!"; |
||
| 308 | $entry->free(); |
||
| 309 | return FALSE; |
||
| 310 | } |
||
| 311 | } |
||
| 312 | if ( $entry->num_rows > 1 ) {$warn = "<$value> seems to be present more than once in <$listdep>. Contact a sysadmin NOW!";} |
||
| 313 | } |
||
| 314 | $entry->free(); |
||
| 315 | } |
||
| 316 | |||
| 317 | return TRUE; |
||
| 318 | } |
||
| 319 | |||
| 320 | function searchentry ($myconn,$value,$tablelist) { |
||
| 321 | /* Make a MYSQL query and return result */ |
||
| 322 | |||
| 323 | $type = $tablelist['field']; |
||
| 324 | |||
| 325 | if ( $tablelist['milter'] ) { |
||
| 326 | $table = milterTable($type); |
||
| 327 | if ($value == 'ALL') |
||
| 328 | $query = sprintf('SELECT *, GROUP_CONCAT(milt.name) as miltnames FROM `%s` LEFT JOIN milt ON (%s.idmilt=milt.id) GROUP by idmilt', |
||
| 329 | $table,$table); |
||
| 330 | else { |
||
| 331 | switch ($type) { |
||
| 332 | View Code Duplication | case 'network': |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 333 | list($sub['net'],$sub['mask'])=explode('/',$value); |
||
| 334 | $query = sprintf('SELECT * FROM ( |
||
| 335 | SELECT *, GROUP_CONCAT(milt.name) as miltnames FROM `%s` LEFT JOIN milt ON (%s.idmilt=milt.id) |
||
| 336 | WHERE ( |
||
| 337 | inet_aton(\'%s\') >= network AND |
||
| 338 | ( inet_aton(\'%s\') | ( inet_aton(\'%s\') ^ (power(2,32)-1) ) ) |
||
| 339 | <= network | ( netmask ^ (power(2,32)-1) ) |
||
| 340 | ) |
||
| 341 | GROUP by idmilt |
||
| 342 | ) AS val WHERE val.network IS NOT null', $table, $table, $sub['net'], $sub['net'], $sub['mask']); |
||
|
0 ignored issues
–
show
|
|||
| 343 | break; |
||
| 344 | case 'ip': |
||
| 345 | $query = sprintf('SELECT * FROM ( |
||
| 346 | SELECT *, GROUP_CONCAT(milt.name) as miltnames FROM `%s` LEFT JOIN milt ON (%s.idmilt=milt.id)' . |
||
| 347 | 'WHERE `ip` = INET_ATON(\'%s\') |
||
| 348 | ) AS val WHERE val.ip IS NOT null', $table, $table, $value); |
||
| 349 | break; |
||
| 350 | default: |
||
| 351 | syslog(LOG_EMERG, 'ALERT: The type <'.$type.'> is not allowed for milter lists.' ); |
||
| 352 | return FALSE; |
||
| 353 | } |
||
| 354 | } |
||
| 355 | } |
||
| 356 | |||
| 357 | else { |
||
| 358 | $table = $tablelist['name']; |
||
| 359 | if ($value == 'ALL') $query = 'select * from '.$table; |
||
| 360 | else { |
||
| 361 | switch ($type) { |
||
| 362 | case 'ip': |
||
| 363 | $query= "select * from $table where $type = INET_ATON('$value')"; |
||
| 364 | break; |
||
| 365 | View Code Duplication | case 'network': |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 366 | list($sub['net'],$sub['mask'])=explode('/',$value); |
||
| 367 | $query= sprintf('select * from `%s` |
||
| 368 | WHERE ( |
||
| 369 | inet_aton(\'%s\') >= network AND |
||
| 370 | ( inet_aton(\'%s\') | ( inet_aton(\'%s\') ^ (power(2,32)-1) ) ) |
||
| 371 | <= network | ( netmask ^ (power(2,32)-1) ) |
||
| 372 | )', $table, $sub['net'], $sub['net'], $sub['mask']); |
||
| 373 | ; |
||
| 374 | break; |
||
| 375 | default: |
||
| 376 | $query= "select * from $table where $type = '$value'"; |
||
| 377 | } |
||
| 378 | } |
||
| 379 | } |
||
| 380 | |||
| 381 | $result = $myconn->query($query); |
||
| 382 | if($result === false) |
||
| 383 | syslog(LOG_EMERG, "ALERT: Query <$query> failed: ".$myconn->error); |
||
| 384 | return $result; |
||
| 385 | } |
||
| 386 | |||
| 387 | function countListed ($myconn,$table) { |
||
| 388 | /* Return number of current listed items into a rbl table */ |
||
| 389 | $query = "SELECT COUNT(*) as `count` FROM `$table` WHERE (`active`=1 AND TIMESTAMPDIFF(MICROSECOND,NOW(),`exp`)>0) GROUP BY `active` ORDER BY `count` DESC LIMIT 1"; |
||
| 390 | $row = $myconn->query($query); |
||
| 391 | $number = $row->fetch_array(MYSQLI_ASSOC); |
||
| 392 | $number = $number['count']; |
||
| 393 | $row->free(); |
||
| 394 | return $number; |
||
| 395 | } |
||
| 396 | |||
| 397 | |||
| 398 | function isFull($myconn,$typedesc,$alltables) { |
||
| 399 | if (isset($alltables["$typedesc"]['limit'])) { |
||
| 400 | if ( $alltables["$typedesc"]['milter'] ) |
||
| 401 | $tab = 'net'; |
||
| 402 | else |
||
| 403 | $tab = $alltables["$typedesc"]['name']; |
||
| 404 | if ( countListed($myconn,$tab) >= $alltables["$typedesc"]['limit'] ) |
||
| 405 | return TRUE; |
||
| 406 | } |
||
| 407 | return FALSE; |
||
| 408 | } |
||
| 409 | |||
| 410 | function rlookup ($myconn,$user,$adm,$value,$typedesc,$tables) { |
||
| 411 | |||
| 412 | $type = $tables["$typedesc"]['field']; |
||
| 413 | $whynot=NULL; |
||
| 414 | |||
| 415 | $tabhtm = <<<END |
||
| 416 | <table><thead><tr><th>$type</th><th title="The date this object has been listed for the first time">DateAdd</th><th>DateMod</th><th>Exp</th><th>Status</th><th title="Number of times this object has been listed">#List</th> |
||
| 417 | END; |
||
| 418 | if ( $tables["$typedesc"]['milter'] ) |
||
| 419 | $tabhtm .= '<th title="Milter active for this object">Milters</th>'; |
||
| 420 | $tabhtm .= '<th>Authored by</th><th width="250">Reason</th><th>Action</th></tr></thead><tfoot><tr></tr></tfoot><tbody>'."\n"; |
||
| 421 | |||
| 422 | if (($type == 'domain') AND ($value != 'ALL')) |
||
| 423 | $value = nsdom($value); |
||
| 424 | if (is_null($value)) |
||
| 425 | return FALSE; |
||
| 426 | |||
| 427 | $result = searchentry ($myconn,$value,$tables["$typedesc"]); |
||
| 428 | if ($result) { |
||
| 429 | printf("<pre>Your request for $type <$value> returned %d items.\n</pre>", $result->num_rows); |
||
| 430 | |||
| 431 | /* Check for limit in number of listed items */ |
||
| 432 | $full = isFull($myconn,$typedesc,$tables); |
||
| 433 | if ($full) print '<p>'.htmlspecialchars("$typedesc has reached maximum value of ".$tables["$typedesc"]['limit'].' listed items.').'</p>'; |
||
| 434 | |||
| 435 | if ($result->num_rows) { |
||
| 436 | print $tabhtm; |
||
| 437 | $i=0; |
||
| 438 | while ($riga = $result->fetch_array(MYSQLI_ASSOC)) { |
||
| 439 | if (isListed($riga)) { |
||
| 440 | if ($tables["$typedesc"]['bl']) $listed='Listed'; |
||
| 441 | else $listed='WhiteListed'; |
||
| 442 | } |
||
| 443 | else |
||
| 444 | $listed='Ok'; |
||
| 445 | |||
| 446 | switch ($type) { |
||
| 447 | case 'ip': |
||
| 448 | $element = long2ip($riga['ip']); |
||
| 449 | break; |
||
| 450 | View Code Duplication | case 'network': |
|
| 451 | $element = long2ip($riga['network']).'/'.long2ip($riga['netmask']); |
||
| 452 | break; |
||
| 453 | default: |
||
| 454 | $element = $riga["$type"]; |
||
| 455 | } |
||
| 456 | |||
| 457 | if ( $tables["$typedesc"]['milter'] AND checkMilterConf($tables["$typedesc"]) ) |
||
| 458 | printf ("<tr id=id$i><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td nowrap id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td>%s</td></tr>\n", |
||
| 459 | $element, $riga['date'], $riga['datemod'], $riga['exp'], $riga['active'], $riga['nlist'], askMilter($myconn,$i,$element,$typedesc,$riga['idmilt'],$riga['miltnames'],$user,$adm), $riga['user'],htmlspecialchars($riga['reason']),ask($myconn,$i,$listed,$tables,$typedesc,$element,$full,$user,$adm)); |
||
| 460 | else |
||
| 461 | printf ("<tr id=id$i><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td id='status$listed'>%s</td><td>%s</td></tr>\n", |
||
| 462 | $element, $riga['date'], $riga['datemod'], $riga['exp'], $riga['active'], $riga['nlist'], $riga['user'],htmlspecialchars($riga['reason']),ask($myconn,$i,$listed,$tables,$typedesc,$element,$full,$user,$adm)); |
||
| 463 | $i++; |
||
| 464 | } |
||
| 465 | print '</tbody></table>'; |
||
| 466 | } |
||
| 467 | else { |
||
| 468 | print "<pre>$type <$value> is not listed!\n</pre>"; |
||
| 469 | if ( in_array($user,array_keys($adm)) AND ($value != 'ALL') ) |
||
| 470 | if ( (!$full) AND (consistentListing($myconn,$tables,$typedesc,$value,$whynot)) ) require_once('listForm.php'); |
||
| 471 | else print '<p>'.htmlspecialchars($whynot).'</p>'; |
||
| 472 | |||
| 473 | } |
||
| 474 | $result->free(); |
||
| 475 | } |
||
| 476 | else print '<pre>Query error or something wrong in DB schema'."\n</pre>"; |
||
| 477 | } |
||
| 478 | |||
| 479 | |||
| 480 | |||
| 481 | |||
| 482 | function sendEmailWarn($tplf,$from,$to,$sbj,$emailListed,$intervalToExpire,$detail) { |
||
| 483 | $now = time(); |
||
| 484 | setlocale (LC_TIME, 'it_IT'); |
||
| 485 | $date = date("r",$now); |
||
| 486 | $messageID = md5(uniqid($now,1)) . '@' . gethostname(); |
||
| 487 | $mua = 'PHP/' . phpversion(); |
||
| 488 | |||
| 489 | /* Parsing headers */ |
||
| 490 | View Code Duplication | if (!file_exists($tplf['header'])) { |
|
| 491 | syslog(LOG_ERR, 'Sending email... template file <'.$tplf['header'].'> not found!'); |
||
| 492 | exit; |
||
| 493 | } |
||
| 494 | |||
| 495 | $head_tmpl = file_get_contents($tplf['header']); |
||
| 496 | $arr_tpl_vars = array('{from}','{to}','{date}','{messageID}','{mua}'); |
||
| 497 | $arr_tpl_data = array($from,$to,$date,$messageID,$mua); |
||
| 498 | $headers = str_replace($arr_tpl_vars, $arr_tpl_data, $head_tmpl); |
||
| 499 | $headers = preg_replace( '/\r|\n/', "\r\n", $headers ); |
||
| 500 | |||
| 501 | /* Parsing body */ |
||
| 502 | |||
| 503 | View Code Duplication | if (!file_exists($tplf['body'])) { |
|
| 504 | syslog(LOG_ERR, 'Sending email... template file <'.$tplf['body'].'> not found!'); |
||
| 505 | exit; |
||
| 506 | } |
||
| 507 | |||
| 508 | $body_tmpl = file_get_contents($tplf['body']); |
||
| 509 | $arr_tpl_vars = array('{emailListed}','{expInterval}','{reason}'); |
||
| 510 | $arr_tpl_data = array($emailListed,$intervalToExpire,$detail); |
||
| 511 | $body = str_replace($arr_tpl_vars, $arr_tpl_data, $body_tmpl); |
||
| 512 | $body = preg_replace( "/\r|\n/", "\r\n", $body ); |
||
| 513 | $body = wordwrap ( $body, 75 , "\r\n" ); |
||
| 514 | |||
| 515 | /* Send the mail! */ |
||
| 516 | if ( strlen(ini_get("safe_mode"))< 1) { |
||
| 517 | $old_mailfrom = ini_get("sendmail_from"); |
||
| 518 | ini_set("sendmail_from", $from); |
||
| 519 | $params = sprintf("-oi -f %s", '<>'); |
||
| 520 | View Code Duplication | if (!(mail($to,$sbj, $body,$headers,$params))) $flag=FALSE; |
|
| 521 | else $flag=TRUE; |
||
| 522 | if (isset($old_mailfrom)) |
||
| 523 | ini_set("sendmail_from", $old_mailfrom); |
||
| 524 | } |
||
| 525 | View Code Duplication | else { |
|
| 526 | if (!(mail($to,$sbj, $body,$headers))) $flag=FALSE; |
||
| 527 | else $flag=TRUE; |
||
| 528 | } |
||
| 529 | return $flag; |
||
| 530 | } |
||
| 531 | |||
| 532 | function emailToNotify($notify_file,$dom) { |
||
| 533 | $ini_array = parse_ini_file($notify_file); |
||
| 534 | if (in_array($dom,array_keys($ini_array))) |
||
| 535 | return $ini_array["$dom"]; |
||
| 536 | else return FALSE; |
||
| 537 | } |
||
| 538 | |||
| 539 | |||
| 540 | function searchAndList ($myconn,$loguser,$tables,$typedesc,$value,$unit,&$quantity,&$reason) { |
||
| 541 | |||
| 542 | /* Search and list value */ |
||
| 543 | $type = $tables["$typedesc"]['field']; |
||
| 544 | $table = $tables["$typedesc"]['name']; |
||
| 545 | $result = searchentry ($myconn,$value,$tables["$typedesc"]); |
||
| 546 | |||
| 547 | /* Manage abnormal conditions */ |
||
| 548 | /* Value already present in db more than once. This is absurd. Panic! */ |
||
| 549 | if ($result->num_rows > 1) { |
||
| 550 | syslog(LOG_EMERG,"$loguser: PANIC! Select for $type '$value' returned ". $result->num_rows ." items instead of one. Abnormal. Contact a sysadmin or a developer."); |
||
| 551 | $result->free(); |
||
| 552 | return FALSE; |
||
| 553 | } |
||
| 554 | |||
| 555 | /* Value already present in db or not present: to list anyway */ |
||
| 556 | if ($result->num_rows >= 0) { |
||
| 557 | /* First, check for limit in number of listed items */ |
||
| 558 | if (isFull($myconn,$typedesc,$tables)) { |
||
| 559 | syslog(LOG_EMERG,"$loguser: $typedesc has reached maximum value of ".$tables["$typedesc"]['limit'].' listed items. Abnormal exit.'); |
||
| 560 | $result->free(); |
||
| 561 | return FALSE; |
||
| 562 | } |
||
| 563 | /* Second, check if the (re)list would be consistent now */ |
||
| 564 | if (! consistentListing($myconn,$tables,$typedesc,$value,$whynot) ) { |
||
| 565 | syslog(LOG_ERR, $loguser.': '.$whynot); |
||
| 566 | $result->free(); |
||
| 567 | return FALSE; |
||
| 568 | } |
||
| 569 | } |
||
| 570 | /* End of abnormal conditions */ |
||
| 571 | |||
| 572 | |||
| 573 | /* Finally, here I can list the value! */ |
||
| 574 | $thisentry = $result->fetch_array(MYSQLI_ASSOC); |
||
| 575 | switch ($result->num_rows) { |
||
| 576 | /* Relist value if already present */ |
||
| 577 | case 1: |
||
| 578 | if ( isListed($thisentry) ) { |
||
| 579 | /* Entry already listed */ |
||
| 580 | $expdate = $thisentry['exp']; |
||
| 581 | $reason = sprintf('%s. Already listed. Adding 1 DAY to previous expire date.', |
||
| 582 | $reason); |
||
| 583 | $quantity = 1; |
||
| 584 | $unit = 'DAY'; |
||
| 585 | } |
||
| 586 | else { |
||
| 587 | /* Entry delisted */ |
||
| 588 | $quantity *= $thisentry['nlist']; |
||
| 589 | $expdate = 0; /* This forces expiration from CURRENT_TIMESTAMP */ |
||
| 590 | } |
||
| 591 | $result->free(); |
||
| 592 | return relist ($myconn,$loguser,$value,$type,$table,$unit,$quantity,$reason, $expdate); |
||
| 593 | |||
| 594 | /* First time list value */ |
||
| 595 | case 0: |
||
| 596 | $result->free(); |
||
| 597 | return addtolist ($myconn,$loguser,$value,$tables["$typedesc"],$unit,$quantity,$reason,$_); |
||
| 598 | } |
||
| 599 | } |
||
| 600 | |||
| 601 | |||
| 602 | /*************** Functions to check if two net overlap each other ********************/ |
||
| 603 | |||
| 604 | function ipRange ($range) { |
||
| 605 | /* List IP in range */ |
||
| 606 | return array_map('long2ip', range( ip2long($range[0]), ip2long($range[1]) ) ); |
||
| 607 | } |
||
| 608 | |||
| 609 | function isIn($netA, $netB) { |
||
| 610 | /* TRUE if an IP of $netA is contained in netB */ |
||
| 611 | list($addressA,$maskA) = explode('/', $netA); |
||
| 612 | list($addressB,$maskB) = explode('/', $netB); |
||
| 613 | require_once 'vendor/autoload.php'; |
||
| 614 | $net = new \dautkom\ipv4\IPv4(); |
||
| 615 | $range = $net->address($addressA)->mask($maskA)->getRange(); |
||
| 616 | $ips = ipRange($range); |
||
| 617 | foreach ( $ips as $ip ) |
||
| 618 | if ( $net->address($addressB)->mask($maskB)->has($ip) ) |
||
| 619 | return TRUE; |
||
| 620 | return FALSE; |
||
| 621 | } |
||
| 622 | |||
| 623 | function netOverlap($myconn, $tabletype, $net, &$thisNet, $loguser) { |
||
| 624 | /* return TRUE if $net overlap an existing network into DB */ |
||
| 625 | $thisNet = NULL; |
||
| 626 | if ($tabletype['field'] != 'network') { |
||
| 627 | syslog(LOG_ERR, $loguser.': '.$tabletype['name'].' is not a network list.'); |
||
| 628 | return FALSE; |
||
| 629 | } |
||
| 630 | $result = searchentry ($myconn,'ALL',$tabletype); |
||
| 631 | if ($result->num_rows) { |
||
| 632 | while ($row = $result->fetch_array(MYSQLI_ASSOC)) { |
||
| 633 | $thisNet = long2ip($row['network']).'/'.long2ip($row['netmask']); |
||
| 634 | if ( isIn($thisNet, $net) ) { |
||
| 635 | $result->free(); |
||
| 636 | syslog(LOG_INFO, "$loguser: the net <$net> overlaps the existing network <$thisNet>."); |
||
| 637 | return TRUE; |
||
| 638 | } |
||
| 639 | } |
||
| 640 | } |
||
| 641 | $result->free(); |
||
| 642 | return FALSE; |
||
| 643 | } |
||
| 644 | |||
| 645 | /*********************************************************************************************/ |
||
| 646 | |||
| 647 | |||
| 648 | /* For miltermap */ |
||
| 649 | function checkMilterConf($table) { |
||
| 650 | if (isset($table['milter'])) { |
||
| 651 | if ($table['milter'] === TRUE) { |
||
| 652 | switch ( $table['field'] ) { |
||
| 653 | case 'network': |
||
| 654 | case 'ip': |
||
| 655 | return TRUE; |
||
| 656 | } |
||
| 657 | } |
||
| 658 | } |
||
| 659 | return FALSE; |
||
| 660 | } |
||
| 661 | |||
| 662 | /* |
||
| 663 | function enterDBMilt($myconn,$tables,$loguser) { |
||
| 664 | if (!($myconn->select_db($tables('name')))) { |
||
| 665 | syslog(LOG_ERR, $loguser.': Can\'t enter into DB '.$tables('name')); |
||
| 666 | return FALSE; |
||
| 667 | } |
||
| 668 | return TRUE; |
||
| 669 | } |
||
| 670 | */ |
||
| 671 | |||
| 672 | function milterTable($t) { |
||
| 673 | /* Return the milter object table for type t or FALSE on error */ |
||
| 674 | switch ($t) { |
||
| 675 | case 'network': |
||
| 676 | return 'net'; |
||
| 677 | case 'ip': |
||
| 678 | return 'ips'; |
||
| 679 | default: |
||
| 680 | syslog(LOG_EMERG, "ALERT: type <$t> not allowed in configuration. "); |
||
| 681 | return FALSE; |
||
| 682 | } |
||
| 683 | } |
||
| 684 | |||
| 685 | |||
| 686 | function readMiltName($myconn,$loguser) { |
||
| 687 | $milters=array(); |
||
| 688 | $query = 'SELECT `name` FROM `config`'; |
||
| 689 | |||
| 690 | $result = $myconn->query($query); |
||
| 691 | if($result === false) { |
||
| 692 | syslog(LOG_EMERG, "$loguser: ALERT: Query <$query> failed: ".$myconn->error); |
||
| 693 | return FALSE; |
||
| 694 | } |
||
| 695 | if ($result->num_rows) { |
||
| 696 | while ($milt = $result->fetch_array(MYSQLI_ASSOC)) |
||
| 697 | $milters[] = $milt['name']; |
||
| 698 | } |
||
| 699 | $result->free(); |
||
| 700 | return $milters; |
||
| 701 | } |
||
| 702 | |||
| 703 | function changeMilter ($myconn,$loguser,$miltVal,$table,$miltID) { |
||
| 704 | $query = array(); |
||
| 705 | foreach ( $miltVal as $value => $action ) { |
||
| 706 | switch ( $action ) { |
||
| 707 | case 'keep': |
||
| 708 | break; |
||
| 709 | case 'add': |
||
| 710 | $query[] = sprintf( "INSERT INTO `milt` ( |
||
| 711 | `id` , |
||
| 712 | `name` |
||
| 713 | ) |
||
| 714 | VALUES ( |
||
| 715 | %d , |
||
| 716 | '%s' |
||
| 717 | )",$miltID,$value); |
||
| 718 | break; |
||
| 719 | case 'del': |
||
| 720 | $query[] = "DELETE FROM `milt` WHERE (`id` = '$miltID' AND `name` = '$value')"; |
||
| 721 | } |
||
| 722 | } |
||
| 723 | if ( count($query) ) /* This "if" is redundant, because if I call this I already checked there is a change */ |
||
| 724 | /* I update datemod because the user couldn't change */ |
||
| 725 | $query[] = sprintf('UPDATE `%s` SET |
||
| 726 | `user`=\'%s\', |
||
| 727 | `datemod`= CURRENT_TIMESTAMP |
||
| 728 | WHERE `idmilt`=%d', $table, $loguser, $miltID); |
||
| 729 | |||
| 730 | |||
| 731 | /* Start a safe transaction: it commits only if all queries happen */ |
||
| 732 | $myconn->autocommit(FALSE); |
||
| 733 | $myconn->begin_transaction(MYSQLI_TRANS_START_READ_ONLY); |
||
| 734 | $ok = TRUE; |
||
| 735 | foreach ( $query as $q ) { |
||
| 736 | if ($myconn->query($q) !== TRUE) { |
||
| 737 | $ok = FALSE; |
||
| 738 | syslog(LOG_ERR, "$loguser: Error: ".$myconn->error); |
||
| 739 | } |
||
| 740 | } |
||
| 741 | if ( $ok ) { |
||
| 742 | if ( $myconn->commit() ) |
||
| 743 | syslog(LOG_INFO, "$loguser: Milter setting changed successfully."); |
||
| 744 | else { |
||
| 745 | syslog(LOG_ERR, "$loguser: Milter setting NOT changed for an unpredictable COMMIT error."); |
||
| 746 | if ( $myconn->rollback() ) |
||
| 747 | syslog(LOG_INFO, "$loguser: rollback succeeded."); |
||
| 748 | else |
||
| 749 | syslog(LOG_ERR, "$loguser: rollback failed. Your db could be compromized. Check it!"); |
||
| 750 | $ok = FALSE; |
||
| 751 | } |
||
| 752 | } |
||
| 753 | else |
||
| 754 | syslog(LOG_ERR, "$loguser: Error: Milter setting NOT changed. See at above errors."); |
||
| 755 | return $ok; |
||
| 756 | |||
| 757 | } |
||
| 758 | |||
| 759 | |||
| 760 | function curl_get($url, array $get = NULL, array $options = array(), $loguser) |
||
| 761 | { |
||
| 762 | $defaults = array( |
||
| 763 | CURLOPT_URL => $url. (strpos($url, '?') === FALSE ? '?' : ''). http_build_query($get), |
||
| 764 | CURLOPT_HEADER => 0, |
||
| 765 | CURLOPT_RETURNTRANSFER => TRUE, |
||
| 766 | CURLOPT_TIMEOUT => 4 |
||
| 767 | ); |
||
| 768 | |||
| 769 | $ch = curl_init(); |
||
| 770 | curl_setopt_array($ch, ($options + $defaults)); |
||
| 771 | if( ! $result = curl_exec($ch)) |
||
| 772 | { |
||
| 773 | syslog(LOG_ERR, sprintf('%s: CURL Error: <%s>', $loguser, curl_error($ch))); |
||
| 774 | } |
||
| 775 | curl_close($ch); |
||
| 776 | return $result; |
||
| 777 | } |
||
| 778 | |||
| 779 | |||
| 780 | function nsdom($dom) { |
||
| 781 | /* Return the first lowercase upper domain (or domain itself) with NS record */ |
||
| 782 | /* checkdnsrr doesn't work with alias... use dns_get_record */ |
||
| 783 | if (dns_get_record ( $dom , DNS_NS )) |
||
| 784 | return strtolower(rtrim($dom, '.')); |
||
| 785 | if (dns_get_record ( $dom , DNS_A )) |
||
| 786 | return nsdom( ltrim(strstr($dom, '.'), '.') ); |
||
| 787 | return NULL; |
||
| 788 | } |
||
| 789 | |||
| 790 | function isValid($dom) { |
||
| 791 | /* Return TRUE id domain has NS or A record */ |
||
| 792 | if (preg_match('/^(?!:\/\/)([a-zA-Z0-9-]+\.){0,5}[a-zA-Z0-9-][a-zA-Z0-9-]+\.[a-zA-Z]{2,64}?\.{0,1}$/i',$dom) === 1) { |
||
| 793 | if (checkdnsrr ( $dom , 'NS' )) |
||
| 794 | return TRUE; |
||
| 795 | if (checkdnsrr ( $dom , 'A' )) |
||
| 796 | return TRUE; |
||
| 797 | } |
||
| 798 | return FALSE; |
||
| 799 | } |
||
| 800 | |||
| 801 | /* |
||
| 802 | function checkEmailAddress($email) { |
||
| 803 | if(preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/", $email)) |
||
| 804 | return true; |
||
| 805 | return false; |
||
| 806 | } |
||
| 807 | |||
| 808 | function checkIP($ip) |
||
| 809 | { |
||
| 810 | $cIP = ip2long($ip); |
||
| 811 | $fIP = long2ip($cIP); |
||
| 812 | if ($fIP == '0.0.0.0') return FALSE; |
||
| 813 | return TRUE; |
||
| 814 | } |
||
| 815 | */ |
||
| 816 | ?> |
||
| 817 | |||
| 818 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.