WSDL and complex type definitions

60 views
Skip to first unread message

James Connell

unread,
May 3, 2005, 6:55:53 PM5/3/05
to soa...@googlegroups.com
I am trying to integrate paypal web services. In their wsdl
definition, they define types in a seperate xsd file like so:

(in http://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl )
<xs:element name="TransactionID" type="ebl:TransactionId" />

were ebl types are defined at:
http://www.sandbox.paypal.com/wsdl/eBLBaseComponents.xsd

How do I include the xsd file so that SOAP::WDSLDriverFactory will
understand these types?

NAKAMURA, Hiroshi

unread,
May 3, 2005, 9:06:08 PM5/3/05
to soa...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,
The latest snapshot should read that... arg, I found a bug of soap4r.
PayPalSvc WSDL uses xsd:import, not wsdl:import and there's the bug in
xsd:import.

When I fixed this problem, I found another one. eBLBaseComponents.xsd
and CoreComponentTypes.xsd are importing each other and soap4r cannot
detect the loop...

I'll fix it tonight. Please wait for a while.

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)

iD8DBQFCeCAAf6b33ts2dPkRArppAKDHRYJLMTmcwJRie8VNMySMXtbyQgCfRwIj
a/NaPgGi1ZfJBPHS22CXAdU=
=exPE
-----END PGP SIGNATURE-----

NAKAMURA, Hiroshi

unread,
May 4, 2005, 10:37:05 PM5/4/05
to soa...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

NAKAMURA, Hiroshi wrote:
>>>(in http://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl )

> The latest snapshot should read that... arg, I found a bug of soap4r.
> PayPalSvc WSDL uses xsd:import, not wsdl:import and there's the bug in
> xsd:import.
>
> When I fixed this problem, I found another one. eBLBaseComponents.xsd
> and CoreComponentTypes.xsd are importing each other and soap4r cannot
> detect the loop...
>
> I'll fix it tonight. Please wait for a while.

Updated snapshot tarball is at http://dev.ctor.org/download/

% ruby -rsoap/wsdlDriver -e 'SOAP::WSDLDriverFactory.new(
"http://sandbox.paypal.com/wsdl/PayPalSvc.wsdl"
).create_rpc_driver'

should not raise any error (2 warnings) though I didn't test the actual
service. Would you please try it at your leisure?

I think you may consider to use wsdl2ruby.rb instead of soap/wsdlDriver
for complex service like this (fetching and parsing schema definition
files for each time is flexible for service change but is time
consuming...).

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)

iD8DBQFCeYbRf6b33ts2dPkRAmOfAKDF/Kwi5h9tNCIfFbFU5hSgM02X9QCaAnst
h6HXHgI5MrUaSVxDgebNgNs=
=z3Fm
-----END PGP SIGNATURE-----

James Connell

unread,
May 5, 2005, 6:26:31 PM5/5/05
to soa...@googlegroups.com
Thank you very much. I will certainly try this out and let you know if
anything strange happens.

-James Connell

NAKAMURA, Hiroshi

unread,
May 5, 2005, 9:48:01 PM5/5/05
to soa...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi James,

James Connell wrote:
> Thank you very much. I will certainly try this out and let you know if
> anything strange happens.

Thanks in advance. Support of document/literal service such as this
PayPalSvc is the key feature of soap4r-1.5.4, which will be released
soon (and hopefully included in ruby-1.8.3.) Feel free to ask me here
anything strange behavior about it.

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)

iD8DBQFCeszRf6b33ts2dPkRAij6AJ0bLfpCjksMnxQ5SxzL2E1YeLi8pgCeM73R
MTR9Kyw6m+xlmeAmzmZ+dpg=
=b/5p
-----END PGP SIGNATURE-----

James Connell

unread,
May 8, 2005, 7:43:45 PM5/8/05
to soa...@googlegroups.com
first thing I encountered, I assume I am misssing an option for ssl:

================================
irb(main):117:0> soap.getTransactionDetails(req)
Wire dump:

