From: Aki Tuomi Date: Sun, 17 May 2015 15:08:09 +0000 (+0300) Subject: Add support for token login in after startup X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~28^2~42^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24e0b3054595f89ce60c3d88cf4bd6c9640c1eaa;p=thirdparty%2Fpdns.git Add support for token login in after startup --- diff --git a/pdns/dynhandler.cc b/pdns/dynhandler.cc index de76b508d6..fa7651ac60 100644 --- a/pdns/dynhandler.cc +++ b/pdns/dynhandler.cc @@ -393,3 +393,24 @@ string DLPolicy(const vector&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&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(parts.size()); + } + + if (PKCS11ModuleSlotLogin(parts[1], boost::lexical_cast(parts[2]), parts[3])) { + return "logged in"; + } else { + return "could not log in, check logs"; + } +#endif +} diff --git a/pdns/dynhandler.hh b/pdns/dynhandler.hh index 4f112dec76..767332aa17 100644 --- a/pdns/dynhandler.hh +++ b/pdns/dynhandler.hh @@ -56,5 +56,6 @@ string DLNotifyRetrieveHandler(const vector&parts, Utility::pid_t ppid); string DLCurrentConfigHandler(const vector&parts, Utility::pid_t ppid); string DLListZones(const vector&parts, Utility::pid_t ppid); string DLPolicy(const vector&parts, Utility::pid_t ppid); +string DLTokenLogin(const vector&parts, Utility::pid_t ppid); uint64_t udpErrorStats(const std::string& str); #endif /* PDNS_DYNHANDLER_HH */ diff --git a/pdns/pkcs11signers.cc b/pdns/pkcs11signers.cc index 0a3380b36f..35007013dd 100644 --- a/pdns/pkcs11signers.cc +++ b/pdns/pkcs11signers.cc @@ -262,6 +262,8 @@ class Pkcs11Slot { CK_FUNCTION_LIST* f() { return d_functions; } pthread_mutex_t *m() { return &d_m; } + + static std::shared_ptr 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 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& pubAttributes, std::vector& privAttributes, CK_OBJECT_HANDLE_PTR pubKey, CK_OBJECT_HANDLE_PTR privKey) { @@ -613,25 +622,18 @@ class Pkcs11Token { static std::map > pkcs11_slots; static std::map > pkcs11_tokens; -std::shared_ptr Pkcs11Token::GetToken(const std::string& module, const CK_SLOT_ID& slotId, const std::string& label) { +std::shared_ptr 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(slotId)); - std::string sidx = tidx; - tidx.append("|"); - tidx.append(label); - std::map >::iterator tokenIter; + std::string sidx = module; + sidx.append("|"); + sidx.append(boost::lexical_cast(slotId)); std::map >::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(slotIter->second, label); - return pkcs11_tokens[tidx]; + return slotIter->second; } #ifdef HAVE_P11KIT1_V2 @@ -658,9 +660,21 @@ std::shared_ptr Pkcs11Token::GetToken(const std::string& module, co // store slot pkcs11_slots[sidx] = std::make_shared(functions, slotId); - // looks ok to me. - pkcs11_tokens[tidx] = std::make_shared(pkcs11_slots[sidx], label); + return pkcs11_slots[sidx]; +} +std::shared_ptr 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(slotId)); + tidx.append("|"); + tidx.append(label); + std::map >::iterator tokenIter; + if ((tokenIter = pkcs11_tokens.find(tidx)) != pkcs11_tokens.end()) return tokenIter->second; + + std::shared_ptr slot = Pkcs11Slot::GetSlot(module, slotId); + pkcs11_tokens[tidx] = std::make_shared(slot, label); return pkcs11_tokens[tidx]; } @@ -670,6 +684,7 @@ Pkcs11Token::Pkcs11Token(const std::shared_ptr& 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& slot, const std::str Pkcs11Token::~Pkcs11Token() { } +bool PKCS11ModuleSlotLogin(const std::string& module, int slotId, const std::string& pin) +{ + std::shared_ptr 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) {} diff --git a/pdns/pkcs11signers.hh b/pdns/pkcs11signers.hh index 97277a9d54..148d5ef724 100644 --- a/pdns/pkcs11signers.hh +++ b/pdns/pkcs11signers.hh @@ -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 */ diff --git a/pdns/receiver.cc b/pdns/receiver.cc index c7d6081a3b..35e8585bd2 100644 --- a/pdns/receiver.cc +++ b/pdns/receiver.cc @@ -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", " "); if(!::arg()["tcp-control-address"].empty()) { DynListener* dlTCP=new DynListener(ComboAddress(::arg()["tcp-control-address"], ::arg().asNum("tcp-control-port")));