2003-08-15 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-auth-script.c
index a9df6d9..37f8890 100644 (file)
@@ -30,6 +30,7 @@
 #include "dbus-hash.h"
 #include "dbus-internals.h"
 #include "dbus-marshal.h"
+#include "dbus-userdb.h"
 
 /**
  * @defgroup DBusAuthScript code for running unit test scripts for DBusAuth
  * @{
  */
 
+/* this is slightly different from the other append_quoted_string
+ * in dbus-message-builder.c
+ */
 static dbus_bool_t
 append_quoted_string (DBusString       *dest,
                       const DBusString *quoted)
 {
   dbus_bool_t in_quotes = FALSE;
+  dbus_bool_t in_backslash = FALSE;
   int i;
 
   i = 0;
@@ -55,8 +60,33 @@ append_quoted_string (DBusString       *dest,
       unsigned char b;
 
       b = _dbus_string_get_byte (quoted, i);
-      
-      if (in_quotes)
+
+      if (in_backslash)
+        {
+          unsigned char a;
+          
+          if (b == 'r')
+            a = '\r';
+          else if (b == 'n')
+            a = '\n';
+          else if (b == '\\')
+            a = '\\';
+          else
+            {
+              _dbus_warn ("bad backslashed byte %c\n", b);
+              return FALSE;
+            }
+
+          if (!_dbus_string_append_byte (dest, a))
+            return FALSE;
+          
+          in_backslash = FALSE;
+        }
+      else if (b == '\\')
+        {
+          in_backslash = TRUE;
+        }
+      else if (in_quotes)
         {
           if (b == '\'')
             in_quotes = FALSE;
@@ -82,8 +112,6 @@ append_quoted_string (DBusString       *dest,
       ++i;
     }
 
-  if (!_dbus_string_append_byte (dest, '\0'))
-    return FALSE;
   return TRUE;
 }
 
@@ -143,44 +171,55 @@ auth_state_to_string (DBusAuthState state)
   return "unknown";
 }
 
+/**
+ * Runs an "auth script" which is a script for testing the
+ * authentication protocol. Scripts send and receive data, and then
+ * include assertions about the state of both ends of the connection
+ * after processing the data. A script succeeds if these assertions
+ * hold.
+ *
+ * @param filename the file containing the script to run
+ * @returns #TRUE if the script succeeds, #FALSE otherwise
+ */
 dbus_bool_t
 _dbus_auth_script_run (const DBusString *filename)
 {
   DBusString file;
-  DBusResultCode result;
+  DBusError error;
   DBusString line;
   dbus_bool_t retval;
   int line_no;
   DBusAuth *auth;
   DBusString from_auth;
   DBusAuthState state;
+  DBusString context;
   
   retval = FALSE;
   auth = NULL;
+
+  _dbus_string_init_const (&context, "org_freedesktop_test");
   
-  if (!_dbus_string_init (&file, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&file))
     return FALSE;
 
-  if (!_dbus_string_init (&line, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&line))
     {
       _dbus_string_free (&file);
       return FALSE;
     }
 
-  if (!_dbus_string_init (&from_auth, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&from_auth))
     {
       _dbus_string_free (&file);
       _dbus_string_free (&line);
       return FALSE;
     }
-  
-  if ((result = _dbus_file_get_contents (&file, filename)) != DBUS_RESULT_SUCCESS)
-    {
-      const char *s;
-      _dbus_string_get_const_data (filename, &s);
+
+  dbus_error_init (&error);
+  if (!_dbus_file_get_contents (&file, filename, &error))    {
       _dbus_warn ("Getting contents of %s failed: %s\n",
-                  s, dbus_result_to_string (result));
-                     
+                  _dbus_string_get_const_data (filename), error.message);
+      dbus_error_free (&error);
       goto out;
     }
 
@@ -224,6 +263,8 @@ _dbus_auth_script_run (const DBusString *filename)
       else if (_dbus_string_starts_with_c_str (&line,
                                                "CLIENT"))
         {
+          DBusCredentials creds;
+          
           if (auth != NULL)
             {
               _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n");
@@ -236,10 +277,19 @@ _dbus_auth_script_run (const DBusString *filename)
               _dbus_warn ("no memory to create DBusAuth\n");
               goto out;
             }
+
+          /* test ref/unref */
+          _dbus_auth_ref (auth);
+          _dbus_auth_unref (auth);
+          
+          _dbus_credentials_from_current_process (&creds);
+          _dbus_auth_set_credentials (auth, &creds);
         }
       else if (_dbus_string_starts_with_c_str (&line,
                                                "SERVER"))
         {
+          DBusCredentials creds;
+          
           if (auth != NULL)
             {
               _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n");
@@ -252,6 +302,14 @@ _dbus_auth_script_run (const DBusString *filename)
               _dbus_warn ("no memory to create DBusAuth\n");
               goto out;
             }
+
+          /* test ref/unref */
+          _dbus_auth_ref (auth);
+          _dbus_auth_unref (auth);
+          
+          _dbus_credentials_from_current_process (&creds);
+          _dbus_auth_set_credentials (auth, &creds);
+          _dbus_auth_set_context (auth, &context);
         }
       else if (auth == NULL)
         {
@@ -260,13 +318,31 @@ _dbus_auth_script_run (const DBusString *filename)
 
         }
       else if (_dbus_string_starts_with_c_str (&line,
+                                               "NO_CREDENTIALS"))
+        {
+          DBusCredentials creds = { -1, -1, -1 };
+          _dbus_auth_set_credentials (auth, &creds);
+        }
+      else if (_dbus_string_starts_with_c_str (&line,
+                                               "ROOT_CREDENTIALS"))
+        {
+          DBusCredentials creds = { -1, 0, 0 };
+          _dbus_auth_set_credentials (auth, &creds);          
+        }
+      else if (_dbus_string_starts_with_c_str (&line,
+                                               "SILLY_CREDENTIALS"))
+        {
+          DBusCredentials creds = { -1, 4312, 1232 };
+          _dbus_auth_set_credentials (auth, &creds);          
+        }
+      else if (_dbus_string_starts_with_c_str (&line,
                                                "SEND"))
         {
           DBusString to_send;
           
           _dbus_string_delete_first_word (&line);
 
-          if (!_dbus_string_init (&to_send, _DBUS_INT_MAX))
+          if (!_dbus_string_init (&to_send))
             {
               _dbus_warn ("no memory to allocate string\n");
               goto out;
@@ -280,13 +356,108 @@ _dbus_auth_script_run (const DBusString *filename)
               goto out;
             }
 
-          if (!_dbus_auth_bytes_received (auth, &to_send))
+          _dbus_verbose ("Sending '%s'\n", _dbus_string_get_const_data (&to_send));
+          
+          if (!_dbus_string_append (&to_send, "\r\n"))
             {
-              _dbus_warn ("not enough memory to call bytes_received\n");
+              _dbus_warn ("failed to append \r\n from line %d\n",
+                          line_no);
               _dbus_string_free (&to_send);
               goto out;
             }
 
+          /* Replace USERID_BASE64 with our username in base64 */
+          {
+            int where;
+            
+            if (_dbus_string_find (&to_send, 0,
+                                   "USERID_BASE64", &where))
+              {
+                DBusString username;
+
+                if (!_dbus_string_init (&username))
+                  {
+                    _dbus_warn ("no memory for userid\n");
+                    _dbus_string_free (&to_send);
+                    goto out;
+                  }
+
+                if (!_dbus_string_append_uint (&username,
+                                               _dbus_getuid ()))
+                  {
+                    _dbus_warn ("no memory for userid\n");
+                    _dbus_string_free (&username);
+                    _dbus_string_free (&to_send);
+                    goto out;
+                  }
+
+                _dbus_string_delete (&to_send, where, strlen ("USERID_BASE64"));
+                
+                if (!_dbus_string_base64_encode (&username, 0,
+                                                 &to_send, where))
+                  {
+                    _dbus_warn ("no memory to subst USERID_BASE64\n");
+                    _dbus_string_free (&username);
+                    _dbus_string_free (&to_send);
+                    goto out;
+                  }
+
+                _dbus_string_free (&username);
+              }
+            else if (_dbus_string_find (&to_send, 0,
+                                        "USERNAME_BASE64", &where))
+              {
+                DBusString username;
+                const DBusString *u;
+                
+                if (!_dbus_string_init (&username))
+                  {
+                    _dbus_warn ("no memory for username\n");
+                    _dbus_string_free (&to_send);
+                    goto out;
+                  }
+
+                if (!_dbus_username_from_current_process (&u) ||
+                    !_dbus_string_copy (u, 0, &username,
+                                        _dbus_string_get_length (&username)))
+                  {
+                    _dbus_warn ("no memory for username\n");
+                    _dbus_string_free (&username);
+                    _dbus_string_free (&to_send);
+                    goto out;
+                  }
+
+                _dbus_string_delete (&to_send, where, strlen ("USERNAME_BASE64"));
+                
+                if (!_dbus_string_base64_encode (&username, 0,
+                                                 &to_send, where))
+                  {
+                    _dbus_warn ("no memory to subst USERNAME_BASE64\n");
+                    _dbus_string_free (&username);
+                    _dbus_string_free (&to_send);
+                    goto out;
+                  }
+
+                _dbus_string_free (&username);
+              }
+          }
+
+          {
+            DBusString *buffer;
+
+            _dbus_auth_get_buffer (auth, &buffer);
+            if (!_dbus_string_copy (&to_send, 0,
+                                    buffer, _dbus_string_get_length (buffer)))
+              {
+                _dbus_warn ("not enough memory to call bytes_received, or can't add bytes to auth object already in end state\n");
+                _dbus_string_free (&to_send);
+                _dbus_auth_return_buffer (auth, buffer, 0);
+                goto out;
+              }
+
+            _dbus_auth_return_buffer (auth, buffer, _dbus_string_get_length (&to_send));
+          }
+          
           _dbus_string_free (&to_send);
         }
       else if (_dbus_string_starts_with_c_str (&line,
@@ -319,7 +490,7 @@ _dbus_auth_script_run (const DBusString *filename)
           
           _dbus_string_delete_first_word (&line);
 
-          if (!_dbus_string_init (&received, _DBUS_INT_MAX))
+          if (!_dbus_string_init (&received))
             {
               _dbus_warn ("no mem to allocate string received\n");
               goto out;
@@ -327,27 +498,99 @@ _dbus_auth_script_run (const DBusString *filename)
 
           if (!_dbus_string_pop_line (&from_auth, &received))
             {
-              const char *command;
-              _dbus_string_get_const_data (&line, &command);
               _dbus_warn ("no line popped from the DBusAuth being tested, expected command %s on line %d\n",
-                          command, line_no);
+                          _dbus_string_get_const_data (&line), line_no);
               _dbus_string_free (&received);
               goto out;
             }
 
           if (!same_first_word (&received, &line))
             {
-              const char *s1, *s2;
-              _dbus_string_get_const_data (&line, &s1);
-              _dbus_string_get_const_data (&received, &s2);
-              _dbus_warn ("expected command '%s' and got '%s' line %d\n",
-                          s1, s2, line_no);
+              _dbus_warn ("line %d expected command '%s' and got '%s'\n",
+                          line_no,
+                          _dbus_string_get_const_data (&line),
+                          _dbus_string_get_const_data (&received));
               _dbus_string_free (&received);
               goto out;
             }
           
           _dbus_string_free (&received);
         }
+      else if (_dbus_string_starts_with_c_str (&line,
+                                               "EXPECT_UNUSED"))
+        {
+          DBusString expected;
+          const DBusString *unused;
+          
+          _dbus_string_delete_first_word (&line);
+
+          if (!_dbus_string_init (&expected))
+            {
+              _dbus_warn ("no mem to allocate string expected\n");
+              goto out;
+            }
+
+          if (!append_quoted_string (&expected, &line))
+            {
+              _dbus_warn ("failed to append quoted string line %d\n",
+                          line_no);
+              _dbus_string_free (&expected);
+              goto out;
+            }
+
+          _dbus_auth_get_unused_bytes (auth, &unused);
+          
+          if (_dbus_string_equal (&expected, unused))
+            {
+              _dbus_auth_delete_unused_bytes (auth);
+              _dbus_string_free (&expected);
+            }
+          else
+            {
+              _dbus_warn ("Expected unused bytes '%s' and have '%s'\n",
+                          _dbus_string_get_const_data (&expected),
+                          _dbus_string_get_const_data (unused));
+              _dbus_string_free (&expected);
+              goto out;
+            }
+        }
+      else if (_dbus_string_starts_with_c_str (&line,
+                                               "EXPECT"))
+        {
+          DBusString expected;
+          
+          _dbus_string_delete_first_word (&line);
+
+          if (!_dbus_string_init (&expected))
+            {
+              _dbus_warn ("no mem to allocate string expected\n");
+              goto out;
+            }
+
+          if (!append_quoted_string (&expected, &line))
+            {
+              _dbus_warn ("failed to append quoted string line %d\n",
+                          line_no);
+              _dbus_string_free (&expected);
+              goto out;
+            }
+
+          if (_dbus_string_equal_len (&expected, &from_auth,
+                                      _dbus_string_get_length (&expected)))
+            {
+              _dbus_string_delete (&from_auth, 0,
+                                   _dbus_string_get_length (&expected));
+              _dbus_string_free (&expected);
+            }
+          else
+            {
+              _dbus_warn ("Expected exact string '%s' and have '%s'\n",
+                          _dbus_string_get_const_data (&expected),
+                          _dbus_string_get_const_data (&from_auth));
+              _dbus_string_free (&expected);
+              goto out;
+            }
+        }
       else
         goto parse_failed;
 
@@ -355,10 +598,8 @@ _dbus_auth_script_run (const DBusString *filename)
       
     parse_failed:
       {
-        const char *s;
-        _dbus_string_get_const_data (&line, &s);
         _dbus_warn ("couldn't process line %d \"%s\"\n",
-                    line_no, s);
+                    line_no, _dbus_string_get_const_data (&line));
         goto out;
       }
     }
@@ -372,10 +613,8 @@ _dbus_auth_script_run (const DBusString *filename)
 
   if (_dbus_string_get_length (&from_auth) > 0)
     {
-      const char *s;
       _dbus_warn ("script did not have EXPECT_ statements for all the data received from the DBusAuth\n");
-      _dbus_string_get_const_data (&from_auth, &s);
-      _dbus_warn ("Leftover data: %s\n", s);
+      _dbus_warn ("Leftover data: %s\n", _dbus_string_get_const_data (&from_auth));
       goto out;
     }
   
@@ -386,7 +625,7 @@ _dbus_auth_script_run (const DBusString *filename)
     _dbus_auth_unref (auth);
 
   _dbus_string_free (&file);
-  _dbus_string_free (&file);
+  _dbus_string_free (&line);
   _dbus_string_free (&from_auth);
   
   return retval;