~ubuntu-branches/ubuntu/maverick/dbus/maverick-security

« back to all changes in this revision

Viewing changes to dbus/dbus-auth.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-27 13:06:32 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20100927130632-bqs145trvchd2lmf
Tags: 1.4.0-0ubuntu1
* New upstream release
 - Fixes https://bugs.freedesktop.org/show_bug.cgi?id=17754 Race condition in protected_change_timeout
 - Requested by various upstream KDE developers http://lists.kde.org/?t=128514970000004&r=1&w=2

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
21
 *
22
22
 */
 
23
 
 
24
#include <config.h>
23
25
#include "dbus-auth.h"
24
26
#include "dbus-string.h"
25
27
#include "dbus-list.h"
122
124
  DBUS_AUTH_COMMAND_REJECTED,
123
125
  DBUS_AUTH_COMMAND_OK,
124
126
  DBUS_AUTH_COMMAND_ERROR,
125
 
  DBUS_AUTH_COMMAND_UNKNOWN
 
127
  DBUS_AUTH_COMMAND_UNKNOWN,
 
128
  DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD,
 
129
  DBUS_AUTH_COMMAND_AGREE_UNIX_FD
126
130
} DBusAuthCommand;
127
131
 
128
132
/**
184
188
  unsigned int already_got_mechanisms : 1;       /**< Client already got mech list */
185
189
  unsigned int already_asked_for_initial_response : 1; /**< Already sent a blank challenge to get an initial response */
186
190
  unsigned int buffer_outstanding : 1; /**< Buffer is "checked out" for reading data into */
 
191
 
 
192
  unsigned int unix_fd_possible : 1;  /**< This side could do unix fd passing */
 
193
  unsigned int unix_fd_negotiated : 1; /**< Unix fd was successfully negotiated */
187
194
};
188
195
 
189
196
/**
223
230
static dbus_bool_t send_error                (DBusAuth *auth,
224
231
                                              const char *message);
225
232
static dbus_bool_t send_ok                   (DBusAuth *auth);
226
 
static dbus_bool_t send_begin                (DBusAuth *auth,
227
 
                                              const DBusString *args_from_ok);
 
233
static dbus_bool_t send_begin                (DBusAuth *auth);
228
234
static dbus_bool_t send_cancel               (DBusAuth *auth);
 
235
static dbus_bool_t send_negotiate_unix_fd    (DBusAuth *auth);
 
236
static dbus_bool_t send_agree_unix_fd        (DBusAuth *auth);
229
237
 
230
238
/**
231
239
 * Client states
264
272
static dbus_bool_t handle_client_state_waiting_for_reject (DBusAuth         *auth,
265
273
                                                           DBusAuthCommand   command,
266
274
                                                           const DBusString *args);
 
275
static dbus_bool_t handle_client_state_waiting_for_agree_unix_fd (DBusAuth         *auth,
 
276
                                                           DBusAuthCommand   command,
 
277
                                                           const DBusString *args);
267
278
 
268
279
static const DBusAuthStateData client_state_need_send_auth = {
269
280
  "NeedSendAuth", NULL
277
288
static const DBusAuthStateData client_state_waiting_for_reject = {
278
289
  "WaitingForReject", handle_client_state_waiting_for_reject
279
290
};
280
 
  
 
291
static const DBusAuthStateData client_state_waiting_for_agree_unix_fd = {
 
292
  "WaitingForAgreeUnixFD", handle_client_state_waiting_for_agree_unix_fd
 
293
};
 
294
 
281
295
/**
282
296
 * Common terminal states.  Terminal states have handler == NULL.
283
297
 */
1192
1206
          {
1193
1207
            DBusString plaintext;
1194
1208
            DBusString encoded;
1195
 
            _dbus_string_init_const (&plaintext, "D-Bus " VERSION);
 
1209
            _dbus_string_init_const (&plaintext, "D-Bus " DBUS_VERSION_STRING);
1196
1210
            _dbus_string_init (&encoded);
1197
1211
            _dbus_string_hex_encode (&plaintext, 0,
1198
1212
                                     &encoded,
1250
1264
    return FALSE;
1251
1265
 
1252
1266
  if (!_dbus_string_append (&plaintext,
1253
 
                            "libdbus " VERSION))
 
1267
                            "libdbus " DBUS_VERSION_STRING))
1254
1268
    goto failed;
1255
1269
 
