Ignore:
Timestamp:
Jul 20, 2016, 2:24:37 PM (4 years ago)
Author:
dcorreia
Message:

Added final step of configuration: pam-auth-update execution
Changed user-certificate mapping logic
Added documentation to config module
Code refactoring in config module

File:
1 moved

Legend:

Unmodified
Added
Removed
  • internals/2016/linuxloginsmartcardwizard/trunk/project1/config.py

    r16345 r16354  
    77
    88
    9 INSTALL_COMMAND = "apt-get install "
    10 HASHLINK_COMMAND = "pkcs11_make_hash_link"
    11 WGET_COMMAND = "wget "
    12 GUNZIP_COMMAND = "gunzip "
    13 MV_COMMAND = "mv "
    14 INSPECT_COMMAND = "pkcs11_inspect"
    15 PAMAUTHUP_COMMAND = "pam-auth-update"
     9INSTALL_COMMAND = "apt-get install "        # Package installation
     10HASHLINK_COMMAND = "pkcs11_make_hash_link"  # PKCS11 hash links creation
     11WGET_COMMAND = "wget "                      # Download file with wget
     12GUNZIP_COMMAND = "gunzip "                  # Extract zipped files with gunzip
     13MV_COMMAND = "mv "                          # Move/Rename file
     14INSPECT_COMMAND = "pkcs11_inspect"          # PKCS11 inspect card data
     15COMMONAUTH = "/etc/pam.d/common-auth"       # PAM file with authentication configurations
     16TRASH_OUTPUT = open(os.devnull, "wb")       # Send output to trash file
     17TEMP_OUTPUT = "/tmp/cardData"               # Send output to temporary file
     18USEMODULE_OPTION = "use_pkcs11_module"      # Configuration option to choose the active module
     19USEMAPPERS_OPTION = "use_mappers"           # Configuration option to choose the active mappers
     20# PKCS11 update for common-auth
     21PKCS11AUTH = "auth\tsufficient\tpam_pkcs11.so config_file=/etc/pam_pkcs11/pam_pkcs11.conf"
    1622
    1723
    1824def executeCommand(command, outputPath=None):
    19     '''
    20     Executes a shell command and redirects output if necessary
     25    """
     26    Executes a shell command and redirects output (optional)
    2127    :param command: command to execute
    22     :param outputPath: path to redirect output if necessary
    23     :return: no return value
    24     '''
     28    :param outputPath: path to redirect output (optional)
     29    :return: no return value
     30    """
    2531    try:
    2632        process = subprocess.Popen(command, shell=True, stdout=outputPath, stderr=subprocess.PIPE)
     
    3137
    3238
     39def executeCommandInDirectory(command, directoryPath, outputPath=None):
     40    """
     41    Executes a shell command in a specific directory and redirects output (optional)
     42    :param command: command to execute
     43    :param directoryPath: path of the directory
     44    :param outputPath: path to redirect output (optional)
     45    :return: no return value
     46    """
     47    oldDirectory = os.getcwd()
     48    os.chdir(directoryPath)
     49    executeCommand(command, outputPath)
     50    os.chdir(oldDirectory)
     51
     52
    3353def printDebugInfo(debugData):
    34     '''
     54    """
    3555    Prints debug information
    3656    :param debugData: string of debug data
    3757    :return: no return value
    38     '''
     58    """
    3959    print("DEBUG: %s - %s" % (inspect.stack()[1][3], debugData), file=sys.stderr)
    4060
    4161
    4262def installPackage(packageName):
    43     '''
     63    """
    4464    Installs package using apt-get
    4565    :param packageName: name of the package
    4666    :return: no return value
    47     '''
    48     command = INSTALL_COMMAND + packageName
    49     output = open(os.devnull, "wb")
    50     executeCommand(command, output)
     67    """
     68    executeCommand(INSTALL_COMMAND+packageName, TRASH_OUTPUT)
    5169
    5270
    5371def makeDirectory(directoryPath):
    54     '''
     72    """
    5573    Creates a new directory
    5674    :param directoryPath: path of the new directory
    5775    :return: no return value
    58     '''
     76    """
    5977    try:
    6078        os.mkdir(directoryPath)
     
    6583
    6684def copyFileToDirectory(filePath, directoryPath):
    67     '''
     85    """
    6886    Copy a file to a directory
    6987    :param filePath: path of the file to copy
    7088    :param directoryPath: path of the directory
    7189    :return: no return value
    72     '''
     90    """
    7391    try:
    7492        shutil.copy2(filePath, directoryPath)
     
    7795
    7896
     97def readFileToList(filePath):
     98    """
     99    Reads the file and returns a list with the content
     100    :param filePath: path of the file
     101    :return: list of strings with content of the file
     102    """
     103    return open(filePath, mode="r").readlines()
     104
     105
     106def readFileToString(filePath):
     107    """
     108    Reads a file and returns a string with the content
     109    :param filePath: path of the file
     110    :return: string of content of the file
     111    """
     112    return "".join(readFileToList(filePath))
     113
     114
     115def writeStringToFile(filePath, stringData):
     116    """
     117    Writes input string in the file
     118    :param filePath: path of the file
     119    :param stringData: string to write
     120    :return: no return value
     121    """
     122    open(filePath, mode="w").write(stringData)
     123
     124
     125def writeListToFile(filePath, listData):
     126    """
     127    Write input list of data in the file
     128    :param filePath: path of the file
     129    :param listData: list of data to write
     130    :return: no return value
     131    """
     132    writeStringToFile(filePath, "".join(listData))
     133
     134
     135def appendStringToFile(filePath, stringData):
     136    """
     137    Append input string to the end of the file
     138    :param filePath: path of the file
     139    :param stringData: string of data to write
     140    :return: no return value
     141    """
     142    open(filePath, mode="a").write(stringData)
     143
     144
    79145def makeHashLinks(directoryPath):
    80     '''
     146    """
    81147    Make pkcs11 hash links in a directory
    82148    :param directoryPath: path of directory
    83149    :return: no return value
    84     '''
    85     currentDirectoryPath = os.getcwd()
    86     os.chdir(directoryPath)
    87     executeCommand(HASHLINK_COMMAND)
    88     os.chdir(currentDirectoryPath)
     150    """
     151    executeCommandInDirectory(HASHLINK_COMMAND, directoryPath)
    89152
    90153
    91154def getCRLFile(crlWebLink, directoryPath):
    92     '''
     155    """
    93156    Download crl file into a directory
    94157    :param crlWebLink: link of the crl file
    95158    :param directoryPath: path of the directory
    96159    :return: no return value
    97     '''
    98     currentDirectoryPath = os.getcwd()
    99     os.chdir(directoryPath)
    100     executeCommand(WGET_COMMAND+crlWebLink)
    101     os.chdir(currentDirectoryPath)
     160    """
     161    executeCommandInDirectory(WGET_COMMAND+crlWebLink, directoryPath)
    102162
    103163
    104164def makeConfigFile(configZipPath, configPath, directoryPath):
    105     currentDirectoryPath = os.getcwd()
     165    """
     166    Make pam_pkcs11.conf configuration file
     167    :param configZipPath: path of the configuration file example zip archive
     168    :param configPath: path to store the configuration file
     169    :param directoryPath: path of the directory for shell commands execution
     170    :return: no return value
     171    """
    106172    copyFileToDirectory(configZipPath, directoryPath)
    107     os.chdir(directoryPath)
    108     executeCommand(GUNZIP_COMMAND+"pam_pkcs11.conf.example.gz")
    109     executeCommand(MV_COMMAND+"pam_pkcs11.conf.example "+configPath)
    110     os.chdir(currentDirectoryPath)
     173    executeCommandInDirectory(GUNZIP_COMMAND+"pam_pkcs11.conf.example.gz", directoryPath)
     174    executeCommandInDirectory(MV_COMMAND+"pam_pkcs11.conf.example "+configPath, directoryPath)
    111175
    112176
    113177def addConfigModule(moduleFileName, configPath):
    114     configData = open(configPath, mode="r").readlines()
    115     moduleData = open(moduleFileName, mode="r").readlines()
    116     old_last = configData[len(configData)-1]
    117     configData[len(configData)-1] = "".join(moduleData) + "\n" + old_last
    118     open(configPath,mode="w").write("".join(configData))
    119 
    120 
    121 def changeActiveModule(newModule, configPath):
    122     configData = open(configPath, mode="r").readlines()
    123     for i in range(0,len(configData)):
    124         if "use_pkcs11_module" in configData[i]:
    125             configData[i] = "  use_pkcs11_module = " + newModule + ";\n"
    126             break
    127     open(configPath, mode="w").write("".join(configData))
    128 
    129 
    130 def testInspect():
    131     executeCommand(INSPECT_COMMAND)
    132 
    133 
    134 def changeUseMappers(newValue, configPath):
    135     configData = open(configPath, mode="r").readlines()
    136     for i in range(0, len(configData)):
    137         if "use_mappers = " in configData[i]:
    138             configData[i] = "  #" + configData[i] + "  use_mappers = " + newValue + "\n"
    139             break
    140     open(configPath, mode="w").write("".join(configData))
    141 
    142 
    143 def getCardAuthCertificate(outputFilePath):
    144     executeCommand(INSPECT_COMMAND, open(outputFilePath, mode="w"))
    145     cardData = open(outputFilePath, mode="r").readlines()
    146     for i in range(0, len(cardData)):
    147         if "Autentica" in cardData[i] and "serialNumber=" in cardData[i]:
    148             open(outputFilePath, mode="w").write(cardData[i])
    149             break
    150 
    151 
    152 def addUserMapping(cardDataFilePath, mappingConfigPath, username):
    153     certificate = "".join(open(cardDataFilePath, mode="r").readlines()).strip()
    154     combo = certificate + " -> " + username + "\n"
    155     open(mappingConfigPath, mode="a").write(combo)
     178    """
     179    Add a configuration module to the pam_pkcs11.conf configuration file
     180    :param moduleFileName: name of the module data file
     181    :param configPath: path of the configuration file
     182    :return: no return value
     183    """
     184    configData = readFileToList(configPath)
     185    configData[-1] = readFileToString(moduleFileName) + "\n" + configData[-1]
     186    writeListToFile(configPath, configData)
     187
     188
     189def getIndexOfToken(token, listData):
     190    """
     191    Gets index of list element that contains the input token
     192    :param token: token to find
     193    :param listData: list of data
     194    :return: index where the token was found
     195    """
     196    for i in range(0, len(listData)):
     197        if token in listData[i]:
     198            return i
     199
     200
     201def setConfigurationOption(option, newValue, configPath):
     202    """
     203    Sets value of a configuration option
     204    :param option: the configuration option
     205    :param newValue: the new value to be set
     206    :param configPath: path of the configuration file
     207    :return: no return value
     208    """
     209    configData = readFileToList(configPath)
     210    moduleIndex = getIndexOfToken(option, configData)
     211    configData[moduleIndex] = "  " + option + " = " + newValue + ";\n"
     212    writeListToFile(configPath, configData)
     213
     214
     215def changeUseModule(newModule, configPath):
     216    """
     217    Changes module of the use_pkcs11_module configuration option
     218    :param newModule: new module to be used
     219    :param configPath: path of the configuration file
     220    :return: no return value
     221    """
     222    setConfigurationOption(USEMODULE_OPTION, newModule, configPath)
     223
     224
     225def changeUseMappers(newMappers, configPath):
     226    """
     227    Changes mappers of the use_mappers configuration option
     228    :param newMappers: new mappers to be used
     229    :param configPath: path of the configuration file
     230    :return: no return value
     231    """
     232    setConfigurationOption(USEMAPPERS_OPTION, newMappers, configPath)
     233
     234
     235def getCardAuthCertificate():
     236    """
     237    Gets authentication certificate from the card
     238    :return: certificate in string format
     239    """
     240    executeCommand(INSPECT_COMMAND, open(TEMP_OUTPUT, mode="w"))
     241    cardData = readFileToList(TEMP_OUTPUT)
     242    for line in cardData:
     243        if "Autentica" in line and "serialNumber=" in line:
     244            return line
     245
     246
     247def addUserMapping(mappingConfigPath, username):
     248    """
     249    Add a user mapping with a certificate
     250    :param mappingConfigPath: path of the mapping configurations file
     251    :param username: name of the user
     252    :return: True on success and False on failure
     253    """
     254    certificate = getCardAuthCertificate()
     255    if certificate is None:
     256        printDebugInfo("No certificate found. Make sure the card is inserted and the PIN is correct")
     257        return False
     258    else:
     259        combo = certificate.strip() + " -> " + username + "\n"
     260        appendStringToFile(mappingConfigPath, combo)
     261        return True
    156262
    157263
    158264def runPamAuthUpdate():
    159     executeCommand(PAMAUTHUP_COMMAND)
     265    """
     266    Simulates the execution of pam-auth-update to active pam_pkcs11 in the system
     267    :return: no return value
     268    """
     269    authData = readFileToList(COMMONAUTH)
     270    pkcs11Index = getIndexOfToken("pam_pkcs11.so", authData)
     271    unixIndex = getIndexOfToken("pam_unix.so", authData)
     272    if pkcs11Index is None:
     273        authData[unixIndex] = PKCS11AUTH + "\n" + authData[unixIndex]
     274        writeListToFile(COMMONAUTH, authData)
Note: See TracChangeset for help on using the changeset viewer.