|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* Copyright (C) 2012-2016 Sean Buckheister
|
|
Packit Service |
4684c1 |
* Copyright (C) 2016 Nikos Mavrogiannopoulos
|
|
Packit Service |
4684c1 |
* Copyright (C) 2016 Red Hat, Inc.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* This file is part of GnuTLS.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* GnuTLS is free software; you can redistribute it and/or modify it
|
|
Packit Service |
4684c1 |
* under the terms of the GNU General Public License as published by
|
|
Packit Service |
4684c1 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit Service |
4684c1 |
* (at your option) any later version.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* GnuTLS is distributed in the hope that it will be useful, but
|
|
Packit Service |
4684c1 |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
4684c1 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
4684c1 |
* General Public License for more details.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
4684c1 |
* along with GnuTLS; if not, write to the Free Software Foundation,
|
|
Packit Service |
4684c1 |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/*
|
|
Packit Service |
4684c1 |
* DTLS stress test utility
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* **** Available parameters ****
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* -nb enable nonblocking operations on sessions
|
|
Packit Service |
4684c1 |
* -batch read test identifiers from stdin and run them
|
|
Packit Service |
4684c1 |
* -d increase debug level by one
|
|
Packit Service |
4684c1 |
* -r replay messages (very crude replay mechanism)
|
|
Packit Service |
4684c1 |
* -d <n> set debug level to <n>
|
|
Packit Service |
4684c1 |
* -die don't start new tests after the first detected failure
|
|
Packit Service |
4684c1 |
* -timeout <n> set handshake timeout to <n> seconds. Tests that don't make progress
|
|
Packit Service |
4684c1 |
* within twice this time will be forcibly killed. (default: 120)
|
|
Packit Service |
4684c1 |
* -retransmit <n> set retransmit timeout to <n> milliseconds (default: 100)
|
|
Packit Service |
4684c1 |
* -j <n> run up to <n> tests in parallel
|
|
Packit Service |
4684c1 |
* -full use full handshake with mutual certificate authentication
|
|
Packit Service |
4684c1 |
* -resume use resumed handshake
|
|
Packit Service |
4684c1 |
* -shello <perm> run only one test, with the server hello flight permuted as <perm>
|
|
Packit Service |
4684c1 |
* -sfinished <perm> run only one test, with the server finished flight permuted as <perm>
|
|
Packit Service |
4684c1 |
* -cfinished <perm> run only one test, with the client finished flight permuted as <perm>
|
|
Packit Service |
4684c1 |
* <packet name> run only one test, drop <packet name> three times
|
|
Packit Service |
4684c1 |
* valid values for <packet name> are:
|
|
Packit Service |
4684c1 |
* SHello, SCertificate, SKeyExchange, SCertificateRequest, SHelloDone,
|
|
Packit Service |
4684c1 |
* CCertificate, CKeyExchange, CCertificateVerify, CChangeCipherSpec,
|
|
Packit Service |
4684c1 |
* CFinished, SChangeCipherSpec, SFinished
|
|
Packit Service |
4684c1 |
* using *Certificate* without -full will yield unexpected results
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* **** Permutation handling ****
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Flight length for -sfinished is 2, for -shello and -cfinished they are 5 with -full, 3 otherwise.
|
|
Packit Service |
4684c1 |
* Permutations are given with base 0 and specify the order in which reordered packets are transmitted.
|
|
Packit Service |
4684c1 |
* For example, -full -shello 42130 will transmit server hello flight packets in the order
|
|
Packit Service |
4684c1 |
* SHelloDone, SKeyExchange, SCertificate, SCertificateRequest, SHello
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* When -resume is specified the -sfinished flight length is 3 (same as shello), cfinished is 2.
|
|
Packit Service |
4684c1 |
* The -resume option has to be combined with sfinished or cfinished.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* **** Output format ****
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* Every line printed for any given test is prefixed by a unique id for that test. See run_test_by_id for
|
|
Packit Service |
4684c1 |
* exact composition. Errors encountered during execution are printed, with one status line after test
|
|
Packit Service |
4684c1 |
* completen. The format for this line is as follows:
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* <id> <status> SHello(<shperm>), SFinished(<sfinperm>), CFinished(<cfinperm>) :- <drops>
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* The format for error lines is <id> <role>| <text>, with <role> being the role of the child process
|
|
Packit Service |
4684c1 |
* that encountered the error, and <text> being obvious.
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* <id> is the unique id for the test, it can be used as input to -batch.
|
|
Packit Service |
4684c1 |
* <status> can be ++ for a successful test, -- for a failure, TT for a deadlock timeout killed test,
|
|
Packit Service |
4684c1 |
* or !! for a test has died due to some unforeseen circumstances like syscall failures.
|
|
Packit Service |
4684c1 |
* <shperm>, <sfinperm>, <cfinperm> show the permutation for the respective flights used.
|
|
Packit Service |
4684c1 |
* They can be used as input to -shello, -sfinished, and -cfinished, respectively.
|
|
Packit Service |
4684c1 |
* <drops> is a comma separated list of <packet name>, one for every packet dropped thrice
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* **** Exit status ****
|
|
Packit Service |
4684c1 |
*
|
|
Packit Service |
4684c1 |
* 0 all tests have passed
|
|
Packit Service |
4684c1 |
* 1 some tests have failed
|
|
Packit Service |
4684c1 |
* 4 the master processed has encountered unexpected errors
|
|
Packit Service |
4684c1 |
* 8 error parsing command line
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include <config.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/gnutls.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/openpgp.h>
|
|
Packit Service |
4684c1 |
#include <gnutls/dtls.h>
|
|
Packit Service |
4684c1 |
#include <unistd.h>
|
|
Packit Service |
4684c1 |
#include "../utils.h"
|
|
Packit Service |
4684c1 |
#include <sys/socket.h>
|
|
Packit Service |
4684c1 |
#include <sys/types.h>
|
|
Packit Service |
4684c1 |
#include <netinet/in.h>
|
|
Packit Service |
4684c1 |
#include <fcntl.h>
|
|
Packit Service |
4684c1 |
#include <stdio.h>
|
|
Packit Service |
4684c1 |
#include <stdlib.h>
|
|
Packit Service |
4684c1 |
#include <string.h>
|
|
Packit Service |
4684c1 |
#include <errno.h>
|
|
Packit Service |
4684c1 |
#include <poll.h>
|
|
Packit Service |
4684c1 |
#include <time.h>
|
|
Packit Service |
4684c1 |
#include <assert.h>
|
|
Packit Service |
4684c1 |
#include <sys/wait.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#if _POSIX_TIMERS && (_POSIX_TIMERS - 200112L) >= 0
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ types
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define log(fmt, ...) \
|
|
Packit Service |
4684c1 |
if (debug) fprintf(stdout, "%i %s| "fmt, run_id, role_name, ##__VA_ARGS__)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
typedef struct {
|
|
Packit Service |
4684c1 |
int count;
|
|
Packit Service |
4684c1 |
} filter_packet_state_t;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
typedef struct {
|
|
Packit Service |
4684c1 |
const char *name;
|
|
Packit Service |
4684c1 |
gnutls_datum_t packets[5];
|
|
Packit Service |
4684c1 |
int *order;
|
|
Packit Service |
4684c1 |
int count;
|
|
Packit Service |
4684c1 |
} filter_permute_state_t;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
typedef void (*filter_fn) (gnutls_transport_ptr_t, const unsigned char *,
|
|
Packit Service |
4684c1 |
size_t);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
typedef int (*match_fn) (const unsigned char *, size_t);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
enum role { SERVER, CLIENT };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ static data
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int permutations2[2][2]
|
|
Packit Service |
4684c1 |
= { {0, 1}, {1, 0} };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const char *permutation_names2[]
|
|
Packit Service |
4684c1 |
= { "01", "10", 0 };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int permutations3[6][3]
|
|
Packit Service |
4684c1 |
= { {0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0} };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const char *permutation_names3[]
|
|
Packit Service |
4684c1 |
= { "012", "021", "102", "120", "201", "210", 0 };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int permutations5[120][5] = {
|
|
Packit Service |
4684c1 |
{0, 1, 2, 3, 4}, {0, 2, 1, 3, 4}, {1, 0, 2, 3, 4}, {1, 2, 0, 3, 4},
|
|
Packit Service |
4684c1 |
{2, 0, 1, 3, 4}, {2, 1, 0, 3, 4}, {0, 1, 3, 2, 4}, {0, 2, 3, 1, 4},
|
|
Packit Service |
4684c1 |
{1, 0, 3, 2, 4}, {1, 2, 3, 0, 4}, {2, 0, 3, 1, 4}, {2, 1, 3, 0, 4},
|
|
Packit Service |
4684c1 |
{0, 3, 1, 2, 4}, {0, 3, 2, 1, 4}, {1, 3, 0, 2, 4}, {1, 3, 2, 0, 4},
|
|
Packit Service |
4684c1 |
{2, 3, 0, 1, 4}, {2, 3, 1, 0, 4}, {3, 0, 1, 2, 4}, {3, 0, 2, 1, 4},
|
|
Packit Service |
4684c1 |
{3, 1, 0, 2, 4}, {3, 1, 2, 0, 4}, {3, 2, 0, 1, 4}, {3, 2, 1, 0, 4},
|
|
Packit Service |
4684c1 |
{0, 1, 2, 4, 3}, {0, 2, 1, 4, 3}, {1, 0, 2, 4, 3}, {1, 2, 0, 4, 3},
|
|
Packit Service |
4684c1 |
{2, 0, 1, 4, 3}, {2, 1, 0, 4, 3}, {0, 1, 3, 4, 2}, {0, 2, 3, 4, 1},
|
|
Packit Service |
4684c1 |
{1, 0, 3, 4, 2}, {1, 2, 3, 4, 0}, {2, 0, 3, 4, 1}, {2, 1, 3, 4, 0},
|
|
Packit Service |
4684c1 |
{0, 3, 1, 4, 2}, {0, 3, 2, 4, 1}, {1, 3, 0, 4, 2}, {1, 3, 2, 4, 0},
|
|
Packit Service |
4684c1 |
{2, 3, 0, 4, 1}, {2, 3, 1, 4, 0}, {3, 0, 1, 4, 2}, {3, 0, 2, 4, 1},
|
|
Packit Service |
4684c1 |
{3, 1, 0, 4, 2}, {3, 1, 2, 4, 0}, {3, 2, 0, 4, 1}, {3, 2, 1, 4, 0},
|
|
Packit Service |
4684c1 |
{0, 1, 4, 2, 3}, {0, 2, 4, 1, 3}, {1, 0, 4, 2, 3}, {1, 2, 4, 0, 3},
|
|
Packit Service |
4684c1 |
{2, 0, 4, 1, 3}, {2, 1, 4, 0, 3}, {0, 1, 4, 3, 2}, {0, 2, 4, 3, 1},
|
|
Packit Service |
4684c1 |
{1, 0, 4, 3, 2}, {1, 2, 4, 3, 0}, {2, 0, 4, 3, 1}, {2, 1, 4, 3, 0},
|
|
Packit Service |
4684c1 |
{0, 3, 4, 1, 2}, {0, 3, 4, 2, 1}, {1, 3, 4, 0, 2}, {1, 3, 4, 2, 0},
|
|
Packit Service |
4684c1 |
{2, 3, 4, 0, 1}, {2, 3, 4, 1, 0}, {3, 0, 4, 1, 2}, {3, 0, 4, 2, 1},
|
|
Packit Service |
4684c1 |
{3, 1, 4, 0, 2}, {3, 1, 4, 2, 0}, {3, 2, 4, 0, 1}, {3, 2, 4, 1, 0},
|
|
Packit Service |
4684c1 |
{0, 4, 1, 2, 3}, {0, 4, 2, 1, 3}, {1, 4, 0, 2, 3}, {1, 4, 2, 0, 3},
|
|
Packit Service |
4684c1 |
{2, 4, 0, 1, 3}, {2, 4, 1, 0, 3}, {0, 4, 1, 3, 2}, {0, 4, 2, 3, 1},
|
|
Packit Service |
4684c1 |
{1, 4, 0, 3, 2}, {1, 4, 2, 3, 0}, {2, 4, 0, 3, 1}, {2, 4, 1, 3, 0},
|
|
Packit Service |
4684c1 |
{0, 4, 3, 1, 2}, {0, 4, 3, 2, 1}, {1, 4, 3, 0, 2}, {1, 4, 3, 2, 0},
|
|
Packit Service |
4684c1 |
{2, 4, 3, 0, 1}, {2, 4, 3, 1, 0}, {3, 4, 0, 1, 2}, {3, 4, 0, 2, 1},
|
|
Packit Service |
4684c1 |
{3, 4, 1, 0, 2}, {3, 4, 1, 2, 0}, {3, 4, 2, 0, 1}, {3, 4, 2, 1, 0},
|
|
Packit Service |
4684c1 |
{4, 0, 1, 2, 3}, {4, 0, 2, 1, 3}, {4, 1, 0, 2, 3}, {4, 1, 2, 0, 3},
|
|
Packit Service |
4684c1 |
{4, 2, 0, 1, 3}, {4, 2, 1, 0, 3}, {4, 0, 1, 3, 2}, {4, 0, 2, 3, 1},
|
|
Packit Service |
4684c1 |
{4, 1, 0, 3, 2}, {4, 1, 2, 3, 0}, {4, 2, 0, 3, 1}, {4, 2, 1, 3, 0},
|
|
Packit Service |
4684c1 |
{4, 0, 3, 1, 2}, {4, 0, 3, 2, 1}, {4, 1, 3, 0, 2}, {4, 1, 3, 2, 0},
|
|
Packit Service |
4684c1 |
{4, 2, 3, 0, 1}, {4, 2, 3, 1, 0}, {4, 3, 0, 1, 2}, {4, 3, 0, 2, 1},
|
|
Packit Service |
4684c1 |
{4, 3, 1, 0, 2}, {4, 3, 1, 2, 0}, {4, 3, 2, 0, 1}, {4, 3, 2, 1, 0}
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const char *permutation_names5[]
|
|
Packit Service |
4684c1 |
= { "01234", "02134", "10234", "12034", "20134", "21034", "01324",
|
|
Packit Service |
4684c1 |
"02314", "10324", "12304", "20314", "21304", "03124", "03214",
|
|
Packit Service |
4684c1 |
"13024", "13204", "23014", "23104", "30124", "30214", "31024",
|
|
Packit Service |
4684c1 |
"31204", "32014", "32104", "01243", "02143", "10243", "12043",
|
|
Packit Service |
4684c1 |
"20143", "21043", "01342", "02341", "10342", "12340", "20341",
|
|
Packit Service |
4684c1 |
"21340", "03142", "03241", "13042", "13240", "23041", "23140",
|
|
Packit Service |
4684c1 |
"30142", "30241", "31042", "31240", "32041", "32140", "01423",
|
|
Packit Service |
4684c1 |
"02413", "10423", "12403", "20413", "21403", "01432", "02431",
|
|
Packit Service |
4684c1 |
"10432", "12430", "20431", "21430", "03412", "03421", "13402",
|
|
Packit Service |
4684c1 |
"13420", "23401", "23410", "30412", "30421", "31402", "31420",
|
|
Packit Service |
4684c1 |
"32401", "32410", "04123", "04213", "14023", "14203", "24013",
|
|
Packit Service |
4684c1 |
"24103", "04132", "04231", "14032", "14230", "24031", "24130",
|
|
Packit Service |
4684c1 |
"04312", "04321", "14302", "14320", "24301", "24310", "34012",
|
|
Packit Service |
4684c1 |
"34021", "34102", "34120", "34201", "34210", "40123", "40213",
|
|
Packit Service |
4684c1 |
"41023", "41203", "42013", "42103", "40132", "40231", "41032",
|
|
Packit Service |
4684c1 |
"41230", "42031", "42130", "40312", "40321", "41302", "41320",
|
|
Packit Service |
4684c1 |
"42301", "42310", "43012", "43021", "43102", "43120", "43201",
|
|
Packit Service |
4684c1 |
"43210", 0
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const char *filter_names[8]
|
|
Packit Service |
4684c1 |
= { "SHello",
|
|
Packit Service |
4684c1 |
"SKeyExchange",
|
|
Packit Service |
4684c1 |
"SHelloDone",
|
|
Packit Service |
4684c1 |
"CKeyExchange",
|
|
Packit Service |
4684c1 |
"CChangeCipherSpec",
|
|
Packit Service |
4684c1 |
"CFinished",
|
|
Packit Service |
4684c1 |
"SChangeCipherSpec",
|
|
Packit Service |
4684c1 |
"SFinished"
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const char *filter_names_resume[]
|
|
Packit Service |
4684c1 |
= { "SHello",
|
|
Packit Service |
4684c1 |
"SChangeCipherSpec",
|
|
Packit Service |
4684c1 |
"SFinished",
|
|
Packit Service |
4684c1 |
"CChangeCipherSpec",
|
|
Packit Service |
4684c1 |
"CFinished"
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static const char *filter_names_full[12]
|
|
Packit Service |
4684c1 |
= { "SHello",
|
|
Packit Service |
4684c1 |
"SCertificate",
|
|
Packit Service |
4684c1 |
"SKeyExchange",
|
|
Packit Service |
4684c1 |
"SCertificateRequest",
|
|
Packit Service |
4684c1 |
"SHelloDone",
|
|
Packit Service |
4684c1 |
"CCertificate",
|
|
Packit Service |
4684c1 |
"CKeyExchange",
|
|
Packit Service |
4684c1 |
"CCertificateVerify",
|
|
Packit Service |
4684c1 |
"CChangeCipherSpec",
|
|
Packit Service |
4684c1 |
"CFinished",
|
|
Packit Service |
4684c1 |
"SChangeCipherSpec",
|
|
Packit Service |
4684c1 |
"SFinished"
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "cert-common.h"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ other global state
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
enum role role;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define role_name (role == SERVER ? "server" : "client")
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int debug;
|
|
Packit Service |
4684c1 |
int nonblock;
|
|
Packit Service |
4684c1 |
int replay;
|
|
Packit Service |
4684c1 |
int full;
|
|
Packit Service |
4684c1 |
int resume;
|
|
Packit Service |
4684c1 |
int timeout_seconds;
|
|
Packit Service |
4684c1 |
int retransmit_milliseconds;
|
|
Packit Service |
4684c1 |
int run_to_end;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int run_id;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ logging and error handling
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void logfn(int level, const char *s)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (debug) {
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i %s|<%i> %s", run_id, role_name, level, s);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void auditfn(gnutls_session_t session, const char *s)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (debug) {
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i %s| %s", run_id, role_name, s);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void drop(const char *packet)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (debug) {
|
|
Packit Service |
4684c1 |
log("dropping %s\n", packet);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int _process_error(int loc, int code, int die)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (code < 0 && (die || code != GNUTLS_E_AGAIN)) {
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i <%s tls> line %i: %s", run_id,
|
|
Packit Service |
4684c1 |
role_name, loc, gnutls_strerror(code));
|
|
Packit Service |
4684c1 |
if (gnutls_error_is_fatal(code) || die) {
|
|
Packit Service |
4684c1 |
fprintf(stdout, " (fatal)\n");
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
fprintf(stdout, "\n");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return code;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define die_on_error(code) _process_error(__LINE__, code, 1)
|
|
Packit Service |
4684c1 |
#define process_error(code) _process_error(__LINE__, code, 0)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void _process_error_or_timeout(int loc, int err, time_t tdiff)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (err < 0) {
|
|
Packit Service |
4684c1 |
if (err != GNUTLS_E_TIMEDOUT || tdiff >= 60) {
|
|
Packit Service |
4684c1 |
_process_error(loc, err, 0);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
log("line %i: {spurious timeout} (fatal)", loc);
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define process_error_or_timeout(code, tdiff) _process_error_or_timeout(__LINE__, code, tdiff)
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void rperror(const char *name)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i %s| %s\n", run_id, role_name, name);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ init, shared, and teardown code and data for packet stream filters
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ServerHello = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ServerCertificate = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ServerKeyExchange = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ServerCertificateRequest = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ServerHelloDone = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ClientCertificate = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ClientKeyExchange = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ClientCertificateVerify = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ClientChangeCipherSpec = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ClientFinished = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ClientFinishedResume = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ServerChangeCipherSpec = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ServerFinished = { 0 };
|
|
Packit Service |
4684c1 |
filter_packet_state_t state_packet_ServerFinishedResume = { 0 };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static filter_permute_state_t state_permute_ServerHello =
|
|
Packit Service |
4684c1 |
{ 0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, 0, 0 };
|
|
Packit Service |
4684c1 |
static filter_permute_state_t state_permute_ServerHelloFull =
|
|
Packit Service |
4684c1 |
{ 0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, 0, 0 };
|
|
Packit Service |
4684c1 |
static filter_permute_state_t state_permute_ServerFinished =
|
|
Packit Service |
4684c1 |
{ 0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, 0, 0 };
|
|
Packit Service |
4684c1 |
static filter_permute_state_t state_permute_ServerFinishedResume =
|
|
Packit Service |
4684c1 |
{ 0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, 0, 0 };
|
|
Packit Service |
4684c1 |
static filter_permute_state_t state_permute_ClientFinished =
|
|
Packit Service |
4684c1 |
{ 0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, 0, 0 };
|
|
Packit Service |
4684c1 |
static filter_permute_state_t state_permute_ClientFinishedResume =
|
|
Packit Service |
4684c1 |
{ 0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, 0, 0 };
|
|
Packit Service |
4684c1 |
static filter_permute_state_t state_permute_ClientFinishedFull =
|
|
Packit Service |
4684c1 |
{ 0, {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}}, 0, 0 };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_fn filter_chain[32];
|
|
Packit Service |
4684c1 |
int filter_current_idx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void filter_permute_state_free_buffer(filter_permute_state_t * state)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned int i;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (i = 0; i < sizeof(state->packets) / sizeof(state->packets[0]); i++) {
|
|
Packit Service |
4684c1 |
free(state->packets[i].data);
|
|
Packit Service |
4684c1 |
state->packets[i].data = NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void filter_clear_state(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
filter_current_idx = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_permute_state_free_buffer(&state_permute_ServerHello);
|
|
Packit Service |
4684c1 |
filter_permute_state_free_buffer(&state_permute_ServerHelloFull);
|
|
Packit Service |
4684c1 |
filter_permute_state_free_buffer(&state_permute_ServerFinished);
|
|
Packit Service |
4684c1 |
filter_permute_state_free_buffer(&state_permute_ServerFinishedResume);
|
|
Packit Service |
4684c1 |
filter_permute_state_free_buffer(&state_permute_ClientFinished);
|
|
Packit Service |
4684c1 |
filter_permute_state_free_buffer(&state_permute_ClientFinishedResume);
|
|
Packit Service |
4684c1 |
filter_permute_state_free_buffer(&state_permute_ClientFinishedFull);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&state_packet_ServerHello, 0, sizeof(state_packet_ServerHello));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ServerCertificate, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ServerCertificate));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ServerKeyExchange, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ServerKeyExchange));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ServerCertificateRequest, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ServerCertificateRequest));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ServerHelloDone, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ServerHelloDone));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ClientCertificate, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ClientCertificate));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ClientKeyExchange, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ClientKeyExchange));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ClientCertificateVerify, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ClientCertificateVerify));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ClientChangeCipherSpec, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ClientChangeCipherSpec));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ClientFinished, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ClientFinished));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ClientFinishedResume, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ClientFinishedResume));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ServerChangeCipherSpec, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ServerChangeCipherSpec));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ServerFinished, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ServerFinished));
|
|
Packit Service |
4684c1 |
memset(&state_packet_ServerFinishedResume, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_packet_ServerFinishedResume));
|
|
Packit Service |
4684c1 |
memset(&state_permute_ServerHello, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_permute_ServerHello));
|
|
Packit Service |
4684c1 |
memset(&state_permute_ServerHelloFull, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_permute_ServerHelloFull));
|
|
Packit Service |
4684c1 |
memset(&state_permute_ServerFinished, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_permute_ServerFinished));
|
|
Packit Service |
4684c1 |
memset(&state_permute_ClientFinished, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_permute_ClientFinished));
|
|
Packit Service |
4684c1 |
memset(&state_permute_ClientFinishedResume, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_permute_ClientFinishedResume));
|
|
Packit Service |
4684c1 |
memset(&state_permute_ClientFinishedFull, 0,
|
|
Packit Service |
4684c1 |
sizeof(state_permute_ClientFinishedFull));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
state_permute_ServerHello.name = "ServerHello";
|
|
Packit Service |
4684c1 |
state_permute_ServerHelloFull.name = "ServerHelloFull";
|
|
Packit Service |
4684c1 |
state_permute_ServerFinished.name = "ServerFinished";
|
|
Packit Service |
4684c1 |
state_permute_ServerFinishedResume.name = "ServerFinishedResume";
|
|
Packit Service |
4684c1 |
state_permute_ClientFinished.name = "ClientFinished";
|
|
Packit Service |
4684c1 |
state_permute_ClientFinishedResume.name = "ClientFinishedResume";
|
|
Packit Service |
4684c1 |
state_permute_ClientFinishedFull.name = "ClientFinishedFull";
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* replay buffer */
|
|
Packit Service |
4684c1 |
static int rbuffer[5 * 1024];
|
|
Packit Service |
4684c1 |
unsigned rbuffer_size = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void filter_run_next(gnutls_transport_ptr_t fd,
|
|
Packit Service |
4684c1 |
const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int ret = 0;
|
|
Packit Service |
4684c1 |
filter_fn fn = filter_chain[filter_current_idx];
|
|
Packit Service |
4684c1 |
filter_current_idx++;
|
|
Packit Service |
4684c1 |
if (fn) {
|
|
Packit Service |
4684c1 |
fn(fd, buffer, len);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
ret = send((int)(intptr_t) fd, buffer, len, 0);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
filter_current_idx--;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret > 0 && replay != 0) {
|
|
Packit Service |
4684c1 |
if (rbuffer_size == 0 && len < sizeof(rbuffer)) {
|
|
Packit Service |
4684c1 |
memcpy(rbuffer, buffer, len);
|
|
Packit Service |
4684c1 |
rbuffer_size = len;
|
|
Packit Service |
4684c1 |
} else if (rbuffer_size != 0) {
|
|
Packit Service |
4684c1 |
send((int)(intptr_t) fd, rbuffer, rbuffer_size, 0);
|
|
Packit Service |
4684c1 |
if (len < sizeof(rbuffer) && len > rbuffer_size) {
|
|
Packit Service |
4684c1 |
memcpy(rbuffer, buffer, len);
|
|
Packit Service |
4684c1 |
rbuffer_size = len;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ packet match functions
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ServerHello(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == SERVER && len >= 13 + 1 && buffer[0] == 22
|
|
Packit Service |
4684c1 |
&& buffer[13] == 2;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ServerCertificate(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == SERVER && len >= 13 + 1 && buffer[0] == 22
|
|
Packit Service |
4684c1 |
&& buffer[13] == 11;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ServerKeyExchange(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == SERVER && len >= 13 + 1 && buffer[0] == 22
|
|
Packit Service |
4684c1 |
&& buffer[13] == 12;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ServerCertificateRequest(const unsigned char *buffer,
|
|
Packit Service |
4684c1 |
size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == SERVER && len >= 13 + 1 && buffer[0] == 22
|
|
Packit Service |
4684c1 |
&& buffer[13] == 13;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ServerHelloDone(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == SERVER && len >= 13 + 1 && buffer[0] == 22
|
|
Packit Service |
4684c1 |
&& buffer[13] == 14;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ClientCertificate(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == CLIENT && len >= 13 + 1 && buffer[0] == 22
|
|
Packit Service |
4684c1 |
&& buffer[13] == 11;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ClientKeyExchange(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == CLIENT && len >= 13 + 1 && buffer[0] == 22
|
|
Packit Service |
4684c1 |
&& buffer[13] == 16;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ClientCertificateVerify(const unsigned char *buffer,
|
|
Packit Service |
4684c1 |
size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == CLIENT && len >= 13 + 1 && buffer[0] == 22
|
|
Packit Service |
4684c1 |
&& buffer[13] == 15;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ClientChangeCipherSpec(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == CLIENT && len >= 13 && buffer[0] == 20;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ClientFinished(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == CLIENT && len >= 13 && buffer[0] == 22 && buffer[4] == 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ServerChangeCipherSpec(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == SERVER && len >= 13 && buffer[0] == 20;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int match_ServerFinished(const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return role == SERVER && len >= 13 && buffer[0] == 22 && buffer[4] == 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ packet drop filters
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define FILTER_DROP_COUNT 3
|
|
Packit Service |
4684c1 |
#define DECLARE_FILTER(packet) \
|
|
Packit Service |
4684c1 |
static void filter_packet_##packet(gnutls_transport_ptr_t fd, \
|
|
Packit Service |
4684c1 |
const unsigned char* buffer, size_t len) \
|
|
Packit Service |
4684c1 |
{ \
|
|
Packit Service |
4684c1 |
if (match_##packet(buffer, len) && (state_packet_##packet).count++ < FILTER_DROP_COUNT) { \
|
|
Packit Service |
4684c1 |
drop(#packet); \
|
|
Packit Service |
4684c1 |
} else { \
|
|
Packit Service |
4684c1 |
filter_run_next(fd, buffer, len); \
|
|
Packit Service |
4684c1 |
} \
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ServerHello)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ServerCertificate)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ServerKeyExchange)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ServerCertificateRequest)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ServerHelloDone)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ClientCertificate)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ClientKeyExchange)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ClientCertificateVerify)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ClientChangeCipherSpec)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ClientFinished)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ServerChangeCipherSpec)
|
|
Packit Service |
4684c1 |
DECLARE_FILTER(ServerFinished)
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
// {{{ flight permutation filters
|
|
Packit Service |
4684c1 |
static void filter_permute_state_run(filter_permute_state_t * state,
|
|
Packit Service |
4684c1 |
int packetCount,
|
|
Packit Service |
4684c1 |
gnutls_transport_ptr_t fd,
|
|
Packit Service |
4684c1 |
const unsigned char *buffer, size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned char *data = malloc(len);
|
|
Packit Service |
4684c1 |
int packet = state->order[state->count];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (debug > 2)
|
|
Packit Service |
4684c1 |
log("running permutation for %s/%d/%d\n", state->name, packetCount, state->count);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memcpy(data, buffer, len);
|
|
Packit Service |
4684c1 |
state->packets[packet].data = data;
|
|
Packit Service |
4684c1 |
state->packets[packet].size = len;
|
|
Packit Service |
4684c1 |
state->count++;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (state->count == packetCount) {
|
|
Packit Service |
4684c1 |
for (packet = 0; packet < packetCount; packet++) {
|
|
Packit Service |
4684c1 |
filter_run_next(fd, state->packets[packet].data,
|
|
Packit Service |
4684c1 |
state->packets[packet].size);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
filter_permute_state_free_buffer(state);
|
|
Packit Service |
4684c1 |
state->count = 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define DECLARE_PERMUTE(flight) \
|
|
Packit Service |
4684c1 |
static void filter_permute_##flight(gnutls_transport_ptr_t fd, \
|
|
Packit Service |
4684c1 |
const unsigned char* buffer, size_t len) \
|
|
Packit Service |
4684c1 |
{ \
|
|
Packit Service |
4684c1 |
int count = sizeof(permute_match_##flight) / sizeof(permute_match_##flight[0]); \
|
|
Packit Service |
4684c1 |
int i; \
|
|
Packit Service |
4684c1 |
for (i = 0; i < count; i++) { \
|
|
Packit Service |
4684c1 |
if (permute_match_##flight[i](buffer, len)) { \
|
|
Packit Service |
4684c1 |
filter_permute_state_run(&state_permute_##flight, count, fd, buffer, len); \
|
|
Packit Service |
4684c1 |
return; \
|
|
Packit Service |
4684c1 |
} \
|
|
Packit Service |
4684c1 |
} \
|
|
Packit Service |
4684c1 |
filter_run_next(fd, buffer, len); \
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static match_fn permute_match_ServerHello[] =
|
|
Packit Service |
4684c1 |
{ match_ServerHello, match_ServerKeyExchange, match_ServerHelloDone };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static match_fn permute_match_ServerHelloFull[] =
|
|
Packit Service |
4684c1 |
{ match_ServerHello, match_ServerCertificate, match_ServerKeyExchange,
|
|
Packit Service |
4684c1 |
match_ServerCertificateRequest, match_ServerHelloDone
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static match_fn permute_match_ServerFinished[] =
|
|
Packit Service |
4684c1 |
{ match_ServerChangeCipherSpec, match_ServerFinished };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static match_fn permute_match_ServerFinishedResume[] =
|
|
Packit Service |
4684c1 |
{ match_ServerHello, match_ServerChangeCipherSpec, match_ServerFinished };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static match_fn permute_match_ClientFinished[] =
|
|
Packit Service |
4684c1 |
{ match_ClientKeyExchange, match_ClientChangeCipherSpec,
|
|
Packit Service |
4684c1 |
match_ClientFinished
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static match_fn permute_match_ClientFinishedResume[] =
|
|
Packit Service |
4684c1 |
{ match_ClientChangeCipherSpec, match_ClientFinished
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static match_fn permute_match_ClientFinishedFull[] =
|
|
Packit Service |
4684c1 |
{ match_ClientCertificate, match_ClientKeyExchange,
|
|
Packit Service |
4684c1 |
match_ClientCertificateVerify, match_ClientChangeCipherSpec,
|
|
Packit Service |
4684c1 |
match_ClientFinished
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
DECLARE_PERMUTE(ServerHello)
|
|
Packit Service |
4684c1 |
DECLARE_PERMUTE(ServerHelloFull)
|
|
Packit Service |
4684c1 |
DECLARE_PERMUTE(ServerFinishedResume)
|
|
Packit Service |
4684c1 |
DECLARE_PERMUTE(ServerFinished)
|
|
Packit Service |
4684c1 |
DECLARE_PERMUTE(ClientFinished)
|
|
Packit Service |
4684c1 |
DECLARE_PERMUTE(ClientFinishedResume)
|
|
Packit Service |
4684c1 |
DECLARE_PERMUTE(ClientFinishedFull)
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
// {{{ emergency deadlock resolution time bomb
|
|
Packit Service |
4684c1 |
timer_t killtimer_tid = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void killtimer_set(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct sigevent sig;
|
|
Packit Service |
4684c1 |
struct itimerspec tout = { {0, 0}, {2 * timeout_seconds, 0} };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (killtimer_tid != 0) {
|
|
Packit Service |
4684c1 |
timer_delete(killtimer_tid);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
memset(&sig, 0, sizeof(sig));
|
|
Packit Service |
4684c1 |
sig.sigev_notify = SIGEV_SIGNAL;
|
|
Packit Service |
4684c1 |
sig.sigev_signo = 15;
|
|
Packit Service |
4684c1 |
if (timer_create(CLOCK_MONOTONIC, &sig, &killtimer_tid) < 0) {
|
|
Packit Service |
4684c1 |
rperror("timer_create");
|
|
Packit Service |
4684c1 |
exit(3);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
timer_settime(killtimer_tid, 0, &tout, 0);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ actual gnutls operations
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_certificate_credentials_t cred;
|
|
Packit Service |
4684c1 |
gnutls_session_t session;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static ssize_t writefn(gnutls_transport_ptr_t fd, const void *buffer,
|
|
Packit Service |
4684c1 |
size_t len)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
filter_run_next(fd, (const unsigned char *)buffer, len);
|
|
Packit Service |
4684c1 |
return len;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void await(int fd, int timeout)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (nonblock) {
|
|
Packit Service |
4684c1 |
struct pollfd p = { fd, POLLIN, 0 };
|
|
Packit Service |
4684c1 |
if (poll(&p, 1, timeout) < 0 && errno != EAGAIN
|
|
Packit Service |
4684c1 |
&& errno != EINTR) {
|
|
Packit Service |
4684c1 |
rperror("poll");
|
|
Packit Service |
4684c1 |
exit(3);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void cred_init(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
assert(gnutls_certificate_allocate_credentials(&cred)>=0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_certificate_set_x509_key_mem(cred, &cli_ca3_cert, &cli_ca3_key,
|
|
Packit Service |
4684c1 |
GNUTLS_X509_FMT_PEM);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void session_init(int sock, int server)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_init(&session,
|
|
Packit Service |
4684c1 |
GNUTLS_DATAGRAM | (server ? GNUTLS_SERVER : GNUTLS_CLIENT)
|
|
Packit Service |
4684c1 |
| GNUTLS_NONBLOCK * nonblock);
|
|
Packit Service |
4684c1 |
gnutls_priority_set_direct(session,
|
|
Packit Service |
4684c1 |
"NORMAL:+ECDHE-RSA:+ANON-ECDH",
|
|
Packit Service |
4684c1 |
0);
|
|
Packit Service |
4684c1 |
gnutls_transport_set_int(session, sock);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (full) {
|
|
Packit Service |
4684c1 |
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);
|
|
Packit Service |
4684c1 |
if (server) {
|
|
Packit Service |
4684c1 |
gnutls_certificate_server_set_request(session,
|
|
Packit Service |
4684c1 |
GNUTLS_CERT_REQUIRE);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (server) {
|
|
Packit Service |
4684c1 |
gnutls_anon_server_credentials_t acred;
|
|
Packit Service |
4684c1 |
assert(gnutls_anon_allocate_server_credentials(&acred)>=0);
|
|
Packit Service |
4684c1 |
gnutls_credentials_set(session, GNUTLS_CRD_ANON, acred);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
gnutls_anon_client_credentials_t acred;
|
|
Packit Service |
4684c1 |
assert(gnutls_anon_allocate_client_credentials(&acred)>=0);
|
|
Packit Service |
4684c1 |
gnutls_credentials_set(session, GNUTLS_CRD_ANON, acred);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_dtls_set_mtu(session, 1400);
|
|
Packit Service |
4684c1 |
gnutls_dtls_set_timeouts(session, retransmit_milliseconds,
|
|
Packit Service |
4684c1 |
timeout_seconds * 1000);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void client(int sock)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int err = 0;
|
|
Packit Service |
4684c1 |
time_t started = time(0);
|
|
Packit Service |
4684c1 |
const char *line = "foobar!";
|
|
Packit Service |
4684c1 |
char buffer[8192];
|
|
Packit Service |
4684c1 |
int len, ret;
|
|
Packit Service |
4684c1 |
gnutls_datum_t data = {NULL, 0};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session_init(sock, 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
killtimer_set();
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (resume) {
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
err = process_error(gnutls_handshake(session));
|
|
Packit Service |
4684c1 |
if (err != 0) {
|
|
Packit Service |
4684c1 |
int t = gnutls_dtls_get_timeout(session);
|
|
Packit Service |
4684c1 |
await(sock, t ? t : 100);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} while (err != 0);
|
|
Packit Service |
4684c1 |
process_error_or_timeout(err, time(0) - started);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
ret = gnutls_session_get_data2(session, &data);
|
|
Packit Service |
4684c1 |
if (ret < 0) {
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
gnutls_deinit(session);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session_init(sock, 0);
|
|
Packit Service |
4684c1 |
gnutls_session_set_data(session, data.data, data.size);
|
|
Packit Service |
4684c1 |
gnutls_free(data.data);
|
|
Packit Service |
4684c1 |
data.data = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (debug) {
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i %s| initial handshake complete\n", run_id, role_name);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_transport_set_push_function(session, writefn);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
killtimer_set();
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
err = process_error(gnutls_handshake(session));
|
|
Packit Service |
4684c1 |
if (err != 0) {
|
|
Packit Service |
4684c1 |
int t = gnutls_dtls_get_timeout(session);
|
|
Packit Service |
4684c1 |
await(sock, t ? t : 100);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} while (err != 0);
|
|
Packit Service |
4684c1 |
process_error_or_timeout(err, time(0) - started);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (debug) {
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i %s| handshake complete\n", run_id, role_name);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (resume) {
|
|
Packit Service |
4684c1 |
killtimer_set();
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
await(sock, -1);
|
|
Packit Service |
4684c1 |
len =
|
|
Packit Service |
4684c1 |
process_error(gnutls_record_recv
|
|
Packit Service |
4684c1 |
(session, buffer, sizeof(buffer)));
|
|
Packit Service |
4684c1 |
} while (len < 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("received data\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
die_on_error(gnutls_record_send(session, buffer, len));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("sent data\n");
|
|
Packit Service |
4684c1 |
exit(0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
killtimer_set();
|
|
Packit Service |
4684c1 |
die_on_error(gnutls_record_send(session, line, strlen(line)));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("sent data\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
await(sock, -1);
|
|
Packit Service |
4684c1 |
len =
|
|
Packit Service |
4684c1 |
process_error(gnutls_record_recv
|
|
Packit Service |
4684c1 |
(session, buffer, sizeof(buffer)));
|
|
Packit Service |
4684c1 |
} while (len < 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("received data\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (len > 0 && strncmp(line, buffer, len) == 0) {
|
|
Packit Service |
4684c1 |
exit(0);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static gnutls_datum_t saved_data = {NULL, 0};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static gnutls_datum_t db_fetch(void *dbf, gnutls_datum_t key)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
gnutls_datum_t t = {NULL, 0};
|
|
Packit Service |
4684c1 |
t.data = malloc(saved_data.size);
|
|
Packit Service |
4684c1 |
if (t.data == NULL)
|
|
Packit Service |
4684c1 |
return t;
|
|
Packit Service |
4684c1 |
memcpy(t.data, saved_data.data, saved_data.size);
|
|
Packit Service |
4684c1 |
t.size = saved_data.size;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return t;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int db_delete(void *dbf, gnutls_datum_t key)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int db_store(void *dbf, gnutls_datum_t key, gnutls_datum_t data)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
saved_data.data = malloc(data.size);
|
|
Packit Service |
4684c1 |
if (saved_data.data == NULL)
|
|
Packit Service |
4684c1 |
return -1;
|
|
Packit Service |
4684c1 |
memcpy(saved_data.data, data.data, data.size);
|
|
Packit Service |
4684c1 |
saved_data.size = data.size;
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void server(int sock)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int err;
|
|
Packit Service |
4684c1 |
const char *line = "server foobar!";
|
|
Packit Service |
4684c1 |
time_t started = time(0);
|
|
Packit Service |
4684c1 |
char buffer[8192];
|
|
Packit Service |
4684c1 |
int len;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session_init(sock, 1);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
await(sock, -1);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
killtimer_set();
|
|
Packit Service |
4684c1 |
if (resume) {
|
|
Packit Service |
4684c1 |
gnutls_db_set_retrieve_function(session, db_fetch);
|
|
Packit Service |
4684c1 |
gnutls_db_set_store_function(session, db_store);
|
|
Packit Service |
4684c1 |
gnutls_db_set_remove_function(session, db_delete);
|
|
Packit Service |
4684c1 |
gnutls_db_set_ptr(session, NULL);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
err = process_error(gnutls_handshake(session));
|
|
Packit Service |
4684c1 |
if (err != 0) {
|
|
Packit Service |
4684c1 |
int t = gnutls_dtls_get_timeout(session);
|
|
Packit Service |
4684c1 |
await(sock, t ? t : 100);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} while (err != 0);
|
|
Packit Service |
4684c1 |
process_error_or_timeout(err, time(0) - started);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_deinit(session);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
session_init(sock, 1);
|
|
Packit Service |
4684c1 |
gnutls_db_set_retrieve_function(session, db_fetch);
|
|
Packit Service |
4684c1 |
gnutls_db_set_store_function(session, db_store);
|
|
Packit Service |
4684c1 |
gnutls_db_set_remove_function(session, db_delete);
|
|
Packit Service |
4684c1 |
gnutls_db_set_ptr(session, NULL);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (debug) {
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i %s| initial handshake complete\n", run_id, role_name);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
gnutls_transport_set_push_function(session, writefn);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
await(sock, -1);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
killtimer_set();
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
err = process_error(gnutls_handshake(session));
|
|
Packit Service |
4684c1 |
if (err != 0) {
|
|
Packit Service |
4684c1 |
int t = gnutls_dtls_get_timeout(session);
|
|
Packit Service |
4684c1 |
await(sock, t ? t : 100);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} while (err != 0);
|
|
Packit Service |
4684c1 |
process_error_or_timeout(err, time(0) - started);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("handshake complete\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (resume) {
|
|
Packit Service |
4684c1 |
free(saved_data.data);
|
|
Packit Service |
4684c1 |
saved_data.data = NULL;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (resume) {
|
|
Packit Service |
4684c1 |
killtimer_set();
|
|
Packit Service |
4684c1 |
die_on_error(gnutls_record_send(session, line, strlen(line)));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("sent data\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
await(sock, -1);
|
|
Packit Service |
4684c1 |
len =
|
|
Packit Service |
4684c1 |
process_error(gnutls_record_recv
|
|
Packit Service |
4684c1 |
(session, buffer, sizeof(buffer)));
|
|
Packit Service |
4684c1 |
} while (len < 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("received data\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (len > 0 && strncmp(line, buffer, len) == 0) {
|
|
Packit Service |
4684c1 |
exit(0);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
killtimer_set();
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
do {
|
|
Packit Service |
4684c1 |
await(sock, -1);
|
|
Packit Service |
4684c1 |
len =
|
|
Packit Service |
4684c1 |
process_error(gnutls_record_recv
|
|
Packit Service |
4684c1 |
(session, buffer, sizeof(buffer)));
|
|
Packit Service |
4684c1 |
} while (len < 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("received data\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
die_on_error(gnutls_record_send(session, buffer, len));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
log("sent data\n");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
exit(0);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// {{{ test running/handling itself
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#if 0
|
|
Packit Service |
4684c1 |
static void udp_sockpair(int *socks)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
struct sockaddr_in6 sa =
|
|
Packit Service |
4684c1 |
{ AF_INET6, htons(30000), 0, in6addr_loopback, 0 };
|
|
Packit Service |
4684c1 |
struct sockaddr_in6 sb =
|
|
Packit Service |
4684c1 |
{ AF_INET6, htons(20000), 0, in6addr_loopback, 0 };
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
socks[0] = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
Packit Service |
4684c1 |
socks[1] = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
bind(socks[0], (struct sockaddr *)&sa, sizeof(sa));
|
|
Packit Service |
4684c1 |
bind(socks[1], (struct sockaddr *)&sb, sizeof(sb));
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
connect(socks[1], (struct sockaddr *)&sa, sizeof(sa));
|
|
Packit Service |
4684c1 |
connect(socks[0], (struct sockaddr *)&sb, sizeof(sb));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int run_test(void)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int fds[2];
|
|
Packit Service |
4684c1 |
int pid1, pid2;
|
|
Packit Service |
4684c1 |
int status2;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) {
|
|
Packit Service |
4684c1 |
rperror("socketpair");
|
|
Packit Service |
4684c1 |
exit(2);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (nonblock) {
|
|
Packit Service |
4684c1 |
fcntl(fds[0], F_SETFL, (long)O_NONBLOCK);
|
|
Packit Service |
4684c1 |
fcntl(fds[1], F_SETFL, (long)O_NONBLOCK);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!(pid1 = fork())) {
|
|
Packit Service |
4684c1 |
role = SERVER;
|
|
Packit Service |
4684c1 |
server(fds[1]); // noreturn
|
|
Packit Service |
4684c1 |
} else if (pid1 < 0) {
|
|
Packit Service |
4684c1 |
rperror("fork server");
|
|
Packit Service |
4684c1 |
exit(2);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (!(pid2 = fork())) {
|
|
Packit Service |
4684c1 |
role = CLIENT;
|
|
Packit Service |
4684c1 |
client(fds[0]); // noreturn
|
|
Packit Service |
4684c1 |
} else if (pid2 < 0) {
|
|
Packit Service |
4684c1 |
rperror("fork client");
|
|
Packit Service |
4684c1 |
exit(2);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
while (waitpid(pid2, &status2, 0) < 0 && errno == EINTR) ;
|
|
Packit Service |
4684c1 |
kill(pid1, 15);
|
|
Packit Service |
4684c1 |
while (waitpid(pid1, 0, 0) < 0 && errno == EINTR) ;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
close(fds[0]);
|
|
Packit Service |
4684c1 |
close(fds[1]);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!WIFSIGNALED(status2) && WEXITSTATUS(status2) != 3) {
|
|
Packit Service |
4684c1 |
return ! !WEXITSTATUS(status2);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
return 3;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static filter_fn filters[]
|
|
Packit Service |
4684c1 |
= { filter_packet_ServerHello,
|
|
Packit Service |
4684c1 |
filter_packet_ServerKeyExchange,
|
|
Packit Service |
4684c1 |
filter_packet_ServerHelloDone,
|
|
Packit Service |
4684c1 |
filter_packet_ClientKeyExchange,
|
|
Packit Service |
4684c1 |
filter_packet_ClientChangeCipherSpec,
|
|
Packit Service |
4684c1 |
filter_packet_ClientFinished,
|
|
Packit Service |
4684c1 |
filter_packet_ServerChangeCipherSpec,
|
|
Packit Service |
4684c1 |
filter_packet_ServerFinished
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static filter_fn filters_resume[]
|
|
Packit Service |
4684c1 |
= { filter_packet_ServerHello,
|
|
Packit Service |
4684c1 |
filter_packet_ServerChangeCipherSpec,
|
|
Packit Service |
4684c1 |
filter_packet_ServerFinished,
|
|
Packit Service |
4684c1 |
filter_packet_ClientChangeCipherSpec,
|
|
Packit Service |
4684c1 |
filter_packet_ClientFinished
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static filter_fn filters_full[]
|
|
Packit Service |
4684c1 |
= { filter_packet_ServerHello,
|
|
Packit Service |
4684c1 |
filter_packet_ServerCertificate,
|
|
Packit Service |
4684c1 |
filter_packet_ServerKeyExchange,
|
|
Packit Service |
4684c1 |
filter_packet_ServerCertificateRequest,
|
|
Packit Service |
4684c1 |
filter_packet_ServerHelloDone,
|
|
Packit Service |
4684c1 |
filter_packet_ClientCertificate,
|
|
Packit Service |
4684c1 |
filter_packet_ClientKeyExchange,
|
|
Packit Service |
4684c1 |
filter_packet_ClientCertificateVerify,
|
|
Packit Service |
4684c1 |
filter_packet_ClientChangeCipherSpec,
|
|
Packit Service |
4684c1 |
filter_packet_ClientFinished,
|
|
Packit Service |
4684c1 |
filter_packet_ServerChangeCipherSpec,
|
|
Packit Service |
4684c1 |
filter_packet_ServerFinished
|
|
Packit Service |
4684c1 |
};
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int run_one_test(int dropMode, int serverFinishedPermute,
|
|
Packit Service |
4684c1 |
int serverHelloPermute, int clientFinishedPermute)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int fnIdx = 0;
|
|
Packit Service |
4684c1 |
int res, filterIdx;
|
|
Packit Service |
4684c1 |
filter_fn *local_filters;
|
|
Packit Service |
4684c1 |
const char **local_filter_names;
|
|
Packit Service |
4684c1 |
const char **client_finished_permutation_names;
|
|
Packit Service |
4684c1 |
const char **server_finished_permutation_names;
|
|
Packit Service |
4684c1 |
const char **server_hello_permutation_names;
|
|
Packit Service |
4684c1 |
int filter_count;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (full) {
|
|
Packit Service |
4684c1 |
local_filters = filters_full;
|
|
Packit Service |
4684c1 |
local_filter_names = filter_names_full;
|
|
Packit Service |
4684c1 |
filter_count = sizeof(filters_full)/sizeof(filters_full[0]);
|
|
Packit Service |
4684c1 |
client_finished_permutation_names = permutation_names5;
|
|
Packit Service |
4684c1 |
server_finished_permutation_names = permutation_names2;
|
|
Packit Service |
4684c1 |
server_hello_permutation_names = permutation_names5;
|
|
Packit Service |
4684c1 |
} else if (resume) {
|
|
Packit Service |
4684c1 |
local_filters = filters_resume;
|
|
Packit Service |
4684c1 |
local_filter_names = filter_names_resume;
|
|
Packit Service |
4684c1 |
filter_count = sizeof(filters_resume)/sizeof(filters_resume[0]);
|
|
Packit Service |
4684c1 |
client_finished_permutation_names = permutation_names2;
|
|
Packit Service |
4684c1 |
server_finished_permutation_names = permutation_names3;
|
|
Packit Service |
4684c1 |
server_hello_permutation_names = NULL;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
local_filters = filters;
|
|
Packit Service |
4684c1 |
local_filter_names = filter_names;
|
|
Packit Service |
4684c1 |
filter_count = sizeof(filters)/sizeof(filters[0]);
|
|
Packit Service |
4684c1 |
client_finished_permutation_names = permutation_names3;
|
|
Packit Service |
4684c1 |
server_finished_permutation_names = permutation_names2;
|
|
Packit Service |
4684c1 |
server_hello_permutation_names = permutation_names3;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
run_id =
|
|
Packit Service |
4684c1 |
((dropMode * 2 + serverFinishedPermute) * (full ? 120 : 6) +
|
|
Packit Service |
4684c1 |
serverHelloPermute) * (full ? 120 : 6) + clientFinishedPermute;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_clear_state();
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (full) {
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = filter_permute_ServerHelloFull;
|
|
Packit Service |
4684c1 |
state_permute_ServerHelloFull.order =
|
|
Packit Service |
4684c1 |
permutations5[serverHelloPermute];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = filter_permute_ClientFinishedFull;
|
|
Packit Service |
4684c1 |
state_permute_ClientFinishedFull.order =
|
|
Packit Service |
4684c1 |
permutations5[clientFinishedPermute];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = filter_permute_ServerFinished;
|
|
Packit Service |
4684c1 |
state_permute_ServerFinished.order =
|
|
Packit Service |
4684c1 |
permutations2[serverFinishedPermute];
|
|
Packit Service |
4684c1 |
} else if (resume) {
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = filter_permute_ServerFinishedResume;
|
|
Packit Service |
4684c1 |
state_permute_ServerFinishedResume.order =
|
|
Packit Service |
4684c1 |
permutations3[serverFinishedPermute];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = filter_permute_ClientFinishedResume;
|
|
Packit Service |
4684c1 |
state_permute_ClientFinishedResume.order =
|
|
Packit Service |
4684c1 |
permutations2[clientFinishedPermute];
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = filter_permute_ServerHello;
|
|
Packit Service |
4684c1 |
state_permute_ServerHello.order =
|
|
Packit Service |
4684c1 |
permutations3[serverHelloPermute];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = filter_permute_ClientFinished;
|
|
Packit Service |
4684c1 |
state_permute_ClientFinished.order =
|
|
Packit Service |
4684c1 |
permutations3[clientFinishedPermute];
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = filter_permute_ServerFinished;
|
|
Packit Service |
4684c1 |
state_permute_ServerFinished.order =
|
|
Packit Service |
4684c1 |
permutations2[serverFinishedPermute];
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (dropMode) {
|
|
Packit Service |
4684c1 |
for (filterIdx = 0; filterIdx < filter_count; filterIdx++) {
|
|
Packit Service |
4684c1 |
if (dropMode & (1 << filterIdx)) {
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] =
|
|
Packit Service |
4684c1 |
local_filters[filterIdx];
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
filter_chain[fnIdx++] = NULL;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
res = run_test();
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
switch (res) {
|
|
Packit Service |
4684c1 |
case 0:
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i ++ ", run_id);
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
case 1:
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i -- ", run_id);
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
case 2:
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i !! ", run_id);
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
case 3:
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%i TT ", run_id);
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (!resume)
|
|
Packit Service |
4684c1 |
fprintf(stdout, "SHello(%s), ", server_hello_permutation_names[serverHelloPermute]);
|
|
Packit Service |
4684c1 |
fprintf(stdout, "SFinished(%s), ",
|
|
Packit Service |
4684c1 |
server_finished_permutation_names[serverFinishedPermute]);
|
|
Packit Service |
4684c1 |
fprintf(stdout, "CFinished(%s) :- ",
|
|
Packit Service |
4684c1 |
client_finished_permutation_names[clientFinishedPermute]);
|
|
Packit Service |
4684c1 |
if (dropMode) {
|
|
Packit Service |
4684c1 |
for (filterIdx = 0; filterIdx < filter_count; filterIdx++) {
|
|
Packit Service |
4684c1 |
if (dropMode & (1 << filterIdx)) {
|
|
Packit Service |
4684c1 |
if (dropMode & ((1 << filterIdx) - 1)) {
|
|
Packit Service |
4684c1 |
fprintf(stdout, ", ");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
fprintf(stdout, "%s",
|
|
Packit Service |
4684c1 |
local_filter_names[filterIdx]);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
fprintf(stdout, "\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return res;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int run_test_by_id(int id)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int pscale = full ? 120 : 6;
|
|
Packit Service |
4684c1 |
int dropMode, serverFinishedPermute, serverHelloPermute,
|
|
Packit Service |
4684c1 |
clientFinishedPermute;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
clientFinishedPermute = id % pscale;
|
|
Packit Service |
4684c1 |
id /= pscale;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
serverHelloPermute = id % pscale;
|
|
Packit Service |
4684c1 |
id /= pscale;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
serverFinishedPermute = id % 2;
|
|
Packit Service |
4684c1 |
id /= 2;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
dropMode = id;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return run_one_test(dropMode, serverFinishedPermute,
|
|
Packit Service |
4684c1 |
serverHelloPermute, clientFinishedPermute);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int *job_pids;
|
|
Packit Service |
4684c1 |
int job_limit;
|
|
Packit Service |
4684c1 |
int children = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static void register_child(int pid)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int idx;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
children++;
|
|
Packit Service |
4684c1 |
for (idx = 0; idx < job_limit; idx++) {
|
|
Packit Service |
4684c1 |
if (job_pids[idx] == 0) {
|
|
Packit Service |
4684c1 |
job_pids[idx] = pid;
|
|
Packit Service |
4684c1 |
return;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int wait_children(int child_limit)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int fail = 0;
|
|
Packit Service |
4684c1 |
int result = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
while (children > child_limit) {
|
|
Packit Service |
4684c1 |
int status;
|
|
Packit Service |
4684c1 |
int idx;
|
|
Packit Service |
4684c1 |
int pid = waitpid(0, &status, 0);
|
|
Packit Service |
4684c1 |
if (pid < 0 && errno == ECHILD) {
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
for (idx = 0; idx < job_limit; idx++) {
|
|
Packit Service |
4684c1 |
if (job_pids[idx] == pid) {
|
|
Packit Service |
4684c1 |
children--;
|
|
Packit Service |
4684c1 |
if (WEXITSTATUS(status)) {
|
|
Packit Service |
4684c1 |
result = 1;
|
|
Packit Service |
4684c1 |
if (!run_to_end && !fail) {
|
|
Packit Service |
4684c1 |
fprintf(stderr,
|
|
Packit Service |
4684c1 |
"One test failed, waiting for remaining tests\n");
|
|
Packit Service |
4684c1 |
fail = 1;
|
|
Packit Service |
4684c1 |
child_limit = 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
job_pids[idx] = 0;
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (fail) {
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int run_tests_from_id_list(int childcount)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int test_id;
|
|
Packit Service |
4684c1 |
int ret;
|
|
Packit Service |
4684c1 |
int result = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
while ((ret = fscanf(stdin, "%i\n", &test_id)) > 0) {
|
|
Packit Service |
4684c1 |
int pid;
|
|
Packit Service |
4684c1 |
if (test_id < 0
|
|
Packit Service |
4684c1 |
|| test_id >
|
|
Packit Service |
4684c1 |
2 * (full ? 120 * 120 * (1 << 12) : 6 * 6 * 256)) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "Invalid test id %i\n", test_id);
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (!(pid = fork())) {
|
|
Packit Service |
4684c1 |
exit(run_test_by_id(test_id));
|
|
Packit Service |
4684c1 |
} else if (pid < 0) {
|
|
Packit Service |
4684c1 |
rperror("fork");
|
|
Packit Service |
4684c1 |
result = 4;
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
register_child(pid);
|
|
Packit Service |
4684c1 |
result |= wait_children(childcount);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (ret < 0 && ret != EOF) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "Error reading test id list\n");
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result |= wait_children(0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int run_all_tests(int childcount)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int dropMode, serverFinishedPermute, serverHelloPermute,
|
|
Packit Service |
4684c1 |
clientFinishedPermute;
|
|
Packit Service |
4684c1 |
int result = 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (dropMode = 0; dropMode != 1 << (full ? 12 : 8); dropMode++)
|
|
Packit Service |
4684c1 |
for (serverFinishedPermute = 0; serverFinishedPermute < 2;
|
|
Packit Service |
4684c1 |
serverFinishedPermute++)
|
|
Packit Service |
4684c1 |
for (serverHelloPermute = 0;
|
|
Packit Service |
4684c1 |
serverHelloPermute < (full ? 120 : 6);
|
|
Packit Service |
4684c1 |
serverHelloPermute++)
|
|
Packit Service |
4684c1 |
for (clientFinishedPermute = 0;
|
|
Packit Service |
4684c1 |
clientFinishedPermute <
|
|
Packit Service |
4684c1 |
(full ? 120 : 6);
|
|
Packit Service |
4684c1 |
clientFinishedPermute++) {
|
|
Packit Service |
4684c1 |
int pid;
|
|
Packit Service |
4684c1 |
if (!(pid = fork())) {
|
|
Packit Service |
4684c1 |
exit(run_one_test
|
|
Packit Service |
4684c1 |
(dropMode,
|
|
Packit Service |
4684c1 |
serverFinishedPermute,
|
|
Packit Service |
4684c1 |
serverHelloPermute,
|
|
Packit Service |
4684c1 |
clientFinishedPermute));
|
|
Packit Service |
4684c1 |
} else if (pid < 0) {
|
|
Packit Service |
4684c1 |
rperror("fork");
|
|
Packit Service |
4684c1 |
result = 4;
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
register_child(pid);
|
|
Packit Service |
4684c1 |
result |=
|
|
Packit Service |
4684c1 |
wait_children(childcount);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
result |= wait_children(0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return result;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// }}}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
static int parse_permutation(const char *arg, const char *permutations[],
|
|
Packit Service |
4684c1 |
int *val)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
*val = 0;
|
|
Packit Service |
4684c1 |
while (permutations[*val]) {
|
|
Packit Service |
4684c1 |
if (strcmp(permutations[*val], arg) == 0) {
|
|
Packit Service |
4684c1 |
return 1;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
*val += 1;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int main(int argc, const char *argv[])
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
int dropMode = 0;
|
|
Packit Service |
4684c1 |
int serverFinishedPermute = 0;
|
|
Packit Service |
4684c1 |
int serverHelloPermute = 0;
|
|
Packit Service |
4684c1 |
int clientFinishedPermute = 0;
|
|
Packit Service |
4684c1 |
int batch = 0;
|
|
Packit Service |
4684c1 |
unsigned single = 0;
|
|
Packit Service |
4684c1 |
int arg;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
nonblock = 0;
|
|
Packit Service |
4684c1 |
replay = 0;
|
|
Packit Service |
4684c1 |
debug = 0;
|
|
Packit Service |
4684c1 |
timeout_seconds = 120;
|
|
Packit Service |
4684c1 |
retransmit_milliseconds = 100;
|
|
Packit Service |
4684c1 |
full = 0;
|
|
Packit Service |
4684c1 |
run_to_end = 1;
|
|
Packit Service |
4684c1 |
job_limit = 1;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#define NEXT_ARG(name) \
|
|
Packit Service |
4684c1 |
do { \
|
|
Packit Service |
4684c1 |
if (++arg >= argc) { \
|
|
Packit Service |
4684c1 |
fprintf(stderr, "No argument for -" #name "\n"); \
|
|
Packit Service |
4684c1 |
exit(8); \
|
|
Packit Service |
4684c1 |
} \
|
|
Packit Service |
4684c1 |
} while (0);
|
|
Packit Service |
4684c1 |
#define FAIL_ARG(name) \
|
|
Packit Service |
4684c1 |
do { \
|
|
Packit Service |
4684c1 |
fprintf(stderr, "Invalid argument for -" #name "\n"); \
|
|
Packit Service |
4684c1 |
exit(8); \
|
|
Packit Service |
4684c1 |
} while (0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (arg = 1; arg < argc; arg++) {
|
|
Packit Service |
4684c1 |
if (strcmp("-die", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
run_to_end = 0;
|
|
Packit Service |
4684c1 |
} else if (strcmp("-batch", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
batch = 1;
|
|
Packit Service |
4684c1 |
} else if (strcmp("-d", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
char *end;
|
|
Packit Service |
4684c1 |
int level;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (arg+1 < argc) {
|
|
Packit Service |
4684c1 |
level = strtol(argv[arg + 1], &end, 10);
|
|
Packit Service |
4684c1 |
if (*end == '\0') {
|
|
Packit Service |
4684c1 |
debug = level;
|
|
Packit Service |
4684c1 |
arg++;
|
|
Packit Service |
4684c1 |
} else
|
|
Packit Service |
4684c1 |
debug++;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
debug++;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (strcmp("-nb", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
nonblock = 1;
|
|
Packit Service |
4684c1 |
} else if (strcmp("-r", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
replay = 1;
|
|
Packit Service |
4684c1 |
} else if (strcmp("-timeout", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
char *end;
|
|
Packit Service |
4684c1 |
int val;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
NEXT_ARG(timeout);
|
|
Packit Service |
4684c1 |
val = strtol(argv[arg], &end, 10);
|
|
Packit Service |
4684c1 |
if (*end == '\0') {
|
|
Packit Service |
4684c1 |
timeout_seconds = val;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
FAIL_ARG(timeout);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (strcmp("-retransmit", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
char *end;
|
|
Packit Service |
4684c1 |
int val;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
NEXT_ARG(retransmit);
|
|
Packit Service |
4684c1 |
val = strtol(argv[arg], &end, 10);
|
|
Packit Service |
4684c1 |
if (*end == '\0') {
|
|
Packit Service |
4684c1 |
retransmit_milliseconds = val;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
FAIL_ARG(retransmit);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (strcmp("-j", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
char *end;
|
|
Packit Service |
4684c1 |
int val;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
NEXT_ARG(timeout);
|
|
Packit Service |
4684c1 |
val = strtol(argv[arg], &end, 10);
|
|
Packit Service |
4684c1 |
if (*end == '\0') {
|
|
Packit Service |
4684c1 |
job_limit = val;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
FAIL_ARG(j);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
} else if (strcmp("-full", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
if (resume) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "You cannot combine full with resume\n");
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
full = 1;
|
|
Packit Service |
4684c1 |
} else if (strcmp("-resume", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
if (full) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "You cannot combine full with resume\n");
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
resume = 1;
|
|
Packit Service |
4684c1 |
} else if (strcmp("-shello", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
if (resume) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "Please use -sfinished instead of -shello\n");
|
|
Packit Service |
4684c1 |
exit(1);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
NEXT_ARG(shello);
|
|
Packit Service |
4684c1 |
if (!parse_permutation
|
|
Packit Service |
4684c1 |
(argv[arg],
|
|
Packit Service |
4684c1 |
full ? permutation_names5 :
|
|
Packit Service |
4684c1 |
permutation_names3, &serverHelloPermute)) {
|
|
Packit Service |
4684c1 |
FAIL_ARG(shell);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
single++;
|
|
Packit Service |
4684c1 |
} else if (strcmp("-sfinished", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
const char **pname;
|
|
Packit Service |
4684c1 |
NEXT_ARG(cfinished);
|
|
Packit Service |
4684c1 |
if (resume) pname = permutation_names3;
|
|
Packit Service |
4684c1 |
else pname = permutation_names2;
|
|
Packit Service |
4684c1 |
if (!parse_permutation
|
|
Packit Service |
4684c1 |
(argv[arg], pname,
|
|
Packit Service |
4684c1 |
&serverFinishedPermute)) {
|
|
Packit Service |
4684c1 |
FAIL_ARG(cfinished);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
single++;
|
|
Packit Service |
4684c1 |
} else if (strcmp("-cfinished", argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
const char **pname;
|
|
Packit Service |
4684c1 |
NEXT_ARG(cfinished);
|
|
Packit Service |
4684c1 |
if (full) pname = permutation_names5;
|
|
Packit Service |
4684c1 |
else if (resume) pname = permutation_names2;
|
|
Packit Service |
4684c1 |
else pname = permutation_names3;
|
|
Packit Service |
4684c1 |
if (!parse_permutation
|
|
Packit Service |
4684c1 |
(argv[arg], pname,
|
|
Packit Service |
4684c1 |
&clientFinishedPermute)) {
|
|
Packit Service |
4684c1 |
FAIL_ARG(cfinished);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
single++;
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
int drop;
|
|
Packit Service |
4684c1 |
int filter_count;
|
|
Packit Service |
4684c1 |
const char **local_filter_names;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (full) {
|
|
Packit Service |
4684c1 |
local_filter_names = filter_names_full;
|
|
Packit Service |
4684c1 |
filter_count = sizeof(filters_full)/sizeof(filters_full[0]);
|
|
Packit Service |
4684c1 |
} else if (resume) {
|
|
Packit Service |
4684c1 |
local_filter_names = filter_names_resume;
|
|
Packit Service |
4684c1 |
filter_count = sizeof(filters_resume)/sizeof(filters_resume[0]);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
local_filter_names = filter_names;
|
|
Packit Service |
4684c1 |
filter_count = sizeof(filters)/sizeof(filters[0]);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
for (drop = 0; drop < filter_count; drop++) {
|
|
Packit Service |
4684c1 |
if (strcmp
|
|
Packit Service |
4684c1 |
(local_filter_names[drop],
|
|
Packit Service |
4684c1 |
argv[arg]) == 0) {
|
|
Packit Service |
4684c1 |
dropMode |= (1 << drop);
|
|
Packit Service |
4684c1 |
break;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (drop == filter_count) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "Unknown packet %s\n",
|
|
Packit Service |
4684c1 |
argv[arg]);
|
|
Packit Service |
4684c1 |
exit(8);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
single++;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
setlinebuf(stdout);
|
|
Packit Service |
4684c1 |
global_init();
|
|
Packit Service |
4684c1 |
cred_init();
|
|
Packit Service |
4684c1 |
gnutls_global_set_log_function(logfn);
|
|
Packit Service |
4684c1 |
gnutls_global_set_audit_log_function(auditfn);
|
|
Packit Service |
4684c1 |
gnutls_global_set_log_level(debug);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (single) {
|
|
Packit Service |
4684c1 |
if (debug)
|
|
Packit Service |
4684c1 |
fprintf(stderr, "single test mode\n");
|
|
Packit Service |
4684c1 |
return run_one_test(dropMode, serverFinishedPermute,
|
|
Packit Service |
4684c1 |
serverHelloPermute, clientFinishedPermute);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
if (debug)
|
|
Packit Service |
4684c1 |
fprintf(stderr, "multi test mode\n");
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (resume) {
|
|
Packit Service |
4684c1 |
fprintf(stderr, "full run not implemented yet for resumed runs\n");
|
|
Packit Service |
4684c1 |
exit(5);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
job_pids = calloc(sizeof(int), job_limit);
|
|
Packit Service |
4684c1 |
if (batch) {
|
|
Packit Service |
4684c1 |
return run_tests_from_id_list(job_limit);
|
|
Packit Service |
4684c1 |
} else {
|
|
Packit Service |
4684c1 |
return run_all_tests(job_limit);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
// vim: foldmethod=marker
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#else /* NO POSIX TIMERS */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int main(int argc, const char *argv[])
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
exit(77);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#endif
|