@@ -244,6 +244,12 @@ namespace {
244244 if (profile->Has (" ca-file" )) {
245245 Cout << " ca-file: " << profile->GetValue (" ca-file" ).as <TString>() << Endl;
246246 }
247+ if (profile->Has (" client-cert-file" )) {
248+ Cout << " client-cert-file: " << profile->GetValue (" client-cert-file" ).as <TString>() << Endl;
249+ }
250+ if (profile->Has (" client-cert-key-file" )) {
251+ Cout << " client-cert-key-file: " << profile->GetValue (" client-cert-key-file" ).as <TString>() << Endl;
252+ }
247253 }
248254}
249255
@@ -307,6 +313,10 @@ void TCommandConnectionInfo::PrintInfo(TConfig& config) {
307313 if (config.CaCertsFile ) {
308314 Cout << " ca-file: " << config.CaCertsFile << Endl;
309315 }
316+ if (config.ClientCertFile ) {
317+ Cout << " client-cert-file: " << config.ClientCertFile << Endl;
318+ Cout << " client-cert-key-file: " << config.ClientCertPrivateKeyFile << Endl;
319+ }
310320}
311321
312322void TCommandConnectionInfo::PrintVerboseInfo (TConfig& config) {
@@ -382,7 +392,9 @@ void TCommandProfileCommon::GetOptionsFromStdin() {
382392 {" user" , User},
383393 {" password-file" , PasswordFile},
384394 {" iam-endpoint" , IamEndpoint},
385- {" ca-file" , CaCertsFile}
395+ {" ca-file" , CaCertsFile},
396+ {" client-cert-file" , ClientCertFile},
397+ {" client-cert-key-file" , ClientCertPrivateKeyFile},
386398 };
387399 while (Cin.ReadLine (line)) {
388400 Strip (line, trimmedLine);
@@ -432,6 +444,12 @@ void TCommandProfileCommon::ConfigureProfile(const TString& profileName, std::sh
432444 if (cmdLine && CaCertsFile) {
433445 profile->SetValue (" ca-file" , CaCertsFile);
434446 }
447+ if (cmdLine && ClientCertFile) {
448+ profile->SetValue (" client-cert-file" , ClientCertFile);
449+ }
450+ if (cmdLine && ClientCertPrivateKeyFile) {
451+ profile->SetValue (" client-cert-key-file" , ClientCertPrivateKeyFile);
452+ }
435453
436454 if (interactive) {
437455 TString activeProfileName = profileManager->GetActiveProfileName ();
@@ -669,11 +687,22 @@ void TCommandProfileCommon::ValidateAuth() {
669687 }
670688}
671689
690+ void TCommandProfileCommon::ValidateClientCert () {
691+ if (ClientCertFile.empty () && ClientCertPrivateKeyFile.empty ()) {
692+ return ;
693+ }
694+ if (ClientCertFile.empty () || ClientCertPrivateKeyFile.empty ()) { // One option is set, another is not set
695+ throw TMisuseException ()
696+ << " Both \" client-cert-file\" and \" client-cert-key-file\" options must be provided." ;
697+ }
698+ }
699+
672700bool TCommandProfileCommon::AnyProfileOptionInCommandLine () {
673701 return Endpoint || Database || TokenFile || Oauth2KeyFile ||
674702 IamTokenFile || YcTokenFile ||
675703 SaKeyFile || UseMetadataCredentials || User ||
676- PasswordFile || IamEndpoint || AnonymousAuth || CaCertsFile;
704+ PasswordFile || IamEndpoint || AnonymousAuth || CaCertsFile ||
705+ ClientCertFile || ClientCertPrivateKeyFile;
677706}
678707
679708TCommandCreateProfile::TCommandCreateProfile ()
@@ -713,6 +742,12 @@ void TCommandProfileCommon::Config(TConfig& config) {
713742 opts.AddLongOption (" ca-file" ,
714743 " Path to a file containing the PEM encoding of the server root certificates for tls connections." )
715744 .RequiredArgument (" PATH" ).StoreResult (&CaCertsFile);
745+ opts.AddLongOption (" client-cert-file" ,
746+ " Path to a file containing the PEM encoding of the client certificate for tls connections" )
747+ .RequiredArgument (" PATH" ).StoreResult (&ClientCertFile);
748+ opts.AddLongOption (" client-cert-key-file" ,
749+ " Path to a file containing the PEM encoding of the client certificate private key for tls connections" )
750+ .RequiredArgument (" PATH" ).StoreResult (&ClientCertPrivateKeyFile);
716751 if (!IsStdinInteractive ()) {
717752 GetOptionsFromStdin ();
718753 }
@@ -721,6 +756,7 @@ void TCommandProfileCommon::Config(TConfig& config) {
721756void TCommandProfileCommon::Parse (TConfig& config) {
722757 TClientCommand::Parse (config);
723758 ValidateAuth ();
759+ ValidateClientCert ();
724760}
725761
726762void TCommandCreateProfile::Config (TConfig& config) {
@@ -1066,6 +1102,10 @@ void TCommandUpdateProfile::Config(TConfig& config) {
10661102 }
10671103 opts.AddLongOption (" no-ca-file" , " Delete path to file containing the PEM encoding of the "
10681104 " server root certificates for tls connections from the profile" ).StoreTrue (&NoCaCertsFile);
1105+ opts.AddLongOption (" no-client-cert-file" , " Delete path to a file containing the PEM encoding of the "
1106+ " client certificate for tls connections" ).StoreTrue (&NoClientCertFile);
1107+ opts.AddLongOption (" no-client-cert-key-file" , " Delete path to a file containing the PEM encoding of the "
1108+ " client certificate private key for tls connections" ).StoreTrue (&NoClientCertPrivateKeyFile);
10691109}
10701110
10711111void TCommandUpdateProfile::ValidateNoOptions () {
@@ -1082,22 +1122,30 @@ void TCommandUpdateProfile::ValidateNoOptions() {
10821122 TStringBuilder str;
10831123 if (Endpoint && NoEndpoint) {
10841124 str << " \" --endpoint\" and \" --no-endpoint\" " ;
1085- } else {
1086- if (Database && NoDatabase) {
1087- str << " \" --database and \" --no-database\" " ;
1088- } else {
1089- if (IamEndpoint && NoIamEndpoint) {
1090- str << " \" --iam-endpoint\" and \" --no-iam-endpoint\" " ;
1091- } else {
1092- if (CaCertsFile && NoCaCertsFile) {
1093- str << " \" --ca-file\" and \" --no-ca-file\" " ;
1094- }
1095- }
1096- }
10971125 }
1126+ if (!str && Database && NoDatabase) {
1127+ str << " \" --database and \" --no-database\" " ;
1128+ }
1129+ if (!str && IamEndpoint && NoIamEndpoint) {
1130+ str << " \" --iam-endpoint\" and \" --no-iam-endpoint\" " ;
1131+ }
1132+ if (!str && CaCertsFile && NoCaCertsFile) {
1133+ str << " \" --ca-file\" and \" --no-ca-file\" " ;
1134+ }
1135+ if (!str && ClientCertFile && NoClientCertFile) {
1136+ str << " \" --client-cert-file\" and \" --no-client-cert-file\" " ;
1137+ }
1138+ if (!str && ClientCertPrivateKeyFile && NoClientCertPrivateKeyFile) {
1139+ str << " \" --client-cert-key-file\" and \" --no-client-cert-key-file\" " ;
1140+ }
1141+
10981142 if (!str.empty ()) {
10991143 throw TMisuseException () << " Options " << str << " are mutually exclusive" ;
11001144 }
1145+
1146+ if (NoClientCertFile && !NoClientCertPrivateKeyFile || !NoClientCertFile && NoClientCertPrivateKeyFile) {
1147+ throw TMisuseException () << " Options \" --no-client-cert-file\" and \" --no-client-cert-key-file\" must be both set or unset" ;
1148+ }
11011149}
11021150
11031151void TCommandUpdateProfile::DropNoOptions (std::shared_ptr<IProfile> profile) {
@@ -1116,6 +1164,12 @@ void TCommandUpdateProfile::DropNoOptions(std::shared_ptr<IProfile> profile) {
11161164 if (NoCaCertsFile) {
11171165 profile->RemoveValue (" ca-file" );
11181166 }
1167+ if (NoClientCertFile) {
1168+ profile->RemoveValue (" client-cert-file" );
1169+ }
1170+ if (NoClientCertPrivateKeyFile) {
1171+ profile->RemoveValue (" client-cert-key-file" );
1172+ }
11191173}
11201174
11211175void TCommandUpdateProfile::Parse (TConfig& config) {
0 commit comments