opening connection to api.sandbox.paypal.com...
opened
warning: peer certificate won't be verified in this SSL session.
closed
OpenSSL::SSL::SSLError: sslv3 alert handshake failure
from c:/ruby/lib/ruby/site_ruby/1.8/net/protocols.rb:48:in
`connect'
from c:/ruby/lib/ruby/site_ruby/1.8/net/protocols.rb:48:in
`ssl_connect'

from c:/ruby/lib/ruby/site_ruby/1.8/net/https.rb:175:in
`on_connect'
from c:/ruby/lib/ruby/1.8/net/http.rb:433:in `do_start'
from c:/ruby/lib/ruby/1.8/net/http.rb:419:in `start'
from c:/ruby/lib/ruby/1.8/soap/netHttpClient.rb:115:in `start'
from c:/ruby/lib/ruby/1.8/soap/netHttpClient.rb:92:in `post'
from c:/ruby/lib/ruby/1.8/soap/streamHandler.rb:164:in
`send_post'
from c:/ruby/lib/ruby/1.8/soap/streamHandler.rb:106:in `send'
from c:/ruby/lib/ruby/1.8/soap/rpc/proxy.rb:146:in `route'
from c:/ruby/lib/ruby/1.8/soap/rpc/proxy.rb:121:in `call'
from c:/ruby/lib/ruby/1.8/soap/rpc/driver.rb:159:in `call'
from c:/ruby/lib/ruby/1.8/soap/rpc/driver.rb:212:in
`getTransactionDetai
ls'
from c:/ruby/lib/ruby/1.8/soap/rpc/driver.rb:207:in
`getTransactionDetai
ls'
from (irb):117
irb(main):118:0>
===============================

Also, how do I go about generating the header, which looks like this:

<SOAP-ENV:Header>
<RequesterCredentials xmlns="urn:ebay:api:PayPalAPI"
xsi:type="ebl:CustomSecurityHeaderType">
<Credentials xmlns="urn:ebay:apis:eBLBaseComponents"
xsi:type="ebl:UserIdPasswordType">
<Username xsi:type="xs:string">api_username</Username>
<Password xsi:type="xs:string">api_password</Password>
<Subject
xsi:type="xs:string">authorizing_account_emailaddress</Subject>
</Credentials>
</RequesterCredentials>
</SOAP-ENV:Header>

I assume I have to override SOAP::Header::Simplehander, but i have no
idea how do use this in a more complex case (i have seen the example
for Google adwords)... any ideas?

NAKAMURA, Hiroshi

unread,
May 9, 2005, 1:01:21 AM5/9/05
to soa...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

