00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-internals.h"
00026 #include "dbus-server-socket.h"
00027 #include "dbus-transport-socket.h"
00028 #include "dbus-connection-internal.h"
00029 #include "dbus-memory.h"
00030 #include "dbus-nonce.h"
00031 #include "dbus-string.h"
00032
00044 typedef struct DBusServerSocket DBusServerSocket;
00045
00050 struct DBusServerSocket
00051 {
00052 DBusServer base;
00053 int n_fds;
00054 int *fds;
00055 DBusWatch **watch;
00056 char *socket_name;
00057 DBusNonceFile *noncefile;
00058 };
00059
00060 static void
00061 socket_finalize (DBusServer *server)
00062 {
00063 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00064 int i;
00065
00066 _dbus_server_finalize_base (server);
00067
00068 for (i = 0 ; i < socket_server->n_fds ; i++)
00069 if (socket_server->watch[i])
00070 {
00071 _dbus_watch_unref (socket_server->watch[i]);
00072 socket_server->watch[i] = NULL;
00073 }
00074
00075 dbus_free (socket_server->fds);
00076 dbus_free (socket_server->watch);
00077 dbus_free (socket_server->socket_name);
00078 if (socket_server->noncefile)
00079 _dbus_noncefile_delete (socket_server->noncefile, NULL);
00080 dbus_free (socket_server->noncefile);
00081 dbus_free (server);
00082 }
00083
00084
00085 static dbus_bool_t
00086 handle_new_client_fd_and_unlock (DBusServer *server,
00087 int client_fd)
00088 {
00089 DBusConnection *connection;
00090 DBusTransport *transport;
00091 DBusNewConnectionFunction new_connection_function;
00092 DBusServerSocket* socket_server;
00093 void *new_connection_data;
00094
00095 socket_server = (DBusServerSocket*)server;
00096 _dbus_verbose ("Creating new client connection with fd %d\n", client_fd);
00097
00098 HAVE_LOCK_CHECK (server);
00099
00100 if (!_dbus_set_fd_nonblocking (client_fd, NULL))
00101 {
00102 SERVER_UNLOCK (server);
00103 return TRUE;
00104 }
00105
00106 transport = _dbus_transport_new_for_socket (client_fd, &server->guid_hex, FALSE);
00107 if (transport == NULL)
00108 {
00109 _dbus_close_socket (client_fd, NULL);
00110 SERVER_UNLOCK (server);
00111 return FALSE;
00112 }
00113
00114 if (!_dbus_transport_set_auth_mechanisms (transport,
00115 (const char **) server->auth_mechanisms))
00116 {
00117 _dbus_transport_unref (transport);
00118 SERVER_UNLOCK (server);
00119 return FALSE;
00120 }
00121
00122
00123
00124
00125
00126 connection = _dbus_connection_new_for_transport (transport);
00127 _dbus_transport_unref (transport);
00128 transport = NULL;
00129
00130 if (connection == NULL)
00131 {
00132 SERVER_UNLOCK (server);
00133 return FALSE;
00134 }
00135
00136
00137
00138
00139 new_connection_function = server->new_connection_function;
00140 new_connection_data = server->new_connection_data;
00141
00142 _dbus_server_ref_unlocked (server);
00143 SERVER_UNLOCK (server);
00144
00145 if (new_connection_function)
00146 {
00147 (* new_connection_function) (server, connection,
00148 new_connection_data);
00149 }
00150 dbus_server_unref (server);
00151
00152
00153 _dbus_connection_close_if_only_one_ref (connection);
00154 dbus_connection_unref (connection);
00155
00156 return TRUE;
00157 }
00158
00159 static dbus_bool_t
00160 socket_handle_watch (DBusWatch *watch,
00161 unsigned int flags,
00162 void *data)
00163 {
00164 DBusServer *server = data;
00165 DBusServerSocket *socket_server = data;
00166
00167 #ifndef DBUS_DISABLE_ASSERT
00168 int i;
00169 dbus_bool_t found = FALSE;
00170 #endif
00171
00172 SERVER_LOCK (server);
00173
00174 #ifndef DBUS_DISABLE_ASSERT
00175 for (i = 0 ; i < socket_server->n_fds ; i++)
00176 {
00177 if (socket_server->watch[i] == watch)
00178 found = TRUE;
00179 }
00180 _dbus_assert (found);
00181 #endif
00182
00183 _dbus_verbose ("Handling client connection, flags 0x%x\n", flags);
00184
00185 if (flags & DBUS_WATCH_READABLE)
00186 {
00187 int client_fd;
00188 int listen_fd;
00189
00190 listen_fd = dbus_watch_get_socket (watch);
00191
00192 if (socket_server->noncefile)
00193 client_fd = _dbus_accept_with_noncefile (listen_fd, socket_server->noncefile);
00194 else
00195 client_fd = _dbus_accept (listen_fd);
00196
00197 if (client_fd < 0)
00198 {
00199
00200
00201 if (_dbus_get_is_errno_eagain_or_ewouldblock ())
00202 _dbus_verbose ("No client available to accept after all\n");
00203 else
00204 _dbus_verbose ("Failed to accept a client connection: %s\n",
00205 _dbus_strerror_from_errno ());
00206
00207 SERVER_UNLOCK (server);
00208 }
00209 else
00210 {
00211 if (!handle_new_client_fd_and_unlock (server, client_fd))
00212 _dbus_verbose ("Rejected client connection due to lack of memory\n");
00213 }
00214 }
00215
00216 if (flags & DBUS_WATCH_ERROR)
00217 _dbus_verbose ("Error on server listening socket\n");
00218
00219 if (flags & DBUS_WATCH_HANGUP)
00220 _dbus_verbose ("Hangup on server listening socket\n");
00221
00222 return TRUE;
00223 }
00224
00225 static void
00226 socket_disconnect (DBusServer *server)
00227 {
00228 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00229 int i;
00230
00231 HAVE_LOCK_CHECK (server);
00232
00233 for (i = 0 ; i < socket_server->n_fds ; i++)
00234 {
00235 if (socket_server->watch[i])
00236 {
00237 _dbus_server_remove_watch (server,
00238 socket_server->watch[i]);
00239 _dbus_watch_unref (socket_server->watch[i]);
00240 socket_server->watch[i] = NULL;
00241 }
00242
00243 _dbus_close_socket (socket_server->fds[i], NULL);
00244 socket_server->fds[i] = -1;
00245 }
00246
00247 if (socket_server->socket_name != NULL)
00248 {
00249 DBusString tmp;
00250 _dbus_string_init_const (&tmp, socket_server->socket_name);
00251 _dbus_delete_file (&tmp, NULL);
00252 }
00253
00254 if (server->published_address)
00255 _dbus_daemon_unpublish_session_bus_address();
00256
00257 HAVE_LOCK_CHECK (server);
00258 }
00259
00260 static const DBusServerVTable socket_vtable = {
00261 socket_finalize,
00262 socket_disconnect
00263 };
00264
00280 DBusServer*
00281 _dbus_server_new_for_socket (int *fds,
00282 int n_fds,
00283 const DBusString *address,
00284 DBusNonceFile *noncefile)
00285 {
00286 DBusServerSocket *socket_server;
00287 DBusServer *server;
00288 int i;
00289
00290 socket_server = dbus_new0 (DBusServerSocket, 1);
00291 if (socket_server == NULL)
00292 return NULL;
00293
00294 socket_server->noncefile = noncefile;
00295
00296 socket_server->fds = dbus_new (int, n_fds);
00297 if (!socket_server->fds)
00298 goto failed_0;
00299
00300 socket_server->watch = dbus_new0 (DBusWatch *, n_fds);
00301 if (!socket_server->watch)
00302 goto failed_1;
00303
00304 for (i = 0 ; i < n_fds ; i++)
00305 {
00306 DBusWatch *watch;
00307
00308 watch = _dbus_watch_new (fds[i],
00309 DBUS_WATCH_READABLE,
00310 TRUE,
00311 socket_handle_watch, socket_server,
00312 NULL);
00313 if (watch == NULL)
00314 goto failed_2;
00315
00316 socket_server->n_fds++;
00317 socket_server->fds[i] = fds[i];
00318 socket_server->watch[i] = watch;
00319 }
00320
00321 if (!_dbus_server_init_base (&socket_server->base,
00322 &socket_vtable, address))
00323 goto failed_2;
00324
00325 server = (DBusServer*)socket_server;
00326
00327 SERVER_LOCK (server);
00328
00329 for (i = 0 ; i < n_fds ; i++)
00330 {
00331 if (!_dbus_server_add_watch (&socket_server->base,
00332 socket_server->watch[i]))
00333 {
00334 int j;
00335 for (j = 0 ; j < i ; j++)
00336 _dbus_server_remove_watch (server,
00337 socket_server->watch[j]);
00338
00339 SERVER_UNLOCK (server);
00340 _dbus_server_finalize_base (&socket_server->base);
00341 goto failed_2;
00342 }
00343 }
00344
00345 SERVER_UNLOCK (server);
00346
00347 return (DBusServer*) socket_server;
00348
00349 failed_3:
00350 if (socket_server->noncefile)
00351 {
00352 _dbus_noncefile_delete (socket_server->noncefile, NULL);
00353 dbus_free (socket_server->noncefile );
00354 }
00355 failed_2:
00356 for (i = 0 ; i < n_fds ; i++)
00357 {
00358 if (socket_server->watch[i] != NULL)
00359 {
00360 _dbus_watch_unref (socket_server->watch[i]);
00361 socket_server->watch[i] = NULL;
00362 }
00363 }
00364 dbus_free (socket_server->watch);
00365
00366 failed_1:
00367 dbus_free (socket_server->fds);
00368
00369 failed_0:
00370 dbus_free (socket_server);
00371 return NULL;
00372 }
00373
00393 DBusServer*
00394 _dbus_server_new_for_tcp_socket (const char *host,
00395 const char *bind,
00396 const char *port,
00397 const char *family,
00398 DBusError *error,
00399 dbus_bool_t use_nonce)
00400 {
00401 DBusServer *server;
00402 int *listen_fds = NULL;
00403 int nlisten_fds = 0, i;
00404 DBusString address;
00405 DBusString host_str;
00406 DBusString port_str;
00407 DBusNonceFile *noncefile;
00408
00409 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00410
00411 noncefile = NULL;
00412
00413 if (!_dbus_string_init (&address))
00414 {
00415 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00416 return NULL;
00417 }
00418
00419 if (!_dbus_string_init (&port_str))
00420 {
00421 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00422 goto failed_0;
00423 }
00424
00425 if (host == NULL)
00426 host = "localhost";
00427
00428 if (port == NULL)
00429 port = "0";
00430
00431 if (bind == NULL)
00432 bind = host;
00433 else if (strcmp (bind, "*") == 0)
00434 bind = NULL;
00435
00436 nlisten_fds =_dbus_listen_tcp_socket (bind, port, family,
00437 &port_str,
00438 &listen_fds, error);
00439 if (nlisten_fds <= 0)
00440 {
00441 _DBUS_ASSERT_ERROR_IS_SET(error);
00442 goto failed_1;
00443 }
00444
00445 _dbus_string_init_const (&host_str, host);
00446 if (!_dbus_string_append (&address, use_nonce ? "nonce-tcp:host=" : "tcp:host=") ||
00447 !_dbus_address_append_escaped (&address, &host_str) ||
00448 !_dbus_string_append (&address, ",port=") ||
00449 !_dbus_string_append (&address, _dbus_string_get_const_data(&port_str)))
00450 {
00451 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00452 goto failed_2;
00453 }
00454 if (family &&
00455 (!_dbus_string_append (&address, ",family=") ||
00456 !_dbus_string_append (&address, family)))
00457 {
00458 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00459 goto failed_2;
00460 }
00461
00462 if (use_nonce)
00463 {
00464 noncefile = dbus_new0 (DBusNonceFile, 1);
00465 if (noncefile == NULL)
00466 {
00467 goto failed_2;
00468 }
00469
00470 if (!_dbus_noncefile_create (noncefile, NULL))
00471 goto failed_2;
00472
00473 if (!_dbus_string_append (&address, ",noncefile=") ||
00474 !_dbus_address_append_escaped (&address, _dbus_noncefile_get_path (noncefile)))
00475 {
00476 goto failed_2;
00477 }
00478
00479 }
00480
00481 server = _dbus_server_new_for_socket (listen_fds, nlisten_fds, &address, noncefile);
00482 if (server == NULL)
00483 {
00484 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00485 goto failed_2;
00486 }
00487
00488 _dbus_string_free (&port_str);
00489 _dbus_string_free (&address);
00490 dbus_free(listen_fds);
00491
00492 return server;
00493
00494 failed_2:
00495 for (i = 0 ; i < nlisten_fds ; i++)
00496 _dbus_close_socket (listen_fds[i], NULL);
00497 dbus_free(listen_fds);
00498
00499 failed_1:
00500 _dbus_string_free (&port_str);
00501
00502 failed_0:
00503 _dbus_string_free (&address);
00504
00505 return NULL;
00506 }
00507
00520 DBusServerListenResult
00521 _dbus_server_listen_socket (DBusAddressEntry *entry,
00522 DBusServer **server_p,
00523 DBusError *error)
00524 {
00525 const char *method;
00526
00527 *server_p = NULL;
00528
00529 method = dbus_address_entry_get_method (entry);
00530
00531 if (strcmp (method, "tcp") == 0 || strcmp (method, "nonce-tcp") == 0)
00532 {
00533 const char *host;
00534 const char *port;
00535 const char *bind;
00536 const char *family;
00537
00538 host = dbus_address_entry_get_value (entry, "host");
00539 bind = dbus_address_entry_get_value (entry, "bind");
00540 port = dbus_address_entry_get_value (entry, "port");
00541 family = dbus_address_entry_get_value (entry, "family");
00542
00543 *server_p = _dbus_server_new_for_tcp_socket (host, bind, port,
00544 family, error, strcmp (method, "nonce-tcp") == 0 ? TRUE : FALSE);
00545
00546 if (*server_p)
00547 {
00548 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00549 return DBUS_SERVER_LISTEN_OK;
00550 }
00551 else
00552 {
00553 _DBUS_ASSERT_ERROR_IS_SET(error);
00554 return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
00555 }
00556 }
00557 else
00558 {
00559 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00560 return DBUS_SERVER_LISTEN_NOT_HANDLED;
00561 }
00562 }
00563
00573 void
00574 _dbus_server_socket_own_filename (DBusServer *server,
00575 char *filename)
00576 {
00577 DBusServerSocket *socket_server = (DBusServerSocket*) server;
00578
00579 socket_server->socket_name = filename;
00580 }
00581
00582