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
 
 #include "conversation.h"
 
2fade7af
 namespace
 {
2ff5dc7c
 class impl : public conversation_ifc
 {
 private:
     pam pam_;
9b03a29b
     pam_conv_result conversation (const std::string &msg, int msg_style,
                                   const pam_request &request)
     {
12af5aef
         const pam_conv *conv;
         int get_conv_result = pam_.get_conv (request.handle(), &conv);
9b03a29b
 
12af5aef
         if (get_conv_result != PAM_SUCCESS) {
             return pam_conv_result {get_conv_result, PAM_CONV_ERR, std::vector<pam_response *>()};
         }
9b03a29b
 
12af5aef
         pam_message message;
         message.msg = const_cast<char *> (msg.c_str());
         message.msg_style = msg_style;
 
         std::vector<const pam_message *> messages;
         messages.push_back (&message);
         std::vector<pam_response *> responses (1);
 
         int conv_result = conv->conv (1, messages.data(),
9b03a29b
                                       responses.data(),
                                       conv->appdata_ptr);
12af5aef
 
         return pam_conv_result {get_conv_result, conv_result, responses};
     }
 
2ff5dc7c
 public:
     impl (pam &pam) : pam_ (pam) {}
     conversation_result initiate (const pam_request &request)
2fade7af
     {
cac488ec
         conversation_result result;
6de3846a
 
9b03a29b
         pam_conv_result reason_result (conversation ("Reason: ", PAM_PROMPT_ECHO_ON,
3eb69ad7
 						     request));
9b03a29b
 
12af5aef
         if (reason_result.get_conv_result != PAM_SUCCESS) {
cac488ec
             return result;
6f31174c
         }
 
12af5aef
         if (reason_result.conv_result == PAM_SUCCESS) {
             std::string reason (reason_result.responses[0]->resp);
11111aa0
             result.reason = reason;
cac488ec
         }
 
3eb69ad7
         pam_conv_result token_result (conversation ("Dual control token: ",
 						    PAM_PROMPT_ECHO_OFF, request));
 
         if (token_result.get_conv_result != PAM_SUCCESS) {
 	  return result;
         }
 
         if (reason_result.conv_result != PAM_SUCCESS) {
 	  return result;
aea12a9e
         }
 
12af5aef
         std::string token_answer (token_result.responses[0]->resp);
f3049f9f
         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
 }