source: TI12-security/trunk/python/bin/ndgSessionClient.py @ 737

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/bin/ndgSessionClient.py@737
Revision 737, 14.7 KB checked in by pjkersha, 14 years ago (diff)

ndgSetup.sh: fixed slight typo.

mapConfig.xml: added pubKey tag to allow client to Attribute Authority to use it to encrypt
outbound messages to it.

ndgSessionClient.py:

  • include code to set public key of Attribute Authority so that Session Manager can encrypt

messages to it.

  • -r/--req-autho option now requires the AA WSDL URI. -a is now used to set the AA pub key
  • see previous point.

AttAuthorityIO.py:

  • Changed tag 'clntCert' to 'encrCert' so as to be consistent with SessionMgrIO.py code.

attAuthority_services_server.py:

  • Moved encrypt/decrypt code here from AttAuthority? class to be consistent with

sessionMgr_services_server.py.

AttAuthority?.py:

  • Now inherits from dict to allow convenient access to properties file parameters as dictionary

items.

  • Added code to include pubKey tag from mapConfig file in trustedHostInfo returned from

getTrustedHostInfo.

SessionMgrIO.py:

output XML.

  • Shifted test code into separate file in Tests/

SessionClient?.py:

  • Added aaPubKey to reqAuthorisation method - see above re. passing AA public key for

encryption of messages.

sessionMgr_services_server.py:

  • Changes to comments.

Session.py:

private key info of client to allow encrypt of responses from other WSs that SessionMgr? calls.
These are actually passed into CredWallet? instance of UserSession?.

  • AA Public key is passed into reqAuthorisation. This is written to a temp file for use by

XMLSec encryption code.

CredWallet?.py:

  • CredWalletAuthorisationDenied? - make sure extAttCertList gets set to []
  • Added pub/private functionality for encryption of messages to and from Attribute Authorities.
  • reqAuthorisation and getAATrustedHostInfo methods - read in client public key using

straight open/read: using X509Cert.asString() misses out the actual MIME encoded cert text(!)

  • Changed reqAuthorisation() - a required role is now optional with mapFromTrustedHosts flag set.

