~ubuntu-branches/ubuntu/trusty/nordugrid-arc/trusty-proposed

« back to all changes in this revision

Viewing changes to src/clients/credentials/arcproxy.cpp

  • Committer: Package Import Robot
  • Author(s): Mattias Ellert
  • Date: 2013-11-29 13:39:10 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20131129133910-altaxrfowczzl2ev
Tags: 4.0.0-1
4.0.0 Release (Closes: #715131) (LP: #1049798)

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
 
60
60
static void create_proxy(std::string& proxy_cert, Arc::Credential& signer,     
61
61
    const std::string& proxy_policy, Arc::Time& proxy_start, Arc::Period& proxy_period, 
62
 
    const std::string& vomsacseq, bool use_gsi_proxy, int keybits);
 
62
    const std::string& vomsacseq, bool use_gsi_proxy, int keybits,
 
63
    const std::string& signing_algorithm);
63
64
 
64
65
static std::string get_proxypolicy(const std::string& policy_source);
65
66
 
120
121
  return;
121
122
}
122
123
 
123
 
#define PASS_MIN_LENGTH (4)
124
 
static int input_password(char *password, int passwdsz, bool verify,
125
 
                          const std::string& prompt_info,
126
 
                          const std::string& prompt_verify_info,
127
 
                          Arc::Logger& logger) {
128
 
  UI *ui = NULL;
129
 
  int res = 0;
130
 
  ui = UI_new();
131
 
  if (ui) {
132
 
    int ok = 0;
133
 
    char* buf = new char[passwdsz];
134
 
    memset(buf, 0, passwdsz);
135
 
    int ui_flags = 0;
136
 
    char *prompt1 = NULL;
137
 
    char *prompt2 = NULL;
138
 
    prompt1 = UI_construct_prompt(ui, "passphrase", prompt_info.c_str());
139
 
    ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
140
 
    UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
141
 
    ok = UI_add_input_string(ui, prompt1, ui_flags, password,
142
 
                             0, passwdsz - 1);
143
 
    if (ok >= 0) {
144
 
      do {
145
 
        ok = UI_process(ui);
146
 
      } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
147
 
    }
148
 
 
149
 
    if (ok >= 0) res = strlen(password);
150
 
 
151
 
    if (ok >= 0 && verify) {
152
 
      UI_free(ui);
153
 
      ui = UI_new();
154
 
      if(!ui) {
155
 
        ok = -1;
156
 
      } else {
157
 
        // TODO: use some generic password strength evaluation
158
 
        if(res < PASS_MIN_LENGTH) {
159
 
          UI_add_info_string(ui, "WARNING: Your password is too weak (too short)!\n"
160
 
                                 "Make sure this is really what You wanted to enter.\n");
161
 
        }
162
 
        prompt2 = UI_construct_prompt(ui, "passphrase", prompt_verify_info.c_str());
163
 
        ok = UI_add_verify_string(ui, prompt2, ui_flags, buf,
164
 
                                  0, passwdsz - 1, password);
165
 
        if (ok >= 0) {
166
 
          do {
167
 
            ok = UI_process(ui);
168
 
          } while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
169
 
        }
170
 
      }
171
 
    }
172
 
 
173
 
    if (ok == -1) {
174
 
      logger.msg(Arc::ERROR, "User interface error");
175
 
      tls_process_error(logger);
176
 
      memset(password, 0, (unsigned int)passwdsz);
177
 
      res = 0;
178
 
    }
179
 
    if (ok == -2) {
180
 
      logger.msg(Arc::ERROR, "Aborted!");
181
 
      memset(password, 0, (unsigned int)passwdsz);
182
 
      res = 0;
183
 
    }
184
 
    if(ui) UI_free(ui);
185
 
    delete[] buf;
186
 
    if(prompt1) OPENSSL_free(prompt1);
187
 
    if(prompt2) OPENSSL_free(prompt2);
188
 
  }
189
 
  return res;
190
 
}
191
 
 
192
124
static bool is_file(std::string path) {
193
125
  if (Glib::file_test(path, Glib::FILE_TEST_IS_REGULAR))
194
126
    return true;
438
370
 
439
371
#endif
440
372
 
 
373
static std::string signTypeToString(Arc::Signalgorithm alg) {
 
374
  switch(alg) {
 
375
    case Arc::SIGN_SHA1: return "sha1";
 
376
    case Arc::SIGN_SHA224: return "sha224";
 
377
    case Arc::SIGN_SHA256: return "sha256";
 
378
    case Arc::SIGN_SHA384: return "sha384";
 
379
    case Arc::SIGN_SHA512: return "sha512";
 
380
    default:
 
381
      break;
 
382
  }
 
383
  return "unknown";
 
384
}
 
385
 
 
386
typedef enum {
 
387
  pass_all,
 
388
  pass_private_key,
 
389
  pass_myproxy,
 
390
  pass_myproxy_new
 
391
} pass_destination_type;
 
392
 
 
393
std::map<pass_destination_type, Arc::PasswordSource*> passsources;
 
394
 
 
395
class PasswordSourceFile: public Arc::PasswordSource {
 
396
 private:
 
397
  std::ifstream file_;
 
398
 public:
 
399
  PasswordSourceFile(const std::string& filename):file_(filename.c_str()) {
 
400
  };
 
401
  virtual Result Get(std::string& password, int minsize, int maxsize) {
 
402
    if(!file_) return Arc::PasswordSource::NO_PASSWORD;
 
403
    std::getline(file_, password);
 
404
    return Arc::PasswordSource::PASSWORD;
 
405
  };
 
406
};
 
407
 
441
408
int main(int argc, char *argv[]) {
442
409
 
443
410
  setlocale(LC_ALL, "");
465
432
                                    "  e.g. 43200 or 12h or 12H; if not specified, the default is the minimum value of\n"
466
433
                                    "  12 hours and validityPeriod (which is lifetime of the delegated proxy on myproxy server))\n"
467
434
                                    "  proxyPolicy=policy content\n"
468
 
                                    "  proxyPolicyFile=policy file"));
 
