Index: auth/services_ipauth/services_ipauth.inc
===================================================================
RCS file: auth/services_ipauth/services_ipauth.inc
diff -N auth/services_ipauth/services_ipauth.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ auth/services_ipauth/services_ipauth.inc	18 Jul 2010 14:11:23 -0000
@@ -0,0 +1,174 @@
+<?php
+// $Id$
+/**
+ * @file
+ *  Provides a IP address based validation system for services module.
+ */
+
+/**
+ * Settings form.
+ */
+function services_ipauth_security_settings(){
+  $form = array();
+
+  $form['services_ipauth_type'] = array(
+    '#title'    => t('Type of IP filtering'),
+    '#type'     => 'radios',
+    '#options'  => array(
+      SERVICES_IPAUTH_TYPE_DENY   => t('Deny'),
+      SERVICES_IPAUTH_TYPE_ALLOW  => t('Allow'),
+    ),
+    '#description' => t('Choose the method of IP address filtering. "Allow" means you need to list only addresses that can have access. All others will be denied. "Deny" means access will be granted to every address except listed below'),
+    '#default_value' => variable_get('services_ipauth_type', SERVICES_IPAUTH_TYPE_DENY),
+  );
+
+  $form['services_ipauth_addresses'] = array(
+    '#title' => t('IP addresses'),
+    '#type' => 'textarea',
+    '#description' => t('One address per line. Format x.x.x.x'),
+    '#default_value' => variable_get('services_ipauth_addresses', ''),
+  );
+
+  $form['services_use_sessid'] = array(
+    '#type'           => 'checkbox',
+    '#title'          => t('Use sessid'),
+    '#default_value'  => variable_get('services_use_sessid', TRUE),
+    '#description'    => t('When enabled, all method calls must include a valid sessid. Only disable this setting if the application will use browser-based cookies.')
+  );
+
+  return $form;
+}
+
+/**
+ * Settings form validation.
+ *
+ * Checking if IP addresses are in proper format.
+ */
+function services_ipauth_security_settings_validate(&$form, &$form_state){
+  // Take user input.
+  $ip_addresses_input = $form_state['values']['services_ipauth_addresses'];
+  $ip_addresses = explode("\n", $ip_addresses_input);
+  // Check each line as IP address.
+  foreach ($ip_addresses as $ip_addr){
+    $ip_addr = trim($ip_addr);
+    // Skip empty lines.
+    if (empty($ip_addr)) {
+      continue;
+    }
+    // Should consists of four numbers dot separated.
+    if (preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/",$ip_addr)) {
+      $parts = explode(".", $ip_addr);
+      // Check each part can range from 0-255.
+      foreach ($parts as $ip_parts){
+        if ((intval($ip_parts) > 255) || (intval($ip_parts) < 0)) {
+          form_set_error('services_ipauth_addresses', t('Incorrect IP address format.'));
+          return;
+        }
+      }
+    }
+    else {
+      form_set_error('services_ipauth_addresses', t('Incorrect IP address format.'));
+      return;
+    }
+  }
+}
+
+/**
+ * Submission of the settings form.
+ */
+function services_ipauth_security_settings_submit($form_state){
+  // Saving variables.
+  foreach (services_ipauth_security_settings() as $key => $field) {
+    variable_set($key, $form_state['values'][$key]);
+  }
+}
+
+
+/**
+ * Alter method signatures to add required arguments for IP address authentication.
+ *
+ * @param $methods
+ *   An array of all enabled service methods.
+ */
+function services_ipauth_alter_methods(&$methods) {
+  // Skip this if no services have been activated
+  if (!is_array($methods) || empty($methods)) {
+    return;
+  }
+
+  // sessid arg
+  $arg_sessid = array(
+    'name' => 'sessid',
+    'type' => 'string',
+    'description' => t('A valid sessid.'),
+  );
+
+  foreach ($methods as $key => &$method) {
+    // Set method defaults.
+    if (!isset($method['auth'])) {
+      $method['auth'] = TRUE;
+    }
+
+    if ($method['auth'] && variable_get('services_use_sessid', TRUE)) {
+      array_unshift($method['args'], $arg_sessid);
+    }
+  }
+}
+
+/**
+ * Alter service browser form to add required arguments for IP address authentication.
+ *
+ * @param $form
+ *   The services browser form.
+ * @param $method
+ *   The method currently being browsed.
+ */
+function services_ipauth_alter_browse_form(&$form, $method) {
+  foreach ($method['args'] as $key => $arg) {
+    if ($arg['name'] == 'sessid') {
+      $form['arg'][$key]['#title']  = t('Session ID');
+      $form['arg'][$key]['#default_value']  = session_id();
+    }
+  }
+}
+
+/**
+ * Authenticate a services method call with IP address authentication.
+ *
+ * @param $method
+ *   A method definition as returned by services_method_get().
+ * @param $method_name
+ *   The name of the method being called
+ * @param $args
+ *   An array of arguments.
+ */
+function services_ipauth_authenticate_call($method, $method_name, &$args) {
+  // Get remote IP address.
+  $current_ip = ip_address();
+
+  // Prepare list of user typed addresses.
+  $ip_addresses_setting = variable_get('services_ipauth_addresses', '');
+  $ip_addresses = explode("\n", $ip_addresses_setting);
+  $ip_addresses = array_filter($ip_addresses, 'trim');
+
+  // Check whether filtering method is Deny.
+  $filtering_method_deny = (variable_get('services_ipauth_type', SERVICES_IPAUTH_TYPE_DENY) == SERVICES_IPAUTH_TYPE_DENY);
+  // Check whether current ip is in the list.
+  $ip_address_in_list = in_array($current_ip, $ip_addresses);
+
+  // Deny access if address is in list and we user Deny method,
+  // or ip address is not in the list and we user Allow method.
+  if ((($ip_address_in_list) && ($filtering_method_deny)) || ((!$filtering_method_deny) && (!$ip_address_in_list))) {
+    return t('IP address access denied.');
+  }
+
+  // Add additonal processing for methods requiring session.
+  $session_backup = NULL;
+  if ($method['auth'] && variable_get('services_use_sessid', TRUE)) {
+    $sessid = array_shift($args);
+    if (empty($sessid)) {
+      return t('Invalid sessid.');
+    }
+    $session_backup = services_session_load($sessid);
+  }
+}
Index: auth/services_ipauth/services_ipauth.info
===================================================================
RCS file: auth/services_ipauth/services_ipauth.info
diff -N auth/services_ipauth/services_ipauth.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ auth/services_ipauth/services_ipauth.info	18 Jul 2010 14:11:23 -0000
@@ -0,0 +1,6 @@
+; $Id:
+name = IP address Authentication
+description = Provides IP address authentication for services module
+package = Services - authentication
+dependencies[] = services
+core = 6.x
\ No newline at end of file
Index: auth/services_ipauth/services_ipauth.module
===================================================================
RCS file: auth/services_ipauth/services_ipauth.module
diff -N auth/services_ipauth.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ auth/services_ipauth/services_ipauth.module	18 Jul 2010 14:11:24 -0000
@@ -0,0 +1,42 @@
+<?php
+// $Id$
+/**
+ * @file
+ *  Provides a IP address based validation system for services module.
+ */
+
+// Defining constants.
+// Type of IP Filtering (Deny/Allow).
+define('SERVICES_IPAUTH_TYPE_DENY', 0);
+define('SERVICES_IPAUTH_TYPE_ALLOW', 1);
+
+/**
+ * Implementation of hook_authentication_info().
+ */
+function services_ipauth_authentication_info() {
+  return array(
+    'file' => 'services_ipauth.inc',
+    'title' => t('IP address authentication'),
+    'description' => t('The IP address based authentication'),
+    'security_settings' => 'services_ipauth_security_settings',
+    'security_settings_validate' => 'services_ipauth_security_settings_validate',
+    'security_settings_submit' => 'services_ipauth_security_settings_submit',
+    'alter_methods' => 'services_ipauth_alter_methods',
+    'alter_browse_form' => 'services_ipauth_alter_browse_form',
+    'authenticate_call' => 'services_ipauth_authenticate_call',
+  );
+}
+
+/**
+ * Clear cache when ipauth is disabled.
+ */
+function services_ipauth_disable() {
+  cache_clear_all('services:methods', 'cache');
+}
+
+/**
+ * Clear cache when ipauth is enabled.
+ */
+function services_ipauth_enable() {
+  cache_clear_all('services:methods', 'cache');
+}