1256
1270
  if (!_dbus_string_hex_encode (&plaintext, 0,
1522
1536
}
1523
1537
 
1524
1538
static dbus_bool_t
1525
 
send_begin (DBusAuth         *auth,
1526
 
            const DBusString *args_from_ok)
 
1539
send_begin (DBusAuth         *auth)
1527
1540
{
 
1541
 
 
1542
  if (!_dbus_string_append (&auth->outgoing,
 
1543
                            "BEGIN\r\n"))
 
1544
    return FALSE;
 
1545
 
 
1546
  goto_state (auth, &common_state_authenticated);
 
1547
  return TRUE;
 
1548
}
 
1549
 
 
1550
static dbus_bool_t
 
1551
process_ok(DBusAuth *auth,
 
1552
          const DBusString *args_from_ok) {
 
1553
 
1528
1554
  int end_of_hex;
1529
1555
  
1530
1556
  /* "args_from_ok" should be the GUID, whitespace already pulled off the front */
1549
1575
      return TRUE;
1550
1576
    }
1551
1577
 
1552
 
  if (_dbus_string_copy (args_from_ok, 0, &DBUS_AUTH_CLIENT (auth)->guid_from_server, 0) &&
1553
 
      _dbus_string_append (&auth->outgoing, "BEGIN\r\n"))
1554
 
    {
1555
 
      _dbus_verbose ("Got GUID '%s' from the server\n",
1556
 
                     _dbus_string_get_const_data (& DBUS_AUTH_CLIENT (auth)->guid_from_server));
1557
 
      
1558
 
      goto_state (auth, &common_state_authenticated);
1559
 
      return TRUE;
1560
 
    }
1561
 
  else
1562
 
    {
 
1578
  if (!_dbus_string_copy (args_from_ok, 0, &DBUS_AUTH_CLIENT (auth)->guid_from_server, 0)) {
1563
1579
      _dbus_string_set_length (& DBUS_AUTH_CLIENT (auth)->guid_from_server, 0);
1564
1580
      return FALSE;
1565
 
    }
 
1581
  }
 
1582
 
 
1583
  _dbus_verbose ("Got GUID '%s' from the server\n",
 
1584
                 _dbus_string_get_const_data (& DBUS_AUTH_CLIENT (auth)->guid_from_server));
 
1585
 
 
1586
  if (auth->unix_fd_possible)
 
1587
    return send_negotiate_unix_fd(auth);
 
1588
 
 
1589
  _dbus_verbose("Not negotiating unix fd passing, since not possible\n");
 
1590
  return send_begin (auth);
1566
1591
}
1567
1592
 
1568
1593
static dbus_bool_t
1622
1647
}
1623
1648
 
1624
1649
static dbus_bool_t
 
1650
send_negotiate_unix_fd (DBusAuth *auth)
 
1651
{
 
1652
  if (!_dbus_string_append (&auth->outgoing,
 
1653
                            "NEGOTIATE_UNIX_FD\r\n"))
 
1654
    return FALSE;
 
1655
 
 
1656
  goto_state (auth, &client_state_waiting_for_agree_unix_fd);
 
1657
  return TRUE;
 
1658
}
 
1659
 
 
1660
static dbus_bool_t
 
1661
send_agree_unix_fd (DBusAuth *auth)
 
1662
{
 
1663
  _dbus_assert(auth->unix_fd_possible);
 
1664
 
 
1665
  auth->unix_fd_negotiated = TRUE;
 
1666
  _dbus_verbose("Agreed to UNIX FD passing\n");
 
1667
 
 
1668
  if (!_dbus_string_append (&auth->outgoing,
 
1669
                            "AGREE_UNIX_FD\r\n"))
 
1670
    return FALSE;
 
1671
 
 
1672
  goto_state (auth, &server_state_waiting_for_begin);
 
1673
  return TRUE;
 
1674
}
 
1675
 
 
1676
static dbus_bool_t
1625
1677
handle_auth (DBusAuth *auth, const DBusString *args)
1626
1678
{
1627
1679
  if (_dbus_string_get_length (args) == 0)
1712
1764
    case DBUS_AUTH_COMMAND_ERROR:
1713
1765
      return send_rejected (auth);
1714
1766
 
 
1767
    case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD:
 
1768
      return send_error (auth, "Need to authenticate first");
 
1769
 
1715
1770
    case DBUS_AUTH_COMMAND_REJECTED:
1716
1771
    case DBUS_AUTH_COMMAND_OK:
1717
1772
    case DBUS_AUTH_COMMAND_UNKNOWN:
 
1773
    case DBUS_AUTH_COMMAND_AGREE_UNIX_FD:
1718
1774
    default:
1719
1775
      return send_error (auth, "Unknown command");
1720
1776
    }
