#!/usr/bin/env python # # Copyright 2015 clowwindy # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from __future__ import absolute_import, division, print_function, \ with_statement import os import logging def find_library_nt(name): # type: (str) -> list """ find lib in windows in all the directory in path env :param name: can end with `.dll` or not :return: lib results list """ # modified from ctypes.util # ctypes.util.find_library just returns first result he found # but we want to try them all # because on Windows, users may have both 32bit and 64bit version installed results = [] for directory in os.environ['PATH'].split(os.pathsep): fname = os.path.join(directory, name) if os.path.isfile(fname): results.append(fname) if fname.lower().endswith(".dll"): continue fname = fname + ".dll" if os.path.isfile(fname): results.append(fname) return results def find_library(possible_lib_names, search_symbol, library_name): import ctypes.util from ctypes import CDLL paths = [] if type(possible_lib_names) not in (list, tuple): possible_lib_names = [possible_lib_names] lib_names = [] for lib_name in possible_lib_names: lib_names.append(lib_name) lib_names.append('lib' + lib_name) for name in lib_names: if os.name == "nt": paths.extend(find_library_nt(name)) else: path = ctypes.util.find_library(name) if path: paths.append(path) # always find lib on extend path that to avoid ```CDLL()``` failed on some strange linux environment # in that case ```ctypes.util.find_library()``` have different find path from ```CDLL()``` if True: # We may get here when find_library fails because, for example, # the user does not have sufficient privileges to access those # tools underlying find_library on linux. import glob for name in lib_names: patterns = [ '/usr/local/lib*/lib%s.*' % name, '/usr/lib*/lib%s.*' % name, 'lib%s.*' % name, '%s.dll' % name] for pat in patterns: files = glob.glob(pat) if files: paths.extend(files) for path in paths: try: lib = CDLL(path) if hasattr(lib, search_symbol): logging.info('loading %s from %s', library_name, path) return lib else: logging.warn('can\'t find symbol %s in %s', search_symbol, path) except Exception: if path == paths[-1]: raise return None def run_cipher(cipher, decipher): from os import urandom import random import time BLOCK_SIZE = 16384 rounds = 1 * 1024 plain = urandom(BLOCK_SIZE * rounds) results = [] pos = 0 print('test start') start = time.time() while pos < len(plain): l = random.randint(100, 32768) c = cipher.update(plain[pos:pos + l]) results.append(c) pos += l pos = 0 c = b''.join(results) results = [] while pos < len(plain): l = random.randint(100, 32768) results.append(decipher.update(c[pos:pos + l])) pos += l end = time.time() print('speed: %d bytes/s' % (BLOCK_SIZE * rounds / (end - start))) assert b''.join(results) == plain def test_find_library(): assert find_library('c', 'strcpy', 'libc') is not None assert find_library(['c'], 'strcpy', 'libc') is not None assert find_library(('c',), 'strcpy', 'libc') is not None assert find_library(('crypto', 'eay32'), 'EVP_CipherUpdate', 'libcrypto') is not None assert find_library('notexist', 'strcpy', 'libnotexist') is None assert find_library('c', 'symbol_not_exist', 'c') is None assert find_library(('notexist', 'c', 'crypto', 'eay32'), 'EVP_CipherUpdate', 'libc') is not None if __name__ == '__main__': test_find_library()