James Connell wrote:
> first thing I encountered, I assume I am misssing an option for ssl:
>
> ================================
> irb(main):117:0> soap.getTransactionDetails(req)
> Wire dump:
>
> opening connection to api.sandbox.paypal.com...
> opened
> warning: peer certificate won't be verified in this SSL session.
> closed
> OpenSSL::SSL::SSLError: sslv3 alert handshake failure
> from c:/ruby/lib/ruby/site_ruby/1.8/net/protocols.rb:48:in
> `connect'

Hmm. The site https://api-aa.sandbox.paypal.com/2.0/ seems to require
SSL client authentication. You should have a valid X.509 digital
certificate issued from PayPalSvc, and a key. client.pem and
client.key, right?

First you need to install http-access2 to use SSL with soap4r. And you
need to do some extra setting about SSL client authentication. A sample
of SSL client authenticate is at
sample/soap/ssl/sslclient_with_clientauth.rb. test/soap/ssl/test_ssl.rb
could be help, too.

> Also, how do I go about generating the header, which looks like this:
>
> <SOAP-ENV:Header>
> <RequesterCredentials xmlns="urn:ebay:api:PayPalAPI"
> xsi:type="ebl:CustomSecurityHeaderType">
> <Credentials xmlns="urn:ebay:apis:eBLBaseComponents"
> xsi:type="ebl:UserIdPasswordType">
> <Username xsi:type="xs:string">api_username</Username>
> <Password xsi:type="xs:string">api_password</Password>
> <Subject
> xsi:type="xs:string">authorizing_account_emailaddress</Subject>
> </Credentials>
> </RequesterCredentials>
> </SOAP-ENV:Header>
>
> I assume I have to override SOAP::Header::Simplehander, but i have no
> idea how do use this in a more complex case (i have seen the example
> for Google adwords)... any ideas?

I hope the following code works but you may need override
SOAP::Header::Handler (not SimpleHandler).

require 'soap/header/simplehandler'

class RequesterCredentialsHandler < SOAP::Header::SimpleHandler
HeaderName = XSD::QName.new('urn:ebay:api:PayPalAPI',
'RequesterCredentials')
CredentialsName =
XSD::QName.new('urn:ebay:apis:eBLBaseComponents', 'Credentials')
UsernameName = XSD::QName.new(nil, 'Username')
PasswordName = XSD::QName.new(nil, 'Password')
SubjectName = XSD::QName.new(nil, 'Subject')

def initialize(username, password, subject)
super(HeaderName)
@username, @password, @subject = username, password, subject
end

def on_simple_outbound
{CredentialsName => {UsernameName => @username, PasswordName =>
@password,
SubjectName => @subject}}
end
end

endpoint_url = ARGV.shift
obj = PayPalAPIInterface.new(endpoint_url)
obj.headerhandler << RequesterCredentialsHandler.new('NaHi', 'pass',
'authorizing_account_emailaddress')

Hmm. It should be easier to write header handler, especially if the
WSDL definition were given (like PayPalSvc). In the future...

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)

iD8DBQFCfu6hf6b33ts2dPkRAkUqAJ46HKxcBL15fb/zFS55GvYIDSa0RACfQzNr
gRarX9UB7gm4ljWiSqcVB1Y=
=OOTk
-----END PGP SIGNATURE-----

James Connell

unread,
May 10, 2005, 6:07:47 PM5/10/05
to soa...@googlegroups.com
I think i found a minor bug:

code:
WSDL_URL = "http://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl"

@soap = SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driver
@soap.options["protocol.http.ssl_config.verify_mode"] =
OpenSSL::SSL::VERIFY_NONE
@soap.options["protocol.http.ssl_config.client_cert"] = "keys/crt.txt"
@soap.options["protocol.http.ssl_config.client_key"] = "keys/key.txt"

gives the error:
NoMethodError: undefined method `empty?' for 0:Fixnum
from
c:/ruby/lib/ruby/site_ruby/1.8/soap/httpconfigloader.rb:95:in `ssl_
config_int'
from
c:/ruby/lib/ruby/site_ruby/1.8/soap/httpconfigloader.rb:77:in `set_
ssl_config'
from
c:/ruby/lib/ruby/site_ruby/1.8/soap/httpconfigloader.rb:61:in `each
'
from c:/ruby/lib/ruby/1.8/soap/property.rb:139:in `each'
from c:/ruby/lib/ruby/1.8/soap/property.rb:139:in `each'
from
c:/ruby/lib/ruby/site_ruby/1.8/soap/httpconfigloader.rb:61:in `set_
ssl_config'
from
c:/ruby/lib/ruby/site_ruby/1.8/soap/httpconfigloader.rb:36:in `set_
options'
from
c:/ruby/lib/ruby/site_ruby/1.8/soap/httpconfigloader.rb:35:in `call
'
from c:/ruby/lib/ruby/1.8/soap/property.rb:115:in `[]='
from c:/ruby/lib/ruby/1.8/soap/property.rb:114:in `each'
from c:/ruby/lib/ruby/1.8/soap/property.rb:114:in `[]='
from ./paypal.rb:28
from (irb):2:in `load'
from (irb):2
irb(main):003:0>

the offending code calls empty? on a Fixnum, which i dont think its
supposed to do:

def ssl_config_int(value)
if value.nil? or value.empty?
nil
else
begin
Integer(value)
rescue ArgumentError
::SOAP::Property::Util.const_from_name(value)
end
end
end

NAKAMURA, Hiroshi

unread,
May 10, 2005, 11:41:31 PM5/10/05
to soa...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

James Connell wrote:
> I think i found a minor bug:

Thank you. It definitely should work. I fixed it at the repository.
http://dev.ctor.org/soap4r/changeset/1542

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)