435
                                    "  proxyPolicyFile=policy file\n"
 
436
                                    "  keybits=number - length of the key to generate. Default is 1024 bits.\n"
 
437
                                    "  Special value 'inherit' is to use key length of signing certificate.\n"
 
438
                                    "  signingAlgorithm=name - signing algorithm to use for signing public key of proxy.\n"
 
439
                                    "  Possible values are sha1, sha2 (alias for sha256), sha224, sha256, sha384, sha512\n"
 
440
                                    "  and inherit (use algorithm of signing certificate). Default is inherit.\n"
 
441
                                    "\n"
 
442
                                    "Supported information item names are:\n"
 
443
                                    "  subject - subject name of proxy certificate.\n"
 
444
                                    "  identity - identity subject name of proxy certificate.\n"
 
445
                                    "  issuer - issuer subject name of proxy certificate.\n"
 
446
                                    "  ca - subject name of CA ehich issued initial certificate\n"
 
447
                                    "  path - file system path to file containing proxy.\n"
 
448
                                    "  type - type of proxy certificate.\n"
 
449
                                    "  validityStart - timestamp when proxy validity starts.\n"
 
450
                                    "  validityEnd - timestamp when proxy validity ends.\n"
 
451
                                    "  validityPeriod - duration of proxy validity in seconds.\n"
 
452
                                    "  validityLeft - duration of proxy validity left in seconds.\n"
 
453
                                    "  vomsVO - VO name  represented by VOMS attribute\n"
 
454
                                    "  vomsSubject - subject of certificate for which VOMS attribute is issued\n"
 
455
                                    "  vomsIssuer - subject of service which issued VOMS certificate\n"
 
456
                                    "  vomsACvalidityStart - timestamp when VOMS attribute validity starts.\n"
 
457
                                    "  vomsACvalidityEnd - timestamp when VOMS attribute validity ends.\n"
 
458
                                    "  vomsACvalidityPeriod - duration of VOMS attribute validity in seconds.\n"
 
