Fix SASL.
[m6w6/libmemcached] / libmemcached / response.cc
index ff517e31bf08bfa3b68ec0c95ac1ca89391a4444..809d5b6fb7606793b71d06c9c60e21e47d515958 100644 (file)
@@ -55,6 +55,9 @@ static memcached_return_t textual_value_fetch(memcached_server_write_instance_st
   string_ptr+= 6; /* "VALUE " */
 
 
+  // Just used for cases of AES decrypt currently
+  memcached_return_t rc= MEMCACHED_SUCCESS;
+
   /* We load the key */
   {
     char *key= result->item_key;
@@ -169,7 +172,34 @@ static memcached_return_t textual_value_fetch(memcached_server_write_instance_st
     memcached_string_set_length(&result->value, value_length);
   }
 
-  return MEMCACHED_SUCCESS;
+  if (memcached_is_encrypted(instance->root) and memcached_result_length(result))
+  {
+    hashkit_string_st *destination;
+
+    if ((destination= hashkit_decrypt(&instance->root->hashkit,
+                                      memcached_result_value(result), memcached_result_length(result))) == NULL)
+    {
+      rc= memcached_set_error(*instance->root, MEMCACHED_FAILURE, 
+                              MEMCACHED_AT, memcached_literal_param("hashkit_decrypt() failed"));
+    }
+    else
+    {
+      memcached_result_reset_value(result);
+      if (memcached_failed(memcached_result_set_value(result, hashkit_string_c_str(destination), hashkit_string_length(destination))))
+      {
+        rc= memcached_set_error(*instance->root, MEMCACHED_FAILURE, 
+                                MEMCACHED_AT, memcached_literal_param("hashkit_decrypt() failed"));
+      }
+    }
+
+    if (memcached_failed(rc))
+    {
+      memcached_result_reset(result);
+    }
+    hashkit_string_free(destination);
+  }
+
+  return rc;
 
 read_error:
   memcached_io_reset(instance);
@@ -206,9 +236,9 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
       {
         /* Find the space, and then move one past it to copy version */
         char *response_ptr= index(buffer, ' ');
-        response_ptr++;
 
-        long int version= strtol(response_ptr, (char **)NULL, 10);
+        char *endptr;
+        long int version= strtol(response_ptr, &endptr, 10);
         if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
@@ -216,10 +246,8 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
         }
         instance->major_version= uint8_t(version);
 
-        response_ptr= index(response_ptr, '.');
-        response_ptr++;
-
-        version= strtol(response_ptr, (char **)NULL, 10);
+        endptr++;
+        version= strtol(endptr, &endptr, 10);
         if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
@@ -227,10 +255,8 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta
         }
         instance->minor_version= uint8_t(version);
 
-        response_ptr= index(response_ptr, '.');
-        response_ptr++;
-
-        version= strtol(response_ptr, (char **)NULL, 10);
+        endptr++;
+        version= strtol(endptr, &endptr, 10);
         if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
@@ -558,6 +584,21 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan
       break;
 
     case PROTOCOL_BINARY_CMD_SASL_LIST_MECHS:
+      {
+        if (header.response.keylen != 0 || bodylen + 1 > buffer_length)
+        {
+          return MEMCACHED_UNKNOWN_READ_FAILURE;
+        }
+        else
+        {
+          if ((rc= memcached_safe_read(instance, buffer, bodylen)) != MEMCACHED_SUCCESS)
+          {
+            return MEMCACHED_UNKNOWN_READ_FAILURE;
+          }
+        }
+      }
+      break;
+
     case PROTOCOL_BINARY_CMD_VERSION:
       {
         char version_buffer[32]; // @todo document this number
@@ -568,8 +609,8 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan
           return MEMCACHED_UNKNOWN_READ_FAILURE;
         }
 
-        char *p;
-        long int version= strtol(version_buffer, &p, 10);
+        char *endptr;
+        long int version= strtol(version_buffer, &endptr, 10);
         if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
@@ -577,16 +618,18 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan
         }
         instance->major_version= uint8_t(version);
 
-        version= strtol(p +1, &p, 10);
+        endptr++;
+        version= strtol(endptr, &endptr, 10);
         if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-          return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
+          return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version"));
         }
         instance->minor_version= uint8_t(version);
 
-        version= strtol(p + 1, NULL, 10);
-        if (errno == ERANGE)
+        endptr++;
+        version= strtol(endptr, &endptr, 10);
+        if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
         {
           instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
           return memcached_set_error(*instance, MEMCACHED_UNKNOWN_READ_FAILURE, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));