Python-Pam错误输出 - SyntaxError:语法无效

时间:2018-05-23 22:13:39

标签: python python-3.x syntax-error pam

我正在使用Python 3并尝试安装pam,这是成功的。它安装了pam-0.1.4版本。

C:\Users\anjan>pip install pam
Collecting pam
  Downloading https://files.pythonhosted.org/packages/d6/cb/73c7725f4c7ee14205d85c6777a44f9b33e51d31fd5fc1bb0aa7f35cf8d2/pam-0.1.4.tar.gz
Building wheels for collected packages: pam
  Running setup.py bdist_wheel for pam ... done
  Stored in directory: C:\Users\anjan\AppData\Local\pip\Cache\wheels\24\8d\30\48fca5978b858d699565ee0cde875798229022bbb4e86e8b43
Successfully built pam
Installing collected packages: pam
Successfully installed pam-0.1.4

接下来,当我尝试导入pam时,它会抛出以下语法错误。看起来pam.py文件仍在Python2.x上。

有谁知道如何解决这个问题?

    >>> import pam
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\anjan\Anaconda3\lib\site-packages\pam.py", line 129
    print authenticate(getpass.getuser(), getpass.getpass())
                     ^
SyntaxError: invalid syntax

pam.py文件如下所示。

# (c) 2007 Chris AtLee <chris@atlee.ca>
# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license.php
"""
PAM module for python

Provides an authenticate function that will allow the caller to authenticate
a user against the Pluggable Authentication Modules (PAM) on the system.

Implemented using ctypes, so no compilation is necessary.
"""
__all__ = ['authenticate']

from ctypes import CDLL, POINTER, Structure, CFUNCTYPE, cast, pointer, sizeof
from ctypes import c_void_p, c_uint, c_char_p, c_char, c_int
from ctypes.util import find_library

LIBPAM = CDLL(find_library("pam"))
LIBC = CDLL(find_library("c"))

CALLOC = LIBC.calloc
CALLOC.restype = c_void_p
CALLOC.argtypes = [c_uint, c_uint]

STRDUP = LIBC.strdup
STRDUP.argstypes = [c_char_p]
STRDUP.restype = POINTER(c_char) # NOT c_char_p !!!!

# Various constants
PAM_PROMPT_ECHO_OFF = 1
PAM_PROMPT_ECHO_ON = 2
PAM_ERROR_MSG = 3
PAM_TEXT_INFO = 4

class PamHandle(Structure):
    """wrapper class for pam_handle_t"""
    _fields_ = [
            ("handle", c_void_p)
            ]

    def __init__(self):
        Structure.__init__(self)
        self.handle = 0

class PamMessage(Structure):
    """wrapper class for pam_message structure"""
    _fields_ = [
            ("msg_style", c_int),
            ("msg", POINTER(c_char)),
            ]

    def __repr__(self):
        return "<PamMessage %i '%s'>" % (self.msg_style, self.msg)

class PamResponse(Structure):
    """wrapper class for pam_response structure"""
    _fields_ = [
            ("resp", POINTER(c_char)),
            ("resp_retcode", c_int),
            ]

    def __repr__(self):
        return "<PamResponse %i '%s'>" % (self.resp_retcode, self.resp)

CONV_FUNC = CFUNCTYPE(c_int,
        c_int, POINTER(POINTER(PamMessage)),
               POINTER(POINTER(PamResponse)), c_void_p)

class PamConv(Structure):
    """wrapper class for pam_conv structure"""
    _fields_ = [
            ("conv", CONV_FUNC),
            ("appdata_ptr", c_void_p)
            ]

PAM_START = LIBPAM.pam_start
PAM_START.restype = c_int
PAM_START.argtypes = [c_char_p, c_char_p, POINTER(PamConv),
        POINTER(PamHandle)]

PAM_END = LIBPAM.pam_end
PAM_END.restpe = c_int
PAM_END.argtypes = [PamHandle, c_int]

PAM_AUTHENTICATE = LIBPAM.pam_authenticate
PAM_AUTHENTICATE.restype = c_int
PAM_AUTHENTICATE.argtypes = [PamHandle, c_int]

def authenticate(username, password, service='login'):
    """Returns True if the given username and password authenticate for the
    given service.  Returns False otherwise

    ``username``: the username to authenticate

    ``password``: the password in plain text

    ``service``: the PAM service to authenticate against.
                 Defaults to 'login'"""
    @CONV_FUNC
    def my_conv(n_messages, messages, p_response, app_data):
        """Simple conversation function that responds to any
        prompt where the echo is off with the supplied password"""
        # Create an array of n_messages response objects
        addr = CALLOC(n_messages, sizeof(PamResponse))
        p_response[0] = cast(addr, POINTER(PamResponse))
        for i in range(n_messages):
            if messages[i].contents.msg_style == PAM_PROMPT_ECHO_OFF:
                pw_copy = STRDUP(str(password))
                p_response.contents[i].resp = pw_copy
                p_response.contents[i].resp_retcode = 0
        return 0

    handle = PamHandle()
    conv = PamConv(my_conv, 0)
    retval = PAM_START(service, username, pointer(conv), pointer(handle))

    if retval != 0:
        # TODO: This is not an authentication error, something
        # has gone wrong starting up PAM
        PAM_END(handle, retval)
        return False

    retval = PAM_AUTHENTICATE(handle, 0)
    e = PAM_END(handle, retval)
    return retval == 0 and e == 0

if __name__ == "__main__":
    import getpass
    print authenticate(getpass.getuser(), getpass.getpass())

2 个答案:

答案 0 :(得分:0)

print是Python 3中的一个函数。

将其更改为

print(authenticate(getpass.getuser(), getpass.getpass()))
#    ^ Note the braces that make it a function call

编写它的方式仅在Python 2中有效。

答案 1 :(得分:0)

Pam 0.1.4用于python2,因此出错。 python3有一个pam,但它被称为simplepam -0.1.5。我想这应该是我的问题的一个可能的解决方案。 [link](pypi.org/project/simplepam)