test_conf.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. #define SUPERSEDE_FONTSPEC_FOR_TESTING
  2. #include "putty.h"
  3. #include "storage.h"
  4. void modalfatalbox(const char *p, ...)
  5. {
  6. va_list ap;
  7. fprintf(stderr, "FATAL ERROR: ");
  8. va_start(ap, p);
  9. vfprintf(stderr, p, ap);
  10. va_end(ap);
  11. fputc('\n', stderr);
  12. exit(1);
  13. }
  14. char *platform_default_s(const char *name)
  15. { return NULL; }
  16. bool platform_default_b(const char *name, bool def)
  17. { return def; }
  18. int platform_default_i(const char *name, int def)
  19. { return def; }
  20. FontSpec *platform_default_fontspec(const char *name)
  21. { return fontspec_new_default(); }
  22. Filename *platform_default_filename(const char *name)
  23. { return filename_from_str(""); }
  24. char *platform_get_x_display(void) { return NULL; }
  25. void read_random_seed(noise_consumer_t consumer) {}
  26. void write_random_seed(void *data, int len)
  27. { unreachable("no random seed in this application"); }
  28. bool have_ssh_host_key(const char *hostname, int port,
  29. const char *keytype) { return false; }
  30. int check_stored_host_key(const char *hostname, int port,
  31. const char *keytype, const char *key) { return 1; }
  32. void store_host_key(Seat *seat, const char *hostname, int port,
  33. const char *keytype, const char *key)
  34. { unreachable("no actual host keys in this application"); }
  35. host_ca_enum *enum_host_ca_start(void) { return NULL; }
  36. bool enum_host_ca_next(host_ca_enum *handle, strbuf *out) { return false; }
  37. void enum_host_ca_finish(host_ca_enum *handle) {}
  38. host_ca *host_ca_load(const char *name) { return NULL; }
  39. void old_keyfile_warning(void) { }
  40. const bool share_can_be_upstream = false;
  41. const bool share_can_be_downstream = false;
  42. struct FontSpec {
  43. char *name;
  44. };
  45. FontSpec *fontspec_new(const char *name)
  46. {
  47. FontSpec *f = snew(FontSpec);
  48. f->name = dupstr(name);
  49. return f;
  50. }
  51. FontSpec *fontspec_new_default(void)
  52. {
  53. return fontspec_new("");
  54. }
  55. FontSpec *fontspec_copy(const FontSpec *f)
  56. {
  57. return fontspec_new(f->name);
  58. }
  59. void fontspec_free(FontSpec *f)
  60. {
  61. sfree(f->name);
  62. sfree(f);
  63. }
  64. void fontspec_serialise(BinarySink *bs, FontSpec *f)
  65. {
  66. put_asciz(bs, f->name);
  67. }
  68. FontSpec *fontspec_deserialise(BinarySource *src)
  69. {
  70. return fontspec_new(get_asciz(src));
  71. }
  72. #define MAXKEY 16
  73. typedef enum {
  74. SAVE_UNSET, SAVE_S, SAVE_I, SAVE_FONTSPEC, SAVE_FILENAME
  75. } SaveType;
  76. typedef struct SaveItem {
  77. const char *key;
  78. SaveType type;
  79. union {
  80. char sval[4096];
  81. int ival;
  82. };
  83. } SaveItem;
  84. struct settings_w {
  85. size_t n;
  86. SaveItem si[MAXKEY];
  87. };
  88. settings_w *open_settings_w(const char *sessionname, char **errmsg)
  89. { return NULL; }
  90. void close_settings_w(settings_w *sw)
  91. { unreachable("we don't open and close in this test program"); }
  92. settings_r *open_settings_r(const char *sessionname)
  93. { return NULL; }
  94. void close_settings_r(settings_r *sr) { }
  95. /* Work around lack of true snprintf before VS2015 */
  96. #if defined _WINDOWS && \
  97. !defined __MINGW32__ && \
  98. !defined __WINE__ && \
  99. _MSC_VER < 1900
  100. #define snprintf _snprintf
  101. #endif
  102. void write_setting_s(settings_w *sw, const char *key, const char *value)
  103. {
  104. for (size_t i = 0; i < sw->n; i++) {
  105. if (!strcmp(key, sw->si[i].key)) {
  106. sw->si[i].type = SAVE_S;
  107. snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s", value);
  108. break;
  109. }
  110. }
  111. }
  112. void write_setting_i(settings_w *sw, const char *key, int value)
  113. {
  114. for (size_t i = 0; i < sw->n; i++) {
  115. if (!strcmp(key, sw->si[i].key)) {
  116. sw->si[i].type = SAVE_I;
  117. sw->si[i].ival = value;
  118. break;
  119. }
  120. }
  121. }
  122. void write_setting_fontspec(settings_w *sw, const char *key, FontSpec *fs)
  123. {
  124. for (size_t i = 0; i < sw->n; i++) {
  125. if (!strcmp(key, sw->si[i].key)) {
  126. sw->si[i].type = SAVE_FONTSPEC;
  127. snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s", fs->name);
  128. break;
  129. }
  130. }
  131. }
  132. void write_setting_filename(settings_w *sw, const char *key, Filename *fn)
  133. {
  134. for (size_t i = 0; i < sw->n; i++) {
  135. if (!strcmp(key, sw->si[i].key)) {
  136. sw->si[i].type = SAVE_FILENAME;
  137. snprintf(sw->si[i].sval, sizeof(sw->si[i].sval), "%s",
  138. filename_to_str(fn));
  139. break;
  140. }
  141. }
  142. }
  143. struct settings_r {
  144. size_t n;
  145. SaveItem si[MAXKEY];
  146. };
  147. char *read_setting_s(settings_r *sr, const char *key)
  148. {
  149. if (sr)
  150. for (size_t i = 0; i < sr->n; i++)
  151. if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_S)
  152. return dupstr(sr->si[i].sval);
  153. return NULL;
  154. }
  155. int read_setting_i(settings_r *sr, const char *key, int defvalue)
  156. {
  157. if (sr)
  158. for (size_t i = 0; i < sr->n; i++)
  159. if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_I)
  160. return sr->si[i].ival;
  161. return defvalue;
  162. }
  163. FontSpec *read_setting_fontspec(settings_r *sr, const char *key)
  164. {
  165. if (sr)
  166. for (size_t i = 0; i < sr->n; i++)
  167. if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_FONTSPEC)
  168. return fontspec_new(sr->si[i].sval);
  169. return NULL;
  170. }
  171. Filename *read_setting_filename(settings_r *sr, const char *key)
  172. {
  173. if (sr)
  174. for (size_t i = 0; i < sr->n; i++)
  175. if (!strcmp(key, sr->si[i].key) && sr->si[i].type == SAVE_FILENAME)
  176. return filename_from_str(sr->si[i].sval);
  177. return NULL;
  178. }
  179. void del_settings(const char *sessionname) {}
  180. settings_e *enum_settings_start(void)
  181. { return NULL; }
  182. bool enum_settings_next(settings_e *handle, strbuf *out)
  183. { unreachable("where did you get a settings_e from?"); }
  184. void enum_settings_finish(settings_e *handle)
  185. { unreachable("where did you get a settings_e from?"); }
  186. static int nfails = 0;
  187. void test_str_simple(int confid, const char *saveid, const char *defexp)
  188. {
  189. Conf *conf = conf_new();
  190. do_defaults(NULL, conf);
  191. const char *defgot = conf_get_str(conf, confid);
  192. if (0 != strcmp(defgot, defexp)) {
  193. printf("fail test_str_simple(%s): default = '%s', expected '%s'\n",
  194. saveid, defgot, defexp);
  195. nfails++;
  196. }
  197. for (int i = 0; i < 2; i++) {
  198. settings_w sw = {
  199. .n = 1,
  200. .si[0].key = saveid,
  201. .si[0].type = SAVE_UNSET,
  202. };
  203. static const char *const teststrings[] = { "foo", "bar" };
  204. const char *teststring = teststrings[i];
  205. conf_set_str(conf, confid, teststring);
  206. save_open_settings(&sw, conf);
  207. if (sw.si[0].type != SAVE_S) {
  208. printf("fail test_str_simple(%s): saved type = %d, expected %d\n",
  209. saveid, sw.si[0].type, SAVE_S);
  210. nfails++;
  211. } else if (0 != strcmp(sw.si[0].sval, teststring)) {
  212. printf("fail test_str_simple(%s): "
  213. "saved string = '%s', expected '%s'\n",
  214. saveid, sw.si[0].sval, teststring);
  215. nfails++;
  216. }
  217. conf_clear(conf);
  218. settings_r sr = {
  219. .n = 1,
  220. .si[0].key = saveid,
  221. .si[0].type = SAVE_S,
  222. };
  223. snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
  224. load_open_settings(&sr, conf);
  225. const char *loaded = conf_get_str(conf, confid);
  226. if (0 != strcmp(loaded, teststring)) {
  227. printf("fail test_str_simple(%s): "
  228. "loaded string = '%s', expected '%s'\n",
  229. saveid, loaded, teststring);
  230. nfails++;
  231. }
  232. }
  233. conf_free(conf);
  234. }
  235. void test_int_simple(int confid, const char *saveid, int defexp)
  236. {
  237. Conf *conf = conf_new();
  238. do_defaults(NULL, conf);
  239. int defgot = conf_get_int(conf, confid);
  240. if (defgot != defexp) {
  241. printf("fail test_int_simple(%s): default = %d, expected %d\n",
  242. saveid, defgot, defexp);
  243. nfails++;
  244. }
  245. for (int i = 0; i < 2; i++) {
  246. settings_w sw = {
  247. .n = 1,
  248. .si[0].key = saveid,
  249. .si[0].type = SAVE_UNSET,
  250. };
  251. static const int testints[] = { 12345, 54321 };
  252. int testint = testints[i];
  253. conf_set_int(conf, confid, testint);
  254. save_open_settings(&sw, conf);
  255. if (sw.si[0].type != SAVE_I) {
  256. printf("fail test_int_simple(%s): saved type = %d, expected %d\n",
  257. saveid, sw.si[0].type, SAVE_I);
  258. nfails++;
  259. } else if (sw.si[0].ival != testint) {
  260. printf("fail test_int_simple(%s): "
  261. "saved integer = %d, expected %d\n",
  262. saveid, sw.si[0].ival, testint);
  263. nfails++;
  264. }
  265. conf_clear(conf);
  266. settings_r sr = {
  267. .n = 1,
  268. .si[0].key = saveid,
  269. .si[0].type = SAVE_I,
  270. .si[0].ival = testint,
  271. };
  272. load_open_settings(&sr, conf);
  273. int loaded = conf_get_int(conf, confid);
  274. if (loaded != testint) {
  275. printf("fail test_int_simple(%s): "
  276. "loaded integer = %d, expected %d\n",
  277. saveid, loaded, testint);
  278. nfails++;
  279. }
  280. }
  281. conf_free(conf);
  282. }
  283. void test_int_translated_internal(
  284. int confid, const char *saveid, bool test_save, bool test_load,
  285. void (*load_prepare)(settings_r *), int defexp, va_list ap)
  286. {
  287. Conf *conf = conf_new();
  288. do_defaults(NULL, conf);
  289. int defgot = conf_get_int(conf, confid);
  290. if (defgot != defexp) {
  291. printf("fail test_int_translated(%s): default = %d, expected %d\n",
  292. saveid, defgot, defexp);
  293. nfails++;
  294. }
  295. int confval = va_arg(ap, int);
  296. while (confval != -1) {
  297. int storageval = va_arg(ap, int);
  298. if (test_save) {
  299. settings_w sw = {
  300. .n = 1,
  301. .si[0].key = saveid,
  302. .si[0].type = SAVE_UNSET,
  303. };
  304. conf_set_int(conf, confid, confval);
  305. save_open_settings(&sw, conf);
  306. if (sw.si[0].type != SAVE_I) {
  307. printf("fail test_int_translated(%s): "
  308. "saved type = %d, expected %d\n",
  309. saveid, sw.si[0].type, SAVE_I);
  310. nfails++;
  311. } else if (sw.si[0].ival != storageval) {
  312. printf("fail test_int_translated(%s.%d.%d): "
  313. "saved integer = %d, expected %d\n",
  314. saveid, confval, storageval, sw.si[0].ival, storageval);
  315. nfails++;
  316. }
  317. }
  318. if (test_load) {
  319. conf_clear(conf);
  320. settings_r sr = {
  321. .n = 1,
  322. .si[0].key = saveid,
  323. .si[0].type = SAVE_I,
  324. .si[0].ival = storageval,
  325. };
  326. if (load_prepare)
  327. load_prepare(&sr);
  328. load_open_settings(&sr, conf);
  329. int loaded = conf_get_int(conf, confid);
  330. if (loaded != confval) {
  331. printf("fail test_int_translated(%s.%d.%d): "
  332. "loaded integer = %d, expected %d\n",
  333. saveid, confval, storageval, loaded, confval);
  334. nfails++;
  335. }
  336. }
  337. confval = va_arg(ap, int);
  338. }
  339. conf_free(conf);
  340. }
  341. void test_int_translated(int confid, const char *saveid, int defexp, ...)
  342. {
  343. va_list ap;
  344. va_start(ap, defexp);
  345. test_int_translated_internal(confid, saveid, true, true, NULL, defexp, ap);
  346. va_end(ap);
  347. }
  348. void test_int_translated_load_legacy(
  349. int confid, const char *saveid, void (*load_prepare)(settings_r *),
  350. int defexp, ...)
  351. {
  352. va_list ap;
  353. va_start(ap, defexp);
  354. test_int_translated_internal(confid, saveid, false, true, load_prepare,
  355. defexp, ap);
  356. va_end(ap);
  357. }
  358. void test_bool_simple(int confid, const char *saveid, bool defexp)
  359. {
  360. Conf *conf = conf_new();
  361. do_defaults(NULL, conf);
  362. bool defgot = conf_get_bool(conf, confid);
  363. if (defgot != defexp) {
  364. printf("fail test_bool_simple(%s): default = %d, expected %d\n",
  365. saveid, defgot, defexp);
  366. nfails++;
  367. }
  368. for (int i = 0; i < 2; i++) {
  369. settings_w sw = {
  370. .n = 1,
  371. .si[0].key = saveid,
  372. .si[0].type = SAVE_UNSET,
  373. };
  374. static const bool testbools[] = { false, true };
  375. bool testbool = testbools[i];
  376. conf_set_bool(conf, confid, testbool);
  377. save_open_settings(&sw, conf);
  378. if (sw.si[0].type != SAVE_I) {
  379. printf("fail test_bool_simple(%s): saved type = %d, expected %d\n",
  380. saveid, sw.si[0].type, SAVE_I);
  381. nfails++;
  382. } else if (sw.si[0].ival != testbool) {
  383. printf("fail test_bool_simple(%s): "
  384. "saved integer = %d, expected %d\n",
  385. saveid, sw.si[0].ival, testbool);
  386. nfails++;
  387. }
  388. conf_clear(conf);
  389. settings_r sr = {
  390. .n = 1,
  391. .si[0].key = saveid,
  392. .si[0].type = SAVE_I,
  393. .si[0].ival = testbool,
  394. };
  395. load_open_settings(&sr, conf);
  396. bool loaded = conf_get_bool(conf, confid);
  397. if (loaded != testbool) {
  398. printf("fail test_bool_simple(%s): "
  399. "loaded boolean = %d, expected %d\n",
  400. saveid, loaded, testbool);
  401. nfails++;
  402. }
  403. }
  404. conf_free(conf);
  405. }
  406. void test_file_simple(int confid, const char *saveid)
  407. {
  408. Conf *conf = conf_new();
  409. do_defaults(NULL, conf);
  410. for (int i = 0; i < 2; i++) {
  411. settings_w sw = {
  412. .n = 1,
  413. .si[0].key = saveid,
  414. .si[0].type = SAVE_UNSET,
  415. };
  416. static const char *const teststrings[] = { "foo", "bar" };
  417. const char *teststring = teststrings[i];
  418. Filename *testfn = filename_from_str(teststring);
  419. conf_set_filename(conf, confid, testfn);
  420. filename_free(testfn);
  421. save_open_settings(&sw, conf);
  422. if (sw.si[0].type != SAVE_FILENAME) {
  423. printf("fail test_file_simple(%s): saved type = %d, expected %d\n",
  424. saveid, sw.si[0].type, SAVE_FILENAME);
  425. nfails++;
  426. } else if (0 != strcmp(sw.si[0].sval, teststring)) {
  427. printf("fail test_file_simple(%s): "
  428. "saved string = '%s', expected '%s'\n",
  429. saveid, sw.si[0].sval, teststring);
  430. nfails++;
  431. }
  432. conf_clear(conf);
  433. settings_r sr = {
  434. .n = 1,
  435. .si[0].key = saveid,
  436. .si[0].type = SAVE_FILENAME,
  437. };
  438. snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
  439. load_open_settings(&sr, conf);
  440. const char *loaded = filename_to_str(conf_get_filename(conf, confid));
  441. if (0 != strcmp(loaded, teststring)) {
  442. printf("fail test_file_simple(%s): "
  443. "loaded string = '%s', expected '%s'\n",
  444. saveid, loaded, teststring);
  445. nfails++;
  446. }
  447. }
  448. conf_free(conf);
  449. }
  450. void test_font_simple(int confid, const char *saveid)
  451. {
  452. Conf *conf = conf_new();
  453. do_defaults(NULL, conf);
  454. for (int i = 0; i < 2; i++) {
  455. settings_w sw = {
  456. .n = 1,
  457. .si[0].key = saveid,
  458. .si[0].type = SAVE_UNSET,
  459. };
  460. static const char *const teststrings[] = { "foo", "bar" };
  461. const char *teststring = teststrings[i];
  462. FontSpec *testfs = fontspec_new(teststring);
  463. conf_set_fontspec(conf, confid, testfs);
  464. fontspec_free(testfs);
  465. save_open_settings(&sw, conf);
  466. if (sw.si[0].type != SAVE_FONTSPEC) {
  467. printf("fail test_font_simple(%s): saved type = %d, expected %d\n",
  468. saveid, sw.si[0].type, SAVE_FONTSPEC);
  469. nfails++;
  470. } else if (0 != strcmp(sw.si[0].sval, teststring)) {
  471. printf("fail test_font_simple(%s): "
  472. "saved string = '%s', expected '%s'\n",
  473. saveid, sw.si[0].sval, teststring);
  474. nfails++;
  475. }
  476. conf_clear(conf);
  477. settings_r sr = {
  478. .n = 1,
  479. .si[0].key = saveid,
  480. .si[0].type = SAVE_FONTSPEC,
  481. };
  482. snprintf(sr.si[0].sval, sizeof(sr.si[0].sval), "%s", teststring);
  483. load_open_settings(&sr, conf);
  484. const char *loaded = conf_get_fontspec(conf, confid)->name;
  485. if (0 != strcmp(loaded, teststring)) {
  486. printf("fail test_file_simple(%s): "
  487. "loaded string = '%s', expected '%s'\n",
  488. saveid, loaded, teststring);
  489. nfails++;
  490. }
  491. }
  492. conf_free(conf);
  493. }
  494. static void load_prepare_socks4(settings_r *sr)
  495. {
  496. size_t pos = sr->n++;
  497. sr->si[pos].key = "ProxySOCKSVersion";
  498. sr->si[pos].type = SAVE_I;
  499. sr->si[pos].ival = 4;
  500. }
  501. void test_simple(void)
  502. {
  503. test_str_simple(CONF_host, "HostName", "");
  504. test_int_translated(CONF_addressfamily, "AddressFamily", ADDRTYPE_UNSPEC,
  505. ADDRTYPE_UNSPEC, 0, ADDRTYPE_IPV4, 1,
  506. ADDRTYPE_IPV6, 2, -1);
  507. test_bool_simple(CONF_warn_on_close, "WarnOnClose", true);
  508. test_bool_simple(CONF_tcp_nodelay, "TCPNoDelay", true);
  509. test_bool_simple(CONF_tcp_keepalives, "TCPKeepalives", false);
  510. test_str_simple(CONF_loghost, "LogHost", "");
  511. test_str_simple(CONF_proxy_exclude_list, "ProxyExcludeList", "");
  512. test_bool_simple(CONF_even_proxy_localhost, "ProxyLocalhost", false);
  513. test_str_simple(CONF_proxy_host, "ProxyHost", "proxy");
  514. test_int_simple(CONF_proxy_port, "ProxyPort", 80);
  515. test_str_simple(CONF_proxy_username, "ProxyUsername", "");
  516. test_str_simple(CONF_proxy_password, "ProxyPassword", "");
  517. test_str_simple(CONF_proxy_telnet_command, "ProxyTelnetCommand", "connect %host %port\\n");
  518. test_int_translated(CONF_proxy_log_to_term, "ProxyLogToTerm", FORCE_OFF,
  519. FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
  520. test_str_simple(CONF_remote_cmd, "RemoteCommand", "");
  521. test_bool_simple(CONF_nopty, "NoPTY", false);
  522. test_bool_simple(CONF_compression, "Compression", false);
  523. test_bool_simple(CONF_ssh_prefer_known_hostkeys, "PreferKnownHostKeys", true);
  524. test_int_simple(CONF_ssh_rekey_time, "RekeyTime", 60);
  525. test_str_simple(CONF_ssh_rekey_data, "RekeyBytes", "1G");
  526. test_bool_simple(CONF_tryagent, "TryAgent", true);
  527. test_bool_simple(CONF_agentfwd, "AgentFwd", false);
  528. test_bool_simple(CONF_change_username, "ChangeUsername", false);
  529. test_file_simple(CONF_keyfile, "PublicKeyFile");
  530. test_file_simple(CONF_detached_cert, "DetachedCertificate");
  531. test_str_simple(CONF_auth_plugin, "AuthPlugin", "");
  532. test_bool_simple(CONF_ssh2_des_cbc, "SSH2DES", false);
  533. test_bool_simple(CONF_ssh_no_userauth, "SshNoAuth", false);
  534. test_bool_simple(CONF_ssh_no_trivial_userauth, "SshNoTrivialAuth", false);
  535. test_bool_simple(CONF_ssh_show_banner, "SshBanner", true);
  536. test_bool_simple(CONF_try_tis_auth, "AuthTIS", false);
  537. test_bool_simple(CONF_try_ki_auth, "AuthKI", true);
  538. test_bool_simple(CONF_ssh_no_shell, "SshNoShell", false);
  539. test_str_simple(CONF_termtype, "TerminalType", "xterm");
  540. test_str_simple(CONF_termspeed, "TerminalSpeed", "38400,38400");
  541. test_str_simple(CONF_username, "UserName", "");
  542. test_bool_simple(CONF_username_from_env, "UserNameFromEnvironment", false);
  543. test_str_simple(CONF_localusername, "LocalUserName", "");
  544. test_bool_simple(CONF_rfc_environ, "RFCEnviron", false);
  545. test_bool_simple(CONF_passive_telnet, "PassiveTelnet", false);
  546. test_str_simple(CONF_serline, "SerialLine", "");
  547. test_int_simple(CONF_serspeed, "SerialSpeed", 9600);
  548. test_int_simple(CONF_serdatabits, "SerialDataBits", 8);
  549. test_int_simple(CONF_serstopbits, "SerialStopHalfbits", 2);
  550. test_int_translated(CONF_serparity, "SerialParity", SER_PAR_NONE,
  551. SER_PAR_NONE, 0, SER_PAR_ODD, 1, SER_PAR_EVEN, 2,
  552. SER_PAR_MARK, 3, SER_PAR_SPACE, 4, -1);
  553. test_int_translated(CONF_serflow, "SerialFlowControl", SER_FLOW_XONXOFF,
  554. SER_FLOW_NONE, 0, SER_FLOW_XONXOFF, 1,
  555. SER_FLOW_RTSCTS, 2, SER_FLOW_DSRDTR, 3, -1);
  556. test_str_simple(CONF_supdup_location, "SUPDUPLocation", "The Internet");
  557. test_int_translated(CONF_supdup_ascii_set, "SUPDUPCharset",
  558. SUPDUP_CHARSET_ASCII,
  559. SUPDUP_CHARSET_ASCII, 0,
  560. SUPDUP_CHARSET_ITS, 1,
  561. SUPDUP_CHARSET_WAITS, 2, -1);
  562. test_bool_simple(CONF_supdup_more, "SUPDUPMoreProcessing", false);
  563. test_bool_simple(CONF_supdup_scroll, "SUPDUPScrolling", false);
  564. test_bool_simple(CONF_bksp_is_delete, "BackspaceIsDelete", true);
  565. test_bool_simple(CONF_rxvt_homeend, "RXVTHomeEnd", false);
  566. test_int_translated(CONF_funky_type, "LinuxFunctionKeys", FUNKY_TILDE,
  567. FUNKY_TILDE, 0, FUNKY_LINUX, 1, FUNKY_XTERM, 2,
  568. FUNKY_VT400, 3, FUNKY_VT100P, 4, FUNKY_SCO, 5,
  569. FUNKY_XTERM_216, 6, -1);
  570. test_int_translated(CONF_sharrow_type, "ShiftedArrowKeys",
  571. SHARROW_APPLICATION,
  572. SHARROW_APPLICATION, 0, SHARROW_BITMAP, 1, -1);
  573. test_bool_simple(CONF_no_applic_c, "NoApplicationCursors", false);
  574. test_bool_simple(CONF_no_applic_k, "NoApplicationKeys", false);
  575. test_bool_simple(CONF_no_mouse_rep, "NoMouseReporting", false);
  576. test_bool_simple(CONF_no_remote_resize, "NoRemoteResize", false);
  577. test_bool_simple(CONF_no_alt_screen, "NoAltScreen", false);
  578. test_bool_simple(CONF_no_remote_wintitle, "NoRemoteWinTitle", false);
  579. test_bool_simple(CONF_no_remote_clearscroll, "NoRemoteClearScroll", false);
  580. test_bool_simple(CONF_no_dbackspace, "NoDBackspace", false);
  581. test_bool_simple(CONF_no_remote_charset, "NoRemoteCharset", false);
  582. /* note we have no test for CONF_remote_qtitle_action because no default */
  583. test_bool_simple(CONF_app_cursor, "ApplicationCursorKeys", false);
  584. test_bool_simple(CONF_app_keypad, "ApplicationKeypad", false);
  585. test_bool_simple(CONF_nethack_keypad, "NetHackKeypad", false);
  586. test_bool_simple(CONF_telnet_keyboard, "TelnetKey", false);
  587. test_bool_simple(CONF_telnet_newline, "TelnetRet", true);
  588. test_bool_simple(CONF_alt_f4, "AltF4", true);
  589. test_bool_simple(CONF_alt_space, "AltSpace", false);
  590. test_bool_simple(CONF_alt_only, "AltOnly", false);
  591. test_int_translated(CONF_localecho, "LocalEcho", AUTO,
  592. FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
  593. test_int_translated(CONF_localedit, "LocalEdit", AUTO,
  594. FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
  595. test_bool_simple(CONF_alwaysontop, "AlwaysOnTop", false);
  596. test_bool_simple(CONF_fullscreenonaltenter, "FullScreenOnAltEnter", false);
  597. test_bool_simple(CONF_scroll_on_key, "ScrollOnKey", false);
  598. test_bool_simple(CONF_scroll_on_disp, "ScrollOnDisp", true);
  599. test_bool_simple(CONF_erase_to_scrollback, "EraseToScrollback", true);
  600. test_bool_simple(CONF_compose_key, "ComposeKey", false);
  601. test_bool_simple(CONF_ctrlaltkeys, "CtrlAltKeys", true);
  602. test_str_simple(CONF_wintitle, "WinTitle", "");
  603. test_int_simple(CONF_savelines, "ScrollbackLines", 2000);
  604. test_bool_simple(CONF_dec_om, "DECOriginMode", false);
  605. test_bool_simple(CONF_wrap_mode, "AutoWrapMode", true);
  606. test_bool_simple(CONF_lfhascr, "LFImpliesCR", false);
  607. test_int_translated(CONF_cursor_type, "CurType", CURSOR_BLOCK,
  608. CURSOR_BLOCK, 0, CURSOR_UNDERLINE, 1,
  609. CURSOR_VERTICAL_LINE, 2, -1);
  610. test_bool_simple(CONF_blink_cur, "BlinkCur", false);
  611. test_int_translated(CONF_beep, "Beep", 1,
  612. BELL_DISABLED, 0, BELL_DEFAULT, 1, BELL_VISUAL, 2,
  613. BELL_WAVEFILE, 3, BELL_PCSPEAKER, 4, -1);
  614. test_int_translated(CONF_beep_ind, "BeepInd", 0,
  615. B_IND_DISABLED, 0, B_IND_FLASH, 1, B_IND_STEADY, 2, -1);
  616. test_bool_simple(CONF_bellovl, "BellOverload", true);
  617. test_int_simple(CONF_bellovl_n, "BellOverloadN", 5);
  618. test_file_simple(CONF_bell_wavefile, "BellWaveFile");
  619. test_bool_simple(CONF_scrollbar, "ScrollBar", true);
  620. test_bool_simple(CONF_scrollbar_in_fullscreen, "ScrollBarFullScreen", false);
  621. test_int_translated(CONF_resize_action, "LockSize", RESIZE_TERM,
  622. RESIZE_TERM, 0, RESIZE_DISABLED, 1, RESIZE_FONT, 2,
  623. RESIZE_EITHER, 3, -1);
  624. test_bool_simple(CONF_bce, "BCE", true);
  625. test_bool_simple(CONF_blinktext, "BlinkText", false);
  626. test_bool_simple(CONF_win_name_always, "WinNameAlways", true);
  627. test_int_simple(CONF_width, "TermWidth", 80);
  628. test_int_simple(CONF_height, "TermHeight", 24);
  629. test_font_simple(CONF_font, "Font");
  630. test_int_translated(CONF_font_quality, "FontQuality", FQ_DEFAULT,
  631. FQ_DEFAULT, 0, FQ_ANTIALIASED, 1, FQ_NONANTIALIASED, 2,
  632. FQ_CLEARTYPE, 3, -1);
  633. test_file_simple(CONF_logfilename, "LogFileName");
  634. test_int_translated(CONF_logtype, "LogType", LGTYP_NONE,
  635. LGTYP_NONE, 0, LGTYP_ASCII, 1, LGTYP_DEBUG, 2,
  636. LGTYP_PACKETS, 3, LGTYP_SSHRAW, 4, -1);
  637. /* FIXME: this won't work because -1 is also the terminator, darn */
  638. test_int_translated(CONF_logxfovr, "LogFileClash", LGXF_ASK,
  639. LGXF_OVR, 1, LGXF_APN, 0, LGXF_ASK, -1, -1);
  640. test_bool_simple(CONF_logflush, "LogFlush", true);
  641. test_bool_simple(CONF_logheader, "LogHeader", true);
  642. test_bool_simple(CONF_logomitpass, "SSHLogOmitPasswords", true);
  643. test_bool_simple(CONF_logomitdata, "SSHLogOmitData", false);
  644. test_bool_simple(CONF_hide_mouseptr, "HideMousePtr", false);
  645. test_bool_simple(CONF_sunken_edge, "SunkenEdge", false);
  646. test_int_simple(CONF_window_border, "WindowBorder", 1);
  647. test_str_simple(CONF_answerback, "Answerback", "PuTTY");
  648. test_str_simple(CONF_printer, "Printer", "");
  649. test_bool_simple(CONF_no_arabicshaping, "DisableArabicShaping", false);
  650. test_bool_simple(CONF_no_bidi, "DisableBidi", false);
  651. test_bool_simple(CONF_ansi_colour, "ANSIColour", true);
  652. test_bool_simple(CONF_xterm_256_colour, "Xterm256Colour", true);
  653. test_bool_simple(CONF_true_colour, "TrueColour", true);
  654. test_bool_simple(CONF_system_colour, "UseSystemColours", false);
  655. test_bool_simple(CONF_try_palette, "TryPalette", false);
  656. test_int_translated(CONF_mouse_is_xterm, "MouseIsXterm", 0,
  657. MOUSE_COMPROMISE, 0, MOUSE_XTERM, 1,
  658. MOUSE_WINDOWS, 2, -1);
  659. test_bool_simple(CONF_rect_select, "RectSelect", false);
  660. test_bool_simple(CONF_paste_controls, "PasteControls", false);
  661. test_bool_simple(CONF_rawcnp, "RawCNP", false);
  662. test_bool_simple(CONF_utf8linedraw, "UTF8linedraw", false);
  663. test_bool_simple(CONF_rtf_paste, "PasteRTF", false);
  664. test_bool_simple(CONF_mouse_override, "MouseOverride", true);
  665. test_bool_simple(CONF_mouseautocopy, "MouseAutocopy", CLIPUI_DEFAULT_AUTOCOPY);
  666. test_int_translated(CONF_vtmode, "FontVTMode", VT_UNICODE,
  667. VT_XWINDOWS, 0,
  668. VT_OEMANSI, 1,
  669. VT_OEMONLY, 2,
  670. VT_POORMAN, 3,
  671. VT_UNICODE, 4,
  672. -1);
  673. test_str_simple(CONF_line_codepage, "LineCodePage", "");
  674. test_bool_simple(CONF_cjk_ambig_wide, "CJKAmbigWide", false);
  675. test_bool_simple(CONF_utf8_override, "UTF8Override", true);
  676. test_bool_simple(CONF_xlat_capslockcyr, "CapsLockCyr", false);
  677. test_bool_simple(CONF_x11_forward, "X11Forward", false);
  678. test_str_simple(CONF_x11_display, "X11Display", "");
  679. test_int_translated(CONF_x11_auth, "X11AuthType", X11_MIT,
  680. X11_NO_AUTH, 0, X11_MIT, 1, X11_XDM, 2, -1);
  681. test_file_simple(CONF_xauthfile, "X11AuthFile");
  682. test_bool_simple(CONF_lport_acceptall, "LocalPortAcceptAll", false);
  683. test_bool_simple(CONF_rport_acceptall, "RemotePortAcceptAll", false);
  684. test_bool_simple(CONF_ssh_connection_sharing, "ConnectionSharing", false);
  685. test_bool_simple(CONF_ssh_connection_sharing_upstream, "ConnectionSharingUpstream", true);
  686. test_bool_simple(CONF_ssh_connection_sharing_downstream, "ConnectionSharingDownstream", true);
  687. test_bool_simple(CONF_stamp_utmp, "StampUtmp", true);
  688. test_bool_simple(CONF_login_shell, "LoginShell", true);
  689. test_bool_simple(CONF_scrollbar_on_left, "ScrollbarOnLeft", false);
  690. test_bool_simple(CONF_shadowbold, "ShadowBold", false);
  691. test_font_simple(CONF_boldfont, "BoldFont");
  692. test_font_simple(CONF_widefont, "WideFont");
  693. test_font_simple(CONF_wideboldfont, "WideBoldFont");
  694. test_int_simple(CONF_shadowboldoffset, "ShadowBoldOffset", 1);
  695. test_bool_simple(CONF_crhaslf, "CRImpliesLF", false);
  696. test_str_simple(CONF_winclass, "WindowClass", "");
  697. test_int_translated(CONF_close_on_exit, "CloseOnExit", AUTO,
  698. FORCE_OFF, 0, AUTO, 1, FORCE_ON, 2, -1);
  699. test_int_translated(CONF_proxy_dns, "ProxyDNS", AUTO,
  700. FORCE_OFF, 0, AUTO, 1, FORCE_ON, 2, -1);
  701. test_int_translated(CONF_bold_style, "BoldAsColour", AUTO,
  702. 1, 0, 2, 1, 3, 2, -1);
  703. test_int_translated(CONF_sshbug_ignore1, "BugIgnore1", AUTO,
  704. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  705. test_int_translated(CONF_sshbug_plainpw1, "BugPlainPW1", AUTO,
  706. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  707. test_int_translated(CONF_sshbug_rsa1, "BugRSA1", AUTO,
  708. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  709. test_int_translated(CONF_sshbug_ignore2, "BugIgnore2", AUTO,
  710. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  711. test_int_translated(CONF_sshbug_derivekey2, "BugDeriveKey2", AUTO,
  712. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  713. test_int_translated(CONF_sshbug_rsapad2, "BugRSAPad2", AUTO,
  714. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  715. test_int_translated(CONF_sshbug_pksessid2, "BugPKSessID2", AUTO,
  716. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  717. test_int_translated(CONF_sshbug_rekey2, "BugRekey2", AUTO,
  718. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  719. test_int_translated(CONF_sshbug_maxpkt2, "BugMaxPkt2", AUTO,
  720. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  721. test_int_translated(CONF_sshbug_oldgex2, "BugOldGex2", AUTO,
  722. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  723. test_int_translated(CONF_sshbug_winadj, "BugWinadj", AUTO,
  724. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  725. test_int_translated(CONF_sshbug_chanreq, "BugChanReq", AUTO,
  726. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  727. test_int_translated(CONF_sshbug_dropstart, "BugDropStart", FORCE_OFF,
  728. FORCE_OFF, 1, FORCE_ON, 2, -1);
  729. test_int_translated(CONF_sshbug_filter_kexinit, "BugFilterKexinit", FORCE_OFF,
  730. FORCE_OFF, 1, FORCE_ON, 2, -1);
  731. test_int_translated(CONF_sshbug_rsa_sha2_cert_userauth, "BugRSASHA2CertUserauth", AUTO,
  732. AUTO, 0, FORCE_OFF, 1, FORCE_ON, 2, -1);
  733. test_int_translated(CONF_proxy_type, "ProxyMethod", PROXY_NONE,
  734. PROXY_NONE, 0, PROXY_SOCKS4, 1, PROXY_SOCKS5, 2,
  735. PROXY_HTTP, 3, PROXY_TELNET, 4, PROXY_CMD, 5,
  736. PROXY_SSH_TCPIP, 6, PROXY_SSH_EXEC, 7,
  737. PROXY_SSH_SUBSYSTEM, 8, -1);
  738. test_int_translated_load_legacy(
  739. CONF_proxy_type, "ProxyType", NULL, PROXY_NONE,
  740. PROXY_HTTP, 1, PROXY_SOCKS5, 2, PROXY_TELNET, 3, PROXY_CMD, 4, -1);
  741. test_int_translated_load_legacy(
  742. CONF_proxy_type, "ProxyType", load_prepare_socks4, PROXY_NONE,
  743. PROXY_HTTP, 1, PROXY_SOCKS4, 2, PROXY_TELNET, 3, PROXY_CMD, 4, -1);
  744. test_int_translated(CONF_remote_qtitle_action, "RemoteQTitleAction", TITLE_EMPTY,
  745. TITLE_NONE, 0, TITLE_EMPTY, 1, TITLE_REAL, 2, -1);
  746. test_int_translated_load_legacy(
  747. CONF_remote_qtitle_action, "NoRemoteQTitle", NULL, TITLE_EMPTY,
  748. TITLE_REAL, 0, TITLE_EMPTY, 1, -1);
  749. }
  750. void test_conf_key_info(void)
  751. {
  752. struct test_data {
  753. const char *name;
  754. bool got_value_type : 1;
  755. bool got_subkey_type : 1;
  756. bool got_default : 1;
  757. bool got_default_int : 1;
  758. bool got_default_str : 1;
  759. bool got_default_bool : 1;
  760. bool got_save_keyword : 1;
  761. bool got_storage_enum : 1;
  762. bool save_custom : 1;
  763. bool load_custom : 1;
  764. bool not_saved : 1;
  765. };
  766. #define CONF_OPTION(id, ...) { .name = "CONF_" #id, __VA_ARGS__ },
  767. #define VALUE_TYPE(x) .got_value_type = true
  768. #define SUBKEY_TYPE(x) .got_subkey_type = true
  769. #define DEFAULT_INT(x) .got_default_int = true, .got_default = true
  770. #define DEFAULT_STR(x) .got_default_str = true, .got_default = true
  771. #define DEFAULT_BOOL(x) .got_default_bool = true, .got_default = true
  772. #define SAVE_KEYWORD(x) .got_save_keyword = true
  773. #define STORAGE_ENUM(x) .got_storage_enum = true
  774. #define SAVE_CUSTOM .save_custom = true
  775. #define LOAD_CUSTOM .load_custom = true
  776. #define NOT_SAVED .not_saved = true
  777. static const struct test_data conf_key_test_data[] = {
  778. #include "conf.h"
  779. };
  780. for (size_t key = 0; key < N_CONFIG_OPTIONS; key++) {
  781. const ConfKeyInfo *info = &conf_key_info[key];
  782. const struct test_data *td = &conf_key_test_data[key];
  783. if (!td->got_value_type) {
  784. fprintf(stderr, "%s: no value type\n", td->name);
  785. nfails++;
  786. }
  787. if (td->got_default && info->subkey_type != CONF_TYPE_NONE) {
  788. fprintf(stderr, "%s: is a mapping but has a default\n", td->name);
  789. nfails++;
  790. }
  791. if ((td->got_default_int && info->value_type != CONF_TYPE_INT) ||
  792. (td->got_default_str && info->value_type != CONF_TYPE_STR) ||
  793. (td->got_default_bool && info->value_type != CONF_TYPE_BOOL)) {
  794. fprintf(stderr, "%s: default doesn't match type\n", td->name);
  795. nfails++;
  796. }
  797. if (td->got_storage_enum && info->value_type != CONF_TYPE_INT) {
  798. fprintf(stderr, "%s: has STORAGE_ENUM but isn't an int\n",
  799. td->name);
  800. nfails++;
  801. }
  802. if (td->not_saved) {
  803. if (!td->got_default && info->subkey_type == CONF_TYPE_NONE) {
  804. fprintf(stderr, "%s: simple unsaved setting but has no "
  805. "default\n", td->name);
  806. nfails++;
  807. }
  808. if (td->got_save_keyword) {
  809. fprintf(stderr, "%s: not saved but has SAVE_KEYWORD\n",
  810. td->name);
  811. nfails++;
  812. }
  813. if (td->save_custom) {
  814. fprintf(stderr, "%s: not saved but has SAVE_CUSTOM\n",
  815. td->name);
  816. nfails++;
  817. }
  818. if (td->load_custom) {
  819. fprintf(stderr, "%s: not saved but has LOAD_CUSTOM\n",
  820. td->name);
  821. nfails++;
  822. }
  823. if (td->got_storage_enum) {
  824. fprintf(stderr, "%s: not saved but has STORAGE_ENUM\n",
  825. td->name);
  826. nfails++;
  827. }
  828. } else {
  829. if (td->load_custom && td->save_custom) {
  830. if (td->got_save_keyword) {
  831. fprintf(stderr, "%s: no automatic save or load but has "
  832. "SAVE_KEYWORD\n", td->name);
  833. nfails++;
  834. }
  835. if (td->got_storage_enum) {
  836. fprintf(stderr, "%s: no automatic save or load but has "
  837. "STORAGE_ENUM\n", td->name);
  838. nfails++;
  839. }
  840. } else {
  841. if (!td->got_save_keyword) {
  842. fprintf(stderr, "%s: missing SAVE_KEYWORD\n", td->name);
  843. nfails++;
  844. }
  845. }
  846. }
  847. }
  848. }
  849. int main(void)
  850. {
  851. test_conf_key_info();
  852. test_simple();
  853. return nfails != 0;
  854. }