python filenotfounderror_文件存在时出现FileNotFoundError(在当前脚本中创建时)

我正在尝试创建一个安全的(例如,SSL/HTTPS)XML-RPC客户机服务器。当我的系统上有所需的证书时,客户机-服务器部分可以完美地工作;但是,当我在执行过程中尝试创建证书时,即使证书清晰地存在,当打开ssl包装的套接字时,也会收到一个FileNotFoundError(因为前面的函数创建了他们。)

为什么文件存在时会给出FileNotFoundError?(如果我只是简单地关闭并重新启动python脚本,那么在打开套接字时不会产生任何错误,而且一切正常工作都不会有任何问题。)

我在其他地方寻找解决方案,但我找到的最好/最接近的答案可能是,创建证书和打开证书之间的“竞争条件”。但是,我尝试添加“sleep”来减轻竞争条件的可能性(以及通过用户输入菜单单独运行每个函数),每次都会出现相同的错误。在

我错过了什么?在

下面是我的代码片段:import os

import threading

import ssl

from xmlrpc.server import SimpleXMLRPCServer

import certs.gencert as gencert # <---- My python module for generating certs

...

rootDomain = "mydomain"

CERTFILE = "certs/mydomain.cert"

KEYFILE = "certs/mydomain.key"

...

def listenNow(ipAdd, portNum, serverCert, serverKey):

# Create XMLRPC Server, based on ipAdd/port received

server = SimpleXMLRPCServer((ipAdd, portNum))

# **THIS** is what causes the FileNotFoundError ONLY if

# the certificates are created during THE SAME execution

# of the program.

server.socket = ssl.wrap_socket(server.socket,

certfile=serverCert,

keyfile=serverKey,

do_handshake_on_connect=True,

server_side=True)

...

# Start server listening [forever]

server.serve_forever()

...

# Verify Certificates are present; if not present,

# create new certificates

def verifyCerts():

# If cert or key file not present, create new certs

if not os.path.isfile(CERTFILE) or not os.path.isfile(KEYFILE):

# NOTE: This [genert] will create certificates matching

# the file names listed in CERTFILE and KEYFILE at the top

gencert.gencert(rootDomain)

print("Certfile(s) NOT present; new certs created.")

else:

print("Certfiles Verified Present")

# Start a thread to run server connection as a daemon

def startServer(hostIP, serverPort):

# Verify certificates present prior to starting server

verifyCerts()

# Now, start thread

t = threading.Thread(name="ServerDaemon",

target=listenNow,

args=(hostIP,

serverPort,

CERTFILE,

KEYFILE

)

)

t.daemon = True

t.start()

if __name__ == '__main__':

startServer("127.0.0.1", 12345)

time.sleep(60) # <--To allow me to connect w/client before closing

当我在没有证书的情况下运行上述程序时,收到的错误是:

^{pr2}$

当我第二次重新运行脚本时(也就是说,启动时证书文件已经存在),一切都按预期运行,没有错误,我可以很好地连接我的客户机。在$ python3 test.py

Certfiles Verified Present

是什么阻止了ssl.wrap_套接字从查看/访问刚刚创建的文件(从而产生FileNotFoundError异常)开始执行此操作?在

编辑1:

感谢约翰·戈登的评论。这是一份gencert.py,由Atul Varm提供,可在此处找到https://gist.github.com/toolness/3073310import os

import sys

import hashlib

import subprocess

import datetime

OPENSSL_CONFIG_TEMPLATE = """

prompt = no

distinguished_name = req_distinguished_name

req_extensions = v3_req

[ req_distinguished_name ]

C = US

ST = IL

L = Chicago

O = Toolness

OU = Experimental Software Authority

CN = %(domain)s

emailAddress = varmaa@toolness.com

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE

keyUsage = nonRepudiation, digitalSignature, keyEncipherment

subjectAltName = @alt_names

[ alt_names ]

DNS.1 = %(domain)s

DNS.2 = *.%(domain)s

"""

MYDIR = os.path.abspath(os.path.dirname(__file__))

OPENSSL = '/usr/bin/openssl'

KEY_SIZE = 1024

DAYS = 3650

CA_CERT = 'ca.cert'

CA_KEY = 'ca.key'

# Extra X509 args. Consider using e.g. ('-passin', 'pass:blah') if your

# CA password is 'blah'. For more information, see:

#

# http://www.openssl.org/docs/apps/openssl.html#PASS_PHRASE_ARGUMENTS

X509_EXTRA_ARGS = ()

def openssl(*args):

cmdline = [OPENSSL] + list(args)

subprocess.check_call(cmdline)

def gencert(domain, rootdir=MYDIR, keysize=KEY_SIZE, days=DAYS,

ca_cert=CA_CERT, ca_key=CA_KEY):

def dfile(ext):

return os.path.join('domains', '%s.%s' % (domain, ext))

os.chdir(rootdir)

if not os.path.exists('domains'):

os.mkdir('domains')

if not os.path.exists(dfile('key')):

openssl('genrsa', '-out', dfile('key'), str(keysize))

# EDIT 3: mydomain.key gets output here during execution

config = open(dfile('config'), 'w')

config.write(OPENSSL_CONFIG_TEMPLATE % {'domain': domain})

config.close()

# EDIT 3: mydomain.config gets output here during execution

openssl('req', '-new', '-key', dfile('key'), '-out', dfile('request'),

'-config', dfile('config'))

# EDIT 3: mydomain.request gets output here during execution

openssl('x509', '-req', '-days', str(days), '-in', dfile('request'),

'-CA', ca_cert, '-CAkey', ca_key,

'-set_serial',

'0x%s' % hashlib.md5(domain +

str(datetime.datetime.now())).hexdigest(),

'-out', dfile('cert'),

'-extensions', 'v3_req', '-extfile', dfile('config'),

*X509_EXTRA_ARGS)

# EDIT 3: mydomain.cert gets output here during execution

print "Done. The private key is at %s, the cert is at %s, and the " \

"CA cert is at %s." % (dfile('key'), dfile('cert'), ca_cert)

if __name__ == "__main__":

if len(sys.argv) < 2:

print "usage: %s " % sys.argv[0]

sys.exit(1)

gencert(sys.argv[1])

编辑2:

关于John的评论,“这可能意味着正在创建这些文件,但不是在[I]expect“目录中:

当我在另一个窗口中打开目录时,我看到文件在执行过程中弹出到正确的位置。另外,当第二次运行test.py脚本时,文件将被标识为存在于正确(相同)的位置。这让我相信文件位置不是问题所在。谢谢你的建议。我会继续找的。在

编辑3:

我穿过了gencert.py在执行过程中,每个文件都在正确的时间正确地输出。我在上面的文件中指出了它们的确切输出时间,标记为“edit3”

当gencert暂停等待我的输入(原始输入)时,我可以毫无问题地在另一个程序中打开/查看/编辑提到的文件。在

另外,第一个测试.py实例运行(暂停,等待用户输入,就在我的域名.cert出现),我可以运行测试.py在另一个终端上,它可以看到/使用文件。在

但是,在第一个实例中,如果我继续这个程序,它将输出“FileNotFoundError”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值