Skip to content

Commit f429c3b

Browse files
authored
Merge pull request #5663 from larsewi/protocol
ENT-12519: Added option to choose protocol version in cf-net
2 parents 04e8624 + 341e6f9 commit f429c3b

File tree

2 files changed

+62
-21
lines changed

2 files changed

+62
-21
lines changed

cf-net/cf-net.c

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ typedef struct
5555
bool used_default;
5656
char *min_tls_version;
5757
char *allow_ciphers;
58+
char *use_protocol_version;
5859
} CFNetOptions;
5960

6061
//*******************************************************************
@@ -112,6 +113,7 @@ static const struct option OPTIONS[] =
112113
{"inform", no_argument, 0, 'I'},
113114
{"tls-version", required_argument, 0, 't'},
114115
{"ciphers", required_argument, 0, 'c'},
116+
{"protocol", required_argument, 0, 'p'},
115117
{NULL, 0, 0, '\0'}
116118
};
117119

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

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

178181
// PROTOCOL:
179-
static AgentConnection *CFNetOpenConnection(const char *server);
182+
static AgentConnection *CFNetOpenConnection(const char *server, const char *use_protocol_version);
180183
static void CFNetDisconnect(AgentConnection *conn);
181184
static int JustConnect(const char *server, char *port);
182185

183186
// COMMANDS:
184187
static int CFNetHelpTopic(const char *topic);
185188
static int CFNetHelp(const char *topic);
186-
static int CFNetConnectSingle(const char *server, bool print);
187-
static int CFNetConnect(const char *hostname, char **args);
189+
static int CFNetConnectSingle(const char *server, const char *use_protocol_version, bool print);
190+
static int CFNetConnect(const char *hostname, const char *use_protocol_version, char **args);
188191
static void CFNetStatPrint(const char *file, int st_mode, const char *server);
189192
static int CFNetStat(CFNetOptions *opts, const char *hostname, char **args);
190193
static int CFNetGet(CFNetOptions *opts, const char *hostname, char **args);
191194
static int CFNetOpenDir(CFNetOptions *opts, const char *hostname, char **args);
192195
static int CFNetMulti(const char *server);
193-
static int CFNetMultiTLS(const char *server);
196+
static int CFNetMultiTLS(const char *server, const char *use_protocol_version);
194197

195198

196199
//*******************************************************************
@@ -230,13 +233,15 @@ static void CFNetSetDefault(CFNetOptions *opts){
230233
opts->used_default= false;
231234
opts->min_tls_version = NULL;
232235
opts->allow_ciphers = NULL;
236+
opts->use_protocol_version = NULL;
233237
}
234238

235239
static void CFNetOptionsClear(CFNetOptions *opts)
236240
{
237241
assert(opts != NULL);
238242
free(opts->min_tls_version);
239243
free(opts->allow_ciphers);
244+
free(opts->use_protocol_version);
240245
}
241246

