Changeset 2785

Show
Ignore:
Timestamp:
03/05/06 21:35:03 (18 years ago)
Author:
jerome
Message:

Authentication can now be checked through PAM.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • pykota/trunk/bin/pknotify

    r2781 r2785  
    3131import xmlrpclib 
    3232 
     33try : 
     34    import PAM 
     35except ImportError :     
     36    hasPAM = 0 
     37else :     
     38    hasPAM = 1 
     39 
    3340from pykota.tool import Tool, PyKotaToolError, PyKotaCommandLineError, crashed, N_ 
    3441 
     
    5461                             user. Then pknotify will output the result. 
    5562                        
     63  -C | --checkauth           When --ask is used and an 'username' and a  
     64                             'password' are asked to the end user, then 
     65                             pknotify will try to authenticate the user 
     66                             through PAM. If authentified, this program 
     67                             will print "AUTH=YES", else "AUTH=NO". 
     68                             If a field is missing, "AUTH=IMPOSSIBLE" will 
     69                             be printed. 
     70                              
    5671  -c | --confirm             Tells pknotify to ask for either a confirmation                        
    5772                             or abortion. 
     
    7590                 VAR2NAME=VAR2VALUE 
    7691                 ... 
    77                  If the dialog was cancelled, nothing will be  
     92                 If the dialog was cancelled, nothing will be 
    7893                 printed. If one of the varname is 'password' 
    7994                 then this field is asked as a password (you won't 
    80                  see what you type in). 
     95                 see what you type in), and is NOT printed. Although 
     96                 it is not printed, it will be used to check if 
     97                 authentication is valid if you specify --checkauth. 
    8198                  
    8299    -c | --confirm : A single argument is expected, representing the 
     
    92109  pknotify -d client:7654 --confirm "This job costs :\n10 credits !" 
    93110   
    94   would display the cost of a print job and asks for confirmation. 
     111  Would display the cost of a print job and asks for confirmation. 
     112   
     113  pknotify --destination $PYKOTAJOBORIGINATINGHOSTNAME:7654 \\ 
     114           --checkauth --ask "Your name:username:" "Your password:password:" 
     115            
     116  Asks an username and password, and checks if they are valid.          
     117  NB : The PYKOTAJOBORIGINATINGHOSTNAME environment variable is 
     118  only set if you launch pknotify from cupspykota through a directive 
     119  in ~pykota/pykota.conf 
    95120""") 
    96121         
     
    101126        return xmlrpclib.Binary(msg.replace("\\n", "\n")) 
    102127         
     128    def convPAM(self, auth, queries, userdata) : 
     129        """Prepares PAM datas.""" 
     130        response = [] 
     131        for (query, qtype) in queries : 
     132            if qtype == PAM.PAM_PROMPT_ECHO_OFF : 
     133                response.append((self.password, 0)) 
     134            elif qtype in (PAM.PAM_PROMPT_ECHO_ON, PAM.PAM_ERROR_MSG, PAM.PAM_TEXT_INFO) : 
     135                self.printInfo("Unexpected PAM query : %s (%s)" % (query, qtype), "warn") 
     136                response.append(('', 0)) 
     137            else: 
     138                return None 
     139        return response 
     140 
     141    def checkAuth(self, username, password) :     
     142        """Checks if we could authenticate an username with a password.""" 
     143        if not hasPAM :     
     144            raise PyKotaCommandLineError, _("You MUST install PyPAM for this functionnality to work !") 
     145        else :     
     146            retcode = False 
     147            self.password = password 
     148            self.regainPriv() 
     149            auth = PAM.pam() 
     150            auth.start("passwd") 
     151            auth.set_item(PAM.PAM_USER, username) 
     152            auth.set_item(PAM.PAM_CONV, self.convPAM) 
     153            try : 
     154                auth.authenticate() 
     155                auth.acct_mgmt() 
     156            except PAM.error, resp : 
     157                self.printInfo(_("Authentication error for user %s : %s") % (username, resp), "warn") 
     158            except : 
     159                self.printInfo(_("Internal error : can't authenticate user %s") % username, "error") 
     160            else : 
     161                self.logdebug(_("Password correct for user %s") % username) 
     162                retcode = True 
     163            self.dropPriv()     
     164            return retcode 
     165             
    103166    def main(self, arguments, options) : 
    104167        """Notifies or asks questions to end users through PyKotIcon.""" 
     
    126189                if result["isValid"] : 
    127190                    for varname in varnames : 
    128                         print "%s=%s" % (varname.upper(), result[varname]) 
     191                        result[varname] = result[varname].data 
     192                        if (varname != "password") : 
     193                            print "%s=%s" % (varname.upper(), result[varname]) 
     194                    if options["checkauth"] : 
     195                        if ("username" in varnames) and ("password" in varnames) : 
     196                            if self.checkAuth(result["username"], result["password"]) : 
     197                                print "AUTH=YES" 
     198                            else :     
     199                                print "AUTH=NO" 
     200                        else :         
     201                            print "AUTH=IMPOSSIBLE" 
    129202            elif options["confirm"] : 
    130203                print server.showDialog(self.sanitizeMessage(arguments[0]), True) 
     
    142215        defaults = { \ 
    143216                   } 
    144         short_options = "vhd:acnq" 
     217        short_options = "vhd:acnqC" 
    145218        long_options = ["help", "version", "destination=", \ 
    146                         "ask", "confirm", "notify", "quit" ] 
     219                        "ask", "checkauth", "confirm", "notify", "quit" ] 
    147220         
    148221        # Initializes the command line tool 
     
    161234        options["notify"] = options["n"] or options["notify"] 
    162235        options["quit"] = options["q"] or options["quit"] 
     236        options["checkauth"] = options["C"] or options["checkauth"] 
    163237         
    164238        if options["help"] : 
     
    168242        elif (options["ask"] and (options["confirm"] or options["notify"])) \ 
    169243             or (options["confirm"] and (options["ask"] or options["notify"])) \ 
     244             or (options["checkauth"] and not options["ask"]) \ 
    170245             or (options["notify"] and (options["ask"] or options["confirm"])) : 
    171246            raise PyKotaCommandLineError, _("incompatible options, see help.")