iD8DBQFCgX7rf6b33ts2dPkRAmGsAJ91cWZGDTsfxFNVvw1fNAGD5oWnWgCgpKN9
THrzaQCKv6Ij9WrkhlwAq6E=
=K57t
-----END PGP SIGNATURE-----

James Connell

unread,
Jun 2, 2005, 2:51:47 PM6/2/05
to soa...@googlegroups.com
When using soap4r with http_access2 and SSL, I run into a problem with
the certificates given to me by paypal. It tells me I have a self
signed certificate in my certificate chain, which is true (paypal signs
their own certs), but I want to use it anyway. Here is my code:

class PaypalAPI
WSDL_URL = "http://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl"

def initialize


@soap = SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driver
@soap.options["protocol.http.ssl_config.verify_mode"] =
OpenSSL::SSL::VERIFY_NONE
@soap.options["protocol.http.ssl_config.client_cert"] =
"keys/crt.txt"
@soap.options["protocol.http.ssl_config.client_key"] =
"keys/key.txt"

@soap.headerhandler << RequesterCredentialsHandler.new("username",
"pass", "")
@soap.wiredump_dev = STDOUT
end

def GetTransaction
req = GetTransactionDetailsReq.new("5F744114GD361381K")
result = @soap.getTransactionDetails(req)
end
end

and the result:

irb(main):009:0> result = paypal.GetTransaction
Wire dump:

= Request

! CONNECTION ESTABLISHED
at depth 2 - 19: self signed certificate in certificate chain


= Response

! CONNECTION CLOSED

what paypal gives me is a username/password along with and x509 cert
and RSA key in pem format that they create.

NAKAMURA, Hiroshi

unread,
Jun 5, 2005, 10:21:43 AM6/5/05
to soa...@googlegroups.com
Hi James,

Sorry for late reply.

James Connell wrote:
> When using soap4r with http_access2 and SSL, I run into a problem with
> the certificates given to me by paypal. It tells me I have a self
> signed certificate in my certificate chain, which is true (paypal signs
> their own certs), but I want to use it anyway. Here is my code:
>
> class PaypalAPI
> WSDL_URL = "http://www.sandbox.paypal.com/wsdl/PayPalSvc.wsdl"
>
> def initialize
> @soap = SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driver
> @soap.options["protocol.http.ssl_config.verify_mode"] =
> OpenSSL::SSL::VERIFY_NONE
> @soap.options["protocol.http.ssl_config.client_cert"] =
> "keys/crt.txt"
> @soap.options["protocol.http.ssl_config.client_key"] =
> "keys/key.txt"
> @soap.headerhandler << RequesterCredentialsHandler.new("username",
> "pass", "")
> @soap.wiredump_dev = STDOUT
> end

You must set "protocol.http.ssl_config.ca_file" which your client
trusts. The PayPal server certificate seems to be issued by
"/C=US/ST=California/L=San Jose/O=Paypal, Inc./OU=Information
Systems/OU=Terms of use at www.verisign.com/rpa
(c)00/CN=api.sandbox.paypal.com" which is issued by "/O=VeriSign Trust
Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class
3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign"
which is issued by "/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary
Certification Authority", which is a root.

So you should set the certificate of "/C=US/O=VeriSign, Inc./OU=Class 3
Public Primary Certification Authority" as
@soap.options["protocol.http.ssl_config.ca_file"]. I attached the
certificate file to this mail, BUT do NOT trust this certificate. I may
be trying to do phishing on you. (believe me I don't :-)

Setting trust anchor is the most important part of setting PKI security
correctly. You should carefully download the certificate from
VeriSign's website (I don't know we can download it but I think it
should be able to) or export the certificate from your IE or some web
browser.

> what paypal gives me is a username/password along with and x509 cert
> and RSA key in pem format that they create.

Does paypal not give you the root certificate (the certificate of issuer
of their server certificate) ?

Regards,
// NaHi
signature.asc
verisign.pem

NAKAMURA, Hiroshi

unread,
Jun 5, 2005, 9:29:00 PM6/5/05
to soa...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi again,