459
                                    "  vomsACvalidityLeft - duration of VOMS attribute validity left in seconds.\n"
 
460
                                    "  proxyPolicy\n"
 
461
                                    "  keybits - size of proxy certificate key in bits.\n"
 
462
                                    "  signingAlgorithm - algorith used to sign proxy certificate.\n"
 
463
                                    "Items are printed in requested order and are separated by newline.\n"
 
464
                                    "If item has multiple values they are printed in same line separated by |."
 
465
  ));
469
466
 
470
467
  std::string proxy_path;
471
468
  options.AddOption('P', "proxy", istring("path to the proxy file"),
525
522
  options.AddOption('O', "old", istring("use GSI proxy (RFC 3820 compliant proxy is default)"), use_gsi_proxy);
526
523
 
527
524
  bool info = false;
528
 
  options.AddOption('I', "info", istring("print all information about this proxy. \n"
529
 
                                         "              In order to show the Identity (DN without CN as suffix for proxy) \n"
530
 
                                         "              of the certificate, the 'trusted certdir' is needed."
531
 
                                         ),
532
 
                    info);
 
525
  options.AddOption('I', "info", istring("print all information about this proxy."), info);
 
526
 
 
527
  std::list<std::string> infoitemlist;
 
528
  options.AddOption('i', "infoitem", istring("print selected information about this proxy."), istring("string"), infoitemlist);
533
529
 
534
530
  bool remove_proxy = false;
535
531
  options.AddOption('r', "remove", istring("remove proxy"), remove_proxy);
560
556
 
561
557
  std::string myproxy_command; //command to myproxy server
562
558
  options.AddOption('M', "myproxycmd", istring("command to MyProxy server. The command can be PUT or GET.\n"
563
 
                                               "              PUT/put/Put -- put a delegated credential to the MyProxy server; \n"
564
 
                                               "              GET/get/Get -- get a delegated credential from the MyProxy server, \n"
 
559
                                               "              PUT -- put a delegated credential to the MyProxy server; \n"
 
560
                                               "              GET -- get a delegated credential from the MyProxy server, \n"
565
561
                                               "              credential (certificate and key) is not needed in this case. \n"
566
562
                                               "              MyProxy functionality can be used together with VOMS\n"
567
563
                                               "              functionality.\n"
580
576
  options.AddOption('c', "constraint", istring("proxy constraints"),
581
577
                    istring("string"), constraintlist);
582
578
 
 
579
  std::list<std::string> passsourcelist;
 
580
  options.AddOption('p', "passwordsource", istring("password sources"),
 
581
                    istring("string"), passsourcelist);
 
582
 
583
583
  int timeout = -1;
584
584
  options.AddOption('t', "timeout", istring("timeout in seconds (default 20)"),
585
585
                    istring("seconds"), timeout);
632
632
  // Check for needed credentials objects
633
633
  // Can proxy be used for? Could not find it in documentation.
634
634
  // Key and certificate not needed if only printing proxy information
635
 
  if (!(myproxy_command == "get" || myproxy_command == "GET" || myproxy_command == "Get")) {
 
635
  if (!(Arc::lower(myproxy_command) == "get")) {
636
636
    if((usercfg.CertificatePath().empty() || 
637
637
        (
638
638
         usercfg.KeyPath().empty() && 
639
639
         (usercfg.CertificatePath().find(".p12") == std::string::npos)
640
640
        )
641
 
       ) && !(info || remove_proxy)) {
 
641
       ) && !(info || (infoitemlist.size() > 0) || remove_proxy)) {
642
642
      logger.msg(Arc::ERROR, "Failed to find certificate and/or private key or files have improper permissions or ownership.");
643
643
      logger.msg(Arc::ERROR, "You may try to increase verbosity to get more information.");
644
644
      return EXIT_FAILURE;
733
733
      std::cout << Arc::IString("Time left for proxy: %s", (holder.GetEndTime() - now).istr()) << std::endl;
734
734
    std::cout << Arc::IString("Proxy path: %s", proxy_path) << std::endl;
735
735
    std::cout << Arc::IString("Proxy type: %s", certTypeToString(holder.GetType())) << std::endl;
 
736
    std::cout << Arc::IString("Proxy key length: %i", holder.GetKeybits()) << std::endl;
 
737
    std::cout << Arc::IString("Proxy signature: %s", signTypeToString(holder.GetSigningAlgorithm())) << std::endl;
736
738
 
737
739
    Arc::VOMSTrustList voms_trust_dn;
738
740
    voms_trust_dn.AddRegex(".*");
828
830
    }
829
831
    return EXIT_SUCCESS;
830
832
  }
 
833
  if(infoitemlist.size() > 0) {
 
834
    std::vector<Arc::VOMSACInfo> voms_attributes;
 
835
    Arc::Credential holder(proxy_path, "", "", "");
 
836
    Arc::VOMSTrustList voms_trust_dn;
 
837
    voms_trust_dn.AddRegex(".*");
 
838
    parseVOMSAC(holder, ca_dir, "", voms_dir, voms_trust_dn, voms_attributes, true, true);
 
839
    for(std::list<std::string>::iterator ii = infoitemlist.begin();
 
840
                           ii != infoitemlist.end(); ++ii) {
 
841
      if(*ii == "subject") {
 
842
        std::cout << holder.GetDN() << std::endl;
 
843
      } else if(*ii == "identity") {
 
844
        std::cout << holder.GetIdentityName() << std::endl;
 
845
      } else if(*ii == "issuer") {
 
846
        std::cout << holder.GetIssuerName() << std::endl;
 
847
      } else if(*ii == "ca") {
 
848
        std::cout << holder.GetCAName() << std::endl;
 
849
      } else if(*ii == "path") {
 
850
        std::cout << proxy_path << std::endl;
 
851
      } else if(*ii == "type") {
 
852
        std::cout << certTypeToString(holder.GetType()) << std::endl; // todo:less human readable
 
853
      } else if(*ii == "validityStart") {
 
854
        std::cout << holder.GetStartTime().GetTime() << std::endl;
 
855
      } else if(*ii == "validityEnd") {
 
856
        std::cout << holder.GetEndTime().GetTime() << std::endl;
 
857
      } else if(*ii == "validityPeriod") {
 
858
        std::cout << (holder.GetEndTime() - holder.GetStartTime()).GetPeriod() << std::endl;
 
859
      } else if(*ii == "validityLeft") {
 
860
        std::cout << ((now<holder.GetEndTime())?(holder.GetEndTime()-now):Arc::Period(0)).GetPeriod() << std::endl;
 
861
      } else if(*ii == "vomsVO") {
 
862
        for(int n = 0; n<voms_attributes.size(); ++n) {
 
863
          if(n) std::cout << "|";
 
864
          std::cout << voms_attributes[n].voname;
 
865
        }
 
866
        std::cout << std::endl;
 
867
      } else if(*ii == "vomsSubject") {
 
868
        for(int n = 0; n<voms_attributes.size(); ++n) {
 
869
          if(n) std::cout << "|";
 
870
          std::cout << voms_attributes[n].holder;
 
871
        }
 
872
        std::cout << std::endl;
 
873
      } else if(*ii == "vomsIssuer") {
 
874
        for(int n = 0; n<voms_attributes.size(); ++n) {
 
875
          if(n) std::cout << "|";
 
876
          std::cout << voms_attributes[n].issuer;
 
877
        }
 
878
        std::cout << std::endl;
 
879
      } else if(*ii == "vomsACvalidityStart") {
 
880
        for(int n = 0; n<voms_attributes.size(); ++n) {
 
881
          if(n) std::cout << "|";
 
882
          std::cout << voms_attributes[n].from.GetTime();
 
883
        }
 
884
        std::cout << std::endl;
 
885
      } else if(*ii == "vomsACvalidityEnd") {
 
886
        for(int n = 0; n<voms_attributes.size(); ++n) {
 
887
          if(n) std::cout << "|";
 
888
          std::cout << voms_attributes[n].till.GetTime();
 
889
        }
 
890
        std::cout << std::endl;
 
891
      } else if(*ii == "vomsACvalidityPeriod") {
 
892
        for(int n = 0; n<voms_attributes.size(); ++n) {
 
893
          if(n) std::cout << "|";
 
894
          std::cout << (voms_attributes[n].till-voms_attributes[n].from).GetPeriod();
 
895
        }
 
896
        std::cout << std::endl;
 
897
      } else if(*ii == "vomsACvalidityLeft") {
 
898
        for(int n = 0; n<voms_attributes.size(); ++n) {
 
899
          if(n) std::cout << "|";
 
900
          std::cout << ((voms_attributes[n].till>now)?(voms_attributes[n].till-now):Arc::Period(0)).GetPeriod();
 
901
        }
 
902
        std::cout << std::endl;
 
903
      } else if(*ii == "proxyPolicy") {
 
904
        std::cout << holder.GetProxyPolicy() << std::endl;
 
905
      } else if(*ii == "keybits") {
 
906
        std::cout << holder.GetKeybits() << std::endl;
 
907
      } else if(*ii == "signingAlgorithm") {
 
908
        std::cout << signTypeToString(holder.GetSigningAlgorithm()) << std::endl;
 
909
      } else {
 
910
        logger.msg(Arc::ERROR, "Information item '%s' is not known",*ii);
 
911
      }
 
912
    }
 
913
    return EXIT_SUCCESS;
 
914
  }
831
915
 
832
916
  if ((cert_path.empty() || key_path.empty()) && 
833
 
      ((myproxy_command == "PUT") || (myproxy_command == "put") || (myproxy_command == "Put"))) {
 
917
      (Arc::lower(myproxy_command) == "put")) {
834
918
    if (cert_path.empty())
835
919
      logger.msg(Arc::ERROR, "Cannot find the user certificate path, "
836
920
                 "please setup environment X509_USER_CERT, "
852
936
      constraints[*it] = "";
853
937
  }
854
938
 
 
939
  std::map<pass_destination_type, std::pair<std::string,bool> > passprompts;
 
940
  passprompts[pass_private_key] = std::pair<std::string,bool>("private key",false);
 
941
  passprompts[pass_myproxy] = std::pair<std::string,bool>("MyProxy server",false);
 
942
  passprompts[pass_myproxy_new] = std::pair<std::string,bool>("MyProxy server (new)",true);
 
943
  for (std::list<std::string>::iterator it = passsourcelist.begin();
 
944
       it != passsourcelist.end(); it++) {
 
945
    std::string::size_type pos = it->find('=');
 
946
    if (pos == std::string::npos) {
 
947
      logger.msg(Arc::ERROR, "Cannot parse password source expression %s "
 
948
                 "it must be of type=source format", *it);
 
949
      return EXIT_FAILURE;
 
950
    }
 
951
    std::string dest = it->substr(0, pos);
 
952
    pass_destination_type pass_dest;
 
953
    if(dest == "key") {
 
954
      pass_dest = pass_private_key;
 
955
    } else {
 
956
      logger.msg(Arc::ERROR, "Cannot parse password type %s. "
 
957
                 "Currently supported value is 'key'.", dest);
 
958
      return EXIT_FAILURE;
 
959
    }
 
960
    std::string pass = it->substr(pos + 1);
 
961
    if((pass[0] == '"') && (pass[pass.length()-1] == '"')) {
 
962
      passsources[pass_dest] = new Arc::PasswordSourceString(pass.substr(1,pass.length()-2));
 
963
    } else if(pass == "int") {
 
964
      passsources[pass_dest] = new Arc::PasswordSourceInteractive(passprompts[pass_private_key].first,passprompts[pass_private_key].second);
 
965
    } else if(pass == "stdin") {
 
966
      passsources[pass_dest] = new Arc::PasswordSourceStream(&std::cin);
 
967
    } else {
 
968
      pos = pass.find(':');
 
969
      if(pos == std::string::npos) {
 
970
        logger.msg(Arc::ERROR, "Cannot parse password source %s "
 
971
                   "it must be of source_type or source_type:data format. "
 
972
                   "Supported source types are int,stdin,stream,file.", pass);
 
973
        return EXIT_FAILURE;
 
974
      }
 
975
      std::string data = pass.substr(pos + 1);
 
976
      pass.resize(pos);
 
977
      if(pass == "file") {
 
978
        passsources[pass_dest] = new PasswordSourceFile(data);
 
979
        // TODO: combine same files
 
980
      } else if(pass == "stream") {
 
981
        if(data == "0") {
 
982
          passsources[pass_dest] = new Arc::PasswordSourceStream(&std::cin);
 
983
        } else {
 
984
          logger.msg(Arc::ERROR, "Only standard input is currently supported "
 
985
                     "for password source.");
 
986
          return EXIT_FAILURE;
 
987
        }
 
988
      } else {
 
989
        logger.msg(Arc::ERROR, "Cannot parse password source type %s. "
 
990
                   "Supported source types are int,stdin,stream,file.", pass);
 
991
        return EXIT_FAILURE;
 
992
      }
 
993
    }
 
994
  }
 
995
  for(std::map<pass_destination_type, std::pair<std::string,bool> >::iterator p = passprompts.begin();
 
996
                            p != passprompts.end();++p) {
 
997
    if(passsources.find(p->first) == passsources.end()) {
 
998
      passsources[p->first] = new Arc::PasswordSourceInteractive(p->second.first,p->second.second);
 
999
    }
 
1000
  }
 
1001
 
855
1002
  //proxy validity period
856
1003
  //Set the default proxy validity lifetime to 12 hours if there is
857
1004
  //no validity lifetime provided by command caller
948
1095
  }
949
1096
  std::string myproxy_period = Arc::tostring(myproxyvalidityPeriod.GetPeriod());
950
1097
 
 
1098
  std::string signing_algorithm = constraints["signingAlgorithm"];
 
1099
  int keybits = 0;
 
1100
  if(!constraints["keybits"].empty()) {
 
1101
    if(constraints["keybits"] == "inherit") {
 
1102
      keybits = -1;
 
1103
    } else if((!Arc::stringto(constraints["keybits"],keybits)) || (keybits <= 0)) {
 
1104
      std::cerr << Arc::IString("The keybits constraint is wrong: %s.", (std::string)constraints["keybits"]) << std::endl;
 
1105
      return EXIT_FAILURE;
 
1106
    }
 
1107
  }
951
1108
 
952
1109
 
953
1110
#ifdef HAVE_NSS
1105
1262
    proxy_start = proxy_start - Arc::Period(300);
1106
1263
    proxy_period.SetPeriod(proxy_period.GetPeriod() + 300);
1107
1264
  }
1108
 
  std::string policy;
1109
 
  policy = constraints["proxyPolicy"].empty() ? constraints["proxyPolicyFile"] : constraints["proxyPolicy"];
 
1265
  std::string policy = constraints["proxyPolicy"].empty() ? constraints["proxyPolicyFile"] : constraints["proxyPolicy"];
1110
1266
 
1111
1267
  if (!myproxy_command.empty() && (myproxy_command != "put" && myproxy_command != "PUT" && myproxy_command != "Put")) {
1112
1268
    bool res = contact_myproxy_server(myproxy_server, myproxy_command, 
1133
1289
          Arc::Credential signer(proxy_path, proxy_path, "", "");
1134
1290
          std::string proxy_cert;
1135
1291
          create_proxy(proxy_cert, signer, policy, proxy_start, proxy_period, 
1136
 
              vomsacseq, use_gsi_proxy, 1024);
 
1292
              vomsacseq, use_gsi_proxy, keybits, signing_algorithm);
1137
1293
          write_proxy_file(proxy_path, proxy_cert);
1138
1294
        }
1139
1295
      }
1144
1300
 
1145
1301
  //Create proxy or voms proxy
1146
1302
  try {
1147
 
    Arc::Credential signer(cert_path, key_path, "", "");
 
1303
    Arc::Credential signer(cert_path, key_path, "", "", *passsources[pass_private_key]);
1148
1304
    if (signer.GetIdentityName().empty()) {
1149
1305
      std::cerr << Arc::IString("Proxy generation failed: No valid certificate found.") << std::endl;
1150
1306
      return EXIT_FAILURE;
1181
1337
 
1182
1338
    std::string proxy_cert;
1183
1339
    create_proxy(proxy_cert, signer, policy, proxy_start, proxy_period,      
1184
 
        vomsacseq, use_gsi_proxy, 1024);
 
1340
        vomsacseq, use_gsi_proxy, keybits, signing_algorithm);
1185
1341
 
1186
1342
    //If myproxy command is "Put", then the proxy path is set to /tmp/myproxy-proxy.uid.pid 
1187
1343
    if (myproxy_command == "put" || myproxy_command == "PUT" || myproxy_command == "Put")
1236
1392
 
1237
1393
static void create_proxy(std::string& proxy_cert, Arc::Credential& signer, 
1238
1394
    const std::string& proxy_policy, Arc::Time& proxy_start, Arc::Period& proxy_period, 
1239
 
    const std::string& vomsacseq, bool use_gsi_proxy, int keybits) {
 
1395
    const std::string& vomsacseq, bool use_gsi_proxy, int keybits,
 
1396
    const std::string& signing_algorithm) {
1240
1397
 
1241
1398
  std::string private_key, signing_cert, signing_cert_chain;
1242
1399
  std::string req_str;
 
1400
  if(keybits < 0) keybits = signer.GetKeybits();
1243
1401
 
1244
1402
  Arc::Credential cred_request(proxy_start, proxy_period, keybits);
 
1403
  cred_request.SetSigningAlgorithm(signer.GetSigningAlgorithm());
 
1404
 
 
1405
  if(!signing_algorithm.empty() && signing_algorithm != "inherit") {
 
1406
    if(signing_algorithm == "sha1") {
 
1407
      cred_request.SetSigningAlgorithm(Arc::SIGN_SHA1);
 
1408
    } else if(signing_algorithm == "sha2") {
 
1409
      cred_request.SetSigningAlgorithm(Arc::SIGN_SHA256);
 
1410
    } else if(signing_algorithm == "sha224") {
 
1411
      cred_request.SetSigningAlgorithm(Arc::SIGN_SHA224);
 
1412
    } else if(signing_algorithm == "sha256") {
 
1413
      cred_request.SetSigningAlgorithm(Arc::SIGN_SHA256);
 
1414
    } else if(signing_algorithm == "sha384") {
 
1415
      cred_request.SetSigningAlgorithm(Arc::SIGN_SHA384);
 
1416
    } else if(signing_algorithm == "sha512") {
 
1417
      cred_request.SetSigningAlgorithm(Arc::SIGN_SHA512);
 
1418
    } else {
 
1419
      throw std::runtime_error("Unknown signing algorithm specified: "+signing_algorithm);
 
1420
    }
 
1421
  }
1245
1422
  cred_request.GenerateRequest(req_str);
1246
1423
  cred_request.OutputPrivatekey(private_key);
1247
1424
  signer.OutputCertificate(signing_cert);
1577
1754
  //information about the existence of stored credentials 
1578
1755
  //on the myproxy server.
1579
1756
  try {
1580
 
    if (myproxy_command == "newpass" || myproxy_command == "NEWPASS" || myproxy_command == "Newpass" || myproxy_command == "NewPass") {
 
1757
    if (Arc::lower(myproxy_command) == "newpass") {
1581
1758
      if (myproxy_server.empty())
1582
1759
        throw std::invalid_argument("URL of MyProxy server is missing");
1583
1760
 
1587
1764
      if (user_name.empty())
1588
1765
        throw std::invalid_argument("Username to MyProxy server is missing");
1589
1766
 
1590
 
      std::string prompt1 = "MyProxy server";
1591
 
      char password[256];
1592
1767
      std::string passphrase;
1593
 
      int res = input_password(password, 256, false, prompt1, "", logger);
1594
 
      if (!res)
 
1768
      if(passsources[pass_myproxy]->Get(passphrase, 4, 256) != Arc::PasswordSource::PASSWORD) 
1595
1769
        throw std::invalid_argument("Error entering passphrase");
1596
 
      passphrase = password;
1597
1770
     
1598
 
      std::string prompt2 = "MyProxy server";
1599
 
      char newpassword[256];
1600
1771
      std::string newpassphrase;
1601
 
      res = input_password(newpassword, 256, true, prompt1, prompt2, logger);
1602
 
      if (!res)
 
1772
      if(passsources[pass_myproxy_new]->Get(newpassphrase, 4, 256) != Arc::PasswordSource::PASSWORD) 
1603
1773
        throw std::invalid_argument("Error entering passphrase");
1604
 
      newpassphrase = newpassword;
1605
1774
     
1606
1775
      if(usercfg.ProxyPath().empty() && !proxy_path.empty()) usercfg.ProxyPath(proxy_path);
1607
1776
      else {
1643
1812
      if (user_name.empty())
1644
1813
        throw std::invalid_argument("Username to MyProxy server is missing");
1645
1814
 
1646
 
      std::string prompt1 = "MyProxy server";
1647
 
      char password[256];
1648
1815
      std::string passphrase;
1649
 
      int res = input_password(password, 256, false, prompt1, "", logger);
1650
 
      if (!res)
 
1816
      if(passsources[pass_myproxy]->Get(passphrase, 4, 256) != Arc::PasswordSource::PASSWORD) 
1651
1817
        throw std::invalid_argument("Error entering passphrase");
1652
 
      passphrase = password;
1653
1818
 
1654
1819
      std::string respinfo;
1655
1820
 
1692
1857
      if (user_name.empty())
1693
1858
        throw std::invalid_argument("Username to MyProxy server is missing");
1694
1859
 
1695
 
      std::string prompt1 = "MyProxy server";
1696
 
      char password[256];
1697
 
 
1698
 
      std::string passphrase = password;
 
1860
      std::string passphrase;
1699
1861
      if(!use_empty_passphrase) {
1700
 
        int res = input_password(password, 256, false, prompt1, "", logger);
1701
 
        if (!res)
 
1862
        if(passsources[pass_myproxy]->Get(passphrase, 4, 256) != Arc::PasswordSource::PASSWORD)
1702
1863
          throw std::invalid_argument("Error entering passphrase");
1703
 
        passphrase = password;
1704
1864
      }
1705
1865
 
1706
1866
      std::string proxy_cred_str_pem;
1770
1930
  //Delegate the former self-delegated credential to
1771
1931
  //myproxy server
1772
1932
  try {
1773
 
    if (myproxy_command == "put" || myproxy_command == "PUT" || myproxy_command == "Put") {
 
1933
    if (Arc::lower(myproxy_command) == "put") {
1774
1934
      if (myproxy_server.empty())
1775
1935
        throw std::invalid_argument("URL of MyProxy server is missing");
1776
1936
      if(user_name.empty()) {
1780
1940
        throw std::invalid_argument("Username to MyProxy server is missing");
1781
1941
 
1782
1942
      std::string prompt1 = "MyProxy server";
1783
 
      std::string prompt2 = "MyProxy server";
1784
 
      char password[256];
1785
1943
      std::string passphrase;
1786
1944
      if(retrievable_by_cert.empty()) {
1787
 
        int res = input_password(password, 256, true, prompt1, prompt2, logger);
1788
 
        if (!res)
 
1945
        if(passsources[pass_myproxy_new]->Get(passphrase, 4, 256) != Arc::PasswordSource::PASSWORD)
1789
1946
          throw std::invalid_argument("Error entering passphrase");
1790
 
        passphrase = password;
1791
1947
      }
1792
1948
 
1793
1949
      std::string proxy_cred_str_pem;