git.fiddlerwoaroof.com
conversation.cc
7684972a
 /* Copyright (C) CJ Affiliate
  *
  * You may use, distribute and modify this code under  the
  * terms of the  GNU General Public License  version 2  or
  * later.
  *
  * You should have received a copy of the license with this
  * file. If not, you will find a copy in the "LICENSE" file
  * at https://github.com/cjdev/dual-control.
  */
 
7699d7ec
 #include <security/pam_modules.h>
01c00cfe
 #include <algorithm>
 #include <vector>
 #include <string>
7699d7ec
 
cac488ec
 #include "trace.h"
 
7699d7ec
 #include "conversation.h"
 
2fade7af
 namespace
 {
2ff5dc7c
 class impl : public conversation_ifc
 {
 private:
     pam pam_;
 public:
     impl (pam &pam) : pam_ (pam) {}
     conversation_result initiate (const pam_request &request)
2fade7af
     {
cac488ec
         conversation_result result;
11111aa0
         const pam_conv *token_conv;
         const pam_conv *reason_conv;
         int get_token_conv = pam_.get_conv (request.handle(), &token_conv);
         int get_reason_conv = pam_.get_conv (request.handle(), &reason_conv);
6de3846a
 
11111aa0
         if (get_token_conv != 0 || get_reason_conv != 0) {
cac488ec
             return result;
6f31174c
         }
 
cac488ec
         pam_message token_message;
         token_message.msg = const_cast<char *> ("Dual control token: ");
         token_message.msg_style = PAM_PROMPT_ECHO_OFF;
         pam_message reason_message;
         reason_message.msg = const_cast<char *> ("Reason: ");
         reason_message.msg_style = PAM_PROMPT_ECHO_OFF;
531238a7
 
11111aa0
         std::vector<const pam_message *> token_messages;
         token_messages.push_back (&token_message);
         std::vector<const pam_message *> reason_messages;
         reason_messages.push_back(&reason_message);
531238a7
 
11111aa0
         std::vector<pam_response *> token_responses (1);
         std::vector<pam_response *> reason_responses (1);
531238a7
 
11111aa0
         int token_result = token_conv->conv (1, token_messages.data(), token_responses.data(),
                                       token_conv->appdata_ptr);
         int reason_result = reason_conv->conv (1, reason_messages.data(), reason_responses.data(),
                                       reason_conv->appdata_ptr);
531238a7
 
11111aa0
         if (reason_result == PAM_SUCCESS) {
             std::string reason(reason_responses[0]->resp);
             result.reason = reason;
cac488ec
         }
 
11111aa0
         if (token_result != PAM_SUCCESS) {
            return result;
aea12a9e
         }
 
11111aa0
         std::string token_answer (token_responses[0]->resp);
         std::string::iterator delim = std::find (token_answer.begin(), token_answer.end(), ':');
2ff5dc7c
 
11111aa0
         if (delim == token_answer.end()) {
cac488ec
             return result;
2ff5dc7c
         }
6de3846a
 
11111aa0
         result.user_name = std::string (token_answer.begin(), delim);
         result.token = std::string (delim + 1, token_answer.end());
cac488ec
         return result;
2ff5dc7c
     }
 };
2fade7af
 }
 
da1b9b25
 conversation conversation::create (pam &pam)
2ff5dc7c
 {
     return conversation (std::shared_ptr<conversation_ifc> (new impl (pam)));
2fade7af
 }
6de3846a