Skip to content

Commit

Permalink
Merge pull request #5663 from larsewi/protocol
Browse files Browse the repository at this point in the history
ENT-12519: Added option to choose protocol version in cf-net
  • Loading branch information
larsewi authored Dec 16, 2024
2 parents 04e8624 + 341e6f9 commit f429c3b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 21 deletions.
81 changes: 60 additions & 21 deletions cf-net/cf-net.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ typedef struct
bool used_default;
char *min_tls_version;
char *allow_ciphers;
char *use_protocol_version;
} CFNetOptions;

//*******************************************************************
Expand Down Expand Up @@ -112,6 +113,7 @@ static const struct option OPTIONS[] =
{"inform", no_argument, 0, 'I'},
{"tls-version", required_argument, 0, 't'},
{"ciphers", required_argument, 0, 'c'},
{"protocol", required_argument, 0, 'p'},
{NULL, 0, 0, '\0'}
};

Expand All @@ -126,6 +128,7 @@ static const char *const HINTS[] =
"Enable basic information output",
"Minimum TLS version to use",
"TLS ciphers to use (comma-separated list)",
"Specify CFEngine protocol to use. Possible values: 'classic', 'tls', 'cookie', 'filestream', 'latest' (default)",
NULL
};

Expand Down Expand Up @@ -176,21 +179,21 @@ static int CFNetRun(CFNetOptions *opts, char **args, char *hostnames);
static char *RequireHostname(char *hostnames);

// PROTOCOL:
static AgentConnection *CFNetOpenConnection(const char *server);
static AgentConnection *CFNetOpenConnection(const char *server, const char *use_protocol_version);
static void CFNetDisconnect(AgentConnection *conn);
static int JustConnect(const char *server, char *port);

// COMMANDS:
static int CFNetHelpTopic(const char *topic);
static int CFNetHelp(const char *topic);
static int CFNetConnectSingle(const char *server, bool print);
static int CFNetConnect(const char *hostname, char **args);
static int CFNetConnectSingle(const char *server, const char *use_protocol_version, bool print);
static int CFNetConnect(const char *hostname, const char *use_protocol_version, char **args);
static void CFNetStatPrint(const char *file, int st_mode, const char *server);
static int CFNetStat(CFNetOptions *opts, const char *hostname, char **args);
static int CFNetGet(CFNetOptions *opts, const char *hostname, char **args);
static int CFNetOpenDir(CFNetOptions *opts, const char *hostname, char **args);
static int CFNetMulti(const char *server);
static int CFNetMultiTLS(const char *server);
static int CFNetMultiTLS(const char *server, const char *use_protocol_version);


//*******************************************************************
Expand Down Expand Up @@ -230,13 +233,15 @@ static void CFNetSetDefault(CFNetOptions *opts){
opts->used_default= false;
opts->min_tls_version = NULL;
opts->allow_ciphers = NULL;
opts->use_protocol_version = NULL;
}

static void CFNetOptionsClear(CFNetOptions *opts)
{
assert(opts != NULL);
free(opts->min_tls_version);
free(opts->allow_ciphers);
free(opts->use_protocol_version);
}

