Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
      2 /* dbus-auth-script.c Test DBusAuth using a special script file (internal to D-Bus implementation)
      3  *
      4  * Copyright (C) 2003 Red Hat, Inc.
      5  *
      6  * Licensed under the Academic Free License version 2.1
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation; either version 2 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     21  *
     22  */
     23 #include <config.h>
     24 
     25 #ifdef DBUS_BUILD_TESTS
     26 
     27 #include "dbus-auth-script.h"
     28 #include "dbus-auth.h"
     29 #include "dbus-string.h"
     30 #include "dbus-hash.h"
     31 #include "dbus-credentials.h"
     32 #include "dbus-internals.h"
     33 
     34 /**
     35  * @defgroup DBusAuthScript code for running unit test scripts for DBusAuth
     36  * @ingroup  DBusInternals
     37  * @brief DBusAuth unit test scripting
     38  *
     39  * The code in here is used for unit testing, it loads
     40  * up a script that tests DBusAuth.
     41  *
     42  * @{
     43  */
     44 
     45 /* this is slightly different from the other append_quoted_string
     46  * in dbus-message-builder.c
     47  */
     48 static dbus_bool_t
     49 append_quoted_string (DBusString       *dest,
     50                       const DBusString *quoted)
     51 {
     52   dbus_bool_t in_quotes = FALSE;
     53   dbus_bool_t in_backslash = FALSE;
     54   int i;
     55 
     56   i = 0;
     57   while (i < _dbus_string_get_length (quoted))
     58     {
     59       unsigned char b;
     60 
     61       b = _dbus_string_get_byte (quoted, i);
     62 
     63       if (in_backslash)
     64         {
     65           unsigned char a;
     66 
     67           if (b == 'r')
     68             a = '\r';
     69           else if (b == 'n')
     70             a = '\n';
     71           else if (b == '\\')
     72             a = '\\';
     73           else
     74             {
     75               _dbus_warn ("bad backslashed byte %c\n", b);
     76               return FALSE;
     77             }
     78 
     79           if (!_dbus_string_append_byte (dest, a))
     80             return FALSE;
     81 
     82           in_backslash = FALSE;
     83         }
     84       else if (b == '\\')
     85         {
     86           in_backslash = TRUE;
     87         }
     88       else if (in_quotes)
     89         {
     90           if (b == '\'')
     91             in_quotes = FALSE;
     92           else
     93             {
     94               if (!_dbus_string_append_byte (dest, b))
     95                 return FALSE;
     96             }
     97         }
     98       else
     99         {
    100           if (b == '\'')
    101             in_quotes = TRUE;
    102           else if (b == ' ' || b == '\n' || b == '\t')
    103             break; /* end on whitespace if not quoted */
    104           else
    105             {
    106               if (!_dbus_string_append_byte (dest, b))
    107                 return FALSE;
    108             }
    109         }
    110 
    111       ++i;
    112     }
    113 
    114   return TRUE;
    115 }
    116 
    117 static dbus_bool_t
    118 same_first_word (const DBusString *a,
    119                  const DBusString *b)
    120 {
    121   int first_a_blank, first_b_blank;
    122 
    123   _dbus_string_find_blank (a, 0, &first_a_blank);
    124   _dbus_string_find_blank (b, 0, &first_b_blank);
    125 
    126   if (first_a_blank != first_b_blank)
    127     return FALSE;
    128 
    129   return _dbus_string_equal_len (a, b, first_a_blank);
    130 }
    131 
    132 static DBusAuthState
    133 auth_state_from_string (const DBusString *str)
    134 {
    135   if (_dbus_string_starts_with_c_str (str, "WAITING_FOR_INPUT"))
    136     return DBUS_AUTH_STATE_WAITING_FOR_INPUT;
    137   else if (_dbus_string_starts_with_c_str (str, "WAITING_FOR_MEMORY"))
    138     return DBUS_AUTH_STATE_WAITING_FOR_MEMORY;
    139   else if (_dbus_string_starts_with_c_str (str, "HAVE_BYTES_TO_SEND"))
    140     return DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND;
    141   else if (_dbus_string_starts_with_c_str (str, "NEED_DISCONNECT"))
    142     return DBUS_AUTH_STATE_NEED_DISCONNECT;
    143   else if (_dbus_string_starts_with_c_str (str, "AUTHENTICATED"))
    144     return DBUS_AUTH_STATE_AUTHENTICATED;
    145   else
    146     return -1;
    147 }
    148 
    149 static const char*
    150 auth_state_to_string (DBusAuthState state)
    151 {
    152   switch (state)
    153     {
    154     case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
    155       return "WAITING_FOR_INPUT";
    156     case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
    157       return "WAITING_FOR_MEMORY";
    158     case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
    159       return "HAVE_BYTES_TO_SEND";
    160     case DBUS_AUTH_STATE_NEED_DISCONNECT:
    161       return "NEED_DISCONNECT";
    162     case DBUS_AUTH_STATE_AUTHENTICATED:
    163       return "AUTHENTICATED";
    164     }
    165 
    166   return "unknown";
    167 }
    168 
    169 static char **
    170 split_string (DBusString *str)
    171 {
    172   int i, j, k, count, end;
    173   char **array;
    174 
    175   end = _dbus_string_get_length (str);
    176 
    177   i = 0;
    178   _dbus_string_skip_blank (str, i, &i);
    179   for (count = 0; i < end; count++)
    180     {
    181       _dbus_string_find_blank (str, i, &i);
    182       _dbus_string_skip_blank (str, i, &i);
    183     }
    184 
    185   array = dbus_new0 (char *, count + 1);
    186   if (array == NULL)
    187     return NULL;
    188 
    189   i = 0;
    190   _dbus_string_skip_blank (str, i, &i);
    191   for (k = 0; k < count; k++)
    192     {
    193       _dbus_string_find_blank (str, i, &j);
    194 
    195       array[k] = dbus_malloc (j - i + 1);
    196       if (array[k] == NULL)
    197         {
    198           dbus_free_string_array (array);
    199           return NULL;
    200         }
    201       memcpy (array[k],
    202               _dbus_string_get_const_data_len (str, i, j - i), j - i);
    203       array[k][j - i] = '\0';
    204 
    205       _dbus_string_skip_blank (str, j, &i);
    206     }
    207   array[k] = NULL;
    208 
    209   return array;
    210 }
    211 
    212 static void
    213 auth_set_unix_credentials(DBusAuth  *auth,
    214                           dbus_uid_t uid,
    215                           dbus_pid_t pid)
    216 {
    217   DBusCredentials *credentials;
    218 
    219   credentials = _dbus_credentials_new ();
    220   if (credentials == NULL)
    221     _dbus_assert_not_reached ("no memory");
    222 
    223   if (uid != DBUS_UID_UNSET)
    224     _dbus_credentials_add_unix_uid (credentials, uid);
    225   if (pid != DBUS_PID_UNSET)
    226     _dbus_credentials_add_unix_pid (credentials, pid);
    227 
    228   _dbus_auth_set_credentials (auth, credentials);
    229 
    230   _dbus_credentials_unref (credentials);
    231 }
    232 
    233 /**
    234  * Runs an "auth script" which is a script for testing the
    235  * authentication protocol. Scripts send and receive data, and then
    236  * include assertions about the state of both ends of the connection
    237  * after processing the data. A script succeeds if these assertions
    238  * hold.
    239  *
    240  * @param filename the file containing the script to run
    241  * @returns #TRUE if the script succeeds, #FALSE otherwise
    242  */
    243 dbus_bool_t
    244 _dbus_auth_script_run (const DBusString *filename)
    245 {
    246   DBusString file;
    247   DBusError error = DBUS_ERROR_INIT;
    248   DBusString line;
    249   dbus_bool_t retval;
    250   int line_no;
    251   DBusAuth *auth;
    252   DBusString from_auth;
    253   DBusAuthState state;
    254   DBusString context;
    255   DBusString guid;
    256 
    257   retval = FALSE;
    258   auth = NULL;
    259 
    260   _dbus_string_init_const (&guid, "5fa01f4202cd837709a3274ca0df9d00");
    261   _dbus_string_init_const (&context, "org_freedesktop_test");
    262 
    263   if (!_dbus_string_init (&file))
    264     return FALSE;
    265 
    266   if (!_dbus_string_init (&line))
    267     {
    268       _dbus_string_free (&file);
    269       return FALSE;
    270     }
    271 
    272   if (!_dbus_string_init (&from_auth))
    273     {
    274       _dbus_string_free (&file);
    275       _dbus_string_free (&line);
    276       return FALSE;
    277     }
    278 
    279   if (!_dbus_file_get_contents (&file, filename, &error))    {
    280       _dbus_warn ("Getting contents of %s failed: %s\n",
    281                   _dbus_string_get_const_data (filename), error.message);
    282       dbus_error_free (&error);
    283       goto out;
    284     }
    285 
    286   state = DBUS_AUTH_STATE_NEED_DISCONNECT;
    287   line_no = 0;
    288 
    289  next_iteration:
    290   while (_dbus_string_pop_line (&file, &line))
    291     {
    292       line_no += 1;
    293 
    294       /* _dbus_warn ("%s\n", _dbus_string_get_const_data (&line)); */
    295 
    296       _dbus_string_delete_leading_blanks (&line);
    297 
    298       if (auth != NULL)
    299         {
    300           while ((state = _dbus_auth_do_work (auth)) ==
    301                  DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
    302             {
    303               const DBusString *tmp;
    304               if (_dbus_auth_get_bytes_to_send (auth, &tmp))
    305                 {
    306                   int count = _dbus_string_get_length (tmp);
    307 
    308                   if (_dbus_string_copy (tmp, 0, &from_auth,
    309                                          _dbus_string_get_length (&from_auth)))
    310                     _dbus_auth_bytes_sent (auth, count);
    311                 }
    312             }
    313         }
    314 
    315       if (_dbus_string_get_length (&line) == 0)
    316         {
    317           /* empty line */
    318           goto next_iteration;
    319         }
    320       else if (_dbus_string_starts_with_c_str (&line,
    321                                                "#"))
    322         {
    323           /* Ignore this comment */
    324           goto next_iteration;
    325         }
    326 #ifdef DBUS_WIN
    327       else if (_dbus_string_starts_with_c_str (&line,
    328                                                "WIN_ONLY"))
    329         {
    330           /* Ignore this line */
    331           goto next_iteration;
    332         }
    333       else if (_dbus_string_starts_with_c_str (&line,
    334                                                "UNIX_ONLY"))
    335         {
    336           /* skip this file */
    337           _dbus_warn ("skipping unix only auth script\n");
    338           retval = TRUE;
    339           goto out;
    340         }
    341 #endif
    342 #ifdef DBUS_UNIX
    343       else if (_dbus_string_starts_with_c_str (&line,
    344                                                "UNIX_ONLY"))
    345         {
    346           /* Ignore this line */
    347           goto next_iteration;
    348         }
    349       else if (_dbus_string_starts_with_c_str (&line,
    350                                                "WIN_ONLY"))
    351         {
    352           /* skip this file */
    353           _dbus_warn ("skipping windows only auth script\n");
    354           retval = TRUE;
    355           goto out;
    356         }
    357 #endif
    358       else if (_dbus_string_starts_with_c_str (&line,
    359                                                "CLIENT"))
    360         {
    361           DBusCredentials *creds;
    362 
    363           if (auth != NULL)
    364             {
    365               _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n");
    366               goto out;
    367             }
    368 
    369           auth = _dbus_auth_client_new ();
    370           if (auth == NULL)
    371             {
    372               _dbus_warn ("no memory to create DBusAuth\n");
    373               goto out;
    374             }
    375 
    376           /* test ref/unref */
    377           _dbus_auth_ref (auth);
    378           _dbus_auth_unref (auth);
    379 
    380           creds = _dbus_credentials_new_from_current_process ();
    381           if (creds == NULL)
    382             {
    383               _dbus_warn ("no memory for credentials\n");
    384               _dbus_auth_unref (auth);
    385               auth = NULL;
    386               goto out;
    387             }
    388 
    389           if (!_dbus_auth_set_credentials (auth, creds))
    390             {
    391               _dbus_warn ("no memory for setting credentials\n");
    392               _dbus_auth_unref (auth);
    393               auth = NULL;
    394               _dbus_credentials_unref (creds);
    395               goto out;
    396             }
    397 
    398           _dbus_credentials_unref (creds);
    399         }
    400       else if (_dbus_string_starts_with_c_str (&line,
    401                                                "SERVER"))
    402         {
    403           DBusCredentials *creds;
    404 
    405           if (auth != NULL)
    406             {
    407               _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n");
    408               goto out;
    409             }
    410 
    411           auth = _dbus_auth_server_new (&guid);
    412           if (auth == NULL)
    413             {
    414               _dbus_warn ("no memory to create DBusAuth\n");
    415               goto out;
    416             }
    417 
    418           /* test ref/unref */
    419           _dbus_auth_ref (auth);
    420           _dbus_auth_unref (auth);
    421 
    422           creds = _dbus_credentials_new_from_current_process ();
    423           if (creds == NULL)
    424             {
    425               _dbus_warn ("no memory for credentials\n");
    426               _dbus_auth_unref (auth);
    427               auth = NULL;
    428               goto out;
    429             }
    430 
    431           if (!_dbus_auth_set_credentials (auth, creds))
    432             {
    433               _dbus_warn ("no memory for setting credentials\n");
    434               _dbus_auth_unref (auth);
    435               auth = NULL;
    436               _dbus_credentials_unref (creds);
    437               goto out;
    438             }
    439 
    440           _dbus_credentials_unref (creds);
    441 
    442           _dbus_auth_set_context (auth, &context);
    443         }
    444       else if (auth == NULL)
    445         {
    446           _dbus_warn ("must specify CLIENT or SERVER\n");
    447           goto out;
    448 
    449         }
    450       else if (_dbus_string_starts_with_c_str (&line,
    451                                                "NO_CREDENTIALS"))
    452         {
    453           auth_set_unix_credentials (auth, DBUS_UID_UNSET, DBUS_PID_UNSET);
    454         }
    455       else if (_dbus_string_starts_with_c_str (&line,
    456                                                "ROOT_CREDENTIALS"))
    457         {
    458           auth_set_unix_credentials (auth, 0, DBUS_PID_UNSET);
    459         }
    460       else if (_dbus_string_starts_with_c_str (&line,
    461                                                "SILLY_CREDENTIALS"))
    462         {
    463           auth_set_unix_credentials (auth, 4312, DBUS_PID_UNSET);
    464         }
    465       else if (_dbus_string_starts_with_c_str (&line,
    466                                                "ALLOWED_MECHS"))
    467         {
    468           char **mechs;
    469 
    470           _dbus_string_delete_first_word (&line);
    471           mechs = split_string (&line);
    472           _dbus_auth_set_mechanisms (auth, (const char **) mechs);
    473           dbus_free_string_array (mechs);
    474         }
    475       else if (_dbus_string_starts_with_c_str (&line,
    476                                                "SEND"))
    477         {
    478           DBusString to_send;
    479 
    480           _dbus_string_delete_first_word (&line);
    481 
    482           if (!_dbus_string_init (&to_send))
    483             {
    484               _dbus_warn ("no memory to allocate string\n");
    485               goto out;
    486             }
    487 
    488           if (!append_quoted_string (&to_send, &line))
    489             {
    490               _dbus_warn ("failed to append quoted string line %d\n",
    491                           line_no);
    492               _dbus_string_free (&to_send);
    493               goto out;
    494             }
    495 
    496           _dbus_verbose ("Sending '%s'\n", _dbus_string_get_const_data (&to_send));
    497 
    498           if (!_dbus_string_append (&to_send, "\r\n"))
    499             {
    500               _dbus_warn ("failed to append \r\n from line %d\n",
    501                           line_no);
    502               _dbus_string_free (&to_send);
    503               goto out;
    504             }
    505 
    506           /* Replace USERID_HEX with our username in hex */
    507           {
    508             int where;
    509 
    510             if (_dbus_string_find (&to_send, 0,
    511                                    "USERID_HEX", &where))
    512               {
    513                 DBusString username;
    514 
    515                 if (!_dbus_string_init (&username))
    516                   {
    517                     _dbus_warn ("no memory for userid\n");
    518                     _dbus_string_free (&to_send);
    519                     goto out;
    520                   }
    521 
    522                 if (!_dbus_append_user_from_current_process (&username))
    523                   {
    524                     _dbus_warn ("no memory for userid\n");
    525                     _dbus_string_free (&username);
    526                     _dbus_string_free (&to_send);
    527                     goto out;
    528                   }
    529 
    530                 _dbus_string_delete (&to_send, where, strlen ("USERID_HEX"));
    531 
    532                 if (!_dbus_string_hex_encode (&username, 0,
    533 					      &to_send, where))
    534                   {
    535                     _dbus_warn ("no memory to subst USERID_HEX\n");
    536                     _dbus_string_free (&username);
    537                     _dbus_string_free (&to_send);
    538                     goto out;
    539                   }
    540 
    541                 _dbus_string_free (&username);
    542               }
    543             else if (_dbus_string_find (&to_send, 0,
    544                                         "USERNAME_HEX", &where))
    545               {
    546                 DBusString username;
    547 
    548                 if (!_dbus_string_init (&username))
    549                   {
    550                     _dbus_warn ("no memory for username\n");
    551                     _dbus_string_free (&to_send);
    552                     goto out;
    553                   }
    554 
    555                 if (!_dbus_append_user_from_current_process (&username))
    556                   {
    557                     _dbus_warn ("no memory for username\n");
    558                     _dbus_string_free (&username);
    559                     _dbus_string_free (&to_send);
    560                     goto out;
    561                   }
    562 
    563                 _dbus_string_delete (&to_send, where, strlen ("USERNAME_HEX"));
    564 
    565                 if (!_dbus_string_hex_encode (&username, 0,
    566 					      &to_send, where))
    567                   {
    568                     _dbus_warn ("no memory to subst USERNAME_HEX\n");
    569                     _dbus_string_free (&username);
    570                     _dbus_string_free (&to_send);
    571                     goto out;
    572                   }
    573 
    574                 _dbus_string_free (&username);
    575               }
    576           }
    577 
    578           {
    579             DBusString *buffer;
    580 
    581             _dbus_auth_get_buffer (auth, &buffer);
    582             if (!_dbus_string_copy (&to_send, 0,
    583                                     buffer, _dbus_string_get_length (buffer)))
    584               {
    585                 _dbus_warn ("not enough memory to call bytes_received, or can't add bytes to auth object already in end state\n");
    586                 _dbus_string_free (&to_send);
    587                 _dbus_auth_return_buffer (auth, buffer, 0);
    588                 goto out;
    589               }
    590 
    591             _dbus_auth_return_buffer (auth, buffer, _dbus_string_get_length (&to_send));
    592           }
    593 
    594           _dbus_string_free (&to_send);
    595         }
    596       else if (_dbus_string_starts_with_c_str (&line,
    597                                                "EXPECT_STATE"))
    598         {
    599           DBusAuthState expected;
    600 
    601           _dbus_string_delete_first_word (&line);
    602 
    603           expected = auth_state_from_string (&line);
    604           if (expected < 0)
    605             {
    606               _dbus_warn ("bad auth state given to EXPECT_STATE\n");
    607               goto parse_failed;
    608             }
    609 
    610           if (expected != state)
    611             {
    612               _dbus_warn ("expected auth state %s but got %s on line %d\n",
    613                           auth_state_to_string (expected),
    614                           auth_state_to_string (state),
    615                           line_no);
    616               goto out;
    617             }
    618         }
    619       else if (_dbus_string_starts_with_c_str (&line,
    620                                                "EXPECT_COMMAND"))
    621         {
    622           DBusString received;
    623 
    624           _dbus_string_delete_first_word (&line);
    625 
    626           if (!_dbus_string_init (&received))
    627             {
    628               _dbus_warn ("no mem to allocate string received\n");
    629               goto out;
    630             }
    631 
    632           if (!_dbus_string_pop_line (&from_auth, &received))
    633             {
    634               _dbus_warn ("no line popped from the DBusAuth being tested, expected command %s on line %d\n",
    635                           _dbus_string_get_const_data (&line), line_no);
    636               _dbus_string_free (&received);
    637               goto out;
    638             }
    639 
    640           if (!same_first_word (&received, &line))
    641             {
    642               _dbus_warn ("line %d expected command '%s' and got '%s'\n",
    643                           line_no,
    644                           _dbus_string_get_const_data (&line),
    645                           _dbus_string_get_const_data (&received));
    646               _dbus_string_free (&received);
    647               goto out;
    648             }
    649 
    650           _dbus_string_free (&received);
    651         }
    652       else if (_dbus_string_starts_with_c_str (&line,
    653                                                "EXPECT_UNUSED"))
    654         {
    655           DBusString expected;
    656           const DBusString *unused;
    657 
    658           _dbus_string_delete_first_word (&line);
    659 
    660           if (!_dbus_string_init (&expected))
    661             {
    662               _dbus_warn ("no mem to allocate string expected\n");
    663               goto out;
    664             }
    665 
    666           if (!append_quoted_string (&expected, &line))
    667             {
    668               _dbus_warn ("failed to append quoted string line %d\n",
    669                           line_no);
    670               _dbus_string_free (&expected);
    671               goto out;
    672             }
    673 
    674           _dbus_auth_get_unused_bytes (auth, &unused);
    675 
    676           if (_dbus_string_equal (&expected, unused))
    677             {
    678               _dbus_auth_delete_unused_bytes (auth);
    679               _dbus_string_free (&expected);
    680             }
    681           else
    682             {
    683               _dbus_warn ("Expected unused bytes '%s' and have '%s'\n",
    684                           _dbus_string_get_const_data (&expected),
    685                           _dbus_string_get_const_data (unused));
    686               _dbus_string_free (&expected);
    687               goto out;
    688             }
    689         }
    690       else if (_dbus_string_starts_with_c_str (&line,
    691                                                "EXPECT_HAVE_NO_CREDENTIALS"))
    692         {
    693           DBusCredentials *authorized_identity;
    694 
    695           authorized_identity = _dbus_auth_get_identity (auth);
    696           if (!_dbus_credentials_are_anonymous (authorized_identity))
    697             {
    698               _dbus_warn ("Expected anonymous login or failed login, but some credentials were authorized\n");
    699               goto out;
    700             }
    701         }
    702       else if (_dbus_string_starts_with_c_str (&line,
    703                                                "EXPECT_HAVE_SOME_CREDENTIALS"))
    704         {
    705           DBusCredentials *authorized_identity;
    706 
    707           authorized_identity = _dbus_auth_get_identity (auth);
    708           if (_dbus_credentials_are_anonymous (authorized_identity))
    709             {
    710               _dbus_warn ("Expected to have some credentials, but we don't\n");
    711               goto out;
    712             }
    713         }
    714       else if (_dbus_string_starts_with_c_str (&line,
    715                                                "EXPECT"))
    716         {
    717           DBusString expected;
    718 
    719           _dbus_string_delete_first_word (&line);
    720 
    721           if (!_dbus_string_init (&expected))
    722             {
    723               _dbus_warn ("no mem to allocate string expected\n");
    724               goto out;
    725             }
    726 
    727           if (!append_quoted_string (&expected, &line))
    728             {
    729               _dbus_warn ("failed to append quoted string line %d\n",
    730                           line_no);
    731               _dbus_string_free (&expected);
    732               goto out;
    733             }
    734 
    735           if (_dbus_string_equal_len (&expected, &from_auth,
    736                                       _dbus_string_get_length (&expected)))
    737             {
    738               _dbus_string_delete (&from_auth, 0,
    739                                    _dbus_string_get_length (&expected));
    740               _dbus_string_free (&expected);
    741             }
    742           else
    743             {
    744               _dbus_warn ("Expected exact string '%s' and have '%s'\n",
    745                           _dbus_string_get_const_data (&expected),
    746                           _dbus_string_get_const_data (&from_auth));
    747               _dbus_string_free (&expected);
    748               goto out;
    749             }
    750         }
    751       else
    752         goto parse_failed;
    753 
    754       goto next_iteration; /* skip parse_failed */
    755 
    756     parse_failed:
    757       {
    758         _dbus_warn ("couldn't process line %d \"%s\"\n",
    759                     line_no, _dbus_string_get_const_data (&line));
    760         goto out;
    761       }
    762     }
    763 
    764   if (auth == NULL)
    765     {
    766       _dbus_warn ("Auth script is bogus, did not even have CLIENT or SERVER\n");
    767       goto out;
    768     }
    769   else if (state == DBUS_AUTH_STATE_AUTHENTICATED)
    770     {
    771       const DBusString *unused;
    772 
    773       _dbus_auth_get_unused_bytes (auth, &unused);
    774 
    775       if (_dbus_string_get_length (unused) > 0)
    776         {
    777           _dbus_warn ("did not expect unused bytes (scripts must specify explicitly if they are expected)\n");
    778           goto out;
    779         }
    780     }
    781 
    782   if (_dbus_string_get_length (&from_auth) > 0)
    783     {
    784       _dbus_warn ("script did not have EXPECT_ statements for all the data received from the DBusAuth\n");
    785       _dbus_warn ("Leftover data: %s\n", _dbus_string_get_const_data (&from_auth));
    786       goto out;
    787     }
    788 
    789   retval = TRUE;
    790 
    791  out:
    792   if (auth)
    793     _dbus_auth_unref (auth);
    794 
    795   _dbus_string_free (&file);
    796   _dbus_string_free (&line);
    797   _dbus_string_free (&from_auth);
    798 
    799   return retval;
    800 }
    801 
    802 /** @} */
    803 #endif /* DBUS_BUILD_TESTS */
    804