]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add support for token login in after startup
authorAki Tuomi <cmouse@cmouse.fi>
Sun, 17 May 2015 15:08:09 +0000 (18:08 +0300)
committerAki Tuomi <cmouse@cmouse.fi>
Sun, 17 May 2015 15:10:33 +0000 (18:10 +0300)
pdns/dynhandler.cc
pdns/dynhandler.hh
pdns/pkcs11signers.cc
pdns/pkcs11signers.hh
pdns/receiver.cc

index de76b508d6dcefd67b8e4d746d0c65358716c37c..fa7651ac60a8721dea454fbb8c14eab11133e3ba 100644 (file)
@@ -393,3 +393,24 @@ string DLPolicy(const vector<string>&parts, Utility::pid_t ppid)
     return "no policy script loaded";
   }
 }
+
+#ifdef HAVE_P11KIT1
+extern bool PKCS11ModuleSlotLogin(const std::string& module, int slot, const std::string& pin);
+#endif
+
+string DLTokenLogin(const vector<string>&parts, Utility::pid_t ppid)
+{
+#ifndef HAVE_P11KIT1
+  return "PKCS#11 support not compiled in";
+#else
+  if (parts.size() != 4) {
+    return "invalid number of parameters, needs 4, got " + boost::lexical_cast<string>(parts.size());
+  }
+
+  if (PKCS11ModuleSlotLogin(parts[1], boost::lexical_cast<int>(parts[2]), parts[3])) {
+    return "logged in";
+  } else {
+    return "could not log in, check logs";
+  }
+#endif
+}
index 4f112dec766403c7610b9eab884ec2ca99862304..767332aa17e9d0cdfe62b356c74c9a03915e3b60 100644 (file)
@@ -56,5 +56,6 @@ string DLNotifyRetrieveHandler(const vector<string>&parts, Utility::pid_t ppid);
 string DLCurrentConfigHandler(const vector<string>&parts, Utility::pid_t ppid);
 string DLListZones(const vector<string>&parts, Utility::pid_t ppid);
 string DLPolicy(const vector<string>&parts, Utility::pid_t ppid);
+string DLTokenLogin(const vector<string>&parts, Utility::pid_t ppid);
 uint64_t udpErrorStats(const std::string& str);
 #endif /* PDNS_DYNHANDLER_HH */