static void CFNetInit(const char *min_tls_version, const char *allow_ciphers)
Expand Down Expand Up @@ -351,6 +356,11 @@ static int CFNetParse(int argc, char **argv,
opts->allow_ciphers = xstrdup(optarg);
break;
}
case 'p':
{
opts->use_protocol_version = xstrdup(optarg);
break;
}
default:
{
// printf("Default optarg = '%s', c = '%c' = %i\n",
Expand Down Expand Up @@ -381,9 +391,11 @@ static int CFNetCommandNumber(char *command)
static int CFNetCommandSwitch(CFNetOptions *opts, const char *hostname,
char **args, enum command_enum cmd)
{
assert(opts != NULL);

switch (cmd) {
case CFNET_CMD_CONNECT:
return CFNetConnect(hostname, args);
return CFNetConnect(hostname, opts->use_protocol_version, args);
case CFNET_CMD_STAT:
return CFNetStat(opts, hostname, args);
case CFNET_CMD_GET:
Expand All @@ -393,7 +405,7 @@ static int CFNetCommandSwitch(CFNetOptions *opts, const char *hostname,
case CFNET_CMD_MULTI:
return CFNetMulti(hostname);
case CFNET_CMD_MULTITLS:
return CFNetMultiTLS(hostname);
return CFNetMultiTLS(hostname, opts->use_protocol_version);
default:
break;
}
Expand Down Expand Up @@ -471,12 +483,22 @@ static int CFNetRun(CFNetOptions *opts, char **args, char *hostnames)
// PROTOCOL:
//*******************************************************************

static AgentConnection *CFNetOpenConnection(const char *server)
static AgentConnection *CFNetOpenConnection(const char *server, const char *use_protocol_version)
{
ProtocolVersion protocol_version = (use_protocol_version == NULL)
? CF_PROTOCOL_LATEST
: ParseProtocolVersionPolicy(use_protocol_version);
if (protocol_version == CF_PROTOCOL_UNDEFINED)
{
Log(LOG_LEVEL_ERR, "Unknown CFEngine protocol version '%s'",
use_protocol_version);
return NULL;
}

AgentConnection *conn = NULL;
ConnectionFlags connflags =
{
.protocol_version = CF_PROTOCOL_LATEST,
.protocol_version = protocol_version,
.trust_server = true,
.off_the_record = true
};
Expand All @@ -495,6 +517,19 @@ static AgentConnection *CFNetOpenConnection(const char *server)
printf("Failed to connect to '%s'\n", server);
return NULL;
}

ProtocolVersion negotiated_version = ConnectionInfoProtocolVersion(conn->conn_info);
if ((use_protocol_version != NULL) && (negotiated_version != protocol_version))
{
Log(LOG_LEVEL_ERR,
"Negotiated protocol version '%s' does not match specified protocol version '%s'. "
"Maybe the server does not support it?",
ProtocolVersionString(negotiated_version),
use_protocol_version);
DisconnectServer(conn);
return NULL;
}

return conn;
}

Expand Down Expand Up @@ -572,9 +607,9 @@ static int CFNetHelp(const char *topic)
return 0;
}

static int CFNetConnectSingle(const char *server, bool print)
static int CFNetConnectSingle(const char *server, const char *use_protocol_version, bool print)
{
AgentConnection *conn = CFNetOpenConnection(server);
AgentConnection *conn = CFNetOpenConnection(server, use_protocol_version);
if (conn == NULL)
{
return -1;
Expand All @@ -587,7 +622,7 @@ static int CFNetConnectSingle(const char *server, bool print)
return 0;
}

static int CFNetConnect(const char *hostname, char **args)
static int CFNetConnect(const char *hostname, const char *use_protocol_version, char **args)
{
assert(args != NULL);
if (args[1] != NULL)
Expand All @@ -601,7 +636,7 @@ static int CFNetConnect(const char *hostname, char **args)
Log(LOG_LEVEL_ERR, "No hostname specified");
return -1;
}
CFNetConnectSingle(hostname, true);
CFNetConnectSingle(hostname, use_protocol_version, true);
return 0;
}

Expand Down Expand Up @@ -649,9 +684,10 @@ static void CFNetStatPrint(const char *file, int st_mode, const char *server)

static int CFNetStat(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **args)
{
assert(opts);
assert(opts != NULL);

char *file = args[1];
AgentConnection *conn = CFNetOpenConnection(hostname);
AgentConnection *conn = CFNetOpenConnection(hostname, opts->use_protocol_version);
if (conn == NULL)
{
return -1;
Expand Down Expand Up @@ -687,6 +723,7 @@ static int invalid_command(const char *cmd)

typedef struct _GetFileData {
const char *hostname;
const char *use_protocol_version;
char remote_file[PATH_MAX];
char local_file[PATH_MAX];
bool ret;
Expand All @@ -695,7 +732,7 @@ typedef struct _GetFileData {
static void *CFNetGetFile(void *arg)
{
GetFileData *data = (GetFileData *) arg;
AgentConnection *conn = CFNetOpenConnection(data->hostname);
AgentConnection *conn = CFNetOpenConnection(data->hostname, data->use_protocol_version);
if (conn == NULL)
{
data->ret = false;
Expand Down Expand Up @@ -819,6 +856,7 @@ static int CFNetGet(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **
threads[i] = (CFNetThreadData*) xcalloc(1, sizeof(CFNetThreadData));
threads[i]->data = (GetFileData*) xcalloc(1, sizeof(GetFileData));
threads[i]->data->hostname = hostname;
threads[i]->data->use_protocol_version = opts->use_protocol_version;
if (n_threads > 1)
{
if (strstr(local_file, "%d") != NULL)
Expand Down Expand Up @@ -891,10 +929,11 @@ static void PrintDirs(const Seq *list)

static int CFNetOpenDir(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **args)
{
assert(opts);
assert(hostname);
assert(args);
AgentConnection *conn = CFNetOpenConnection(hostname);
assert(opts != NULL);
assert(hostname != NULL);
assert(args != NULL);

AgentConnection *conn = CFNetOpenConnection(hostname, opts->use_protocol_version);
if (conn == NULL)
{
return -1;
Expand Down Expand Up @@ -962,7 +1001,7 @@ static int CFNetMulti(const char *server)
return 0;
}

static int CFNetMultiTLS(const char *server)
static int CFNetMultiTLS(const char *server, const char *use_protocol_version)
{
time_t start;
time(&start);
Expand All @@ -972,7 +1011,7 @@ static int CFNetMultiTLS(const char *server)
int attempts = 0;
while(ret == 0)
{
ret = CFNetConnectSingle(server, false);
ret = CFNetConnectSingle(server, use_protocol_version, false);
++attempts;
}
time_t stop;
Expand Down
2 changes: 2 additions & 0 deletions cf-serverd/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ static void *HandleConnection(void *c)
}

ProtocolVersion protocol_version = ConnectionInfoProtocolVersion(conn->conn_info);
Log(LOG_LEVEL_DEBUG, "CFEngine protocol version '%s'", ProtocolVersionString(protocol_version));

if (ProtocolIsTLS(protocol_version))
{
bool established = ServerTLSSessionEstablish(conn, NULL);
Expand Down

0 comments on commit f429c3b

Please sign in to comment.