--- services_keyauth.admin.inc	Sat Aug 08 04:55:05 2009
+++ services_keyauth.admin.inc	Mon Oct 26 23:01:06 2009
@@ -8,7 +8,7 @@
 
 function services_keyauth_admin_keys_list() {
   $keys = services_keyauth_get_keys();
-  $header = array(t('Key'), t('Title'), t('Domain'), array('data' => t('Operations'), 'colspan' => '2'));
+  $header = array(t('Key'), t('Title'), t('Domain'), t('IP Addresses'), array('data' => t('Operations'), 'colspan' => '2'));
   $rows = array();
 
   foreach ($keys as $kid => $key) {
@@ -17,6 +17,7 @@
     $row[] = $kid;
     $row[] = $key->title;
     $row[] = $key->domain;
+    $row[] = check_plain(implode(',', array_map("trim", explode("\n", $key->ip_addresses))));
 
     // Populate the operations field.
     $operations = array();
@@ -34,7 +35,7 @@
   }
 
   if (empty($rows)) {
-    $rows[] = array(array('data' => t('No API keys created.'), 'colspan' => '5', 'class' => 'message'));
+    $rows[] = array(array('data' => t('No API keys created.'), 'colspan' => '6', 'class' => 'message'));
   }
 
   return theme('table', $header, $rows);
@@ -78,7 +79,15 @@
     '#description'    => t('External domain allowed to use this key.'),
     '#required'       => TRUE,
   );
-  
+  $form['ip_addresses'] = array(
+    '#title'          => t('Allowed IP Addresses'),
+    '#type'           => 'textarea',
+    '#rows'           => 5,
+    '#default_value'  => $key->ip_addresses,
+    '#required'       => FALSE,
+    '#description'    => t('Write one IP address per line')
+  );
+
   $methods = services_get_all();
   foreach ($methods as $method) {
     $form_methods[$method['#method']] = $method['#method'];
@@ -113,14 +122,14 @@
     WHERE kid = '%s'", $key['kid']));
 
   if ($is_existing) {
-    db_query("UPDATE {services_keys} SET title = '%s', domain = '%s'
-      WHERE kid = '%s'", $key['title'], $key['domain'], $key['kid']);
+    db_query("UPDATE {services_keys} SET title = '%s', domain = '%s', ip_addresses = '%s'
+      WHERE kid = '%s'", $key['title'], $key['domain'], $key['ip_addresses'], $key['kid']);
     db_query("DELETE FROM {services_key_permissions} WHERE kid = '%s'", $key['kid']);
     $return = SAVED_UPDATED;
   }
   else {
-    db_query("INSERT INTO {services_keys} (kid, title, domain)
-      VALUES ('%s', '%s', '%s')", $key['kid'], $key['title'], $key['domain']);
+    db_query("INSERT INTO {services_keys} (kid, title, domain, ip_addresses)
+      VALUES ('%s', '%s', '%s', '%s')", $key['kid'], $key['title'], $key['domain'], $key['ip_addresses']);
     $return = SAVED_NEW;
   }
   foreach ($key['method_access'] as $method => $value) {
@@ -128,7 +137,7 @@
       db_query("INSERT INTO {services_key_permissions} (kid, method) VALUES ('%s', '%s')", $key['kid'], $value);
     }
   }
-  return $return; 
+  return $return;
 }
 
 function services_keyauth_admin_keys_delete($kid) {
--- services_keyauth.inc	Mon Nov 02 20:42:33 2009
+++ services_keyauth.inc	Wed Nov 04 13:41:56 2009
@@ -1,5 +1,5 @@
 <?php
-// $Id: services_keyauth.inc,v 1.1.2.8.2.6 2009/11/02 19:42:33 heyrocker Exp $
+// $Id: services_keyauth.inc,v 1.1.2.8.2.4 2009/10/15 02:59:56 marcingy Exp $
 
 /**
  * @file
@@ -93,7 +93,7 @@
         $method['#key'] = TRUE;
         $method['#auth'] = TRUE;
     }
-    
+
     if ($method['#auth'] && variable_get('services_use_sessid', TRUE)) {
       array_unshift($method['#args'], $arg_sessid);
     }
@@ -164,15 +164,21 @@
         VALUES ('%s', %d, '%s')", $domain, $timestamp, $nonce);
     }
 
-    $api_key = db_result(db_query("SELECT kid FROM {services_keys} WHERE domain = '%s'", $domain));
+    $key = db_fetch_object(db_query("SELECT * FROM {services_keys} WHERE domain = '%s'", $domain));
 
     //if (!services_keyauth_validate_key($api_key, $timestamp, $domain, $nonce, $method_name, $hash_parameters, $hash)) {
     if ($hash != services_get_hash($timestamp, $domain, $nonce, $method, $args)) {
       return services_error(t('Invalid API key.'), 401);
     }
-    
-    if (!db_result(db_query("SELECT COUNT(*) FROM {services_key_permissions} 
-        WHERE kid = '%s' AND method = '%s'", $api_key, $method_name))) {
+
+    // authenticate IP address
+    $ip_addresses = array_map("trim", explode("\n", $key->ip_addresses));
+    if ($key && count($ip_addresses) && !in_array($_SERVER['REMOTE_ADDR'], $ip_addresses)) {
+      return services_error(t('Forbidden IP Address'), 401);
+    }
+
+    if (!db_result(db_query("SELECT COUNT(*) FROM {services_key_permissions}
+        WHERE kid = '%s' AND method = '%s'", $key->kid, $method_name))) {
       return services_error(t('Access denied.'), 401);
     }
   }
@@ -191,7 +197,7 @@
 function _services_keyauth_alter_browse_form_submit($method, &$args) {
   if ($method['#key'] && variable_get('services_use_key', TRUE)) {
     $args_stripped = $args;
-  
+
     for ($i = 1; $i <= 4; $i++) {
       array_shift($args_stripped);
     }
--- services_keyauth.install	Sat Jun 20 21:48:42 2009
+++ services_keyauth.install	Mon Oct 26 21:18:08 2009
@@ -33,6 +33,10 @@
         'not null' => TRUE,
         'default' => ''
       ),
+      'ip_addresses' => array(
+        'description' => 'The IP addresses of the service key',
+        'type' => 'text'
+      )
     ),
     'primary key' => array('kid')
   );
@@ -178,10 +182,19 @@
 
 function services_keyauth_update_6005() {
   $update = array();
-  
+
   // A table might fail to exist in certain circumstances due to an issue with the install.
   if (!db_table_exists('services_key_permissions')) {
     _services_key_auth_permissions($update);
   }
+  return $update;
+}
+
+/*
+ * Add ip_adresses column to services table.
+ */
+function services_keyauth_update_6006() {
+  $update = array();
+  db_add_column($update, 'services_keys', 'ip_addresses', 'text');
   return $update;
 }
