@@ -55,6 +55,7 @@ typedef struct
55
55
bool used_default ;
56
56
char * min_tls_version ;
57
57
char * allow_ciphers ;
58
+ char * use_protocol_version ;
58
59
} CFNetOptions ;
59
60
60
61
//*******************************************************************
@@ -112,6 +113,7 @@ static const struct option OPTIONS[] =
112
113
{"inform" , no_argument , 0 , 'I' },
113
114
{"tls-version" , required_argument , 0 , 't' },
114
115
{"ciphers" , required_argument , 0 , 'c' },
116
+ {"protocol" , required_argument , 0 , 'p' },
115
117
{NULL , 0 , 0 , '\0' }
116
118
};
117
119
@@ -126,6 +128,7 @@ static const char *const HINTS[] =
126
128
"Enable basic information output" ,
127
129
"Minimum TLS version to use" ,
128
130
"TLS ciphers to use (comma-separated list)" ,
131
+ "Specify CFEngine protocol to use. Possible values: 'classic', 'tls', 'cookie', 'filestream', 'latest' (default)" ,
129
132
NULL
130
133
};
131
134
@@ -176,21 +179,21 @@ static int CFNetRun(CFNetOptions *opts, char **args, char *hostnames);
176
179
static char * RequireHostname (char * hostnames );
177
180
178
181
// PROTOCOL:
179
- static AgentConnection * CFNetOpenConnection (const char * server );
182
+ static AgentConnection * CFNetOpenConnection (const char * server , const char * use_protocol_version );
180
183
static void CFNetDisconnect (AgentConnection * conn );
181
184
static int JustConnect (const char * server , char * port );
182
185
183
186
// COMMANDS:
184
187
static int CFNetHelpTopic (const char * topic );
185
188
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 );
188
191
static void CFNetStatPrint (const char * file , int st_mode , const char * server );
189
192
static int CFNetStat (CFNetOptions * opts , const char * hostname , char * * args );
190
193
static int CFNetGet (CFNetOptions * opts , const char * hostname , char * * args );
191
194
static int CFNetOpenDir (CFNetOptions * opts , const char * hostname , char * * args );
192
195
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 );
194
197
195
198
196
199
//*******************************************************************
@@ -230,13 +233,15 @@ static void CFNetSetDefault(CFNetOptions *opts){
230
233
opts -> used_default = false;
231
234
opts -> min_tls_version = NULL ;
232
235
opts -> allow_ciphers = NULL ;
236
+ opts -> use_protocol_version = NULL ;
233
237
}
234
238
235
239
static void CFNetOptionsClear (CFNetOptions * opts )
236
240
{
237
241
assert (opts != NULL );
238
242
free (opts -> min_tls_version );
239
243
free (opts -> allow_ciphers );
244
+ free (opts -> use_protocol_version );
240
245
}
241
246
242
247
static void CFNetInit (const char * min_tls_version , const char * allow_ciphers )
@@ -351,6 +356,11 @@ static int CFNetParse(int argc, char **argv,
351
356
opts -> allow_ciphers = xstrdup (optarg );
352
357
break ;
353
358
}
359
+ case 'p' :
360
+ {
361
+ opts -> use_protocol_version = xstrdup (optarg );
362
+ break ;
363
+ }
354
364
default :
355
365
{
356
366
// printf("Default optarg = '%s', c = '%c' = %i\n",
@@ -381,9 +391,11 @@ static int CFNetCommandNumber(char *command)
381
391
static int CFNetCommandSwitch (CFNetOptions * opts , const char * hostname ,
382
392
char * * args , enum command_enum cmd )
383
393
{
394
+ assert (opts != NULL );
395
+
384
396
switch (cmd ) {
385
397
case CFNET_CMD_CONNECT :
386
- return CFNetConnect (hostname , args );
398
+ return CFNetConnect (hostname , opts -> use_protocol_version , args );
387
399
case CFNET_CMD_STAT :
388
400
return CFNetStat (opts , hostname , args );
389
401
case CFNET_CMD_GET :
@@ -393,7 +405,7 @@ static int CFNetCommandSwitch(CFNetOptions *opts, const char *hostname,
393
405
case CFNET_CMD_MULTI :
394
406
return CFNetMulti (hostname );
395
407
case CFNET_CMD_MULTITLS :
396
- return CFNetMultiTLS (hostname );
408
+ return CFNetMultiTLS (hostname , opts -> use_protocol_version );
397
409
default :
398
410
break ;
399
411
}
@@ -471,12 +483,22 @@ static int CFNetRun(CFNetOptions *opts, char **args, char *hostnames)
471
483
// PROTOCOL:
472
484
//*******************************************************************
473
485
474
- static AgentConnection * CFNetOpenConnection (const char * server )
486
+ static AgentConnection * CFNetOpenConnection (const char * server , const char * use_protocol_version )
475
487
{
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
+
476
498
AgentConnection * conn = NULL ;
477
499
ConnectionFlags connflags =
478
500
{
479
- .protocol_version = CF_PROTOCOL_LATEST ,
501
+ .protocol_version = protocol_version ,
480
502
.trust_server = true,
481
503
.off_the_record = true
482
504
};
@@ -495,6 +517,19 @@ static AgentConnection *CFNetOpenConnection(const char *server)
495
517
printf ("Failed to connect to '%s'\n" , server );
496
518
return NULL ;
497
519
}
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
+
498
533
return conn ;
499
534
}
500
535
@@ -572,9 +607,9 @@ static int CFNetHelp(const char *topic)
572
607
return 0 ;
573
608
}
574
609
575
- static int CFNetConnectSingle (const char * server , bool print )
610
+ static int CFNetConnectSingle (const char * server , const char * use_protocol_version , bool print )
576
611
{
577
- AgentConnection * conn = CFNetOpenConnection (server );
612
+ AgentConnection * conn = CFNetOpenConnection (server , use_protocol_version );
578
613
if (conn == NULL )
579
614
{
580
615
return -1 ;
@@ -587,7 +622,7 @@ static int CFNetConnectSingle(const char *server, bool print)
587
622
return 0 ;
588
623
}
589
624
590
- static int CFNetConnect (const char * hostname , char * * args )
625
+ static int CFNetConnect (const char * hostname , const char * use_protocol_version , char * * args )
591
626
{
592
627
assert (args != NULL );
593
628
if (args [1 ] != NULL )
@@ -601,7 +636,7 @@ static int CFNetConnect(const char *hostname, char **args)
601
636
Log (LOG_LEVEL_ERR , "No hostname specified" );
602
637
return -1 ;
603
638
}
604
- CFNetConnectSingle (hostname , true);
639
+ CFNetConnectSingle (hostname , use_protocol_version , true);
605
640
return 0 ;
606
641
}
607
642
@@ -649,9 +684,10 @@ static void CFNetStatPrint(const char *file, int st_mode, const char *server)
649
684
650
685
static int CFNetStat (ARG_UNUSED CFNetOptions * opts , const char * hostname , char * * args )
651
686
{
652
- assert (opts );
687
+ assert (opts != NULL );
688
+
653
689
char * file = args [1 ];
654
- AgentConnection * conn = CFNetOpenConnection (hostname );
690
+ AgentConnection * conn = CFNetOpenConnection (hostname , opts -> use_protocol_version );
655
691
if (conn == NULL )
656
692
{
657
693
return -1 ;
@@ -687,6 +723,7 @@ static int invalid_command(const char *cmd)
687
723
688
724
typedef struct _GetFileData {
689
725
const char * hostname ;
726
+ const char * use_protocol_version ;
690
727
char remote_file [PATH_MAX ];
691
728
char local_file [PATH_MAX ];
692
729
bool ret ;
@@ -695,7 +732,7 @@ typedef struct _GetFileData {
695
732
static void * CFNetGetFile (void * arg )
696
733
{
697
734
GetFileData * data = (GetFileData * ) arg ;
698
- AgentConnection * conn = CFNetOpenConnection (data -> hostname );
735
+ AgentConnection * conn = CFNetOpenConnection (data -> hostname , data -> use_protocol_version );
699
736
if (conn == NULL )
700
737
{
701
738
data -> ret = false;
@@ -819,6 +856,7 @@ static int CFNetGet(ARG_UNUSED CFNetOptions *opts, const char *hostname, char **
819
856
threads [i ] = (CFNetThreadData * ) xcalloc (1 , sizeof (CFNetThreadData ));
820
857
threads [i ]-> data = (GetFileData * ) xcalloc (1 , sizeof (GetFileData ));
821
858
threads [i ]-> data -> hostname = hostname ;
859
+ threads [i ]-> data -> use_protocol_version = opts -> use_protocol_version ;
822
860
if (n_threads > 1 )
823
861
{
824
862
if (strstr (local_file , "%d" ) != NULL )
@@ -891,10 +929,11 @@ static void PrintDirs(const Seq *list)
891
929
892
930
static int CFNetOpenDir (ARG_UNUSED CFNetOptions * opts , const char * hostname , char * * args )
893
931
{
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 );
898
937
if (conn == NULL )
899
938
{
900
939
return -1 ;
@@ -962,7 +1001,7 @@ static int CFNetMulti(const char *server)
962
1001
return 0 ;
963
1002
}
964
1003
965
- static int CFNetMultiTLS (const char * server )
1004
+ static int CFNetMultiTLS (const char * server , const char * use_protocol_version )
966
1005
{
967
1006
time_t start ;
968
1007
time (& start );
@@ -972,7 +1011,7 @@ static int CFNetMultiTLS(const char *server)
972
1011
int attempts = 0 ;
973
1012
while (ret == 0 )
974
1013
{
975
- ret = CFNetConnectSingle (server , false);
1014
+ ret = CFNetConnectSingle (server , use_protocol_version , false);
976
1015
++ attempts ;
977
1016
}
978
1017
time_t stop ;
0 commit comments