1 /*
2 * platform-cros.c - CrOS platform DBus integration
3 * Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7 #include "config.h"
8
9 #include <ctype.h>
10 #include <dbus/dbus.h>
11 #include <errno.h>
12 #include <signal.h>
13 #include <stdbool.h>
14 #include <stdint.h>
15 #include <string.h>
16 #include <time.h>
17
18 #include <event2/event.h>
19
20 #include "src/dbus.h"
21 #include "src/platform.h"
22 #include "src/tlsdate.h"
23 #include "src/util.h"
24
25 static const char kMatchFormatData[] = "interface='%s',member='%s',arg0='%s'";
26 static const char *kMatchFormat = kMatchFormatData;
27 static const char kMatchNoArgFormatData[] = "interface='%s',member='%s'";
28 static const char *kMatchNoArgFormat = kMatchNoArgFormatData;
29
30 static const char kLibCrosDestData[] = "org.chromium.LibCrosService";
31 static const char *kLibCrosDest = kLibCrosDestData;
32 static const char kLibCrosInterfaceData[] = "org.chromium.LibCrosServiceInterface";
33 static const char *kLibCrosInterface = kLibCrosInterfaceData;
34 static const char kLibCrosPathData[] = "/org/chromium/LibCrosService";
35 static const char *kLibCrosPath = kLibCrosPathData;
36 static const char kResolveNetworkProxyData[] = "ResolveNetworkProxy";
37 static const char *kResolveNetworkProxy = kResolveNetworkProxyData;
38
39 static const char kDBusInterfaceData[] = "org.freedesktop.DBus";
40 static const char *kDBusInterface = kDBusInterfaceData;
41 static const char kNameOwnerChangedData[] = "NameOwnerChanged";
42 static const char *kNameOwnerChanged = kNameOwnerChangedData;
43 static const char kNameAcquiredData[] = "NameAcquired";
44 static const char *kNameAcquired = kNameAcquiredData;
45
46 static const char kManagerInterfaceData[] = "org.chromium.flimflam.Manager";
47 static const char *kManagerInterface = kManagerInterfaceData;
48
49 static const char kServiceInterfaceData[] = "org.chromium.flimflam.Service";
50 static const char *kServiceInterface = kServiceInterfaceData;
51 static const char kMemberData[] = "PropertyChanged";
52 static const char *kMember = kMemberData;
53
54 static const char kProxyConfigData[] = "ProxyConfig";
55 static const char *kProxyConfig = kProxyConfigData;
56 static const char kDefaultServiceData[] = "DefaultService";
57 static const char *kDefaultService = kDefaultServiceData;
58
59 static const char kResolveInterfaceData[] = "org.torproject.tlsdate.Resolver";
60 static const char *kResolveInterface = kResolveInterfaceData;
61 static const char kResolveMemberData[] = "ProxyChange";
62 static const char *kResolveMember = kResolveMemberData;
63
64 /* TODO(wad) Integrate with cros_system_api/dbus/service_constants.h */
65 static const char kPowerManagerInterfaceData[] = "org.chromium.PowerManager";
66 static const char *kPowerManagerInterface = kPowerManagerInterfaceData;
67 static const char kSuspendDoneData[] = "SuspendDone";
68 static const char *kSuspendDone = kSuspendDoneData;
69
70 static const char kErrorServiceUnknownData[] = "org.freedesktop.DBus.Error.ServiceUnknown";
71 static const char *kErrorServiceUnknown = kErrorServiceUnknownData;
72
73 struct platform_state
74 {
75 struct event_base *base;
76 struct state *state;
77 DBusMessage **resolve_msg;
78 int resolve_msg_count;
79 uint32_t resolve_network_proxy_serial;
80 };
81
82 static
83 bool
get_valid_hostport(const char * hostport,char * out,size_t len)84 get_valid_hostport (const char *hostport, char *out, size_t len)
85 {
86 bool host = true;
87 const char *end = hostport + strlen (hostport);
88 const char *c;
89 *out = '\0';
90 /* Hosts begin with alphanumeric only. */
91 if (!isalnum (*hostport))
92 {
93 info ("Host does not start with alnum");
94 return false;
95 }
96 *out++ = *hostport;
97 for (c = hostport + 1; c < end && len > 0; ++c, ++out, --len)
98 {
99 *out = *c;
100 if (host)
101 {
102 if (isalnum (*c) || *c == '-' || *c == '.')
103 {
104 continue;
105 }
106 if (*c == ':')
107 {
108 host = false;
109 continue;
110 }
111 }
112 else
113 {
114 if (isdigit (*c))
115 continue;
116 }
117 *out = '\0';
118 return false;
119 }
120 *out = '\0';
121 return true;
122 }
123
124 /* Convert PAC return format to tlsdated url format */
125 /* TODO(wad) support multiple proxies when Chromium does:
126 * PROXY x.x.x.x:yyyy; PROXY z.z.z.z:aaaaa
127 */
128 static
129 void
canonicalize_pac(const char * pac_fmt,char * proxy_url,size_t len)130 canonicalize_pac (const char *pac_fmt, char *proxy_url, size_t len)
131 {
132 size_t type_len;
133 int copied = 0;
134 const char *space;
135 /* host[255]:port[6]\0 */
136 char hostport[6 + 255 + 2];
137 proxy_url[0] = '\0';
138 if (len < 1)
139 return;
140 if (!strcmp (pac_fmt, "DIRECT"))
141 {
142 return;
143 }
144 /* Find type */
145 space = strchr (pac_fmt, ' ');
146 if (!space)
147 return;
148 type_len = space - pac_fmt;
149 if (!get_valid_hostport (space + 1, hostport, sizeof (hostport)))
150 {
151 error ("invalid host:port: %s", space + 1);
152 return;
153 }
154 proxy_url[0] = '\0';
155 if (!strncmp (pac_fmt, "PROXY", type_len))
156 {
157 copied = snprintf (proxy_url, len, "http://%s", hostport);
158 }
159 else if (!strncmp (pac_fmt, "SOCKS", type_len))
160 {
161 copied = snprintf (proxy_url, len, "socks4://%s", hostport);
162 }
163 else if (!strncmp (pac_fmt, "SOCKS5", type_len))
164 {
165 copied = snprintf (proxy_url, len, "socks5://%s", hostport);
166 }
167 else if (!strncmp (pac_fmt, "HTTPS", type_len))
168 {
169 copied = snprintf (proxy_url, len, "https://%s", hostport);
170 }
171 else
172 {
173 error ("pac_fmt unmatched: '%s' %zu", pac_fmt, type_len);
174 }
175 if (copied < 0 || ((size_t) copied) >= len)
176 {
177 error ("canonicalize_pac: truncation '%s'", proxy_url);
178 proxy_url[0] = '\0';
179 return;
180 }
181 }
182
183 static
184 DBusHandlerResult
handle_service_change(DBusConnection * connection,DBusMessage * message,struct platform_state * ctx)185 handle_service_change (DBusConnection *connection,
186 DBusMessage *message,
187 struct platform_state *ctx)
188 {
189 DBusMessageIter iter, subiter;
190 DBusError error;
191 const char *pname;
192 const char *pval;
193 const char *service;
194 dbus_error_init (&error);
195 verb_debug ("[event:cros:%s]: fired", __func__);
196 /* TODO(wad) Track the current DefaultService only fire when it changes */
197 service = dbus_message_get_path (message);
198 if (!service)
199 return DBUS_HANDLER_RESULT_HANDLED;
200 /* Shill emits string:ProxyConfig variant string:"..." */
201 if (!dbus_message_iter_init (message, &iter))
202 return DBUS_HANDLER_RESULT_HANDLED;
203 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
204 return DBUS_HANDLER_RESULT_HANDLED;
205 dbus_message_iter_get_basic (&iter, &pname);
206 /* Make sure we are only firing on a ProxyConfig property change. */
207 if (strcmp (pname, kProxyConfig))
208 return DBUS_HANDLER_RESULT_HANDLED;
209 if (!dbus_message_iter_next (&iter))
210 return DBUS_HANDLER_RESULT_HANDLED;
211 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT)
212 return DBUS_HANDLER_RESULT_HANDLED;
213 dbus_message_iter_recurse (&iter, &subiter);
214 if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_STRING)
215 return DBUS_HANDLER_RESULT_HANDLED;
216 dbus_message_iter_get_basic (&subiter, &pval);
217 /* Right now, nothing is done with the Shill proxy value because
218 * Chromium handles .pac resolution. This may be more useful for
219 * ignoring incomplete proxy values sent while a user is typing.
220 */
221 action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
222 return DBUS_HANDLER_RESULT_HANDLED;
223 }
224
225 static
226 DBusHandlerResult
handle_manager_change(DBusConnection * connection,DBusMessage * message,struct platform_state * ctx)227 handle_manager_change (DBusConnection *connection,
228 DBusMessage *message,
229 struct platform_state *ctx)
230 {
231 DBusMessageIter iter, subiter;
232 DBusError error;
233 const char *pname;
234 const char *pval;
235 verb_debug ("[event:cros:%s]: fired", __func__);
236 dbus_error_init (&error);
237 if (!dbus_message_iter_init (message, &iter))
238 return DBUS_HANDLER_RESULT_HANDLED;
239 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
240 return DBUS_HANDLER_RESULT_HANDLED;
241 dbus_message_iter_get_basic (&iter, &pname);
242 /* Make sure we caught the right property. */
243 if (strcmp (pname, kDefaultService))
244 return DBUS_HANDLER_RESULT_HANDLED;
245 if (!dbus_message_iter_next (&iter))
246 return DBUS_HANDLER_RESULT_HANDLED;
247 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT)
248 return DBUS_HANDLER_RESULT_HANDLED;
249 dbus_message_iter_recurse (&iter, &subiter);
250 if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_OBJECT_PATH)
251 return DBUS_HANDLER_RESULT_HANDLED;
252 dbus_message_iter_get_basic (&subiter, &pval);
253 /* TODO(wad) Filter on the currently active service in pval. */
254 verb_debug ("[event:cros:%s] service change on path %s",
255 __func__, pval);
256 action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
257 return DBUS_HANDLER_RESULT_HANDLED;
258 }
259
260 static
261 DBusHandlerResult
handle_suspend_done(DBusConnection * connection,DBusMessage * message,struct platform_state * ctx)262 handle_suspend_done (DBusConnection *connection,
263 DBusMessage *message,
264 struct platform_state *ctx)
265 {
266 verb_debug ("[event:cros:%s]: fired", __func__);
267 /* Coming back from resume, trigger a continuity and time
268 * check just in case none of the other events happen.
269 */
270 action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
271 return DBUS_HANDLER_RESULT_HANDLED;
272 }
273
274 static
275 DBusHandlerResult
handle_proxy_change(DBusConnection * connection,DBusMessage * message,struct platform_state * ctx)276 handle_proxy_change (DBusConnection *connection,
277 DBusMessage *message,
278 struct platform_state *ctx)
279 {
280 DBusMessageIter iter;
281 DBusError error;
282 const char *pname;
283 const char *pval;
284 char time_host[MAX_PROXY_URL];
285 int url_len = 0;
286 struct source *src = ctx->state->opts.sources;
287 verb_debug ("[event:cros:%s]: fired", __func__);
288 if (ctx->state->opts.cur_source && ctx->state->opts.cur_source->next)
289 src = ctx->state->opts.cur_source->next;
290 if (!ctx->state->resolving)
291 {
292 info ("[event:cros:%s] Unexpected ResolveNetworkProxy signal seen",
293 __func__);
294 return DBUS_HANDLER_RESULT_HANDLED;
295 }
296 dbus_error_init (&error);
297 /* Shill emits string:ProxyConfig variant string:"..." */
298 if (!dbus_message_iter_init (message, &iter))
299 return DBUS_HANDLER_RESULT_HANDLED;
300 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
301 return DBUS_HANDLER_RESULT_HANDLED;
302 dbus_message_iter_get_basic (&iter, &pname);
303 /* Make sure this was the resolution we asked for */
304 url_len = snprintf (time_host, sizeof (time_host), "https://%s:%s",
305 src->host, src->port);
306 if (url_len < 0 || ((size_t) url_len) >= sizeof (time_host))
307 {
308 error ("[event:cros:%s]: current source url is too long",
309 __func__);
310 }
311 if (strcmp (pname, time_host))
312 {
313 error ("[event:cros:%s]: resolved host mismatch: %s v %s",
314 __func__, pname, time_host);
315 return DBUS_HANDLER_RESULT_HANDLED;
316 }
317 if (!dbus_message_iter_next (&iter))
318 return DBUS_HANDLER_RESULT_HANDLED;
319 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
320 return DBUS_HANDLER_RESULT_HANDLED;
321 dbus_message_iter_get_basic (&iter, &pval);
322 ctx->state->resolving = 0;
323 canonicalize_pac (pval, ctx->state->dynamic_proxy, sizeof (ctx->state->dynamic_proxy));
324 trigger_event (ctx->state, E_TLSDATE, 1);
325 return DBUS_HANDLER_RESULT_HANDLED;
326 }
327
328 static
329 DBusHandlerResult
handle_dbus_change(DBusConnection * connection,DBusMessage * message,struct platform_state * ctx)330 handle_dbus_change (DBusConnection *connection,
331 DBusMessage *message,
332 struct platform_state *ctx)
333 {
334 DBusMessageIter iter;
335 DBusError error;
336 const char *pname;
337 verb_debug ("[event:cros:%s]: fired", __func__);
338 dbus_error_init (&error);
339 if (!dbus_message_iter_init (message, &iter))
340 return DBUS_HANDLER_RESULT_HANDLED;
341 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
342 return DBUS_HANDLER_RESULT_HANDLED;
343 dbus_message_iter_get_basic (&iter, &pname);
344 /* Make sure we caught the right property. */
345 if (strcmp (pname, kLibCrosDest))
346 return DBUS_HANDLER_RESULT_HANDLED;
347 action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state);
348 return DBUS_HANDLER_RESULT_HANDLED;
349 }
350
351 static
352 void
action_resolve_proxy(evutil_socket_t fd,short what,void * arg)353 action_resolve_proxy (evutil_socket_t fd, short what, void *arg)
354 {
355 struct platform_state *ctx = arg;
356 struct dbus_state *dbus_state = ctx->state->dbus;
357 DBusConnection *conn = dbus_state->conn;
358 struct source *src = ctx->state->opts.sources;
359 verb_debug ("[event:%s] fired", __func__);
360 /* Emulate tlsdate-monitor.c:build_argv and choose the next source */
361 if (ctx->state->opts.cur_source && ctx->state->opts.cur_source->next)
362 src = ctx->state->opts.cur_source->next;
363 if (ctx->state->resolving || ctx->resolve_network_proxy_serial)
364 {
365 /* Note, this is not the same as the response signal. It just avoids
366 * multiple requests in a single dispatch window.
367 */
368 info ("[event:%s] no resolve_proxy sent; pending method_reply",
369 __func__);
370 return;
371 }
372 ctx->state->dynamic_proxy[0] = '\0';
373 if (ctx->resolve_msg[src->id] == NULL)
374 {
375 info ("[event:%s] no dynamic proxy for %s:%s", __func__,
376 src->host, src->port);
377 trigger_event (ctx->state, E_TLSDATE, 1);
378 return;
379 }
380 info ("[event:%s] resolving proxy for %s:%s", __func__,
381 src->host, src->port);
382 ctx->state->resolving = 1;
383 if (!dbus_connection_send (conn,
384 ctx->resolve_msg[src->id],
385 &ctx->resolve_network_proxy_serial))
386 {
387 error ("[event:%s] cannot send ResolveNetworkProxy query!", __func__);
388 return;
389 }
390 }
391
392 static
393 DBusHandlerResult
dbus_filter(DBusConnection * connection,DBusMessage * message,void * data)394 dbus_filter (DBusConnection *connection, DBusMessage *message, void *data)
395 {
396 struct platform_state *state = data;
397 /* Terminate gracefully if DBus goes away. */
398 if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
399 {
400 error ("[cros] DBus system bus has become inaccessible. Terminating.");
401 /* Trigger a graceful teardown. */
402 kill (getpid(), SIGINT);
403 return DBUS_HANDLER_RESULT_HANDLED;
404 }
405 /* Hand it over to the service dispatcher. */
406 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
407 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
408
409 /* Handle explicitly defined signals only. */
410 if (dbus_message_is_signal (message, kDBusInterface, kNameAcquired))
411 {
412 info ("[cros] DBus name acquired successfully");
413 return DBUS_HANDLER_RESULT_HANDLED;
414 }
415 if (dbus_message_is_signal (message, kServiceInterface, kMember))
416 return handle_service_change (connection, message, state);
417 if (dbus_message_is_signal (message, kManagerInterface, kMember))
418 return handle_manager_change (connection, message, state);
419 if (dbus_message_is_signal (message, kResolveInterface, kResolveMember))
420 return handle_proxy_change (connection, message, state);
421 if (dbus_message_is_signal (message, kDBusInterface, kNameOwnerChanged))
422 return handle_dbus_change (connection, message, state);
423 if (dbus_message_is_signal (message, kPowerManagerInterface, kSuspendDone))
424 return handle_suspend_done (connection, message, state);
425 if (dbus_message_is_error (message, kErrorServiceUnknown))
426 {
427 info ("[cros] org.chromium.LibCrosService.ResolveNetworkProxy is missing");
428 info ("[cros] skipping proxy resolution for now");
429 /* Fire off tlsdate rather than letting it fail silently. */
430 state->resolve_network_proxy_serial = 0;
431 state->state->resolving = 0;
432 trigger_event (state->state, E_TLSDATE, 1);
433 return DBUS_HANDLER_RESULT_HANDLED;
434 }
435 /* Indicates a successful resolve request was issued. */
436 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
437 {
438 uint32_t serial = dbus_message_get_reply_serial (message);
439 if (serial == state->resolve_network_proxy_serial)
440 {
441 state->resolve_network_proxy_serial = 0;
442 return DBUS_HANDLER_RESULT_HANDLED;
443 }
444 info ("[cros] unknown DBus METHOD_RETURN seen: %u", serial);
445 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
446 }
447 verb_debug ("[cros] unknown message received: "
448 "type=%s dest=%s interface=%s member=%s path=%s sig=%s error_name=%s",
449 dbus_message_type_to_string (dbus_message_get_type (message)),
450 dbus_message_get_destination (message),
451 dbus_message_get_interface (message),
452 dbus_message_get_member (message),
453 dbus_message_get_path (message),
454 dbus_message_get_signature (message),
455 dbus_message_get_error_name (message));
456 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
457 }
458
459 int
add_match(DBusConnection * conn,const char * interface,const char * member,const char * arg0)460 add_match (DBusConnection *conn, const char *interface, const char *member,
461 const char *arg0)
462 {
463 char match[1024];
464 DBusError error;
465 int len;
466 dbus_error_init (&error);
467 if (arg0)
468 {
469 len = snprintf (match, sizeof (match), kMatchFormat,
470 interface, member, arg0);
471 }
472 else
473 {
474 len = snprintf (match, sizeof (match), kMatchNoArgFormat,
475 interface, member);
476 }
477 if (len < 0 || ((size_t) len) >= sizeof (match))
478 {
479 error ("[dbus] match truncated for '%s,%s'", interface, member);
480 return 1;
481 }
482 dbus_bus_add_match (conn, match, &error);
483 if (dbus_error_is_set (&error))
484 {
485 error ("[dbus] failed to add_match for '%s,%s'; error: %s, %s",
486 interface, member, error.name, error.message);
487 dbus_error_free (&error);
488 return 1;
489 }
490 return 0;
491 }
492
493 DBusMessage *
new_resolver_message(const struct source * src)494 new_resolver_message(const struct source *src)
495 {
496 char time_host[MAX_PROXY_URL];
497 void *time_host_ptr = &time_host;
498 int url_len;
499 DBusMessage *res;
500 DBusMessageIter args;
501 if (!src->proxy || strcmp (src->proxy, "dynamic"))
502 {
503 return NULL;
504 }
505 res = dbus_message_new_method_call (kLibCrosDest, kLibCrosPath,
506 kLibCrosInterface, kResolveNetworkProxy);
507 if (!res)
508 {
509 error ("[cros] could not setup dynamic proxy for source %d", src->id);
510 return NULL;
511 }
512 /* Build the time_host */
513 url_len = snprintf (time_host, sizeof (time_host), "https://%s:%s",
514 src->host, src->port);
515 if (url_len < 0 || ((size_t) url_len) >= sizeof (time_host))
516 {
517 fatal ("[cros] source %d url is too long! (%d)", src->id, url_len);
518 }
519 /* Finish the message */
520 dbus_message_iter_init_append (res, &args);
521 if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &time_host_ptr) ||
522 !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &kResolveInterface) ||
523 !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &kResolveMember))
524 {
525 fatal ("[cros could not append arguments for resolver message");
526 }
527 return res;
528 }
529
530 int
platform_init_cros(struct state * state)531 platform_init_cros (struct state *state)
532 {
533 /* Watch for per-service ProxyConfig property changes */
534 struct event_base *base = state->base;
535 struct dbus_state *dbus_state = state->dbus;
536 if (!dbus_state)
537 {
538 info ("[cros] DBus not connected, skipping platform initialization.");
539 return 0;
540 }
541 struct source *src = NULL;
542 int sources = 0;
543 DBusConnection *conn = dbus_state->conn;
544 DBusError error;
545 struct platform_state *platform_state =
546 calloc (1, sizeof (struct platform_state));
547 if (!platform_state)
548 {
549 error ("[cros] could not allocate platform_state");
550 return -1;
551 }
552 /* TODO(wad) Follow up with dbus_error_free() where needed. */
553 dbus_error_init (&error);
554 /* Add watches for: proxy changes, default service changes, proxy resolution,
555 * LibCrosService ownership, and power state changes.
556 */
557 if (add_match (conn, kServiceInterface, kMember, kProxyConfig) ||
558 add_match (conn, kManagerInterface, kMember, kDefaultService) ||
559 add_match (conn, kResolveInterface, kResolveMember, NULL) ||
560 add_match (conn, kDBusInterface, kNameOwnerChanged, kLibCrosDest) ||
561 add_match (conn, kPowerManagerInterface, kSuspendDone, NULL))
562 return 1;
563
564 /* Allocate one per source */
565 for (src = state->opts.sources; src; src = src->next, ++sources);
566 platform_state->resolve_msg_count = sources;
567 platform_state->resolve_msg = calloc (sources, sizeof (DBusMessage *));
568 if (!platform_state->resolve_msg)
569 {
570 error ("[cros] cannot allocate resolver messages");
571 free (platform_state);
572 return -1;
573 }
574 for (src = state->opts.sources; src; src = src->next)
575 {
576 if (src->id >= sources)
577 fatal ("Source ID is greater than available sources!");
578 platform_state->resolve_msg[src->id] = new_resolver_message (src);
579 if (platform_state->resolve_msg[src->id])
580 src->proxy = state->dynamic_proxy;
581 }
582 state->dynamic_proxy[0] = '\0';
583 if (state->opts.proxy && !strcmp (state->opts.proxy, "dynamic"))
584 {
585 info ("[cros] default dynamic proxy support");
586 state->opts.proxy = state->dynamic_proxy;
587 }
588 platform_state->base = base;
589 platform_state->state = state;
590 /* Add the dynamic resolver if tlsdate doesn't already have one. */
591 if (!state->events[E_RESOLVER])
592 {
593 state->events[E_RESOLVER] = event_new (base, -1, EV_TIMEOUT,
594 action_resolve_proxy,
595 platform_state);
596 if (!state->events[E_RESOLVER])
597 /* Let's not clean up DBus. */
598 fatal ("Could not allocated resolver event");
599 /* Wake up as a NET event since it'll self-block until DBus has a chance
600 * to send it.
601 */
602 event_priority_set (state->events[E_RESOLVER], PRI_NET);
603 }
604 /* Each platform can attach their own filter, but the filter func needs to be
605 * willing to DBUS_HANDLER_RESULT_NOT_YET_HANDLED on unexpected events.
606 */
607 /* TODO(wad) add the clean up function as the callback. */
608 if (!dbus_connection_add_filter (conn,
609 dbus_filter, platform_state, NULL))
610 {
611 error ("Failed to register signal handler callback");
612 return 1;
613 }
614 return 0;
615 }
616