|
@@ -38,18 +38,19 @@ function honeypot_permission() {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Implements of hook_cron().
|
|
|
+ * Implements hook_cron().
|
|
|
*/
|
|
|
function honeypot_cron() {
|
|
|
// Delete {honeypot_user} entries older than the value of honeypot_expire.
|
|
|
db_delete('honeypot_user')
|
|
|
- ->condition('timestamp', time() - variable_get('honeypot_expire', 300), '<')
|
|
|
+ ->condition('timestamp', REQUEST_TIME - variable_get('honeypot_expire', 300), '<')
|
|
|
->execute();
|
|
|
|
|
|
- // Regenerate the honeypot css file if it does not exist.
|
|
|
+ // Regenerate the honeypot css file if it does not exist or is outdated.
|
|
|
$honeypot_css = honeypot_get_css_file_path();
|
|
|
- if (!file_exists($honeypot_css)) {
|
|
|
- honeypot_create_css(variable_get('honeypot_element_name', 'url'));
|
|
|
+ $honeypot_element_name = variable_get('honeypot_element_name', 'url');
|
|
|
+ if (!file_exists($honeypot_css) || !honeypot_check_css($honeypot_element_name)) {
|
|
|
+ honeypot_create_css($honeypot_element_name);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -111,7 +112,7 @@ function honeypot_trigger_info() {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Implements hook_rules_event_info()
|
|
|
+ * Implements hook_rules_event_info().
|
|
|
*/
|
|
|
function honeypot_rules_event_info() {
|
|
|
return array(
|
|
@@ -227,7 +228,7 @@ function honeypot_add_form_protection(&$form, &$form_state, $options = array())
|
|
|
$form['honeypot_time'] = array(
|
|
|
'#type' => 'hidden',
|
|
|
'#title' => t('Timestamp'),
|
|
|
- '#default_value' => honeypot_get_signed_timestamp(time()),
|
|
|
+ '#default_value' => honeypot_get_signed_timestamp(REQUEST_TIME),
|
|
|
'#element_validate' => array('_honeypot_time_restriction_validate'),
|
|
|
);
|
|
|
|
|
@@ -261,6 +262,11 @@ function _honeypot_honeypot_validate($element, &$form_state) {
|
|
|
* Validate honeypot's time restriction field.
|
|
|
*/
|
|
|
function _honeypot_time_restriction_validate($element, &$form_state) {
|
|
|
+ if (!empty($form_state['programmed'])) {
|
|
|
+ // Don't do anything if the form was submitted programmatically.
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// Don't do anything if the triggering element is a preview button.
|
|
|
if ($form_state['triggering_element']['#value'] == t('Preview')) {
|
|
|
return;
|
|
@@ -274,11 +280,11 @@ function _honeypot_time_restriction_validate($element, &$form_state) {
|
|
|
|
|
|
// Make sure current time - (time_limit + form time value) is greater than 0.
|
|
|
// If not, throw an error.
|
|
|
- if (!$honeypot_time || time() < ($honeypot_time + $time_limit)) {
|
|
|
+ if (!$honeypot_time || REQUEST_TIME < ($honeypot_time + $time_limit)) {
|
|
|
_honeypot_log($form_state['values']['form_id'], 'honeypot_time');
|
|
|
// Get the time limit again, since it increases after first failure.
|
|
|
$time_limit = honeypot_get_time_limit($form_state['values']);
|
|
|
- $form_state['values']['honeypot_time'] = honeypot_get_signed_timestamp(time());
|
|
|
+ $form_state['values']['honeypot_time'] = honeypot_get_signed_timestamp(REQUEST_TIME);
|
|
|
form_set_error('', t('There was a problem with your form submission. Please wait @limit seconds and try again.', array('@limit' => $time_limit)));
|
|
|
}
|
|
|
}
|
|
@@ -317,21 +323,18 @@ function honeypot_get_time_limit($form_values = array()) {
|
|
|
// Only calculate time limit if honeypot_time_limit has a value > 0.
|
|
|
if ($honeypot_time_limit) {
|
|
|
$expire_time = variable_get('honeypot_expire', 300);
|
|
|
- // Get value from {honeypot_user} table for authenticated users.
|
|
|
- if ($user->uid) {
|
|
|
- $number = db_query("SELECT COUNT(*) FROM {honeypot_user} WHERE uid = :uid AND timestamp > :time", array(
|
|
|
- ':uid' => $user->uid,
|
|
|
- ':time' => time() - $expire_time,
|
|
|
- ))->fetchField();
|
|
|
- }
|
|
|
- // Get value from {flood} table for anonymous users.
|
|
|
- else {
|
|
|
- $number = db_query("SELECT COUNT(*) FROM {flood} WHERE event = :event AND identifier = :hostname AND timestamp > :time", array(
|
|
|
- ':event' => 'honeypot',
|
|
|
- ':hostname' => ip_address(),
|
|
|
- ':time' => time() - $expire_time,
|
|
|
- ))->fetchField();
|
|
|
+ // Query the {honeypot_user} table to determine the number of failed
|
|
|
+ // submissions for the current user.
|
|
|
+ $query = db_select('honeypot_user', 'hs')
|
|
|
+ ->condition('uid', $user->uid)
|
|
|
+ ->condition('timestamp', REQUEST_TIME - $expire_time, '>');
|
|
|
+
|
|
|
+ // For anonymous users, take the hostname into account.
|
|
|
+ if ($user->uid === 0) {
|
|
|
+ $query->condition('hostname', ip_address());
|
|
|
}
|
|
|
+ $number = $query->countQuery()->execute()->fetchField();
|
|
|
+
|
|
|
// Don't add more than 30 days' worth of extra time.
|
|
|
$honeypot_time_limit = (int) min($honeypot_time_limit + exp($number) - 1, 2592000);
|
|
|
$additions = module_invoke_all('honeypot_time_limit', $honeypot_time_limit, $form_values, $number);
|
|
@@ -339,11 +342,12 @@ function honeypot_get_time_limit($form_values = array()) {
|
|
|
$honeypot_time_limit += array_sum($additions);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return $honeypot_time_limit;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Log the failed submision with timestamp.
|
|
|
+ * Log the failed submision with timestamp and hostname.
|
|
|
*
|
|
|
* @param string $form_id
|
|
|
* Form ID for the rejected form submission.
|
|
@@ -355,19 +359,13 @@ function honeypot_get_time_limit($form_values = array()) {
|
|
|
function honeypot_log_failure($form_id, $type) {
|
|
|
global $user;
|
|
|
|
|
|
- // Log failed submissions for authenticated users.
|
|
|
- if ($user->uid) {
|
|
|
- db_insert('honeypot_user')
|
|
|
- ->fields(array(
|
|
|
- 'uid' => $user->uid,
|
|
|
- 'timestamp' => time(),
|
|
|
- ))
|
|
|
- ->execute();
|
|
|
- }
|
|
|
- // Register flood event for anonymous users.
|
|
|
- else {
|
|
|
- flood_register_event('honeypot');
|
|
|
- }
|
|
|
+ db_insert('honeypot_user')
|
|
|
+ ->fields(array(
|
|
|
+ 'uid' => $user->uid,
|
|
|
+ 'hostname' => ip_address(),
|
|
|
+ 'timestamp' => REQUEST_TIME,
|
|
|
+ ))
|
|
|
+ ->execute();
|
|
|
|
|
|
// Allow other modules to react to honeypot rejections.
|
|
|
module_invoke_all('honeypot_reject', $form_id, $user->uid, $type);
|
|
@@ -422,6 +420,30 @@ function honeypot_create_css($element_name) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Check Honeypot's CSS file for a given Honeypot element name.
|
|
|
+ *
|
|
|
+ * This function assumes the Honeypot CSS file already exists.
|
|
|
+ *
|
|
|
+ * @param string $element_name
|
|
|
+ * The honeypot element class name (e.g. 'url').
|
|
|
+ *
|
|
|
+ * @return bool
|
|
|
+ * TRUE if CSS is has element class name, FALSE if not.
|
|
|
+ */
|
|
|
+function honeypot_check_css($element_name) {
|
|
|
+ $path = honeypot_get_css_file_path();
|
|
|
+ $handle = fopen($path, 'r');
|
|
|
+ $contents = fread($handle, filesize($path));
|
|
|
+ fclose($handle);
|
|
|
+
|
|
|
+ if (strpos($contents, $element_name) === 1) {
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ return FALSE;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Sign the timestamp $time.
|
|
|
*
|