1741
1797
      goto_state (auth, &common_state_need_disconnect);
1742
1798
      return TRUE;
1743
1799
 
 
1800
    case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD:
 
1801
      return send_error (auth, "Need to authenticate first");
 
1802
 
1744
1803
    case DBUS_AUTH_COMMAND_REJECTED:
1745
1804
    case DBUS_AUTH_COMMAND_OK:
1746
1805
    case DBUS_AUTH_COMMAND_UNKNOWN:
 
1806
    case DBUS_AUTH_COMMAND_AGREE_UNIX_FD:
1747
1807
    default:
1748
1808
      return send_error (auth, "Unknown command");
1749
1809
    }
1766
1826
      goto_state (auth, &common_state_authenticated);
1767
1827
      return TRUE;
1768
1828
 
 
1829
    case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD:
 
1830
      if (auth->unix_fd_possible)
 
1831
        return send_agree_unix_fd(auth);
 
1832
      else
 
1833
        return send_error(auth, "Unix FD passing not supported, not authenticated or otherwise not possible");
 
1834
 
1769
1835
    case DBUS_AUTH_COMMAND_REJECTED:
1770
1836
    case DBUS_AUTH_COMMAND_OK:
1771
1837
    case DBUS_AUTH_COMMAND_UNKNOWN:
 
1838
    case DBUS_AUTH_COMMAND_AGREE_UNIX_FD:
1772
1839
    default:
1773
1840
      return send_error (auth, "Unknown command");
1774
1841
 
1933
2000
      return process_rejected (auth, args);
1934
2001
 
1935
2002
    case DBUS_AUTH_COMMAND_OK:
1936
 
      return send_begin (auth, args);
 
2003
      return process_ok(auth, args);
1937
2004
 
1938
2005
    case DBUS_AUTH_COMMAND_ERROR:
1939
2006
      return send_cancel (auth);
1942
2009
    case DBUS_AUTH_COMMAND_CANCEL:
1943
2010
    case DBUS_AUTH_COMMAND_BEGIN:
1944
2011
    case DBUS_AUTH_COMMAND_UNKNOWN:
 
2012
    case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD:
 
2013
    case DBUS_AUTH_COMMAND_AGREE_UNIX_FD:
1945
2014
    default:
1946
2015
      return send_error (auth, "Unknown command");
1947
2016
    }
1958
2027
      return process_rejected (auth, args);
1959
2028
 
1960
2029
    case DBUS_AUTH_COMMAND_OK:
1961
 
      return send_begin (auth, args);
 
2030
      return process_ok(auth, args);
1962
2031
 
1963
2032
    case DBUS_AUTH_COMMAND_DATA:
1964
2033
    case DBUS_AUTH_COMMAND_ERROR:
1968
2037
    case DBUS_AUTH_COMMAND_CANCEL:
1969
2038
    case DBUS_AUTH_COMMAND_BEGIN:
1970
2039
    case DBUS_AUTH_COMMAND_UNKNOWN:
 
2040
    case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD:
 
2041
    case DBUS_AUTH_COMMAND_AGREE_UNIX_FD:
1971
2042
    default:
1972
2043
      return send_error (auth, "Unknown command");
1973
2044
    }
1990
2061
    case DBUS_AUTH_COMMAND_OK:
1991
2062
    case DBUS_AUTH_COMMAND_ERROR:
1992
2063
    case DBUS_AUTH_COMMAND_UNKNOWN:
 
2064
    case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD:
 
2065
    case DBUS_AUTH_COMMAND_AGREE_UNIX_FD:
1993
2066
    default:
1994
2067
      goto_state (auth, &common_state_need_disconnect);
1995
2068
      return TRUE;
1996
2069
    }
1997
2070
}
1998
2071
 
 
2072
static dbus_bool_t
 
2073
handle_client_state_waiting_for_agree_unix_fd(DBusAuth         *auth,
 
2074
                                              DBusAuthCommand   command,
 
2075
                                              const DBusString *args)
 
