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