control_getinfo.c 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663
  1. /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  2. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  3. /* See LICENSE for licensing information */
  4. /**
  5. * \file control_getinfo.c
  6. * \brief Implementation for miscellaneous controller getinfo commands.
  7. */
  8. #define CONTROL_EVENTS_PRIVATE
  9. #define CONTROL_MODULE_PRIVATE
  10. #define CONTROL_GETINFO_PRIVATE
  11. #include "core/or/or.h"
  12. #include "app/config/config.h"
  13. #include "core/mainloop/connection.h"
  14. #include "core/mainloop/mainloop.h"
  15. #include "core/or/circuitlist.h"
  16. #include "core/or/connection_edge.h"
  17. #include "core/or/connection_or.h"
  18. #include "core/or/policies.h"
  19. #include "core/or/versions.h"
  20. #include "feature/client/addressmap.h"
  21. #include "feature/client/bridges.h"
  22. #include "feature/client/entrynodes.h"
  23. #include "feature/control/control.h"
  24. #include "feature/control/control_cmd.h"
  25. #include "feature/control/control_events.h"
  26. #include "feature/control/control_fmt.h"
  27. #include "feature/control/control_getinfo.h"
  28. #include "feature/control/control_proto.h"
  29. #include "feature/control/fmt_serverstatus.h"
  30. #include "feature/control/getinfo_geoip.h"
  31. #include "feature/dircache/dirserv.h"
  32. #include "feature/dirclient/dirclient.h"
  33. #include "feature/dirclient/dlstatus.h"
  34. #include "feature/hibernate/hibernate.h"
  35. #include "feature/hs/hs_cache.h"
  36. #include "feature/hs_common/shared_random_client.h"
  37. #include "feature/nodelist/authcert.h"
  38. #include "feature/nodelist/microdesc.h"
  39. #include "feature/nodelist/networkstatus.h"
  40. #include "feature/nodelist/nodelist.h"
  41. #include "feature/nodelist/routerinfo.h"
  42. #include "feature/nodelist/routerlist.h"
  43. #include "feature/relay/router.h"
  44. #include "feature/relay/routermode.h"
  45. #include "feature/relay/selftest.h"
  46. #include "feature/rend/rendcache.h"
  47. #include "feature/stats/geoip_stats.h"
  48. #include "feature/stats/predict_ports.h"
  49. #include "lib/version/torversion.h"
  50. #include "core/or/entry_connection_st.h"
  51. #include "core/or/or_connection_st.h"
  52. #include "core/or/origin_circuit_st.h"
  53. #include "core/or/socks_request_st.h"
  54. #include "feature/control/control_connection_st.h"
  55. #include "feature/control/control_cmd_args_st.h"
  56. #include "feature/dircache/cached_dir_st.h"
  57. #include "feature/nodelist/extrainfo_st.h"
  58. #include "feature/nodelist/microdesc_st.h"
  59. #include "feature/nodelist/networkstatus_st.h"
  60. #include "feature/nodelist/node_st.h"
  61. #include "feature/nodelist/routerinfo_st.h"
  62. #include "feature/nodelist/routerlist_st.h"
  63. #ifdef HAVE_UNISTD_H
  64. #include <unistd.h>
  65. #endif
  66. #ifndef _WIN32
  67. #include <pwd.h>
  68. #endif
  69. static char *list_getinfo_options(void);
  70. static char *download_status_to_string(const download_status_t *dl);
  71. /** Implementation helper for GETINFO: knows the answers for various
  72. * trivial-to-implement questions. */
  73. static int
  74. getinfo_helper_misc(control_connection_t *conn, const char *question,
  75. char **answer, const char **errmsg)
  76. {
  77. (void) conn;
  78. if (!strcmp(question, "version")) {
  79. *answer = tor_strdup(get_version());
  80. } else if (!strcmp(question, "bw-event-cache")) {
  81. *answer = get_bw_samples();
  82. } else if (!strcmp(question, "config-file")) {
  83. const char *a = get_torrc_fname(0);
  84. if (a)
  85. *answer = tor_strdup(a);
  86. } else if (!strcmp(question, "config-defaults-file")) {
  87. const char *a = get_torrc_fname(1);
  88. if (a)
  89. *answer = tor_strdup(a);
  90. } else if (!strcmp(question, "config-text")) {
  91. *answer = options_dump(get_options(), OPTIONS_DUMP_MINIMAL);
  92. } else if (!strcmp(question, "config-can-saveconf")) {
  93. *answer = tor_strdup(get_options()->IncludeUsed ? "0" : "1");
  94. } else if (!strcmp(question, "info/names")) {
  95. *answer = list_getinfo_options();
  96. } else if (!strcmp(question, "dormant")) {
  97. int dormant = rep_hist_circbuilding_dormant(time(NULL));
  98. *answer = tor_strdup(dormant ? "1" : "0");
  99. } else if (!strcmp(question, "events/names")) {
  100. int i;
  101. smartlist_t *event_names = smartlist_new();
  102. for (i = 0; control_event_table[i].event_name != NULL; ++i) {
  103. smartlist_add(event_names, (char *)control_event_table[i].event_name);
  104. }
  105. *answer = smartlist_join_strings(event_names, " ", 0, NULL);
  106. smartlist_free(event_names);
  107. } else if (!strcmp(question, "signal/names")) {
  108. smartlist_t *signal_names = smartlist_new();
  109. int j;
  110. for (j = 0; signal_table[j].signal_name != NULL; ++j) {
  111. smartlist_add(signal_names, (char*)signal_table[j].signal_name);
  112. }
  113. *answer = smartlist_join_strings(signal_names, " ", 0, NULL);
  114. smartlist_free(signal_names);
  115. } else if (!strcmp(question, "features/names")) {
  116. *answer = tor_strdup("VERBOSE_NAMES EXTENDED_EVENTS");
  117. } else if (!strcmp(question, "address")) {
  118. uint32_t addr;
  119. if (router_pick_published_address(get_options(), &addr, 0) < 0) {
  120. *errmsg = "Address unknown";
  121. return -1;
  122. }
  123. *answer = tor_dup_ip(addr);
  124. } else if (!strcmp(question, "traffic/read")) {
  125. tor_asprintf(answer, "%"PRIu64, (get_bytes_read()));
  126. } else if (!strcmp(question, "traffic/written")) {
  127. tor_asprintf(answer, "%"PRIu64, (get_bytes_written()));
  128. } else if (!strcmp(question, "uptime")) {
  129. long uptime_secs = get_uptime();
  130. tor_asprintf(answer, "%ld", uptime_secs);
  131. } else if (!strcmp(question, "process/pid")) {
  132. int myPid = -1;
  133. #ifdef _WIN32
  134. myPid = _getpid();
  135. #else
  136. myPid = getpid();
  137. #endif
  138. tor_asprintf(answer, "%d", myPid);
  139. } else if (!strcmp(question, "process/uid")) {
  140. #ifdef _WIN32
  141. *answer = tor_strdup("-1");
  142. #else
  143. int myUid = geteuid();
  144. tor_asprintf(answer, "%d", myUid);
  145. #endif /* defined(_WIN32) */
  146. } else if (!strcmp(question, "process/user")) {
  147. #ifdef _WIN32
  148. *answer = tor_strdup("");
  149. #else
  150. int myUid = geteuid();
  151. const struct passwd *myPwEntry = tor_getpwuid(myUid);
  152. if (myPwEntry) {
  153. *answer = tor_strdup(myPwEntry->pw_name);
  154. } else {
  155. *answer = tor_strdup("");
  156. }
  157. #endif /* defined(_WIN32) */
  158. } else if (!strcmp(question, "process/descriptor-limit")) {
  159. int max_fds = get_max_sockets();
  160. tor_asprintf(answer, "%d", max_fds);
  161. } else if (!strcmp(question, "limits/max-mem-in-queues")) {
  162. tor_asprintf(answer, "%"PRIu64,
  163. (get_options()->MaxMemInQueues));
  164. } else if (!strcmp(question, "fingerprint")) {
  165. crypto_pk_t *server_key;
  166. if (!server_mode(get_options())) {
  167. *errmsg = "Not running in server mode";
  168. return -1;
  169. }
  170. server_key = get_server_identity_key();
  171. *answer = tor_malloc(HEX_DIGEST_LEN+1);
  172. crypto_pk_get_fingerprint(server_key, *answer, 0);
  173. }
  174. return 0;
  175. }
  176. /** Awful hack: return a newly allocated string based on a routerinfo and
  177. * (possibly) an extrainfo, sticking the read-history and write-history from
  178. * <b>ei</b> into the resulting string. The thing you get back won't
  179. * necessarily have a valid signature.
  180. *
  181. * New code should never use this; it's for backward compatibility.
  182. *
  183. * NOTE: <b>ri_body</b> is as returned by signed_descriptor_get_body: it might
  184. * not be NUL-terminated. */
  185. static char *
  186. munge_extrainfo_into_routerinfo(const char *ri_body,
  187. const signed_descriptor_t *ri,
  188. const signed_descriptor_t *ei)
  189. {
  190. char *out = NULL, *outp;
  191. int i;
  192. const char *router_sig;
  193. const char *ei_body = signed_descriptor_get_body(ei);
  194. size_t ri_len = ri->signed_descriptor_len;
  195. size_t ei_len = ei->signed_descriptor_len;
  196. if (!ei_body)
  197. goto bail;
  198. outp = out = tor_malloc(ri_len+ei_len+1);
  199. if (!(router_sig = tor_memstr(ri_body, ri_len, "\nrouter-signature")))
  200. goto bail;
  201. ++router_sig;
  202. memcpy(out, ri_body, router_sig-ri_body);
  203. outp += router_sig-ri_body;
  204. for (i=0; i < 2; ++i) {
  205. const char *kwd = i ? "\nwrite-history " : "\nread-history ";
  206. const char *cp, *eol;
  207. if (!(cp = tor_memstr(ei_body, ei_len, kwd)))
  208. continue;
  209. ++cp;
  210. if (!(eol = memchr(cp, '\n', ei_len - (cp-ei_body))))
  211. continue;
  212. memcpy(outp, cp, eol-cp+1);
  213. outp += eol-cp+1;
  214. }
  215. memcpy(outp, router_sig, ri_len - (router_sig-ri_body));
  216. *outp++ = '\0';
  217. tor_assert(outp-out < (int)(ri_len+ei_len+1));
  218. return out;
  219. bail:
  220. tor_free(out);
  221. return tor_strndup(ri_body, ri->signed_descriptor_len);
  222. }
  223. /** Implementation helper for GETINFO: answers requests for information about
  224. * which ports are bound. */
  225. static int
  226. getinfo_helper_listeners(control_connection_t *control_conn,
  227. const char *question,
  228. char **answer, const char **errmsg)
  229. {
  230. int type;
  231. smartlist_t *res;
  232. (void)control_conn;
  233. (void)errmsg;
  234. if (!strcmp(question, "net/listeners/or"))
  235. type = CONN_TYPE_OR_LISTENER;
  236. else if (!strcmp(question, "net/listeners/extor"))
  237. type = CONN_TYPE_EXT_OR_LISTENER;
  238. else if (!strcmp(question, "net/listeners/dir"))
  239. type = CONN_TYPE_DIR_LISTENER;
  240. else if (!strcmp(question, "net/listeners/socks"))
  241. type = CONN_TYPE_AP_LISTENER;
  242. else if (!strcmp(question, "net/listeners/trans"))
  243. type = CONN_TYPE_AP_TRANS_LISTENER;
  244. else if (!strcmp(question, "net/listeners/natd"))
  245. type = CONN_TYPE_AP_NATD_LISTENER;
  246. else if (!strcmp(question, "net/listeners/httptunnel"))
  247. type = CONN_TYPE_AP_HTTP_CONNECT_LISTENER;
  248. else if (!strcmp(question, "net/listeners/dns"))
  249. type = CONN_TYPE_AP_DNS_LISTENER;
  250. else if (!strcmp(question, "net/listeners/control"))
  251. type = CONN_TYPE_CONTROL_LISTENER;
  252. else
  253. return 0; /* unknown key */
  254. res = smartlist_new();
  255. SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
  256. struct sockaddr_storage ss;
  257. socklen_t ss_len = sizeof(ss);
  258. if (conn->type != type || conn->marked_for_close || !SOCKET_OK(conn->s))
  259. continue;
  260. if (getsockname(conn->s, (struct sockaddr *)&ss, &ss_len) < 0) {
  261. smartlist_add_asprintf(res, "%s:%d", conn->address, (int)conn->port);
  262. } else {
  263. char *tmp = tor_sockaddr_to_str((struct sockaddr *)&ss);
  264. smartlist_add(res, esc_for_log(tmp));
  265. tor_free(tmp);
  266. }
  267. } SMARTLIST_FOREACH_END(conn);
  268. *answer = smartlist_join_strings(res, " ", 0, NULL);
  269. SMARTLIST_FOREACH(res, char *, cp, tor_free(cp));
  270. smartlist_free(res);
  271. return 0;
  272. }
  273. /** Implementation helper for GETINFO: answers requests for information about
  274. * the current time in both local and UTC forms. */
  275. STATIC int
  276. getinfo_helper_current_time(control_connection_t *control_conn,
  277. const char *question,
  278. char **answer, const char **errmsg)
  279. {
  280. (void)control_conn;
  281. (void)errmsg;
  282. struct timeval now;
  283. tor_gettimeofday(&now);
  284. char timebuf[ISO_TIME_LEN+1];
  285. if (!strcmp(question, "current-time/local"))
  286. format_local_iso_time_nospace(timebuf, (time_t)now.tv_sec);
  287. else if (!strcmp(question, "current-time/utc"))
  288. format_iso_time_nospace(timebuf, (time_t)now.tv_sec);
  289. else
  290. return 0;
  291. *answer = tor_strdup(timebuf);
  292. return 0;
  293. }
  294. /** Implementation helper for GETINFO: knows the answers for questions about
  295. * directory information. */
  296. STATIC int
  297. getinfo_helper_dir(control_connection_t *control_conn,
  298. const char *question, char **answer,
  299. const char **errmsg)
  300. {
  301. (void) control_conn;
  302. if (!strcmpstart(question, "desc/id/")) {
  303. const routerinfo_t *ri = NULL;
  304. const node_t *node = node_get_by_hex_id(question+strlen("desc/id/"), 0);
  305. if (node)
  306. ri = node->ri;
  307. if (ri) {
  308. const char *body = signed_descriptor_get_body(&ri->cache_info);
  309. if (body)
  310. *answer = tor_strndup(body, ri->cache_info.signed_descriptor_len);
  311. } else if (! we_fetch_router_descriptors(get_options())) {
  312. /* Descriptors won't be available, provide proper error */
  313. *errmsg = "We fetch microdescriptors, not router "
  314. "descriptors. You'll need to use md/id/* "
  315. "instead of desc/id/*.";
  316. return 0;
  317. }
  318. } else if (!strcmpstart(question, "desc/name/")) {
  319. const routerinfo_t *ri = NULL;
  320. /* XXX Setting 'warn_if_unnamed' here is a bit silly -- the
  321. * warning goes to the user, not to the controller. */
  322. const node_t *node =
  323. node_get_by_nickname(question+strlen("desc/name/"), 0);
  324. if (node)
  325. ri = node->ri;
  326. if (ri) {
  327. const char *body = signed_descriptor_get_body(&ri->cache_info);
  328. if (body)
  329. *answer = tor_strndup(body, ri->cache_info.signed_descriptor_len);
  330. } else if (! we_fetch_router_descriptors(get_options())) {
  331. /* Descriptors won't be available, provide proper error */
  332. *errmsg = "We fetch microdescriptors, not router "
  333. "descriptors. You'll need to use md/name/* "
  334. "instead of desc/name/*.";
  335. return 0;
  336. }
  337. } else if (!strcmp(question, "desc/download-enabled")) {
  338. int r = we_fetch_router_descriptors(get_options());
  339. tor_asprintf(answer, "%d", !!r);
  340. } else if (!strcmp(question, "desc/all-recent")) {
  341. routerlist_t *routerlist = router_get_routerlist();
  342. smartlist_t *sl = smartlist_new();
  343. if (routerlist && routerlist->routers) {
  344. SMARTLIST_FOREACH(routerlist->routers, const routerinfo_t *, ri,
  345. {
  346. const char *body = signed_descriptor_get_body(&ri->cache_info);
  347. if (body)
  348. smartlist_add(sl,
  349. tor_strndup(body, ri->cache_info.signed_descriptor_len));
  350. });
  351. }
  352. *answer = smartlist_join_strings(sl, "", 0, NULL);
  353. SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
  354. smartlist_free(sl);
  355. } else if (!strcmp(question, "desc/all-recent-extrainfo-hack")) {
  356. /* XXXX Remove this once Torstat asks for extrainfos. */
  357. routerlist_t *routerlist = router_get_routerlist();
  358. smartlist_t *sl = smartlist_new();
  359. if (routerlist && routerlist->routers) {
  360. SMARTLIST_FOREACH_BEGIN(routerlist->routers, const routerinfo_t *, ri) {
  361. const char *body = signed_descriptor_get_body(&ri->cache_info);
  362. signed_descriptor_t *ei = extrainfo_get_by_descriptor_digest(
  363. ri->cache_info.extra_info_digest);
  364. if (ei && body) {
  365. smartlist_add(sl, munge_extrainfo_into_routerinfo(body,
  366. &ri->cache_info, ei));
  367. } else if (body) {
  368. smartlist_add(sl,
  369. tor_strndup(body, ri->cache_info.signed_descriptor_len));
  370. }
  371. } SMARTLIST_FOREACH_END(ri);
  372. }
  373. *answer = smartlist_join_strings(sl, "", 0, NULL);
  374. SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
  375. smartlist_free(sl);
  376. } else if (!strcmpstart(question, "hs/client/desc/id/")) {
  377. hostname_type_t addr_type;
  378. question += strlen("hs/client/desc/id/");
  379. if (rend_valid_v2_service_id(question)) {
  380. addr_type = ONION_V2_HOSTNAME;
  381. } else if (hs_address_is_valid(question)) {
  382. addr_type = ONION_V3_HOSTNAME;
  383. } else {
  384. *errmsg = "Invalid address";
  385. return -1;
  386. }
  387. if (addr_type == ONION_V2_HOSTNAME) {
  388. rend_cache_entry_t *e = NULL;
  389. if (!rend_cache_lookup_entry(question, -1, &e)) {
  390. /* Descriptor found in cache */
  391. *answer = tor_strdup(e->desc);
  392. } else {
  393. *errmsg = "Not found in cache";
  394. return -1;
  395. }
  396. } else {
  397. ed25519_public_key_t service_pk;
  398. const char *desc;
  399. /* The check before this if/else makes sure of this. */
  400. tor_assert(addr_type == ONION_V3_HOSTNAME);
  401. if (hs_parse_address(question, &service_pk, NULL, NULL) < 0) {
  402. *errmsg = "Invalid v3 address";
  403. return -1;
  404. }
  405. desc = hs_cache_lookup_encoded_as_client(&service_pk);
  406. if (desc) {
  407. *answer = tor_strdup(desc);
  408. } else {
  409. *errmsg = "Not found in cache";
  410. return -1;
  411. }
  412. }
  413. } else if (!strcmpstart(question, "hs/service/desc/id/")) {
  414. hostname_type_t addr_type;
  415. question += strlen("hs/service/desc/id/");
  416. if (rend_valid_v2_service_id(question)) {
  417. addr_type = ONION_V2_HOSTNAME;
  418. } else if (hs_address_is_valid(question)) {
  419. addr_type = ONION_V3_HOSTNAME;
  420. } else {
  421. *errmsg = "Invalid address";
  422. return -1;
  423. }
  424. rend_cache_entry_t *e = NULL;
  425. if (addr_type == ONION_V2_HOSTNAME) {
  426. if (!rend_cache_lookup_v2_desc_as_service(question, &e)) {
  427. /* Descriptor found in cache */
  428. *answer = tor_strdup(e->desc);
  429. } else {
  430. *errmsg = "Not found in cache";
  431. return -1;
  432. }
  433. } else {
  434. ed25519_public_key_t service_pk;
  435. char *desc;
  436. /* The check before this if/else makes sure of this. */
  437. tor_assert(addr_type == ONION_V3_HOSTNAME);
  438. if (hs_parse_address(question, &service_pk, NULL, NULL) < 0) {
  439. *errmsg = "Invalid v3 address";
  440. return -1;
  441. }
  442. desc = hs_service_lookup_current_desc(&service_pk);
  443. if (desc) {
  444. /* Newly allocated string, we have ownership. */
  445. *answer = desc;
  446. } else {
  447. *errmsg = "Not found in cache";
  448. return -1;
  449. }
  450. }
  451. } else if (!strcmp(question, "md/all")) {
  452. const smartlist_t *nodes = nodelist_get_list();
  453. tor_assert(nodes);
  454. if (smartlist_len(nodes) == 0) {
  455. *answer = tor_strdup("");
  456. return 0;
  457. }
  458. smartlist_t *microdescs = smartlist_new();
  459. SMARTLIST_FOREACH_BEGIN(nodes, node_t *, n) {
  460. if (n->md && n->md->body) {
  461. char *copy = tor_strndup(n->md->body, n->md->bodylen);
  462. smartlist_add(microdescs, copy);
  463. }
  464. } SMARTLIST_FOREACH_END(n);
  465. *answer = smartlist_join_strings(microdescs, "", 0, NULL);
  466. SMARTLIST_FOREACH(microdescs, char *, md, tor_free(md));
  467. smartlist_free(microdescs);
  468. } else if (!strcmpstart(question, "md/id/")) {
  469. const node_t *node = node_get_by_hex_id(question+strlen("md/id/"), 0);
  470. const microdesc_t *md = NULL;
  471. if (node) md = node->md;
  472. if (md && md->body) {
  473. *answer = tor_strndup(md->body, md->bodylen);
  474. }
  475. } else if (!strcmpstart(question, "md/name/")) {
  476. /* XXX Setting 'warn_if_unnamed' here is a bit silly -- the
  477. * warning goes to the user, not to the controller. */
  478. const node_t *node = node_get_by_nickname(question+strlen("md/name/"), 0);
  479. /* XXXX duplicated code */
  480. const microdesc_t *md = NULL;
  481. if (node) md = node->md;
  482. if (md && md->body) {
  483. *answer = tor_strndup(md->body, md->bodylen);
  484. }
  485. } else if (!strcmp(question, "md/download-enabled")) {
  486. int r = we_fetch_microdescriptors(get_options());
  487. tor_asprintf(answer, "%d", !!r);
  488. } else if (!strcmpstart(question, "desc-annotations/id/")) {
  489. const routerinfo_t *ri = NULL;
  490. const node_t *node =
  491. node_get_by_hex_id(question+strlen("desc-annotations/id/"), 0);
  492. if (node)
  493. ri = node->ri;
  494. if (ri) {
  495. const char *annotations =
  496. signed_descriptor_get_annotations(&ri->cache_info);
  497. if (annotations)
  498. *answer = tor_strndup(annotations,
  499. ri->cache_info.annotations_len);
  500. }
  501. } else if (!strcmpstart(question, "dir/server/")) {
  502. size_t answer_len = 0;
  503. char *url = NULL;
  504. smartlist_t *descs = smartlist_new();
  505. const char *msg;
  506. int res;
  507. char *cp;
  508. tor_asprintf(&url, "/tor/%s", question+4);
  509. res = dirserv_get_routerdescs(descs, url, &msg);
  510. if (res) {
  511. log_warn(LD_CONTROL, "getinfo '%s': %s", question, msg);
  512. smartlist_free(descs);
  513. tor_free(url);
  514. *errmsg = msg;
  515. return -1;
  516. }
  517. SMARTLIST_FOREACH(descs, signed_descriptor_t *, sd,
  518. answer_len += sd->signed_descriptor_len);
  519. cp = *answer = tor_malloc(answer_len+1);
  520. SMARTLIST_FOREACH(descs, signed_descriptor_t *, sd,
  521. {
  522. memcpy(cp, signed_descriptor_get_body(sd),
  523. sd->signed_descriptor_len);
  524. cp += sd->signed_descriptor_len;
  525. });
  526. *cp = '\0';
  527. tor_free(url);
  528. smartlist_free(descs);
  529. } else if (!strcmpstart(question, "dir/status/")) {
  530. *answer = tor_strdup("");
  531. } else if (!strcmp(question, "dir/status-vote/current/consensus")) { /* v3 */
  532. if (we_want_to_fetch_flavor(get_options(), FLAV_NS)) {
  533. const cached_dir_t *consensus = dirserv_get_consensus("ns");
  534. if (consensus)
  535. *answer = tor_strdup(consensus->dir);
  536. }
  537. if (!*answer) { /* try loading it from disk */
  538. tor_mmap_t *mapped = networkstatus_map_cached_consensus("ns");
  539. if (mapped) {
  540. *answer = tor_memdup_nulterm(mapped->data, mapped->size);
  541. tor_munmap_file(mapped);
  542. }
  543. if (!*answer) { /* generate an error */
  544. *errmsg = "Could not open cached consensus. "
  545. "Make sure FetchUselessDescriptors is set to 1.";
  546. return -1;
  547. }
  548. }
  549. } else if (!strcmp(question, "network-status")) { /* v1 */
  550. static int network_status_warned = 0;
  551. if (!network_status_warned) {
  552. log_warn(LD_CONTROL, "GETINFO network-status is deprecated; it will "
  553. "go away in a future version of Tor.");
  554. network_status_warned = 1;
  555. }
  556. routerlist_t *routerlist = router_get_routerlist();
  557. if (!routerlist || !routerlist->routers ||
  558. list_server_status_v1(routerlist->routers, answer, 1) < 0) {
  559. return -1;
  560. }
  561. } else if (!strcmpstart(question, "extra-info/digest/")) {
  562. question += strlen("extra-info/digest/");
  563. if (strlen(question) == HEX_DIGEST_LEN) {
  564. char d[DIGEST_LEN];
  565. signed_descriptor_t *sd = NULL;
  566. if (base16_decode(d, sizeof(d), question, strlen(question))
  567. == sizeof(d)) {
  568. /* XXXX this test should move into extrainfo_get_by_descriptor_digest,
  569. * but I don't want to risk affecting other parts of the code,
  570. * especially since the rules for using our own extrainfo (including
  571. * when it might be freed) are different from those for using one
  572. * we have downloaded. */
  573. if (router_extrainfo_digest_is_me(d))
  574. sd = &(router_get_my_extrainfo()->cache_info);
  575. else
  576. sd = extrainfo_get_by_descriptor_digest(d);
  577. }
  578. if (sd) {
  579. const char *body = signed_descriptor_get_body(sd);
  580. if (body)
  581. *answer = tor_strndup(body, sd->signed_descriptor_len);
  582. }
  583. }
  584. }
  585. return 0;
  586. }
  587. /** Given a smartlist of 20-byte digests, return a newly allocated string
  588. * containing each of those digests in order, formatted in HEX, and terminated
  589. * with a newline. */
  590. static char *
  591. digest_list_to_string(const smartlist_t *sl)
  592. {
  593. int len;
  594. char *result, *s;
  595. /* Allow for newlines, and a \0 at the end */
  596. len = smartlist_len(sl) * (HEX_DIGEST_LEN + 1) + 1;
  597. result = tor_malloc_zero(len);
  598. s = result;
  599. SMARTLIST_FOREACH_BEGIN(sl, const char *, digest) {
  600. base16_encode(s, HEX_DIGEST_LEN + 1, digest, DIGEST_LEN);
  601. s[HEX_DIGEST_LEN] = '\n';
  602. s += HEX_DIGEST_LEN + 1;
  603. } SMARTLIST_FOREACH_END(digest);
  604. *s = '\0';
  605. return result;
  606. }
  607. /** Turn a download_status_t into a human-readable description in a newly
  608. * allocated string. The format is specified in control-spec.txt, under
  609. * the documentation for "GETINFO download/..." . */
  610. static char *
  611. download_status_to_string(const download_status_t *dl)
  612. {
  613. char *rv = NULL;
  614. char tbuf[ISO_TIME_LEN+1];
  615. const char *schedule_str, *want_authority_str;
  616. const char *increment_on_str, *backoff_str;
  617. if (dl) {
  618. /* Get some substrings of the eventual output ready */
  619. format_iso_time(tbuf, download_status_get_next_attempt_at(dl));
  620. switch (dl->schedule) {
  621. case DL_SCHED_GENERIC:
  622. schedule_str = "DL_SCHED_GENERIC";
  623. break;
  624. case DL_SCHED_CONSENSUS:
  625. schedule_str = "DL_SCHED_CONSENSUS";
  626. break;
  627. case DL_SCHED_BRIDGE:
  628. schedule_str = "DL_SCHED_BRIDGE";
  629. break;
  630. default:
  631. schedule_str = "unknown";
  632. break;
  633. }
  634. switch (dl->want_authority) {
  635. case DL_WANT_ANY_DIRSERVER:
  636. want_authority_str = "DL_WANT_ANY_DIRSERVER";
  637. break;
  638. case DL_WANT_AUTHORITY:
  639. want_authority_str = "DL_WANT_AUTHORITY";
  640. break;
  641. default:
  642. want_authority_str = "unknown";
  643. break;
  644. }
  645. switch (dl->increment_on) {
  646. case DL_SCHED_INCREMENT_FAILURE:
  647. increment_on_str = "DL_SCHED_INCREMENT_FAILURE";
  648. break;
  649. case DL_SCHED_INCREMENT_ATTEMPT:
  650. increment_on_str = "DL_SCHED_INCREMENT_ATTEMPT";
  651. break;
  652. default:
  653. increment_on_str = "unknown";
  654. break;
  655. }
  656. backoff_str = "DL_SCHED_RANDOM_EXPONENTIAL";
  657. /* Now assemble them */
  658. tor_asprintf(&rv,
  659. "next-attempt-at %s\n"
  660. "n-download-failures %u\n"
  661. "n-download-attempts %u\n"
  662. "schedule %s\n"
  663. "want-authority %s\n"
  664. "increment-on %s\n"
  665. "backoff %s\n"
  666. "last-backoff-position %u\n"
  667. "last-delay-used %d\n",
  668. tbuf,
  669. dl->n_download_failures,
  670. dl->n_download_attempts,
  671. schedule_str,
  672. want_authority_str,
  673. increment_on_str,
  674. backoff_str,
  675. dl->last_backoff_position,
  676. dl->last_delay_used);
  677. }
  678. return rv;
  679. }
  680. /** Handle the consensus download cases for getinfo_helper_downloads() */
  681. STATIC void
  682. getinfo_helper_downloads_networkstatus(const char *flavor,
  683. download_status_t **dl_to_emit,
  684. const char **errmsg)
  685. {
  686. /*
  687. * We get the one for the current bootstrapped status by default, or
  688. * take an extra /bootstrap or /running suffix
  689. */
  690. if (strcmp(flavor, "ns") == 0) {
  691. *dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_NS);
  692. } else if (strcmp(flavor, "ns/bootstrap") == 0) {
  693. *dl_to_emit = networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_NS);
  694. } else if (strcmp(flavor, "ns/running") == 0 ) {
  695. *dl_to_emit = networkstatus_get_dl_status_by_flavor_running(FLAV_NS);
  696. } else if (strcmp(flavor, "microdesc") == 0) {
  697. *dl_to_emit = networkstatus_get_dl_status_by_flavor(FLAV_MICRODESC);
  698. } else if (strcmp(flavor, "microdesc/bootstrap") == 0) {
  699. *dl_to_emit =
  700. networkstatus_get_dl_status_by_flavor_bootstrap(FLAV_MICRODESC);
  701. } else if (strcmp(flavor, "microdesc/running") == 0) {
  702. *dl_to_emit =
  703. networkstatus_get_dl_status_by_flavor_running(FLAV_MICRODESC);
  704. } else {
  705. *errmsg = "Unknown flavor";
  706. }
  707. }
  708. /** Handle the cert download cases for getinfo_helper_downloads() */
  709. STATIC void
  710. getinfo_helper_downloads_cert(const char *fp_sk_req,
  711. download_status_t **dl_to_emit,
  712. smartlist_t **digest_list,
  713. const char **errmsg)
  714. {
  715. const char *sk_req;
  716. char id_digest[DIGEST_LEN];
  717. char sk_digest[DIGEST_LEN];
  718. /*
  719. * We have to handle four cases; fp_sk_req is the request with
  720. * a prefix of "downloads/cert/" snipped off.
  721. *
  722. * Case 1: fp_sk_req = "fps"
  723. * - We should emit a digest_list with a list of all the identity
  724. * fingerprints that can be queried for certificate download status;
  725. * get it by calling list_authority_ids_with_downloads().
  726. *
  727. * Case 2: fp_sk_req = "fp/<fp>" for some fingerprint fp
  728. * - We want the default certificate for this identity fingerprint's
  729. * download status; this is the download we get from URLs starting
  730. * in /fp/ on the directory server. We can get it with
  731. * id_only_download_status_for_authority_id().
  732. *
  733. * Case 3: fp_sk_req = "fp/<fp>/sks" for some fingerprint fp
  734. * - We want a list of all signing key digests for this identity
  735. * fingerprint which can be queried for certificate download status.
  736. * Get it with list_sk_digests_for_authority_id().
  737. *
  738. * Case 4: fp_sk_req = "fp/<fp>/<sk>" for some fingerprint fp and
  739. * signing key digest sk
  740. * - We want the download status for the certificate for this specific
  741. * signing key and fingerprint. These correspond to the ones we get
  742. * from URLs starting in /fp-sk/ on the directory server. Get it with
  743. * list_sk_digests_for_authority_id().
  744. */
  745. if (strcmp(fp_sk_req, "fps") == 0) {
  746. *digest_list = list_authority_ids_with_downloads();
  747. if (!(*digest_list)) {
  748. *errmsg = "Failed to get list of authority identity digests (!)";
  749. }
  750. } else if (!strcmpstart(fp_sk_req, "fp/")) {
  751. fp_sk_req += strlen("fp/");
  752. /* Okay, look for another / to tell the fp from fp-sk cases */
  753. sk_req = strchr(fp_sk_req, '/');
  754. if (sk_req) {
  755. /* okay, split it here and try to parse <fp> */
  756. if (base16_decode(id_digest, DIGEST_LEN,
  757. fp_sk_req, sk_req - fp_sk_req) == DIGEST_LEN) {
  758. /* Skip past the '/' */
  759. ++sk_req;
  760. if (strcmp(sk_req, "sks") == 0) {
  761. /* We're asking for the list of signing key fingerprints */
  762. *digest_list = list_sk_digests_for_authority_id(id_digest);
  763. if (!(*digest_list)) {
  764. *errmsg = "Failed to get list of signing key digests for this "
  765. "authority identity digest";
  766. }
  767. } else {
  768. /* We've got a signing key digest */
  769. if (base16_decode(sk_digest, DIGEST_LEN,
  770. sk_req, strlen(sk_req)) == DIGEST_LEN) {
  771. *dl_to_emit =
  772. download_status_for_authority_id_and_sk(id_digest, sk_digest);
  773. if (!(*dl_to_emit)) {
  774. *errmsg = "Failed to get download status for this identity/"
  775. "signing key digest pair";
  776. }
  777. } else {
  778. *errmsg = "That didn't look like a signing key digest";
  779. }
  780. }
  781. } else {
  782. *errmsg = "That didn't look like an identity digest";
  783. }
  784. } else {
  785. /* We're either in downloads/certs/fp/<fp>, or we can't parse <fp> */
  786. if (strlen(fp_sk_req) == HEX_DIGEST_LEN) {
  787. if (base16_decode(id_digest, DIGEST_LEN,
  788. fp_sk_req, strlen(fp_sk_req)) == DIGEST_LEN) {
  789. *dl_to_emit = id_only_download_status_for_authority_id(id_digest);
  790. if (!(*dl_to_emit)) {
  791. *errmsg = "Failed to get download status for this authority "
  792. "identity digest";
  793. }
  794. } else {
  795. *errmsg = "That didn't look like a digest";
  796. }
  797. } else {
  798. *errmsg = "That didn't look like a digest";
  799. }
  800. }
  801. } else {
  802. *errmsg = "Unknown certificate download status query";
  803. }
  804. }
  805. /** Handle the routerdesc download cases for getinfo_helper_downloads() */
  806. STATIC void
  807. getinfo_helper_downloads_desc(const char *desc_req,
  808. download_status_t **dl_to_emit,
  809. smartlist_t **digest_list,
  810. const char **errmsg)
  811. {
  812. char desc_digest[DIGEST_LEN];
  813. /*
  814. * Two cases to handle here:
  815. *
  816. * Case 1: desc_req = "descs"
  817. * - Emit a list of all router descriptor digests, which we get by
  818. * calling router_get_descriptor_digests(); this can return NULL
  819. * if we have no current ns-flavor consensus.
  820. *
  821. * Case 2: desc_req = <fp>
  822. * - Check on the specified fingerprint and emit its download_status_t
  823. * using router_get_dl_status_by_descriptor_digest().
  824. */
  825. if (strcmp(desc_req, "descs") == 0) {
  826. *digest_list = router_get_descriptor_digests();
  827. if (!(*digest_list)) {
  828. *errmsg = "We don't seem to have a networkstatus-flavored consensus";
  829. }
  830. /*
  831. * Microdescs don't use the download_status_t mechanism, so we don't
  832. * answer queries about their downloads here; see microdesc.c.
  833. */
  834. } else if (strlen(desc_req) == HEX_DIGEST_LEN) {
  835. if (base16_decode(desc_digest, DIGEST_LEN,
  836. desc_req, strlen(desc_req)) == DIGEST_LEN) {
  837. /* Okay we got a digest-shaped thing; try asking for it */
  838. *dl_to_emit = router_get_dl_status_by_descriptor_digest(desc_digest);
  839. if (!(*dl_to_emit)) {
  840. *errmsg = "No such descriptor digest found";
  841. }
  842. } else {
  843. *errmsg = "That didn't look like a digest";
  844. }
  845. } else {
  846. *errmsg = "Unknown router descriptor download status query";
  847. }
  848. }
  849. /** Handle the bridge download cases for getinfo_helper_downloads() */
  850. STATIC void
  851. getinfo_helper_downloads_bridge(const char *bridge_req,
  852. download_status_t **dl_to_emit,
  853. smartlist_t **digest_list,
  854. const char **errmsg)
  855. {
  856. char bridge_digest[DIGEST_LEN];
  857. /*
  858. * Two cases to handle here:
  859. *
  860. * Case 1: bridge_req = "bridges"
  861. * - Emit a list of all bridge identity digests, which we get by
  862. * calling list_bridge_identities(); this can return NULL if we are
  863. * not using bridges.
  864. *
  865. * Case 2: bridge_req = <fp>
  866. * - Check on the specified fingerprint and emit its download_status_t
  867. * using get_bridge_dl_status_by_id().
  868. */
  869. if (strcmp(bridge_req, "bridges") == 0) {
  870. *digest_list = list_bridge_identities();
  871. if (!(*digest_list)) {
  872. *errmsg = "We don't seem to be using bridges";
  873. }
  874. } else if (strlen(bridge_req) == HEX_DIGEST_LEN) {
  875. if (base16_decode(bridge_digest, DIGEST_LEN,
  876. bridge_req, strlen(bridge_req)) == DIGEST_LEN) {
  877. /* Okay we got a digest-shaped thing; try asking for it */
  878. *dl_to_emit = get_bridge_dl_status_by_id(bridge_digest);
  879. if (!(*dl_to_emit)) {
  880. *errmsg = "No such bridge identity digest found";
  881. }
  882. } else {
  883. *errmsg = "That didn't look like a digest";
  884. }
  885. } else {
  886. *errmsg = "Unknown bridge descriptor download status query";
  887. }
  888. }
  889. /** Implementation helper for GETINFO: knows the answers for questions about
  890. * download status information. */
  891. STATIC int
  892. getinfo_helper_downloads(control_connection_t *control_conn,
  893. const char *question, char **answer,
  894. const char **errmsg)
  895. {
  896. download_status_t *dl_to_emit = NULL;
  897. smartlist_t *digest_list = NULL;
  898. /* Assert args are sane */
  899. tor_assert(control_conn != NULL);
  900. tor_assert(question != NULL);
  901. tor_assert(answer != NULL);
  902. tor_assert(errmsg != NULL);
  903. /* We check for this later to see if we should supply a default */
  904. *errmsg = NULL;
  905. /* Are we after networkstatus downloads? */
  906. if (!strcmpstart(question, "downloads/networkstatus/")) {
  907. getinfo_helper_downloads_networkstatus(
  908. question + strlen("downloads/networkstatus/"),
  909. &dl_to_emit, errmsg);
  910. /* Certificates? */
  911. } else if (!strcmpstart(question, "downloads/cert/")) {
  912. getinfo_helper_downloads_cert(
  913. question + strlen("downloads/cert/"),
  914. &dl_to_emit, &digest_list, errmsg);
  915. /* Router descriptors? */
  916. } else if (!strcmpstart(question, "downloads/desc/")) {
  917. getinfo_helper_downloads_desc(
  918. question + strlen("downloads/desc/"),
  919. &dl_to_emit, &digest_list, errmsg);
  920. /* Bridge descriptors? */
  921. } else if (!strcmpstart(question, "downloads/bridge/")) {
  922. getinfo_helper_downloads_bridge(
  923. question + strlen("downloads/bridge/"),
  924. &dl_to_emit, &digest_list, errmsg);
  925. } else {
  926. *errmsg = "Unknown download status query";
  927. }
  928. if (dl_to_emit) {
  929. *answer = download_status_to_string(dl_to_emit);
  930. return 0;
  931. } else if (digest_list) {
  932. *answer = digest_list_to_string(digest_list);
  933. SMARTLIST_FOREACH(digest_list, void *, s, tor_free(s));
  934. smartlist_free(digest_list);
  935. return 0;
  936. } else {
  937. if (!(*errmsg)) {
  938. *errmsg = "Unknown error";
  939. }
  940. return -1;
  941. }
  942. }
  943. /** Implementation helper for GETINFO: knows how to generate summaries of the
  944. * current states of things we send events about. */
  945. static int
  946. getinfo_helper_events(control_connection_t *control_conn,
  947. const char *question, char **answer,
  948. const char **errmsg)
  949. {
  950. const or_options_t *options = get_options();
  951. (void) control_conn;
  952. if (!strcmp(question, "circuit-status")) {
  953. smartlist_t *status = smartlist_new();
  954. SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, circ_) {
  955. origin_circuit_t *circ;
  956. char *circdesc;
  957. const char *state;
  958. if (! CIRCUIT_IS_ORIGIN(circ_) || circ_->marked_for_close)
  959. continue;
  960. circ = TO_ORIGIN_CIRCUIT(circ_);
  961. if (circ->base_.state == CIRCUIT_STATE_OPEN)
  962. state = "BUILT";
  963. else if (circ->base_.state == CIRCUIT_STATE_GUARD_WAIT)
  964. state = "GUARD_WAIT";
  965. else if (circ->cpath)
  966. state = "EXTENDED";
  967. else
  968. state = "LAUNCHED";
  969. circdesc = circuit_describe_status_for_controller(circ);
  970. smartlist_add_asprintf(status, "%lu %s%s%s",
  971. (unsigned long)circ->global_identifier,
  972. state, *circdesc ? " " : "", circdesc);
  973. tor_free(circdesc);
  974. }
  975. SMARTLIST_FOREACH_END(circ_);
  976. *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
  977. SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
  978. smartlist_free(status);
  979. } else if (!strcmp(question, "stream-status")) {
  980. smartlist_t *conns = get_connection_array();
  981. smartlist_t *status = smartlist_new();
  982. char buf[256];
  983. SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
  984. const char *state;
  985. entry_connection_t *conn;
  986. circuit_t *circ;
  987. origin_circuit_t *origin_circ = NULL;
  988. if (base_conn->type != CONN_TYPE_AP ||
  989. base_conn->marked_for_close ||
  990. base_conn->state == AP_CONN_STATE_SOCKS_WAIT ||
  991. base_conn->state == AP_CONN_STATE_NATD_WAIT)
  992. continue;
  993. conn = TO_ENTRY_CONN(base_conn);
  994. switch (base_conn->state)
  995. {
  996. case AP_CONN_STATE_CONTROLLER_WAIT:
  997. case AP_CONN_STATE_CIRCUIT_WAIT:
  998. if (conn->socks_request &&
  999. SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command))
  1000. state = "NEWRESOLVE";
  1001. else
  1002. state = "NEW";
  1003. break;
  1004. case AP_CONN_STATE_RENDDESC_WAIT:
  1005. case AP_CONN_STATE_CONNECT_WAIT:
  1006. state = "SENTCONNECT"; break;
  1007. case AP_CONN_STATE_RESOLVE_WAIT:
  1008. state = "SENTRESOLVE"; break;
  1009. case AP_CONN_STATE_OPEN:
  1010. state = "SUCCEEDED"; break;
  1011. default:
  1012. log_warn(LD_BUG, "Asked for stream in unknown state %d",
  1013. base_conn->state);
  1014. continue;
  1015. }
  1016. circ = circuit_get_by_edge_conn(ENTRY_TO_EDGE_CONN(conn));
  1017. if (circ && CIRCUIT_IS_ORIGIN(circ))
  1018. origin_circ = TO_ORIGIN_CIRCUIT(circ);
  1019. write_stream_target_to_buf(conn, buf, sizeof(buf));
  1020. smartlist_add_asprintf(status, "%lu %s %lu %s",
  1021. (unsigned long) base_conn->global_identifier,state,
  1022. origin_circ?
  1023. (unsigned long)origin_circ->global_identifier : 0ul,
  1024. buf);
  1025. } SMARTLIST_FOREACH_END(base_conn);
  1026. *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
  1027. SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
  1028. smartlist_free(status);
  1029. } else if (!strcmp(question, "orconn-status")) {
  1030. smartlist_t *conns = get_connection_array();
  1031. smartlist_t *status = smartlist_new();
  1032. SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
  1033. const char *state;
  1034. char name[128];
  1035. or_connection_t *conn;
  1036. if (base_conn->type != CONN_TYPE_OR || base_conn->marked_for_close)
  1037. continue;
  1038. conn = TO_OR_CONN(base_conn);
  1039. if (conn->base_.state == OR_CONN_STATE_OPEN)
  1040. state = "CONNECTED";
  1041. else if (conn->nickname)
  1042. state = "LAUNCHED";
  1043. else
  1044. state = "NEW";
  1045. orconn_target_get_name(name, sizeof(name), conn);
  1046. smartlist_add_asprintf(status, "%s %s", name, state);
  1047. } SMARTLIST_FOREACH_END(base_conn);
  1048. *answer = smartlist_join_strings(status, "\r\n", 0, NULL);
  1049. SMARTLIST_FOREACH(status, char *, cp, tor_free(cp));
  1050. smartlist_free(status);
  1051. } else if (!strcmpstart(question, "address-mappings/")) {
  1052. time_t min_e, max_e;
  1053. smartlist_t *mappings;
  1054. question += strlen("address-mappings/");
  1055. if (!strcmp(question, "all")) {
  1056. min_e = 0; max_e = TIME_MAX;
  1057. } else if (!strcmp(question, "cache")) {
  1058. min_e = 2; max_e = TIME_MAX;
  1059. } else if (!strcmp(question, "config")) {
  1060. min_e = 0; max_e = 0;
  1061. } else if (!strcmp(question, "control")) {
  1062. min_e = 1; max_e = 1;
  1063. } else {
  1064. return 0;
  1065. }
  1066. mappings = smartlist_new();
  1067. addressmap_get_mappings(mappings, min_e, max_e, 1);
  1068. *answer = smartlist_join_strings(mappings, "\r\n", 0, NULL);
  1069. SMARTLIST_FOREACH(mappings, char *, cp, tor_free(cp));
  1070. smartlist_free(mappings);
  1071. } else if (!strcmpstart(question, "status/")) {
  1072. /* Note that status/ is not a catch-all for events; there's only supposed
  1073. * to be a status GETINFO if there's a corresponding STATUS event. */
  1074. if (!strcmp(question, "status/circuit-established")) {
  1075. *answer = tor_strdup(have_completed_a_circuit() ? "1" : "0");
  1076. } else if (!strcmp(question, "status/enough-dir-info")) {
  1077. *answer = tor_strdup(router_have_minimum_dir_info() ? "1" : "0");
  1078. } else if (!strcmp(question, "status/good-server-descriptor") ||
  1079. !strcmp(question, "status/accepted-server-descriptor")) {
  1080. /* They're equivalent for now, until we can figure out how to make
  1081. * good-server-descriptor be what we want. See comment in
  1082. * control-spec.txt. */
  1083. *answer = tor_strdup(directories_have_accepted_server_descriptor()
  1084. ? "1" : "0");
  1085. } else if (!strcmp(question, "status/reachability-succeeded/or")) {
  1086. *answer = tor_strdup(check_whether_orport_reachable(options) ?
  1087. "1" : "0");
  1088. } else if (!strcmp(question, "status/reachability-succeeded/dir")) {
  1089. *answer = tor_strdup(check_whether_dirport_reachable(options) ?
  1090. "1" : "0");
  1091. } else if (!strcmp(question, "status/reachability-succeeded")) {
  1092. tor_asprintf(answer, "OR=%d DIR=%d",
  1093. check_whether_orport_reachable(options) ? 1 : 0,
  1094. check_whether_dirport_reachable(options) ? 1 : 0);
  1095. } else if (!strcmp(question, "status/bootstrap-phase")) {
  1096. *answer = control_event_boot_last_msg();
  1097. } else if (!strcmpstart(question, "status/version/")) {
  1098. int is_server = server_mode(options);
  1099. networkstatus_t *c = networkstatus_get_latest_consensus();
  1100. version_status_t status;
  1101. const char *recommended;
  1102. if (c) {
  1103. recommended = is_server ? c->server_versions : c->client_versions;
  1104. status = tor_version_is_obsolete(VERSION, recommended);
  1105. } else {
  1106. recommended = "?";
  1107. status = VS_UNKNOWN;
  1108. }
  1109. if (!strcmp(question, "status/version/recommended")) {
  1110. *answer = tor_strdup(recommended);
  1111. return 0;
  1112. }
  1113. if (!strcmp(question, "status/version/current")) {
  1114. switch (status)
  1115. {
  1116. case VS_RECOMMENDED: *answer = tor_strdup("recommended"); break;
  1117. case VS_OLD: *answer = tor_strdup("obsolete"); break;
  1118. case VS_NEW: *answer = tor_strdup("new"); break;
  1119. case VS_NEW_IN_SERIES: *answer = tor_strdup("new in series"); break;
  1120. case VS_UNRECOMMENDED: *answer = tor_strdup("unrecommended"); break;
  1121. case VS_EMPTY: *answer = tor_strdup("none recommended"); break;
  1122. case VS_UNKNOWN: *answer = tor_strdup("unknown"); break;
  1123. default: tor_fragile_assert();
  1124. }
  1125. }
  1126. } else if (!strcmp(question, "status/clients-seen")) {
  1127. char *bridge_stats = geoip_get_bridge_stats_controller(time(NULL));
  1128. if (!bridge_stats) {
  1129. *errmsg = "No bridge-client stats available";
  1130. return -1;
  1131. }
  1132. *answer = bridge_stats;
  1133. } else if (!strcmp(question, "status/fresh-relay-descs")) {
  1134. if (!server_mode(options)) {
  1135. *errmsg = "Only relays have descriptors";
  1136. return -1;
  1137. }
  1138. routerinfo_t *r;
  1139. extrainfo_t *e;
  1140. if (router_build_fresh_descriptor(&r, &e) < 0) {
  1141. *errmsg = "Error generating descriptor";
  1142. return -1;
  1143. }
  1144. size_t size = r->cache_info.signed_descriptor_len + 1;
  1145. if (e) {
  1146. size += e->cache_info.signed_descriptor_len + 1;
  1147. }
  1148. tor_assert(r->cache_info.signed_descriptor_len);
  1149. char *descs = tor_malloc(size);
  1150. char *cp = descs;
  1151. memcpy(cp, signed_descriptor_get_body(&r->cache_info),
  1152. r->cache_info.signed_descriptor_len);
  1153. cp += r->cache_info.signed_descriptor_len - 1;
  1154. if (e) {
  1155. if (cp[0] == '\0') {
  1156. cp[0] = '\n';
  1157. } else if (cp[0] != '\n') {
  1158. cp[1] = '\n';
  1159. cp++;
  1160. }
  1161. memcpy(cp, signed_descriptor_get_body(&e->cache_info),
  1162. e->cache_info.signed_descriptor_len);
  1163. cp += e->cache_info.signed_descriptor_len - 1;
  1164. }
  1165. if (cp[0] == '\n') {
  1166. cp[0] = '\0';
  1167. } else if (cp[0] != '\0') {
  1168. cp[1] = '\0';
  1169. }
  1170. *answer = descs;
  1171. routerinfo_free(r);
  1172. extrainfo_free(e);
  1173. } else {
  1174. return 0;
  1175. }
  1176. }
  1177. return 0;
  1178. }
  1179. /** Implementation helper for GETINFO: knows how to enumerate hidden services
  1180. * created via the control port. */
  1181. STATIC int
  1182. getinfo_helper_onions(control_connection_t *control_conn,
  1183. const char *question, char **answer,
  1184. const char **errmsg)
  1185. {
  1186. smartlist_t *onion_list = NULL;
  1187. (void) errmsg; /* no errors from this method */
  1188. if (control_conn && !strcmp(question, "onions/current")) {
  1189. onion_list = control_conn->ephemeral_onion_services;
  1190. } else if (!strcmp(question, "onions/detached")) {
  1191. onion_list = get_detached_onion_services();
  1192. } else {
  1193. return 0;
  1194. }
  1195. if (!onion_list || smartlist_len(onion_list) == 0) {
  1196. if (answer) {
  1197. *answer = tor_strdup("");
  1198. }
  1199. } else {
  1200. if (answer) {
  1201. *answer = smartlist_join_strings(onion_list, "\r\n", 0, NULL);
  1202. }
  1203. }
  1204. return 0;
  1205. }
  1206. /** Implementation helper for GETINFO: answers queries about network
  1207. * liveness. */
  1208. static int
  1209. getinfo_helper_liveness(control_connection_t *control_conn,
  1210. const char *question, char **answer,
  1211. const char **errmsg)
  1212. {
  1213. (void)control_conn;
  1214. (void)errmsg;
  1215. if (strcmp(question, "network-liveness") == 0) {
  1216. if (get_cached_network_liveness()) {
  1217. *answer = tor_strdup("up");
  1218. } else {
  1219. *answer = tor_strdup("down");
  1220. }
  1221. }
  1222. return 0;
  1223. }
  1224. /** Implementation helper for GETINFO: answers queries about shared random
  1225. * value. */
  1226. static int
  1227. getinfo_helper_sr(control_connection_t *control_conn,
  1228. const char *question, char **answer,
  1229. const char **errmsg)
  1230. {
  1231. (void) control_conn;
  1232. (void) errmsg;
  1233. if (!strcmp(question, "sr/current")) {
  1234. *answer = sr_get_current_for_control();
  1235. } else if (!strcmp(question, "sr/previous")) {
  1236. *answer = sr_get_previous_for_control();
  1237. }
  1238. /* Else statement here is unrecognized key so do nothing. */
  1239. return 0;
  1240. }
  1241. /** Callback function for GETINFO: on a given control connection, try to
  1242. * answer the question <b>q</b> and store the newly-allocated answer in
  1243. * *<b>a</b>. If an internal error occurs, return -1 and optionally set
  1244. * *<b>error_out</b> to point to an error message to be delivered to the
  1245. * controller. On success, _or if the key is not recognized_, return 0. Do not
  1246. * set <b>a</b> if the key is not recognized but you may set <b>error_out</b>
  1247. * to improve the error message.
  1248. */
  1249. typedef int (*getinfo_helper_t)(control_connection_t *,
  1250. const char *q, char **a,
  1251. const char **error_out);
  1252. /** A single item for the GETINFO question-to-answer-function table. */
  1253. typedef struct getinfo_item_t {
  1254. const char *varname; /**< The value (or prefix) of the question. */
  1255. getinfo_helper_t fn; /**< The function that knows the answer: NULL if
  1256. * this entry is documentation-only. */
  1257. const char *desc; /**< Description of the variable. */
  1258. int is_prefix; /** Must varname match exactly, or must it be a prefix? */
  1259. } getinfo_item_t;
  1260. #define ITEM(name, fn, desc) { name, getinfo_helper_##fn, desc, 0 }
  1261. #define PREFIX(name, fn, desc) { name, getinfo_helper_##fn, desc, 1 }
  1262. #define DOC(name, desc) { name, NULL, desc, 0 }
  1263. /** Table mapping questions accepted by GETINFO to the functions that know how
  1264. * to answer them. */
  1265. static const getinfo_item_t getinfo_items[] = {
  1266. ITEM("version", misc, "The current version of Tor."),
  1267. ITEM("bw-event-cache", misc, "Cached BW events for a short interval."),
  1268. ITEM("config-file", misc, "Current location of the \"torrc\" file."),
  1269. ITEM("config-defaults-file", misc, "Current location of the defaults file."),
  1270. ITEM("config-text", misc,
  1271. "Return the string that would be written by a saveconf command."),
  1272. ITEM("config-can-saveconf", misc,
  1273. "Is it possible to save the configuration to the \"torrc\" file?"),
  1274. ITEM("accounting/bytes", accounting,
  1275. "Number of bytes read/written so far in the accounting interval."),
  1276. ITEM("accounting/bytes-left", accounting,
  1277. "Number of bytes left to write/read so far in the accounting interval."),
  1278. ITEM("accounting/enabled", accounting, "Is accounting currently enabled?"),
  1279. ITEM("accounting/hibernating", accounting, "Are we hibernating or awake?"),
  1280. ITEM("accounting/interval-start", accounting,
  1281. "Time when the accounting period starts."),
  1282. ITEM("accounting/interval-end", accounting,
  1283. "Time when the accounting period ends."),
  1284. ITEM("accounting/interval-wake", accounting,
  1285. "Time to wake up in this accounting period."),
  1286. ITEM("helper-nodes", entry_guards, NULL), /* deprecated */
  1287. ITEM("entry-guards", entry_guards,
  1288. "Which nodes are we using as entry guards?"),
  1289. ITEM("fingerprint", misc, NULL),
  1290. PREFIX("config/", config, "Current configuration values."),
  1291. DOC("config/names",
  1292. "List of configuration options, types, and documentation."),
  1293. DOC("config/defaults",
  1294. "List of default values for configuration options. "
  1295. "See also config/names"),
  1296. PREFIX("current-time/", current_time, "Current time."),
  1297. DOC("current-time/local", "Current time on the local system."),
  1298. DOC("current-time/utc", "Current UTC time."),
  1299. PREFIX("downloads/networkstatus/", downloads,
  1300. "Download statuses for networkstatus objects"),
  1301. DOC("downloads/networkstatus/ns",
  1302. "Download status for current-mode networkstatus download"),
  1303. DOC("downloads/networkstatus/ns/bootstrap",
  1304. "Download status for bootstrap-time networkstatus download"),
  1305. DOC("downloads/networkstatus/ns/running",
  1306. "Download status for run-time networkstatus download"),
  1307. DOC("downloads/networkstatus/microdesc",
  1308. "Download status for current-mode microdesc download"),
  1309. DOC("downloads/networkstatus/microdesc/bootstrap",
  1310. "Download status for bootstrap-time microdesc download"),
  1311. DOC("downloads/networkstatus/microdesc/running",
  1312. "Download status for run-time microdesc download"),
  1313. PREFIX("downloads/cert/", downloads,
  1314. "Download statuses for certificates, by id fingerprint and "
  1315. "signing key"),
  1316. DOC("downloads/cert/fps",
  1317. "List of authority fingerprints for which any download statuses "
  1318. "exist"),
  1319. DOC("downloads/cert/fp/<fp>",
  1320. "Download status for <fp> with the default signing key; corresponds "
  1321. "to /fp/ URLs on directory server."),
  1322. DOC("downloads/cert/fp/<fp>/sks",
  1323. "List of signing keys for which specific download statuses are "
  1324. "available for this id fingerprint"),
  1325. DOC("downloads/cert/fp/<fp>/<sk>",
  1326. "Download status for <fp> with signing key <sk>; corresponds "
  1327. "to /fp-sk/ URLs on directory server."),
  1328. PREFIX("downloads/desc/", downloads,
  1329. "Download statuses for router descriptors, by descriptor digest"),
  1330. DOC("downloads/desc/descs",
  1331. "Return a list of known router descriptor digests"),
  1332. DOC("downloads/desc/<desc>",
  1333. "Return a download status for a given descriptor digest"),
  1334. PREFIX("downloads/bridge/", downloads,
  1335. "Download statuses for bridge descriptors, by bridge identity "
  1336. "digest"),
  1337. DOC("downloads/bridge/bridges",
  1338. "Return a list of configured bridge identity digests with download "
  1339. "statuses"),
  1340. DOC("downloads/bridge/<desc>",
  1341. "Return a download status for a given bridge identity digest"),
  1342. ITEM("info/names", misc,
  1343. "List of GETINFO options, types, and documentation."),
  1344. ITEM("events/names", misc,
  1345. "Events that the controller can ask for with SETEVENTS."),
  1346. ITEM("signal/names", misc, "Signal names recognized by the SIGNAL command"),
  1347. ITEM("features/names", misc, "What arguments can USEFEATURE take?"),
  1348. PREFIX("desc/id/", dir, "Router descriptors by ID."),
  1349. PREFIX("desc/name/", dir, "Router descriptors by nickname."),
  1350. ITEM("desc/all-recent", dir,
  1351. "All non-expired, non-superseded router descriptors."),
  1352. ITEM("desc/download-enabled", dir,
  1353. "Do we try to download router descriptors?"),
  1354. ITEM("desc/all-recent-extrainfo-hack", dir, NULL), /* Hack. */
  1355. ITEM("md/all", dir, "All known microdescriptors."),
  1356. PREFIX("md/id/", dir, "Microdescriptors by ID"),
  1357. PREFIX("md/name/", dir, "Microdescriptors by name"),
  1358. ITEM("md/download-enabled", dir,
  1359. "Do we try to download microdescriptors?"),
  1360. PREFIX("extra-info/digest/", dir, "Extra-info documents by digest."),
  1361. PREFIX("hs/client/desc/id", dir,
  1362. "Hidden Service descriptor in client's cache by onion."),
  1363. PREFIX("hs/service/desc/id/", dir,
  1364. "Hidden Service descriptor in services's cache by onion."),
  1365. PREFIX("net/listeners/", listeners, "Bound addresses by type"),
  1366. ITEM("ns/all", networkstatus,
  1367. "Brief summary of router status (v2 directory format)"),
  1368. PREFIX("ns/id/", networkstatus,
  1369. "Brief summary of router status by ID (v2 directory format)."),
  1370. PREFIX("ns/name/", networkstatus,
  1371. "Brief summary of router status by nickname (v2 directory format)."),
  1372. PREFIX("ns/purpose/", networkstatus,
  1373. "Brief summary of router status by purpose (v2 directory format)."),
  1374. PREFIX("consensus/", networkstatus,
  1375. "Information about and from the ns consensus."),
  1376. ITEM("network-status", dir,
  1377. "Brief summary of router status (v1 directory format)"),
  1378. ITEM("network-liveness", liveness,
  1379. "Current opinion on whether the network is live"),
  1380. ITEM("circuit-status", events, "List of current circuits originating here."),
  1381. ITEM("stream-status", events,"List of current streams."),
  1382. ITEM("orconn-status", events, "A list of current OR connections."),
  1383. ITEM("dormant", misc,
  1384. "Is Tor dormant (not building circuits because it's idle)?"),
  1385. PREFIX("address-mappings/", events, NULL),
  1386. DOC("address-mappings/all", "Current address mappings."),
  1387. DOC("address-mappings/cache", "Current cached DNS replies."),
  1388. DOC("address-mappings/config",
  1389. "Current address mappings from configuration."),
  1390. DOC("address-mappings/control", "Current address mappings from controller."),
  1391. PREFIX("status/", events, NULL),
  1392. DOC("status/circuit-established",
  1393. "Whether we think client functionality is working."),
  1394. DOC("status/enough-dir-info",
  1395. "Whether we have enough up-to-date directory information to build "
  1396. "circuits."),
  1397. DOC("status/bootstrap-phase",
  1398. "The last bootstrap phase status event that Tor sent."),
  1399. DOC("status/clients-seen",
  1400. "Breakdown of client countries seen by a bridge."),
  1401. DOC("status/fresh-relay-descs",
  1402. "A fresh relay/ei descriptor pair for Tor's current state. Not stored."),
  1403. DOC("status/version/recommended", "List of currently recommended versions."),
  1404. DOC("status/version/current", "Status of the current version."),
  1405. ITEM("address", misc, "IP address of this Tor host, if we can guess it."),
  1406. ITEM("traffic/read", misc,"Bytes read since the process was started."),
  1407. ITEM("traffic/written", misc,
  1408. "Bytes written since the process was started."),
  1409. ITEM("uptime", misc, "Uptime of the Tor daemon in seconds."),
  1410. ITEM("process/pid", misc, "Process id belonging to the main tor process."),
  1411. ITEM("process/uid", misc, "User id running the tor process."),
  1412. ITEM("process/user", misc,
  1413. "Username under which the tor process is running."),
  1414. ITEM("process/descriptor-limit", misc, "File descriptor limit."),
  1415. ITEM("limits/max-mem-in-queues", misc, "Actual limit on memory in queues"),
  1416. PREFIX("desc-annotations/id/", dir, "Router annotations by hexdigest."),
  1417. PREFIX("dir/server/", dir,"Router descriptors as retrieved from a DirPort."),
  1418. PREFIX("dir/status/", dir,
  1419. "v2 networkstatus docs as retrieved from a DirPort."),
  1420. ITEM("dir/status-vote/current/consensus", dir,
  1421. "v3 Networkstatus consensus as retrieved from a DirPort."),
  1422. ITEM("exit-policy/default", policies,
  1423. "The default value appended to the configured exit policy."),
  1424. ITEM("exit-policy/reject-private/default", policies,
  1425. "The default rules appended to the configured exit policy by"
  1426. " ExitPolicyRejectPrivate."),
  1427. ITEM("exit-policy/reject-private/relay", policies,
  1428. "The relay-specific rules appended to the configured exit policy by"
  1429. " ExitPolicyRejectPrivate and/or ExitPolicyRejectLocalInterfaces."),
  1430. ITEM("exit-policy/full", policies, "The entire exit policy of onion router"),
  1431. ITEM("exit-policy/ipv4", policies, "IPv4 parts of exit policy"),
  1432. ITEM("exit-policy/ipv6", policies, "IPv6 parts of exit policy"),
  1433. PREFIX("ip-to-country/", geoip, "Perform a GEOIP lookup"),
  1434. ITEM("onions/current", onions,
  1435. "Onion services owned by the current control connection."),
  1436. ITEM("onions/detached", onions,
  1437. "Onion services detached from the control connection."),
  1438. ITEM("sr/current", sr, "Get current shared random value."),
  1439. ITEM("sr/previous", sr, "Get previous shared random value."),
  1440. { NULL, NULL, NULL, 0 }
  1441. };
  1442. /** Allocate and return a list of recognized GETINFO options. */
  1443. static char *
  1444. list_getinfo_options(void)
  1445. {
  1446. int i;
  1447. smartlist_t *lines = smartlist_new();
  1448. char *ans;
  1449. for (i = 0; getinfo_items[i].varname; ++i) {
  1450. if (!getinfo_items[i].desc)
  1451. continue;
  1452. smartlist_add_asprintf(lines, "%s%s -- %s\n",
  1453. getinfo_items[i].varname,
  1454. getinfo_items[i].is_prefix ? "*" : "",
  1455. getinfo_items[i].desc);
  1456. }
  1457. smartlist_sort_strings(lines);
  1458. ans = smartlist_join_strings(lines, "", 0, NULL);
  1459. SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
  1460. smartlist_free(lines);
  1461. return ans;
  1462. }
  1463. /** Lookup the 'getinfo' entry <b>question</b>, and return
  1464. * the answer in <b>*answer</b> (or NULL if key not recognized).
  1465. * Return 0 if success or unrecognized, or -1 if recognized but
  1466. * internal error. */
  1467. static int
  1468. handle_getinfo_helper(control_connection_t *control_conn,
  1469. const char *question, char **answer,
  1470. const char **err_out)
  1471. {
  1472. int i;
  1473. *answer = NULL; /* unrecognized key by default */
  1474. for (i = 0; getinfo_items[i].varname; ++i) {
  1475. int match;
  1476. if (getinfo_items[i].is_prefix)
  1477. match = !strcmpstart(question, getinfo_items[i].varname);
  1478. else
  1479. match = !strcmp(question, getinfo_items[i].varname);
  1480. if (match) {
  1481. tor_assert(getinfo_items[i].fn);
  1482. return getinfo_items[i].fn(control_conn, question, answer, err_out);
  1483. }
  1484. }
  1485. return 0; /* unrecognized */
  1486. }
  1487. const control_cmd_syntax_t getinfo_syntax = {
  1488. .max_args = UINT_MAX,
  1489. };
  1490. /** Called when we receive a GETINFO command. Try to fetch all requested
  1491. * information, and reply with information or error message. */
  1492. int
  1493. handle_control_getinfo(control_connection_t *conn,
  1494. const control_cmd_args_t *args)
  1495. {
  1496. const smartlist_t *questions = args->args;
  1497. smartlist_t *answers = smartlist_new();
  1498. smartlist_t *unrecognized = smartlist_new();
  1499. char *ans = NULL;
  1500. int i;
  1501. SMARTLIST_FOREACH_BEGIN(questions, const char *, q) {
  1502. const char *errmsg = NULL;
  1503. if (handle_getinfo_helper(conn, q, &ans, &errmsg) < 0) {
  1504. if (!errmsg)
  1505. errmsg = "Internal error";
  1506. connection_printf_to_buf(conn, "551 %s\r\n", errmsg);
  1507. goto done;
  1508. }
  1509. if (!ans) {
  1510. if (errmsg) /* use provided error message */
  1511. smartlist_add_strdup(unrecognized, errmsg);
  1512. else /* use default error message */
  1513. smartlist_add_asprintf(unrecognized, "Unrecognized key \"%s\"", q);
  1514. } else {
  1515. smartlist_add_strdup(answers, q);
  1516. smartlist_add(answers, ans);
  1517. }
  1518. } SMARTLIST_FOREACH_END(q);
  1519. if (smartlist_len(unrecognized)) {
  1520. /* control-spec section 2.3, mid-reply '-' or end of reply ' ' */
  1521. for (i=0; i < smartlist_len(unrecognized)-1; ++i)
  1522. connection_printf_to_buf(conn,
  1523. "552-%s\r\n",
  1524. (char *)smartlist_get(unrecognized, i));
  1525. connection_printf_to_buf(conn,
  1526. "552 %s\r\n",
  1527. (char *)smartlist_get(unrecognized, i));
  1528. goto done;
  1529. }
  1530. for (i = 0; i < smartlist_len(answers); i += 2) {
  1531. char *k = smartlist_get(answers, i);
  1532. char *v = smartlist_get(answers, i+1);
  1533. if (!strchr(v, '\n') && !strchr(v, '\r')) {
  1534. connection_printf_to_buf(conn, "250-%s=", k);
  1535. connection_write_str_to_buf(v, conn);
  1536. connection_write_str_to_buf("\r\n", conn);
  1537. } else {
  1538. char *esc = NULL;
  1539. size_t esc_len;
  1540. esc_len = write_escaped_data(v, strlen(v), &esc);
  1541. connection_printf_to_buf(conn, "250+%s=\r\n", k);
  1542. connection_buf_add(esc, esc_len, TO_CONN(conn));
  1543. tor_free(esc);
  1544. }
  1545. }
  1546. connection_write_str_to_buf("250 OK\r\n", conn);
  1547. done:
  1548. SMARTLIST_FOREACH(answers, char *, cp, tor_free(cp));
  1549. smartlist_free(answers);
  1550. SMARTLIST_FOREACH(unrecognized, char *, cp, tor_free(cp));
  1551. smartlist_free(unrecognized);
  1552. return 0;
  1553. }