1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
/*
* Test suite for version negotiation in the server.
*
* Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2020 Russ Allbery <eagle@eyrie.org>
* Copyright 2006-2007, 2009-2010, 2012-2013
* The Board of Trustees of the Leland Stanford Junior University
*
* SPDX-License-Identifier: MIT
*/
#include <config.h>
#include <portable/gssapi.h>
#include <portable/system.h>
#include <signal.h>
#include <client/internal.h>
#include <client/remctl.h>
#include <tests/tap/basic.h>
#include <tests/tap/kerberos.h>
#include <tests/tap/remctl.h>
#include <util/gss-tokens.h>
#include <util/protocol.h>
/* A command token to run test test. */
/* clang-format off */
static const char token[] = {
9, 1, 0, 0,
0, 0, 0, 2,
0, 0, 0, 4, 't', 'e', 's', 't',
0, 0, 0, 4, 't', 'e', 's', 't'
};
/* clang-format on */
int
main(void)
{
struct kerberos_config *config;
struct remctl *r;
OM_uint32 major, minor;
int flags, status;
gss_buffer_desc tok;
struct sigaction sa;
/* Unless we have Kerberos available, we can't really do anything. */
config = kerberos_setup(TAP_KRB_NEEDS_KEYTAB);
remctld_start(config, "data/conf-simple", NULL);
plan(10);
/* Ignore SIGPIPE signals so that we get errors from write. */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &sa, NULL) < 0)
sysbail("cannot set SIGPIPE handler");
/* Open the connection to the site. */
r = remctl_new();
ok(r != NULL, "remctl_new");
if (r == NULL)
bail("remctl_new returned NULL");
ok(remctl_open(r, "localhost", 14373, config->principal), "remctl_open");
/* Send the command token. */
tok.length = sizeof(token);
tok.value = (char *) token;
status = token_send_priv(r->fd, r->context, TOKEN_DATA | TOKEN_PROTOCOL,
&tok, 0, &major, &minor);
if (status != TOKEN_OK)
bail("cannot send token");
/* Accept the remote token. */
status = token_recv_priv(r->fd, r->context, &flags, &tok, 1024 * 64, 0,
&major, &minor);
is_int(TOKEN_OK, status, "received token correctly");
is_int(TOKEN_DATA | TOKEN_PROTOCOL, flags, "token had correct flags");
is_int(3, tok.length, "token had correct length");
is_int(2, ((char *) tok.value)[0], "protocol version is 2");
is_int(MESSAGE_VERSION, ((char *) tok.value)[1], "message version code");
is_int(3, ((char *) tok.value)[2], "highest supported version is 3");
/*
* Send the token again and get another response to ensure that the server
* hadn't closed the connection.
*/
status = token_send_priv(r->fd, r->context, TOKEN_DATA | TOKEN_PROTOCOL,
&tok, 0, &major, &minor);
is_int(TOKEN_OK, status, "connection is still open");
gss_release_buffer(&minor, &tok);
if (status == TOKEN_OK) {
status = token_recv_priv(r->fd, r->context, &flags, &tok, 1024 * 64, 0,
&major, &minor);
is_int(TOKEN_OK, status, "received token correctly");
gss_release_buffer(&minor, &tok);
} else {
ok(false, "unable to get reply to token");
}
/* Close things out. */
remctl_close(r);
return 0;
}
|