NAKAMURA, Hiroshi wrote:
> You must set "protocol.http.ssl_config.ca_file" which your client
> trusts. The PayPal server certificate seems to be issued by
> "/C=US/ST=California/L=San Jose/O=Paypal, Inc./OU=Information
> Systems/OU=Terms of use at www.verisign.com/rpa
> (c)00/CN=api.sandbox.paypal.com" which is issued by "/O=VeriSign Trust
> Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class
> 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign"
> which is issued by "/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary
> Certification Authority", which is a root.

Sorry, I explained wrong here. "/C=US/ST=California/L=San
Jose/O=Paypal, Inc./OU=Information Systems/OU=Terms of use at
www.verisign.com/rpa (c)00/CN=api.sandbox.paypal.com" IS the subject of
server certificate of the paypal server itself.

Just a correction of above sentence. Other topics are not affected.

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)

iD8DBQFCo6bbf6b33ts2dPkRAgU7AJ9AhoKDMQH+55ZiYQagxVPOrGx2mACgkk1t
2BINt+D5a4qPXEl9bs8PbYc=
=S3sz
-----END PGP SIGNATURE-----

P@

unread,
Jun 24, 2005, 7:18:56 AM6/24/05
to soa...@googlegroups.com
for SSL issues I use a brute force approach, inspired by the
http-access2 ssl sample
@soap.loadproperty('soap/property')
then create a soap/property file in the directory where the program
runs with
#specify ca file to use to lookup cert: did not work for me
#client.protocol.http.ssl_config.ca_file = ca.pem
#client.protocol.http.proxy = http://yourproxy_if_you_need_one:8080
#set verif to empty, this works
client.protocol.http.ssl_config.verify_mode =

NAKAMURA, Hiroshi

unread,
Jul 13, 2005, 9:17:22 PM7/13/05
to soa...@googlegroups.com
Hi P@,

Sorry for late reply but I finally started looking into AdWards
interoperability problem.
Is this for google AdWards server setting, isn't it? I found the server
https://adwords.google.com/api/adwords/v2/CampaignService updated the
SSL server certificate in May, and the certificate authority of the
server was changed. You must update the ca.pem file for server
authentication.

You can export the root CA certificate with IE. Go
https://adwords.google.com/api/adwords/v2/CampaignService and show
certificate dialog with clicking lock icon. Bear in mind that you must
get "Thawte Premium Server CA" certificate, not "adwords.google.com"
certificate. Export the certificate in DER format and convert it to PEM
format with openssl (openssl x509 -inform der -outform pem < ca.cer >
ca.pem).

Attached is the PEM formatted file of Thawte Premium Server CA.
sha1sum: 65f010b52dfacd7684b71afa8cb7357f27a208b6 thawtepremiumserver.pem

Regards,
// NaHi
signature.asc
thawtepremiumserver.pem

Patrick Chanezon

unread,
Jul 14, 2005, 1:47:35 AM7/14/05
to soa...@googlegroups.com
Thanks for the explanation Hiroshi.
I was not very concerned with the certificate problem though:
client.protocol.http.ssl_config.verify_mode =
worked for me.

What concerned me was more the errors when parsing the response.

P@
> -----BEGIN CERTIFICATE-----
> MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
> FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
> VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
> biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
> dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
> MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
> MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
> A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
> b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
> cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
> bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
> VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
> ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
> uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
> 9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
> hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
> pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
> -----END CERTIFICATE-----
>
>
>
>

NAKAMURA, Hiroshi

unread,
Jul 14, 2005, 8:55:30 AM7/14/05
to soa...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Patrick,

Patrick Chanezon wrote:
> Thanks for the explanation Hiroshi.
> I was not very concerned with the certificate problem though:
> client.protocol.http.ssl_config.verify_mode =
> worked for me.

Oh but there's no security there...

> What concerned me was more the errors when parsing the response.

Indeed. Please see the next mail.

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (Cygwin)

iD8DBQFC1mDCf6b33ts2dPkRAlv8AKCxgaS2k417mjUwfR7nsnUJxTf3GgCeIIhV
MeprqorwBBlO5eYRqdq0MVY=
=oga3
-----END PGP SIGNATURE-----
Reply all
Reply to author
Forward
0 new messages