242247
static void CFNetInit(const char *min_tls_version, const char *allow_ciphers)
@@ -351,6 +356,11 @@ static int CFNetParse(int argc, char **argv,
351356
opts->allow_ciphers = xstrdup(optarg);
352357
break;
353358
}
359+
case 'p':
360+
{
361+
opts->use_protocol_version = xstrdup(optarg);
362+
break;
363+
}
354364
default:
355365
{
356366
// printf("Default optarg = '%s', c = '%c' = %i\n",
@@ -381,9 +391,11 @@ static int CFNetCommandNumber(char *command)
381391
static int CFNetCommandSwitch(CFNetOptions *opts, const char *hostname,
382392
char **args, enum command_enum cmd)
383393
{
394+
assert(opts != NULL);
395+
384396
switch (cmd) {
385397
case CFNET_CMD_CONNECT:
386-
return CFNetConnect(hostname, args);
398+
return CFNetConnect(hostname, opts->use_protocol_version, args);
387399
case CFNET_CMD_STAT:
388400
return CFNetStat(opts, hostname, args);
389401
case CFNET_CMD_GET:
@@ -393,7 +405,7 @@ static int CFNetCommandSwitch(CFNetOptions *opts, const char *hostname,
393405
case CFNET_CMD_MULTI:
394406
return CFNetMulti(hostname);
395407
case CFNET_CMD_MULTITLS:
396-
return CFNetMultiTLS(hostname);
408+
return CFNetMultiTLS(hostname, opts->use_protocol_version);
397409
default:
398410
break;
399411
}
@@ -471,12 +483,22 @@ static int CFNetRun(CFNetOptions *opts, char **args, char *hostnames)
471483
// PROTOCOL:
472484
//*******************************************************************
473485

474-
static AgentConnection *CFNetOpenConnection(const char *server)
486+
static AgentConnection *CFNetOpenConnection(const char *server, const char *use_protocol_version)
475487
{
488+
ProtocolVersion protocol_version = (use_protocol_version == NULL)
489+
? CF_PROTOCOL_LATEST
490+
: ParseProtocolVersionPolicy(use_protocol_version);
491+
if (protocol_version == CF_PROTOCOL_UNDEFINED)
492+
{
493+
Log(LOG_LEVEL_ERR, "Unknown CFEngine protocol version '%s'",
494+
use_protocol_version);
495+
return NULL;
496+
}
497+
476498
AgentConnection *conn = NULL;
477499
ConnectionFlags connflags =
478500
{
479-
.protocol_version = CF_PROTOCOL_LATEST,
501+
.protocol_version = protocol_version,
480502
.trust_server = true,
481503
.off_the_record = true
482504
};
@@ -495,6 +517,19 @@ static AgentConnection *CFNetOpenConnection(const char *server)
495517
printf("Failed to connect to '%s'\n", server);
496518
return NULL;
497519
}
520+
521+
ProtocolVersion negotiated_version = ConnectionInfoProtocolVersion(conn->conn_info);
522+
if ((use_protocol_version != NULL) && (negotiated_version != protocol_version))
523+
{
524+
Log(LOG_LEVEL_ERR,
525+
"Negotiated protocol version '%s' does not match specified protocol version '%s'. "
526+
"Maybe the server does not support it?",
527+
ProtocolVersionString(negotiated_version),
528+
use_protocol_version);
529+
DisconnectServer(conn);
530+
return NULL;
531+
}
532+
498533
return conn;
499534
}
500535

@@ -572,9 +607,9 @@ static int CFNetHelp(const char *topic)
572607
return 0;
573608
}
574609

575-
static int CFNetConnectSingle(const char *server, bool print)
610+
static int CFNetConnectSingle(const char *server, const char *use_protocol_version, bool print)
576611
{
577-
AgentConnection *conn = CFNetOpenConnection(server);
612+
AgentConnection *conn = CFNetOpenConnection(server, use_protocol_version);
578613
if (conn == NULL)
579614
{
580615
return -1;
@@ -587,7 +622,7 @@ static int CFNetConnectSingle(const char *server, bool print)
587622
return 0;
588623
}
589624

590-
static int CFNetConnect(const char *hostname, char **args)
625+
static int CFNetConnect(const char *hostname, const char *use_protocol_version, char **args)
591626
{
592627
assert(args != NULL);
593628
if (args[1] != NULL)
@@ -601,7 +636,7 @@ static int CFNetConnect(const char *hostname, char **args)
601636
Log(LOG_LEVEL_ERR, "No hostname specified");
602637
return -1;
603638
}
604-
CFNetConnectSingle(hostname, true);
639+
CFNetConnectSingle(hostname, use_protocol_version, true);
605640
return 0;
606641
}
607642

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

650685
static int CFNetStat(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **args)
651686
{
652-
assert(opts);
687+
assert(opts != NULL);
688+
653689
char *file = args[1];
654-
AgentConnection *conn = CFNetOpenConnection(hostname);
690+
AgentConnection *conn = CFNetOpenConnection(hostname, opts->use_protocol_version);
655691
if (conn == NULL)
656692
{
657693
return -1;
@@ -687,6 +723,7 @@ static int invalid_command(const char *cmd)
687723

688724
typedef struct _GetFileData {
689725
const char *hostname;
726+
const char *use_protocol_version;
690727
char remote_file[PATH_MAX];
691728
char local_file[PATH_MAX];
692729
bool ret;
@@ -695,7 +732,7 @@ typedef struct _GetFileData {
695732
static void *CFNetGetFile(void *arg)
696733
{
697734
GetFileData *data = (GetFileData *) arg;
698-
AgentConnection *conn = CFNetOpenConnection(data->hostname);
735+
AgentConnection *conn = CFNetOpenConnection(data->hostname, data->use_protocol_version);
699736
if (conn == NULL)
700737
{
701738
data->ret = false;
@@ -819,6 +856,7 @@ static int CFNetGet(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **
819856
threads[i] = (CFNetThreadData*) xcalloc(1, sizeof(CFNetThreadData));
820857
threads[i]->data = (GetFileData*) xcalloc(1, sizeof(GetFileData));
821858
threads[i]->data->hostname = hostname;
859+
threads[i]->data->use_protocol_version = opts->use_protocol_version;
822860
if (n_threads > 1)
823861
{
824862
if (strstr(local_file, "%d") != NULL)
@@ -891,10 +929,11 @@ static void PrintDirs(const Seq *list)
891929

892930
static int CFNetOpenDir(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **args)
893931
{
894-
assert(opts);
895-
assert(hostname);
896-
assert(args);
897-
AgentConnection *conn = CFNetOpenConnection(hostname);
932+
assert(opts != NULL);
933+
assert(hostname != NULL);
934+
assert(args != NULL);
935+
936+
AgentConnection *conn = CFNetOpenConnection(hostname, opts->use_protocol_version);
898937
if (conn == NULL)
899938
{
900939
return -1;
@@ -962,7 +1001,7 @@ static int CFNetMulti(const char *server)
9621001
return 0;
9631002
}
9641003

965-
static int CFNetMultiTLS(const char *server)
1004+
static int CFNetMultiTLS(const char *server, const char *use_protocol_version)
9661005
{
9671006
time_t start;
9681007
time(&start);
@@ -972,7 +1011,7 @@ static int CFNetMultiTLS(const char *server)
9721011
int attempts = 0;
9731012
while(ret == 0)
9741013
{
975-
ret = CFNetConnectSingle(server, false);
1014+
ret = CFNetConnectSingle(server, use_protocol_version, false);
9761015
++attempts;
9771016
}
9781017
time_t stop;

cf-serverd/server.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,8 @@ static void *HandleConnection(void *c)
359359
}
360360

361361
ProtocolVersion protocol_version = ConnectionInfoProtocolVersion(conn->conn_info);
362+
Log(LOG_LEVEL_DEBUG, "CFEngine protocol version '%s'", ProtocolVersionString(protocol_version));
363+
362364
if (ProtocolIsTLS(protocol_version))
363365
{
364366
bool established = ServerTLSSessionEstablish(conn, NULL);

0 commit comments

Comments
 (0)