It does help though with finding a suitable AttCert? for mapping.

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2
3"""NDG Session client script - makes requests for authentication and
4authorisation
5
6NERC Data Grid Project
7
8P J Kershaw 08/03/06
9
10Copyright (C) 2006 CCLRC & NERC
11
12This software may be distributed under the terms of the Q Public License,
13version 1.0 or later.
14"""
15# Command line processing
16import sys
17import os
18import optparse
19import re
20import getpass
21
22from Cookie import SimpleCookie
23
24from NDG.SessionClient import *
25
26
27#_____________________________________________________________________________
28def setSoapDebug(option, optStr, value, parser):
29    """Parser Callback function for enabling SOAP debug output"""
30    parser.values.soapDebug = sys.stderr
31
32   
33#_____________________________________________________________________________
34def setSessCookie(option, optStr, value, parser):
35    """Parser Callback function for reading session cookie from command line
36    """
37    try:
38        parser.values.sessCookie = SimpleCookie(open(value).read().strip())
39       
40    except IOError, (errNo, errMsg):
41        raise optparse.OptionValueError(\
42                    "Reading cookie from file \"%s\": %s" % (value, errMsg))
43                           
44    except Exception, e:
45        raise optparse.OptionValueError(\
46                    "Reading cookie from file \"%s\": %s" % (value, str(e)))
47
48
49#_____________________________________________________________________________
50def setSessCookieFromStdin(option, optStr, value, parser):
51    """Parser Callback function for reading cookie from stdin"""
52    try:
53        # Read from standard input
54        parser.values.sessCookie = SimpleCookie(sys.stdin.read().strip())
55
56    except KeyboardInterrupt:
57        raise optparse.OptionValueError(\
58                    "option \"%s\": expecting cookie set from stdin" % optStr)
59         
60    except Exception, e:
61        raise optparse.OptionValueError(\
62                    "option %s: Reading cookie from file \"%s\": %s" % \
63                    (optStr, value, str(e)))
64                   
65
66#_____________________________________________________________________________
67def setClntPriKeyPwd(option, optStr, value, parser):
68    """Parser Callback function for reading client private key password"""
69
70    try:
71        parser.values.clntPriKeyPwd = open(value).read().strip()
72       
73    except IOError, (errNo, errMsg):
74        raise optparse.OptionValueError(\
75                    "Reading password from file \"%s\": %s" % (value, errMsg))
76                           
77    except Exception, e:
78        raise optparse.OptionValueError(\
79                    "Reading password from file \"%s\": %s" % (value, str(e)))
80       
81
82#_____________________________________________________________________________
83def setAApubKey(option, optStr, value, parser):
84    """Parser callback function for reading Attribute Authority Public key"""
85   
86    try:
87        parser.values.aaPubKey = open(value).read().strip()
88       
89    except IOError, (errNo, errMsg):
90        raise optparse.OptionValueError(\
91                "Reading Attribute Authority Public key file \"%s\": %s" % \
92                (value, errMsg))
93                           
94    except Exception, e:
95        raise optparse.OptionValueError(\
96                "Reading Attribute Authority Public key file \"%s\": %s" % \
97                (value, str(e)))
98               
99                     
100#_____________________________________________________________________________
101if __name__ == '__main__':
102
103    usage = os.path.basename(sys.argv[0]) + " [--add-user=<username> ...]|"+\
104            "[--connect=<username> ...]|[--req-autho ...]|" + \
105            "[--connect=<username> ... --req-autho ...]"
106           
107    parser = optparse.OptionParser(usage=usage)
108    parser.add_option("-n", 
109                      "--add-user", 
110                      dest="newUserName",
111                      help="add a new user, see also: -p and -s options")
112
113    parser.add_option("-c", 
114                      "--connect",
115                      dest="userName",
116                      help="""login in to a Session Manager with username.""")
117   
118    parser.add_option("-r", 
119                      "--req-autho", 
120                      dest="attAuthorityWSDLuri", 
121                      help=\
122"""Get a Session Manager to request authorisation from an Attribute Authority
123with the given address.""")
124   
125    parser.add_option("-a", 
126                      "--att-authority-pubkey-file",
127                      action="callback",
128                      callback=setAApubKey,
129                      dest="aaPubKey",
130                      type="string", 
131                      help=\
132"""File Path of Public key of Attribute Authority used by the Session Manager
133to encrypt requests to it.  WARNING: If this is not set, requests will be sent
134in clear text.""")
135
136    parser.add_option("-x",
137                      "--clnt-pubkey-file",
138                      dest="clntPubKeyFilePath",
139                      help=\
140"""X.509 Certificate of client.  This is used by the Session Manager to
141encrypt responses.  WARNING: If this is not set, the response will be sent
142back in clear text""")
143
144    parser.add_option("-k",
145                      "--clnt-prikey-file",
146                      dest="clntPriKeyFilePath",
147                      help=\
148"""Private key file of client.  This is used by the client to decrypt
149responses.  This must be set if -x/--clnt-pubkey-file is set.""")
150
151    parser.add_option("-w",
152                      "--clnt-prikey-pwd-file",
153                      dest="clntPriKeyPwd",
154                      action="callback",
155                      callback=setClntPriKeyPwd,
156                      type="string",
157                      help=\
158"""Pass a file containing the password for the client private key.  If not
159set, it is prompted for from tty.""")
160
161    parser.add_option("-y",
162                      "--session-mgr-pubkey-uri",
163                      dest="smPubKeyURI",
164                      help=\
165"""X.509 Certificate of Session Manager.  This is used to encrypt the request
166to the Session Manager.  Set as a local file path or remote URI.  WARNING:
167If this is not set, the request will be sent in clear text""")
168
169    parser.add_option("-s",
170                      "--session-mgr-wsdl-uri",
171                      dest="sessMgrWSDLuri",
172                      help="Address of Session Manager to connect to")
173
174    parser.add_option("-d",
175                      "--soap-debug",
176                      dest="soapDebug",
177                      action="callback",
178                      callback=setSoapDebug,
179                      help="Print SOAP message output")
180
181    parser.add_option("-p",
182                      "--pass-phrase-from-stdin",
183                      action="store_true",
184                      dest="bPassPhraseFromStdin",
185                      default=False,
186                      help="""\
187Take user's pass-phrase from stdin.  If this flag is omitted, pass-phrase is
188prompted for from tty""")
189
190    parser.add_option("-i",
191                      "--cookie-file",
192                      action="callback",
193                      callback=setSessCookie,
194                      type="string",
195                      dest="sessCookie",
196                      help=\
197"""Session cookie for --req-autho/-r call.  This is returned from a previous
198connect call (-c USERNAME/--connect=USERNAME).  Note that connect and request
199authoirsation calls can be combined.  In this case, this arg is not needed as
200the cookie is passed directly from the connect call output to the
201authorisation request e.g. ... -c username -r -s "http://..." -a
202"http://...""")
203
204    parser.add_option("-e",
205                      "--cookie-from-stdin",
206                      action="callback",
207                      callback=setSessCookieFromStdin,
208                      dest="sessCookie",
209                      help="Read session cookie from stdin.")
210
211    parser.add_option("-m",
212                      "--map-from-trusted-hosts",
213                      action="store_true",
214                      dest="mapFromTrustedHosts",
215                      default=False,
216                      help=\
217"""For use with --req-autho/-r flag.  Set to allow the Session Manager to
218automatically use Attribute Certificates from the user's wallet or, if no
219suitable ones are found, to contact other trusted hosts in order to get
220Attribute Certificates for mapping""")
221
222    parser.add_option("-q",
223                      "--req-role",
224                      dest="reqRole",
225                      help="""\
226For use with --req-autho/-r flag.  Give a hint to the authorisation request as
227to what role is needed in order to get a mapped Attribute Certificate back
228from the Attribute Authority""")
229
230    parser.add_option("-l",
231                      "--rtn-ext-att-cert-list",
232                      action="store_true",
233                      dest="rtnExtAttCertList",
234                      default=False,
235                      help=\
236"""For use with --req-autho/-r flag.  Determines behaviour in the case where
237authorisation is denied by an Attribute Authority.  If set, a list of
238candidate Attribute Certificates from trusted hosts will be returned.  Any one
239of these could be re-input in a subsequent authorisation request by setting
240the --ext-att-cert-list-file option.  The certificates can be used to obtain a
241mapped Attribute Certificate from the import target Attribute Authority""")
242
243    parser.add_option("-f",
244                      "--ext-att-cert-list-file",
245                      dest="extAttCertListFile",
246                      help=\
247"""For use with --req-autho/-r flag.  A file of concatenated Attribute
248Certificates.  These are certificates from other import hosts trusted by the
249Attribute Authority.  The Session Manager tries each in turn until the
250Attribute Authority accepts one and uses it to create and return a mapped
251Attribute Certificate""")
252   
253    parser.add_option("-t",
254                      "--ext-trusted-hosts-file",
255                      dest="extTrustedHostsFile",
256                      help=\
257"""For use with --req-autho/-r flag.  Pass a file containing a comma
258separarated list of hosts that are trusted by the Attribute Authority.  The
259Session Manager will contact these hosts in turn, stopping when one of them
260grants it an Attribute Certificate that it can present to the target Attribute
261Authority in order to get a mapped Attribute Certificate in return.""")
262
263    (options, args) = parser.parse_args()
264
265#    import pdb
266#    pdb.set_trace()
267    if not options.sessMgrWSDLuri:       
268        sys.stderr.write("Error, No Session Manager WSDL URI set.\n\n")
269        parser.print_help()
270        sys.exit(1)
271       
272    passPhrase = None
273   
274    # For connect/addUser a pass-phrase is needed
275    if options.newUserName or options.userName:
276       
277        if options.bPassPhraseFromStdin:
278            # Read from standard input
279            passPhrase = sys.stdin.read().strip()           
280        else:
281            # Obtain from prompt
282            try:
283                passPhrase = getpass.getpass(prompt="Login pass-phrase: ") 
284            except KeyboardInterrupt:
285                sys.exit(1)
286
287    if options.clntPriKeyPwd is None and options.clntPriKeyFilePath:
288        # Obtain from prompt
289        try:
290            options.clntPriKeyPwd = getpass.getpass(\
291                                    prompt="Client private key pass-phrase: ") 
292        except KeyboardInterrupt:
293            sys.exit(1)
294
295                 
296    extAttCertList = None
297               
298    if options.extAttCertListFile:
299        try:
300            # Open and read file removing any <?xml ... ?> headers
301            sExtAttCertListFile = open(options.extAttCertListFile).read()
302            sAttCertTmp = re.sub("\s*<\?xml.*\?>\s*", "", sExtAttCertListFile)
303           
304            # Convert into a list
305            extAttCertList = ['<attributeCertificate>' + ac for ac in \
306                            sAttCertTmp.split('<attributeCertificate>')[1:]]
307        except Exception, e:
308            sys.stderr.write(\
309                "Error parsing file \%s\" for option \"%s\": %s" % \
310                (arg, "--ext-att-cert-list-file\"/\"-f", str(e)))
311
312       
313    extTrustedHostList = None
314
315    if options.extTrustedHostsFile:
316        try:
317            extTrustedHostList = \
318                re.split("\s*,\s*", open(options.extTrustedHostsFile).read())
319           
320        except Exception, e:
321            sys.stderr.write(\
322                "Error parsing file \%s\" for option \"%s\": %s" % \
323                (arg, "--ext-trusted-host-file\"/\"-t", str(e)))
324
325
326    # Initialise session client
327    try:
328        sessClnt = SessionClient(smWSDL=options.sessMgrWSDLuri,
329                             smPubKeyURI=options.smPubKeyURI,
330                             clntPubKeyFilePath=options.clntPubKeyFilePath,
331                             clntPriKeyFilePath=options.clntPriKeyFilePath,
332                             traceFile=options.soapDebug)
333    except Exception, e:
334        sys.stderr.write("Initialising client: %s\n" % str(e))
335        sys.exit(1)
336   
337    methodCall = False   
338    try:
339        if options.newUserName:
340            methodCall = True
341           
342            sessClnt.addUser(userName=options.newUserName, 
343                             pPhrase=passPhrase,
344                             clntPriKeyPwd=options.clntPriKeyPwd)
345            sys.exit(0)
346                           
347        if options.userName:
348            methodCall = True
349           
350            sSessCookie = sessClnt.connect(userName=options.userName, 
351                                       pPhrase=passPhrase,
352                                       clntPriKeyPwd=options.clntPriKeyPwd)           
353            print sSessCookie
354            # Don't exit here - req-autho may have been set too
355           
356        if options.attAuthorityWSDLuri:
357            methodCall = True
358
359            if options.userName:
360                # Connect was set also - parse cookie in order to session ID
361                # and WSDL address
362                options.sessCookie = SimpleCookie(sSessCookie)
363               
364            authResp = sessClnt.reqAuthorisation(\
365                            sessCookie=options.sessCookie,
366                            aaWSDL=options.attAuthorityWSDLuri,
367                            aaPubKey=options.aaPubKey,
368                            mapFromTrustedHosts=options.mapFromTrustedHosts,
369                            reqRole=options.reqRole,
370                            rtnExtAttCertList=options.rtnExtAttCertList,
371                            extAttCertList=extAttCertList,
372                            extTrustedHostList=extTrustedHostList,
373                            clntPriKeyPwd=options.clntPriKeyPwd)
374            print authResp
375       
376
377        if not methodCall:   
378            sys.stderr.write("Set a flag to specify the web-service call " + \
379                             "e.g. --connect=USERNAME\n\n")
380            parser.print_help()
381            sys.exit(1)
382           
383    except Exception, e:
384        sys.stderr.write(str(e) + os.linesep)
385     
386    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.