Add cipher suite selection options to sptps_test.
[tinc] / src / sptps_test.c
index acc692a..37b5a5a 100644 (file)
@@ -118,41 +118,68 @@ static bool receive_record(void *handle, uint8_t type, const void *data, uint16_
        return true;
 }
 
+typedef enum option_t {
+       OPT_BAD_OPTION      = '?',
+       OPT_LONG_OPTION     =  0,
+
+       // Short options
+       OPT_DATAGRAM        = 'd',
+       OPT_QUIT_ON_EOF     = 'q',
+       OPT_READONLY        = 'r',
+       OPT_WRITEONLY       = 'w',
+       OPT_PACKET_LOSS     = 'L',
+       OPT_REPLAY_WINDOW   = 'W',
+       OPT_SPECIAL_CHAR    = 's',
+       OPT_TUN             = 't',
+       OPT_VERBOSE         = 'v',
+        OPT_CIPHER_SUITES   = 'M',
+        OPT_PREFERRED_SUITE = 'P',
+       OPT_IPV4            = '4',
+       OPT_IPV6            = '6',
+
+       // Long options
+       OPT_HELP            = 255,
+} option_t;
+
 static struct option const long_options[] = {
-       {"datagram", no_argument, NULL, 'd'},
-       {"quit", no_argument, NULL, 'q'},
-       {"readonly", no_argument, NULL, 'r'},
-       {"writeonly", no_argument, NULL, 'w'},
-       {"packet-loss", required_argument, NULL, 'L'},
-       {"replay-window", required_argument, NULL, 'W'},
-       {"special", no_argument, NULL, 's'},
-       {"verbose", required_argument, NULL, 'v'},
-       {"help", no_argument, NULL, 1},
-       {NULL, 0, NULL, 0}
+       {"datagram",        no_argument,       NULL, OPT_DATAGRAM},
+       {"quit",            no_argument,       NULL, OPT_QUIT_ON_EOF},
+       {"readonly",        no_argument,       NULL, OPT_READONLY},
+       {"writeonly",       no_argument,       NULL, OPT_WRITEONLY},
+       {"packet-loss",     required_argument, NULL, OPT_PACKET_LOSS},
+       {"replay-window",   required_argument, NULL, OPT_REPLAY_WINDOW},
+       {"special",         no_argument,       NULL, OPT_SPECIAL_CHAR},
+       {"tun",             no_argument,       NULL, OPT_TUN},
+       {"verbose",         required_argument, NULL, OPT_VERBOSE},
+       {"cipher-suites",   required_argument, NULL, OPT_CIPHER_SUITES},
+       {"preferred-suite", required_argument, NULL, OPT_PREFERRED_SUITE},
+       {"help",            no_argument,       NULL, OPT_HELP},
+       {NULL,              0,                 NULL, 0}
 };
 
 static void usage(void) {
-       static const char *message =
+       fprintf(stderr,
                "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n"
                "\n"
                "Valid options are:\n"
-               "  -d, --datagram          Enable datagram mode.\n"
-               "  -q, --quit              Quit when EOF occurs on stdin.\n"
-               "  -r, --readonly          Only send data from the socket to stdout.\n"
+               "  -d, --datagram            Enable datagram mode.\n"
+               "  -q, --quit                Quit when EOF occurs on stdin.\n"
+               "  -r, --readonly            Only send data from the socket to stdout.\n"
 #ifdef HAVE_LINUX
-               "  -t, --tun               Use a tun device instead of stdio.\n"
+               "  -t, --tun                 Use a tun device instead of stdio.\n"
 #endif
-               "  -w, --writeonly         Only send data from stdin to the socket.\n"
-               "  -L, --packet-loss RATE  Fake packet loss of RATE percent.\n"
-               "  -R, --replay-window N   Set replay window to N bytes.\n"
-               "  -s, --special           Enable special handling of lines starting with #, ^ and $.\n"
-               "  -v, --verbose           Display debug messages.\n"
-               "  -4                      Use IPv4.\n"
-               "  -6                      Use IPv6.\n"
+               "  -w, --writeonly           Only send data from stdin to the socket.\n"
+               "  -L, --packet-loss RATE    Fake packet loss of RATE percent.\n"
+               "  -R, --replay-window N     Set replay window to N bytes.\n"
+               "  -M, --cipher-suites MASK  Set the mask of allowed cipher suites.\n"
+               "  -P, --preferred-suite N   Set the preferred cipher suite.\n"
+               "  -s, --special             Enable special handling of lines starting with #, ^ and $.\n"
+               "  -v, --verbose             Display debug messages.\n"
+               "  -4                        Use IPv4.\n"
+               "  -6                        Use IPv6.\n"
                "\n"
-               "Report bugs to tinc@tinc-vpn.org.\n";
-
-       fprintf(stderr, message, program_name);
+               "Report bugs to tinc@tinc-vpn.org.\n",
+               program_name);
 }
 
 #ifdef HAVE_WINDOWS