2076
{
 
2077
  switch (command)
 
2078
    {
 
2079
    case DBUS_AUTH_COMMAND_AGREE_UNIX_FD:
 
2080
      _dbus_assert(auth->unix_fd_possible);
 
2081
      auth->unix_fd_negotiated = TRUE;
 
2082
      _dbus_verbose("Sucessfully negotiated UNIX FD passing\n");
 
2083
      return send_begin (auth);
 
2084
 
 
2085
    case DBUS_AUTH_COMMAND_ERROR:
 
2086
      _dbus_assert(auth->unix_fd_possible);
 
2087
      auth->unix_fd_negotiated = FALSE;
 
2088
      _dbus_verbose("Failed to negotiate UNIX FD passing\n");
 
2089
      return send_begin (auth);
 
2090
 
 
2091
    case DBUS_AUTH_COMMAND_OK:
 
2092
    case DBUS_AUTH_COMMAND_DATA:
 
2093
    case DBUS_AUTH_COMMAND_REJECTED:
 
2094
    case DBUS_AUTH_COMMAND_AUTH:
 
2095
    case DBUS_AUTH_COMMAND_CANCEL:
 
2096
    case DBUS_AUTH_COMMAND_BEGIN:
 
2097
    case DBUS_AUTH_COMMAND_UNKNOWN:
 
2098
    case DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD:
 
2099
    default:
 
2100
      return send_error (auth, "Unknown command");
 
2101
    }
 
2102
}
 
2103
 
1999
2104
/**
2000
2105
 * Mapping from command name to enum
2001
2106
 */
2005
2110
} DBusAuthCommandName;
2006
2111
 
2007
2112
static const DBusAuthCommandName auth_command_names[] = {
2008
 
  { "AUTH",     DBUS_AUTH_COMMAND_AUTH },
2009
 
  { "CANCEL",   DBUS_AUTH_COMMAND_CANCEL },
2010
 
  { "DATA",     DBUS_AUTH_COMMAND_DATA },
2011
 
  { "BEGIN",    DBUS_AUTH_COMMAND_BEGIN },
2012
 
  { "REJECTED", DBUS_AUTH_COMMAND_REJECTED },
2013
 
  { "OK",       DBUS_AUTH_COMMAND_OK },
2014
 
  { "ERROR",    DBUS_AUTH_COMMAND_ERROR }
 
2113
  { "AUTH",              DBUS_AUTH_COMMAND_AUTH },
 
2114
  { "CANCEL",            DBUS_AUTH_COMMAND_CANCEL },
 
2115
  { "DATA",              DBUS_AUTH_COMMAND_DATA },
 
2116
  { "BEGIN",             DBUS_AUTH_COMMAND_BEGIN },
 
2117
  { "REJECTED",          DBUS_AUTH_COMMAND_REJECTED },
 
2118
  { "OK",                DBUS_AUTH_COMMAND_OK },
 
2119
  { "ERROR",             DBUS_AUTH_COMMAND_ERROR },
 
2120
  { "NEGOTIATE_UNIX_FD", DBUS_AUTH_COMMAND_NEGOTIATE_UNIX_FD },
 
2121
  { "AGREE_UNIX_FD",     DBUS_AUTH_COMMAND_AGREE_UNIX_FD }
2015
2122
};
2016
2123
 
2017
2124
static DBusAuthCommand
2685
2792
                                   &auth->context, 0, _dbus_string_get_length (context));
2686
2793
}
2687
2794
 
 
2795
/**
 
2796
 * Sets whether unix fd passing is potentially on the transport and
 
2797
 * hence shall be negotiated.
 
2798
 *
 
2799
 * @param auth the auth conversation
 
2800
 * @param b TRUE when unix fd passing shall be negotiated, otherwise FALSE
 
2801
 */
 
2802
void
 
2803
_dbus_auth_set_unix_fd_possible(DBusAuth *auth, dbus_bool_t b)
 
2804
{
 
2805
  auth->unix_fd_possible = b;
 
2806
}
 
2807
 
 
2808
/**
 
2809
 * Queries whether unix fd passing was sucessfully negotiated.
 
2810
 *
 
2811
 * @param auth the auth conversion
 
2812
 * @returns #TRUE when unix fd passing was negotiated.
 
2813
 */
 
2814
dbus_bool_t
 
2815
_dbus_auth_get_unix_fd_negotiated(DBusAuth *auth)
 
2816
{
 
2817
  return auth->unix_fd_negotiated;
 
2818
}
 
2819
 
2688
2820
/** @} */
2689
2821
 
2690
2822
/* tests in dbus-auth-util.c */