My first attempt at using pysimplesoap (and my first attempt at soap) code
from pysimplesoap.client import SoapClient
j_location = 'http://api.jasperwireless.com/ws/schema'
j_xsd = 'http://api.jasperwireless.com/ws/schema/JasperAPI.xsd'
j_echo_wsdl = 'http://api.jasperwireless.com/ws/schema/Echo.wsdl'
j_billing_wsdl = 'http://api.jasperwireless.com/ws/schema/Billing.wsdl'
print 'Creating client'
myclient = SoapClient(wsdl=j_echo_wsdl)
print 'Target Namespace', myclient.namespace
The error
RuntimeError: No scheme given for url: JasperAPI.xsd
I'm not sure how I am supposed to resolve this error.
I guess the problem is because "JasperAPI.xsd" is referenced as a local file in the WSDL:
<xs:import namespace="http://api.jasperwireless.com/ws/schema" schemaLocation="JasperAPI.xsd"/>
I'm not entirely sure how schemaLocation is supposed to work. At least some software automatically transforms
schemaLocation="JasperAPI.xsd"
into
schemaLocation="http://api.jasperwireless.com/ws/schema/JasperAPI.xsd"
but at least libxml2 - which is used by most (all?) Python SOAP implementations - does not do this.
As a one-time quick fix you could try putting JasperAPI.xsd in your local working directory.
Related
I have been trying to configure proxy for a libtorent session; went through the documentation yet could not figure out a solution.
I tried the approach mentioned here. Did not work for me. This is the error I got-
r = lt.proxy_settings()
AttributeError: module 'libtorrent' has no attribute 'proxy_settings'. Did you mean: 'pe_settings'?
I tried to look for pe_settings() is the documentation but could not find anything like that. Being hopeful, I decided to do as the error message suggests, hoping it would lead me to some other error(from where i can pick up). Hence, I changed lt.proxy_settings() to lt.pe_settings(). The error that I get now is-
ses.set_dht_proxy(r)
Boost.Python.ArgumentError: Python argument types in
session.set_dht_proxy(session, pe_settings)
did not match C++ signature:
set_dht_proxy(libtorrent::session {lvalue}, libtorrent::aux::proxy_settings)
Mismatch in argument while trying to call the setters.
I also tried to use settings_pack. That did not work as well.
Here is what the session configuration looks like-
ses = lt.session()
ses.listen_on(6881, 6891)
r = lt.pe_settings()
r.proxy_hostnames = True
r.proxy_peer_connections = True
r.hostname = self.proxy_ip
r.username = ""
r.password = ""
r.port = self.proxy_port
r.type = lt.proxy_type_t().socks5_pw
#print lt.proxy_type().socks5_pw
#ses.set_dht_proxy(r)
#ses.set_peer_proxy(r)
#ses.set_tracker_proxy(r)
#ses.set_web_seed_proxy(r)
ses.set_proxy(r)
t = ses.settings()
t.force_proxy = True
t.proxy_hostnames = True
t.proxy_peer_connections = True
#t.proxy_tracker_connections = True
t.anonymous_mode = True
ses.set_settings(t)
print (ses.get_settings())
#ses.dht_proxy()
ses.peer_proxy()
#ses.tracker_proxy()
ses.web_seed_proxy()
ses.proxy()
ses.set_settings(t)
Any suggestions/ comments/ insights will be highly appreciated! Thanks!
Versions and platforms-
1. python 3.9
2. libtorrent 2.0.7 (installed it using vcpkg dependency manager)
3. mac os- Monterey
Vcpkg dependency manager installation steps
settings_pack documentation
you configure the proxy via the same settings_pack all other session-wide settings are configured via. Specifically you want to set:
proxy_hostname
proxy_port
proxy_type
Maybe proxy_username and proxy_password (docs)
I am building a Flask webapp and it uses the OpenBabel API (chemistry toolkit) to generate some files for me. When I call this particular function it seems to work fine and generate the files in the directory that I want. However, once it gets back to Flask it crashes and Flask does not render the html template, instead redirecting me to This page isn’t working 127.0.0.1 didn’t send any data. I found that when removing the code in the function it works normally. So it's likely a problem with OpenBabel. The Openbabel function does not ouput any errors itself and seemingly even returns at the end, based on debugging.
I have tried many things from other SO answers, including changing my host to 0.0.0.0, adding threaded=True and some other solutions. All to no avail. I tried debugging it for a long time, but now I am lost because I have tried everything I know. All I could get was a SystemExit exception from Flask. Sometimes it was able to run the print statement following it, but more often it crashes immediately. I have no clue where the problem may lie. Appreciate any help I can get. A sample of the code (shortened it a bit):
#app.route("/", methods=["POST", "GET"])
def form_handler():
if request.method == "POST":
smiles = request.form["smiles_molecule"]
pdb_file = request.files["pdb_molecule"]
no_conformers = int(request.form["no_conformers"])
scoring = request.form["score"]
if smiles:
pattern = re.compile('[^A-Za-z0-9]+')
smiles_no_special_chars = re.sub(pattern, "", smiles)
mol_path = os.path.join(app.config["MOLECULE_UPLOADS"], smiles_no_special_chars[0:10])
if os.path.exists(mol_path):
shutil.rmtree(mol_path)
os.mkdir(mol_path)
os.chdir(mol_path)
x = conf_gen.gen_and_write_confs(smiles, no_conformers, scoring) #<- breaks down here
print(x)
return render_template("index.html", mole=smiles_no_special_chars[0:10])
The function that is called:
def gen_and_write_confs(molecule, no_confs, scoring):
"""Generate and write the conformers to PDB. Takes mol, number of conformers and
scoring method: RCS, MECS and ECS: OBRMSDConformerScore,
OBMinimizingEnergyConformerScore and OBEnergyConformerScore. See OpenBabel docs."""
mole = pybel.readstring("can", molecule)
mole.addh()
mole.make3D()
mole = mole.OBMol
mole.SetChainsPerceived(True)
cs_obj = ob.OBConformerSearch()
cs_obj.Setup(mole, no_confs, 5, 5, 25)
if scoring == "RCS":
score = ob.OBRMSDConformerScore()
elif scoring == "MECS":
score = ob.OBMinimizingEnergyConformerScore()
else:
score = ob.OBEnergyConformerScore()
cs_obj.SetScore(score)
cs_obj.Search()
cs_obj.GetConformers(mole)
mole.DeleteNonPolarHydrogens()
return "Test"
If needed I can upload the project on Github. It does require installing a few dependencies and I am using conda for that right now, but I could make it available through pip too since OpenBabel is available in pip.
Ps: no single error message is shown after it crashes
I try to download a serie of text files from different websites. I am using urllib.request with Python. I want to expend the list of URL without making the code long.
The working sequence is
import urllib.request
url01 = 'https://web.site.com/this.txt'
url02 = 'https://web.site.com/kind.txt'
url03 = 'https://web.site.com/of.txt'
url04 = 'https://web.site.com/link.txt'
[...]
urllib.request.urlretrieve(url01, "Liste n°01.txt")
urllib.request.urlretrieve(url02, "Liste n°02.txt")
urllib.request.urlretrieve(url03, "Liste n°03.txt")
[...]
The number of file to download is increasing and I want to keep the second part of the code short.
I tried
i = 0
while i<51
i = i +1
urllib.request.urlretrieve( i , "Liste n°0+"i"+.txt")
It doesn't work and I am thinking that a while loop can be use for string but not for request.
So I was thinking of making it a function.
def newfunction(i)
return urllib.request.urlretrieve(url"i", "Liste n°0"+1+".txt")
But it seem that I am missing a big chunk of it.
This request is working but it seem I cannot transform it for long list or URL.
As a general suggestion, I'd recommend the requests module for Python, rather than urllib.
Based on that, some naive code for a possible function:
import requests
def get_file(site, filename):
target = site + "/" + filename
try:
r = requests.get(target, allow_redirects=True)
open(filename, 'wb').write(r.content)
return r.status_code
except requests.exceptions.RequestException as e:
print("File not downloaded, error: {}".format(e))
You can then call the function, passing in parameters of site and file name:
get_file('https://web.site.com', 'this.txt')
The function will raise an exception, but not stop execution, if it cannot download a file. You could expand exception handling to deal with files not being writable, but this should be a start.
It seems as if you're not casting the variable i to an integer before your concatenating it to the url string. That may be the reason why you're code isn't working. The while-loop/for-loop approach shouldn't effect whether or not the requests get sent out. I recommend using the requests module for making requests as well. Mike's post covers what the function should kind of look like. I also recommend creating a sessions object if you're going to be making a whole lot of requests in a piece of code. The sessions object will keep the underlying TCP connection open while you make your requests, which should reduce latency, CPU usage, and network congestion (https://en.wikipedia.org/wiki/HTTP_persistent_connection#Advantages). The code would look something like this:
import requests
with requests.Session() as s:
for i in range(10):
s.get(str(i)+'.com') # make request
# write to file here
To cast to a string you would want something like this:
i = 0
while i<51
i = i +1
urllib.request.urlretrieve( i , "Liste n°0" + str(i) + ".txt")
I need to verify an xml signature contained in the answer to a POST request.
The signature is defined by:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>htti3M3ikfm2RooDTNo3Kv7g0K2ongShUfCDUAWpytc=</DigestValue>
</Reference>
</SignedInfo>
and is against a custom CA.
I have no way to change the answer (it is issued by a State Agency) and all my attempts to verify against the certificate supposedly used to sign did result in errors.
One of my attempts has been using the following short test program:
#!/usr/bin/python3
import signxml
cf = 'certificate.cer'
with open(cf, 'r') as fi:
cer = fi.read()
ver = signxml.XMLVerifier()
f = 'response.xml'
with open(f, 'rb') as fi:
xml = fi.read()
try:
vd = ver.verify(xml, x509_cert=cer)
print('OK')
except signxml.exceptions.InvalidSignature as e:
print(e)
This results in:
Signature verification failed: wrong signature length
Other variations have different errors including:
Signature verification failed: invalid padding
and:
unable to get local issuer certificate
I am a seasoned programmer, but NOT a cryptography expert, so it's quite likely I forgot something trivial (to the knowledgeable).
Please point me in the right direction.
Note:: if required I can provide a full example (of failure) as certificate/answer are not "secret".
Unfortunately things are always a bit more complex than expected.
Answer from #stovfl completely missed the relevant point: I need to verify against a non-standard CA.
I already was struggling to use sigxml package, and I had to overcome the following problems:
sigxml will not work (for me) with plain xml.etree; I had to use lxml.etree with a different syntax.
sigxml installed by plain pip3 install sigxml would bomb with a deprecation error; I had to get latest (non-tagged master) from github with pip3 install git+https://github.com/XML-Security/signxml.git.
Examples on sigxml site completely disregard python3 issues with str vs. bytes.
CA Authority used to sign the Certificate I used to sign the outgoing message is different from the CA Authority used to sign response (I have no way to change this!).
This story has an Happy Ending though.
The following test program works (for me):
from signxml import XMLSigner, XMLVerifier, InvalidCertificate
from lxml import etree
outCAroot = 'outCAroot.pem'
inCAroot = 'inCAroot.pem'
cert = open("example.pem").read().encode()
key = open("example.key").read().encode()
file_name = 'test.tosend'
resp_name = 'test.rsp'
xml = etree.parse(file_name) # (data_to_sign)
signer = XMLSigner(c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315')
signed_xml = signer.sign(xml, key=key, cert=cert)
try:
result = XMLVerifier().verify(signed_xml, ca_pem_file=outCAroot)
except InvalidCertificate as e:
print(e)
else:
print('outgoing signature Ok.')
# here I send signed_xml to remote server and get the response (NO ERRORS!)
answer_xml = etree.parse(resp_name) # (signed answer)
try:
result = XMLVerifier().verify(answer_xml, ca_pem_file=inCAroot)
except InvalidCertificate as e:
print(e)
else:
print('incoming signature Ok.')
print('===================')
print(result.signed_data.decode())
print('===================')
I hope this will help whoever is (or will be) in my situation.
Question: I need to verify an xml signature contained in the answer to a POST request.
Do it, like the example in the Documentation SignXML: XML Signature in Python:
SignXML uses the ElementTree API (also supported by lxml) to work with XML data.
from signxml import XMLSigner, XMLVerifier
from xml.etree import ElementTree
cert = open("example.pem").read()
key = open("example.key").read()
xml = ElementTree.parse(file_name) #(data_to_sign)
signed_xml = XMLSigner().sign(xml, key=key, cert=cert)
result = XMLVerifier().verify(signed_xml)
XMLVerifier().verify(...)
Verify the XML signature supplied in the data and return the XML node signed by the signature, or raise an exception if the signature is not valid.
class signxml.VerifyResult
The results of a verification return the signed data, the signed xml and the signature xml
Note: Necessarily read about See what is signed and Establish trust!
Relevant: Python elementtree find function reads Signature as empty (None)
I am using M2Crypto-0.20.2. I want to use engine_pkcs11 from the OpenSC project and the Aladdin PKI client for token based authentication making xmlrpc calls over ssl.
from M2Crypto import Engine
Engine.load_dynamic()
dynamic = Engine.Engine('dynamic')
# Load the engine_pkcs from the OpenSC project
dynamic.ctrl_cmd_string("SO_PATH", "/usr/local/ssl/lib/engines/engine_pkcs11.so")
Engine.cleanup()
Engine.load_dynamic()
# Load the Aladdin PKI Client
aladdin = Engine.Engine('dynamic')
aladdin.ctrl_cmd_string("SO_PATH", "/usr/lib/libeTPkcs11.so")
key = aladdin.load_private_key("PIN","password")
This is the error I receive:
key = pkcs.load_private_key("PIN","eT0ken")
File "/usr/local/lib/python2.4/site-packages/M2Crypto/Engine.py", line 70, in load_private_key
return self._engine_load_key(m2.engine_load_private_key, name, pin)
File "/usr/local/lib/python2.4/site-packages/M2Crypto/Engine.py", line 60, in _engine_load_key
raise EngineError(Err.get_error())
M2Crypto.Engine.EngineError: 23730:error:26096075:engine routines:ENGINE_load_private_key:not initialised:eng_pkey.c:112:
For load_private_key(), what should be passed as the first argument? The M2Crypto documentation does not explain it.
I don't get any errors loading the engines, but I'm not sure if I'm loading them correctly. It seems like the engine ID has to be a specific name but I don't find that list anywhere. 'dynamic' is working for me.
Any help would be appreciated!
Found !!!!
Yes, exactly the way where I came from.
So, actually the ENGINE_init() is not implemented in M2Crypto.Engine. So, only one solution: patching!!! (very small...) so I've created a new Engine method (in Engine.py)
def engine_initz(self):
"""Return engine name"""
return m2.engine_initz(self._ptr)
Why engine_initz ? because engine_init is already define in SWIG/_engine.i,:
void engine_init(PyObject *engine_err) {
Py_INCREF(engine_err);
_engine_err = engine_err;
}
I don't really know what is done, so I've prefered creating a new one... So I've just added the following to SWIG/_engine.i:
%rename(engine_initz) ENGINE_init;
extern int ENGINE_init(ENGINE *);
And recompile the __m2crypto.so, now just add a "pkcs11.engine_initz()" before launching the private key, and it works.....
I don't know what and why the engine_init code present in current M2Crypto is supposed to do. Exposing ENGINE_init() as engine_init2 with the following patch to M2Crypto helps:
Index: SWIG/_engine.i
===================================================================
--- SWIG/_engine.i (revision 719)
+++ SWIG/_engine.i (working copy)
## -44,6 +44,9 ##
%rename(engine_free) ENGINE_free;
extern int ENGINE_free(ENGINE *);
+%rename(engine_init2) ENGINE_init;
+extern int ENGINE_init(ENGINE *);
+
/*
* Engine id/name functions
*/
After this, the following code takes me further (but urllib does not fully work for me currently):
import sys, os, time, cgi, urllib, urlparse
from M2Crypto import m2urllib2 as urllib2
from M2Crypto import m2, SSL, Engine
# load dynamic engine
e = Engine.load_dynamic_engine("pkcs11", "/Users/martin/prefix/lib/engines/engine_pkcs11.so")
pk = Engine.Engine("pkcs11")
pk.ctrl_cmd_string("MODULE_PATH", "/Library/OpenSC/lib/opensc-pkcs11.so")
m2.engine_init2(m2.engine_by_id("pkcs11")) # This makes the trick
cert = e.load_certificate("slot_01-id_01")
key = e.load_private_key("slot_01-id_01", sys.argv[1])
ctx = SSL.Context("sslv23")
ctx.set_cipher_list("HIGH:!aNULL:!eNULL:#STRENGTH")
ctx.set_session_id_ctx("foobar")
m2.ssl_ctx_use_x509(ctx.ctx, cert.x509)
m2.ssl_ctx_use_pkey_privkey(ctx.ctx, key.pkey)
opener = urllib2.build_opener(ctx)
urllib2.install_opener(opener)
Looking at the pastebin link Becky provided, I believe it translates to something like this in the new API:
from M2Crypto import Engine, m2
dynamic = Engine.load_dynamic_engine("pkcs11", "/Users/martin/prefix/lib/engines/engine_pkcs11.so")
pkcs11 = Engine.Engine("pkcs11")
pkcs11.ctrl_cmd_string("MODULE_PATH", "/Library/OpenSC/lib/opensc-pkcs11.so")
r = pkcs11.ctrl_cmd_string("PIN", sys.argv[1])
key = pkcs11.load_private_key("id_01")
So I am betting that if you substitute "/Users/martin/prefix/lib/engines/engine_pkcs11.so" with "/usr/local/ssl/lib/engines/engine_pkcs11.so" and "/Library/OpenSC/lib/opensc-pkcs11.so" with "/usr/lib/libeTPkcs11.so" you might get it to work with Aladdin.
That is exactly the code I've tried. But It ended with the following error:
Traceback (most recent call last):
File "prog9.py", line 13, in <module>
key = pkcs11.load_private_key("id_45")
File "/usr/lib/pymodules/python2.5/M2Crypto/Engine.py", line 70, in load_private_key
return self._engine_load_key(m2.engine_load_private_key, name, pin)
File "/usr/lib/pymodules/python2.5/M2Crypto/Engine.py", line 60, in _engine_load_key
raise EngineError(Err.get_error())
M2Crypto.Engine.EngineError: 11814:error:26096075:engine outines:ENGINE_load_private_key:not initialised:eng_pkey.c:112:
I'm using OpenSC PKCS11 lib, not aladdin lib. But I don't think the problem is closed.
I tried the code that Heikki suggested (minus one line) and got the same error as Erlo. For load_private_key(), how do I know what to put in for the argument?
dynamic = Engine.load_dynamic_engine("pkcs11", "/usr/local/ssl/lib/engines/engine_pkcs11.so")
# m2.engine_free(dynamic) this line gave me an error TypeError: in method 'engine_free', argument 1 of type 'ENGINE *'
pkcs11 = Engine.Engine("pkcs11")
pkcs11.ctrl_cmd_string("MODULE_PATH", "/usr/lib/libeTPkcs11.so")
r = pkcs11.ctrl_cmd_string("PIN", "password")
key = pkcs11.load_private_key("id_01")
I think the problem is not really the "load_private_key()". It's like something is missing between "MODULE_PATH" definition and the load_private_key() call. What happen if you remplace "/usr/lib/libeTPkcs11.so" by a wrong path ? In my case I have no error related to this.
I've run "pcscd" in foreground with high debug level, there is no call to smartcard during the python execution... So definitly, I don't understand what's wrong...
The equivalent in "openssl" is using "-pre" command. The "-pre" (by opposite to the "-post") are command sent to the engine before loading. Perhaps we need to call a methode which "load" the engine after all "ctrl_cmd_string" calls ?? ...
Lost :-/