@@ -326,25 +353,31 @@ static int run_test(int argc, char *argv[]) {
        int r;
        int option_index = 0;
        bool quit = false;
+       unsigned long cipher_suites = SPTPS_ALL_CIPHER_SUITES;
+       unsigned long preferred_suite = 0;
 
        while((r = getopt_long(argc, argv, "dqrstwL:W:v46", long_options, &option_index)) != EOF) {
-               switch(r) {
-               case 0:   /* long option */
+               switch((option_t) r) {
+               case OPT_LONG_OPTION:
                        break;
 
-               case 'd': /* datagram mode */
+               case OPT_BAD_OPTION:
+                       usage();
+                       return 1;
+
+               case OPT_DATAGRAM:
                        datagram = true;
                        break;
 
-               case 'q': /* close connection on EOF from stdin */
+               case OPT_QUIT_ON_EOF:
                        quit = true;
                        break;
 
-               case 'r': /* read only */
+               case OPT_READONLY:
                        readonly = true;
                        break;
 
-               case 't': /* read only */
+               case OPT_TUN:
 #ifdef HAVE_LINUX
                        tun = true;
 #else
@@ -354,39 +387,43 @@ static int run_test(int argc, char *argv[]) {
 #endif
                        break;
 
-               case 'w': /* write only */
+               case OPT_WRITEONLY:
                        writeonly = true;
                        break;
 
-               case 'L': /* packet loss rate */
+               case OPT_PACKET_LOSS:
                        packetloss = atoi(optarg);
                        break;
 
-               case 'W': /* replay window size */
+               case OPT_REPLAY_WINDOW:
                        sptps_replaywin = atoi(optarg);
                        break;
 
-               case 'v': /* be verbose */
+               case OPT_CIPHER_SUITES:
+                       cipher_suites = strtoul(optarg, NULL, 0);
+                       break;
+
+               case OPT_PREFERRED_SUITE:
+                       preferred_suite = strtoul(optarg, NULL, 0);
+                       break;
+
+               case OPT_VERBOSE:
                        verbose = true;
                        break;
 
-               case 's': /* special character handling */
+               case OPT_SPECIAL_CHAR:
                        special = true;
                        break;
 
-               case '?': /* wrong options */
-                       usage();
-                       return 1;
-
-               case '4': /* IPv4 */
+               case OPT_IPV4:
                        addressfamily = AF_INET;
                        break;
 
-               case '6': /* IPv6 */
+               case OPT_IPV6:
                        addressfamily = AF_INET6;
                        break;
 
-               case 1: /* help */
+               case OPT_HELP:
                        usage();
                        return 0;
 
@@ -562,7 +599,20 @@ static int run_test(int argc, char *argv[]) {
 
        sptps_t s;
 
-       if(!sptps_start(&s, &sock, initiator, datagram, mykey, hiskey, "sptps_test", 10, send_data, receive_record)) {
+       sptps_params_t params = {
+               .handle = &sock,
+               .initiator = initiator,
+               .datagram = datagram,
+               .mykey = mykey,
+               .hiskey = hiskey,
+               .label = "sptps_test",
+               .send_data = send_data,
+               .receive_record = receive_record,
+               .cipher_suites = cipher_suites,
+               .preferred_suite = preferred_suite,
+       };
+
+       if(!sptps_start(&s, &params)) {
                ecdsa_free(mykey);
                ecdsa_free(hiskey);
                return 1;