index 0a3380b36fddfee33379c4db530dc13769e2469b..35007013dd4f6fc4dfcf9ae465d58cecc1742f8c 100644 (file)
@@ -262,6 +262,8 @@ class Pkcs11Slot {
     CK_FUNCTION_LIST* f() { return d_functions; }
 
     pthread_mutex_t *m() { return &d_m; }
+
+    static std::shared_ptr<Pkcs11Slot> GetSlot(const std::string& module, const CK_SLOT_ID& slotId);
 };
 
 class Pkcs11Token {
@@ -279,7 +281,7 @@ class Pkcs11Token {
     std::string d_ecdsa_params;
 
     std::string d_label;
-
+    bool d_loaded;
     CK_RV d_err;
 
     void logError(const std::string& operation) const {
@@ -294,9 +296,8 @@ class Pkcs11Token {
     ~Pkcs11Token();
 
     bool Login(const std::string& pin) {
-      if (pin.empty()) return CKR_PIN_INVALID; // no empty pin.
+      if (pin.empty()) return false; // no empty pin.
       Lock l(d_slot->m());
-
       if (d_slot->Login(pin) == true) {
         LoadAttributes();
       }
@@ -304,7 +305,13 @@ class Pkcs11Token {
       return LoggedIn();
     }
 
-    bool LoggedIn() const { return d_slot->LoggedIn(); }
+    bool LoggedIn() {
+      if (d_loaded == false && d_slot->LoggedIn() == true) {
+        Lock l(d_slot->m());
+        LoadAttributes();
+      }
+      return d_slot->LoggedIn();
+    }
 
     void LoadAttributes() {
       std::vector<P11KitAttribute> attr;
@@ -365,6 +372,8 @@ class Pkcs11Token {
       } else {
         throw PDNSException("Cannot load attributes for PCKS#11 public key " + d_label);
       }
+
+      d_loaded = true;
     }
 
     int GenerateKeyPair(CK_MECHANISM_PTR mechanism, std::vector<P11KitAttribute>& pubAttributes, std::vector<P11KitAttribute>& privAttributes, CK_OBJECT_HANDLE_PTR pubKey, CK_OBJECT_HANDLE_PTR privKey) {
@@ -613,25 +622,18 @@ class Pkcs11Token {
 static std::map<std::string, std::shared_ptr<Pkcs11Slot> > pkcs11_slots;
 static std::map<std::string, std::shared_ptr<Pkcs11Token> > pkcs11_tokens;
 
-std::shared_ptr<Pkcs11Token> Pkcs11Token::GetToken(const std::string& module, const CK_SLOT_ID& slotId, const std::string& label) {
+std::shared_ptr<Pkcs11Slot> Pkcs11Slot::GetSlot(const std::string& module, const CK_SLOT_ID& slotId) {
   // see if we can find module
-  std::string tidx = module;
-  tidx.append("|");
-  tidx.append(boost::lexical_cast<std::string>(slotId));
-  std::string sidx = tidx;
-  tidx.append("|");
-  tidx.append(label);
-  std::map<std::string, std::shared_ptr<Pkcs11Token> >::iterator tokenIter;
+  std::string sidx = module;
+  sidx.append("|");
+  sidx.append(boost::lexical_cast<std::string>(slotId));
   std::map<std::string, std::shared_ptr<Pkcs11Slot> >::iterator slotIter;
   CK_RV err;
   CK_FUNCTION_LIST* functions;
 
-  if ((tokenIter = pkcs11_tokens.find(tidx)) != pkcs11_tokens.end()) return tokenIter->second;
-
   // see if we have slot
   if ((slotIter = pkcs11_slots.find(sidx)) != pkcs11_slots.end()) {
-    pkcs11_tokens[tidx] = std::make_shared<Pkcs11Token>(slotIter->second, label);
-    return pkcs11_tokens[tidx];
+    return slotIter->second;
   }
 
 #ifdef HAVE_P11KIT1_V2
@@ -658,9 +660,21 @@ std::shared_ptr<Pkcs11Token> Pkcs11Token::GetToken(const std::string& module, co
   // store slot
   pkcs11_slots[sidx] = std::make_shared<Pkcs11Slot>(functions, slotId);
 
-  // looks ok to me.
-  pkcs11_tokens[tidx] = std::make_shared<Pkcs11Token>(pkcs11_slots[sidx], label);
+  return pkcs11_slots[sidx];
+}
 
+std::shared_ptr<Pkcs11Token> Pkcs11Token::GetToken(const std::string& module, const CK_SLOT_ID& slotId, const std::string& label) {
+  // see if we can find module
+  std::string tidx = module;
+  tidx.append("|");
+  tidx.append(boost::lexical_cast<std::string>(slotId));
+  tidx.append("|");
+  tidx.append(label);
+  std::map<std::string, std::shared_ptr<Pkcs11Token> >::iterator tokenIter;
+  if ((tokenIter = pkcs11_tokens.find(tidx)) != pkcs11_tokens.end()) return tokenIter->second;
+
+  std::shared_ptr<Pkcs11Slot> slot = Pkcs11Slot::GetSlot(module, slotId);
+  pkcs11_tokens[tidx] = std::make_shared<Pkcs11Token>(slot, label);
   return pkcs11_tokens[tidx];
 }
 
@@ -670,6 +684,7 @@ Pkcs11Token::Pkcs11Token(const std::shared_ptr<Pkcs11Slot>& slot, const std::str
   this->d_slot = slot;
   this->d_label = label;
   this->d_err = 0;
+  this->d_loaded = false;
   Lock l(d_slot->m());
   if (this->d_slot->LoggedIn()) LoadAttributes();
 }
@@ -677,6 +692,14 @@ Pkcs11Token::Pkcs11Token(const std::shared_ptr<Pkcs11Slot>& slot, const std::str
 Pkcs11Token::~Pkcs11Token() {
 }
 
+bool PKCS11ModuleSlotLogin(const std::string& module, int slotId, const std::string& pin)
+{
+  std::shared_ptr<Pkcs11Slot> slot;
+  slot = Pkcs11Slot::GetSlot(module, slotId);
+  if (slot->LoggedIn()) return true; // no point failing
+  return slot->Login(pin);
+}
+
 PKCS11DNSCryptoKeyEngine::PKCS11DNSCryptoKeyEngine(unsigned int algorithm): DNSCryptoKeyEngine(algorithm) {}
 PKCS11DNSCryptoKeyEngine::~PKCS11DNSCryptoKeyEngine() {}
 PKCS11DNSCryptoKeyEngine::PKCS11DNSCryptoKeyEngine(const PKCS11DNSCryptoKeyEngine& orig) : DNSCryptoKeyEngine(orig.d_algorithm) {}
index 97277a9d54937c31866fae19e95ce0ed133495e9..148d5ef7241259d1fc1cead4406a2f9dba75d9af 100644 (file)
@@ -44,4 +44,6 @@ class PKCS11DNSCryptoKeyEngine : public DNSCryptoKeyEngine
     static DNSCryptoKeyEngine* maker(unsigned int algorithm);
 };
 
+bool PKCS11ModuleSlotLogin(const std::string& module, int slot, const std::string& pin);
+
 #endif /* PDNS_PKCS11SIGNERS_HH */
index c7d6081a3b97af40fbac9e15f7e7d22d51241151..35e8585bd28a28a69b2378b824375fdbccbc709c 100644 (file)
@@ -558,6 +558,7 @@ int main(int argc, char **argv)
     DynListener::registerFunc("CURRENT-CONFIG",&DLCurrentConfigHandler, "retrieve the current configuration");
     DynListener::registerFunc("LIST-ZONES",&DLListZones, "show list of zones", "[master|slave|native]");
     DynListener::registerFunc("POLICY",&DLPolicy, "interact with policy engine", "[policy command]");
+    DynListener::registerFunc("TOKEN-LOGIN", &DLTokenLogin, "Login to a PKCS#11 token", "<module> <slot> <pin>");
 
     if(!::arg()["tcp-control-address"].empty()) {
       DynListener* dlTCP=new DynListener(ComboAddress(::arg()["tcp-control-address"], ::arg().asNum("tcp-control-port")));