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

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

ndgSessionClient.py: fixed client private key password file read.

AttAuthority?.py: changed X509Cert.isValidTime() calls to give more error info.

XMLSecDoc.py: metaclass for XMLSec initialisation didn't work - do initialisation in class
init as before.

SessionClient?.py: removed test code - this is kept in a separate file in Tests/.

Session.py: modified SessionMgr?.reqAuthorisation() to create a fresh AuthorisationResp? object
from the return from redirectAuthorisationReq() to avoid confusion with encrypted output
message.

  • 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#_____________________________________________________________________________
83if __name__ == '__main__':
84
85    usage = os.path.basename(sys.argv[0]) + " [--add-user=<username> ...]|"+\
86            "[--connect=<username> ...]|[--req-autho ...]|" + \
87            "[--connect=<username> ... --req-autho ...]"
88           
89    parser = optparse.OptionParser(usage=usage)
90    parser.add_option("-n", 
91                      "--add-user", 
92                      dest="newUserName",
93                      help="add a new user, see also: -p and -s options")
94
95    parser.add_option("-c", 
96                      "--connect",
97                      dest="userName",
98                      help="""\
99login in to a Session Manager with username, see also: -u, -p, -x, -y and -s
100options""")
101   
102    parser.add_option("-r", 
103                      "--req-autho", 
104                      action="store_true",
105                      dest="reqAuthorisation", 
106                      default=False, 
107                      help=\
108"""Get a Session Manager to request authorisation from an Attribute Authority
109on behalf of a user; see also: -i, -s, -a, -x, -y [, -t]""")
110
111    parser.add_option("-x",
112                      "--clnt-pubkey-file",
113                      dest="clntPubKeyFilePath",
114                      help=\
115"""X.509 Certificate of client.  This is used by the Session Manager to
116encrypt responses.  WARNING: If this is not set, the response will be sent
117back in clear text""")
118
119    parser.add_option("-k",
120                      "--clnt-prikey-file",
121                      dest="clntPriKeyFilePath",
122                      help=\
123"""Private key file of client.  This is used by the client to decrypt
124responses.  This must be set if -x/--clnt-pubkey-file is set.""")
125
126    parser.add_option("-w",
127                      "--clnt-prikey-pwd-file",
128                      dest="clntPriKeyPwd",
129                      action="callback",
130                      callback=setClntPriKeyPwd,
131                      type="string",
132                      help=\
133"""Pass a file containing the password for the client private key.  If not
134set, it is prompted for from tty.""")
135
136    parser.add_option("-y",
137                      "--session-mgr-pubkey-uri",
138                      dest="smPubKeyURI",
139                      help=\
140"""X.509 Certificate of Session Manager.  This is used to encrypt the request
141to the Session Manager.  Set as a local file path or remote URI.  WARNING:
142If this is not set, the request will be sent in clear text""")
143
144    parser.add_option("-s",
145                      "--session-mgr-wsdl-uri",
146                      dest="sessMgrWSDLuri",
147                      help="Address of Session Manager to connect to")
148
149    parser.add_option("-d",
150                      "--soap-debug",
151                      dest="soapDebug",
152                      action="callback",
153                      callback=setSoapDebug,
154                      help="Print SOAP message output")
155
156    parser.add_option("-p",
157                      "--pass-phrase-from-stdin",
158                      action="store_true",
159                      dest="bPassPhraseFromStdin",
160                      default=False,
161                      help="""\
162Take user's pass-phrase from stdin.  If this flag is omitted, pass-phrase is
163prompted for from tty""")
164
165    parser.add_option("-i",
166                      "--cookie-file",
167                      action="callback",
168                      callback=setSessCookie,
169                      type="string",
170                      dest="sessCookie",
171                      help=\
172"""Session cookie for --req-autho/-r call.  This is returned from a previous
173connect call (-c USERNAME/--connect=USERNAME).  Note that connect and request
174authoirsation calls can be combined.  In this case, this arg is not needed as
175the cookie is passed directly from the connect call output to the
176authorisation request e.g. ... -c username -r -s "http://..." -a
177"http://...""")
178
179    parser.add_option("-e",
180                      "--cookie-from-stdin",
181                      action="callback",
182                      callback=setSessCookieFromStdin,
183                      dest="sessCookie",
184                      help="Read session cookie from stdin.")
185
186    parser.add_option("-a",
187                      "--att-authority-wsdl-uri",
188                      dest="attAuthorityWSDLuri",
189                      help="""\
190For use with --req-autho/-r flag.  The address of the Attribute Authority from
191which to request an Attribute Certificate.""")
192
193    parser.add_option("-m",
194                      "--map-from-trusted-hosts",
195                      action="store_true",
196                      dest="mapFromTrustedHosts",
197                      default=False,
198                      help=\
199"""For use with --req-autho/-r flag.  Set to allow the Session Manager to
200automatically use Attribute Certificates from the user's wallet or, if no
201suitable ones are found, to contact other trusted hosts in order to get
202Attribute Certificates for mapping""")
203
204    parser.add_option("-q",
205                      "--req-role",
206                      dest="reqRole",
207                      help="""\
208For use with --req-autho/-r flag.  Give a hint to the authorisation request as
209to what role is needed in order to get a mapped Attribute Certificate back
210from the Attribute Authority""")
211
212    parser.add_option("-l",
213                      "--rtn-ext-att-cert-list",
214                      action="store_true",
215                      dest="rtnExtAttCertList",
216                      default=False,
217                      help=\
218"""For use with --req-autho/-r flag.  Determines behaviour in the case where
219authorisation is denied by an Attribute Authority.  If set, a list of
220candidate Attribute Certificates from trusted hosts will be returned.  Any one
221of these could be re-input in a subsequent authorisation request by setting
222the --ext-att-cert-list-file option.  The certificates can be used to obtain a
223mapped Attribute Certificate from the import target Attribute Authority""")
224
225    parser.add_option("-f",
226                      "--ext-att-cert-list-file",
227                      dest="extAttCertListFile",
228                      help=\
229"""For use with --req-autho/-r flag.  A file of concatenated Attribute
230Certificates.  These are certificates from other import hosts trusted by the
231Attribute Authority.  The Session Manager tries each in turn until the
232Attribute Authority accepts one and uses it to create and return a mapped
233Attribute Certificate""")
234   
235    parser.add_option("-t",
236                      "--ext-trusted-hosts-file",
237                      dest="extTrustedHostsFile",
238                      help=\
239"""For use with --req-autho/-r flag.  Pass a file containing a comma
240separarated list of hosts that are trusted by the Attribute Authority.  The
241Session Manager will contact these hosts in turn, stopping when one of them
242grants it an Attribute Certificate that it can present to the target Attribute
243Authority in order to get a mapped Attribute Certificate in return.""")
244
245    (options, args) = parser.parse_args()
246
247#    import pdb
248#    pdb.set_trace()
249    if not options.sessMgrWSDLuri:       
250        sys.stderr.write("Error, No Session Manager WSDL URI set.\n\n")
251        parser.print_help()
252        sys.exit(1)
253       
254    passPhrase = None
255   
256    # For connect/addUser a pass-phrase is needed
257    if options.newUserName or options.userName:
258       
259        if options.bPassPhraseFromStdin:
260            # Read from standard input
261            passPhrase = sys.stdin.read().strip()           
262        else:
263            # Obtain from prompt
264            try:
265                passPhrase = getpass.getpass(prompt="Login pass-phrase: ") 
266            except KeyboardInterrupt:
267                sys.exit(1)
268
269    if options.clntPriKeyPwd is None and options.clntPriKeyFilePath:
270        # Obtain from prompt
271        try:
272            options.clntPriKeyPwd = getpass.getpass(\
273                                    prompt="Client private key pass-phrase: ") 
274        except KeyboardInterrupt:
275            sys.exit(1)
276
277                 
278    extAttCertList = None
279               
280    if options.extAttCertListFile:
281        try:
282            # Open and read file removing any <?xml ... ?> headers
283            sExtAttCertListFile = open(options.extAttCertListFile).read()
284            sAttCertTmp = re.sub("\s*<\?xml.*\?>\s*", "", sExtAttCertListFile)
285           
286            # Convert into a list
287            extAttCertList = ['<attributeCertificate>' + ac for ac in \
288                            sAttCertTmp.split('<attributeCertificate>')[1:]]
289        except Exception, e:
290            sys.stderr.write(\
291                "Error parsing file \%s\" for option \"%s\": %s" % \
292                (arg, "--ext-att-cert-list-file\"/\"-f", str(e)))
293
294       
295    extTrustedHostList = None
296
297    if options.extTrustedHostsFile:
298        try:
299            extTrustedHostList = \
300                re.split("\s*,\s*", open(options.extTrustedHostsFile).read())
301           
302        except Exception, e:
303            sys.stderr.write(\
304                "Error parsing file \%s\" for option \"%s\": %s" % \
305                (arg, "--ext-trusted-host-file\"/\"-t", str(e)))
306
307
308    # Initialise session client
309    try:
310        sessClnt = SessionClient(smWSDL=options.sessMgrWSDLuri,
311                             smPubKeyURI=options.smPubKeyURI,
312                             clntPubKeyFilePath=options.clntPubKeyFilePath,
313                             clntPriKeyFilePath=options.clntPriKeyFilePath,
314                             traceFile=options.soapDebug)
315    except Exception, e:
316        sys.stderr.write("Initialising client: %s\n" % str(e))
317        sys.exit(1)
318   
319    methodCall = False   
320    try:
321        if options.newUserName:
322            methodCall = True
323           
324            sessClnt.addUser(userName=options.newUserName, 
325                             pPhrase=passPhrase,
326                             clntPriKeyPwd=options.clntPriKeyPwd)
327            sys.exit(0)
328                           
329        if options.userName:
330            methodCall = True
331           
332            sSessCookie = sessClnt.connect(userName=options.userName, 
333                                       pPhrase=passPhrase,
334                                       clntPriKeyPwd=options.clntPriKeyPwd)           
335            print sSessCookie
336            # Don't exit here - req-autho may have been set too
337           
338        if options.reqAuthorisation:
339            methodCall = True
340
341            if options.userName:
342                # Connect was set also - parse cookie in order to session ID
343                # and WSDL address
344                options.sessCookie = SimpleCookie(sSessCookie)
345               
346            authResp = sessClnt.reqAuthorisation(\
347                            sessCookie=options.sessCookie,
348                            aaWSDL=options.attAuthorityWSDLuri,
349                            mapFromTrustedHosts=options.mapFromTrustedHosts,
350                            reqRole=options.reqRole,
351                            rtnExtAttCertList=options.rtnExtAttCertList,
352                            extAttCertList=extAttCertList,
353                            extTrustedHostList=extTrustedHostList,
354                            clntPriKeyPwd=options.clntPriKeyPwd)
355            print authResp
356       
357
358        if not methodCall:   
359            sys.stderr.write("Set a flag to specify the web-service call " + \
360                             "e.g. --connect=USERNAME\n\n")
361            parser.print_help()
362            sys.exit(1)
363           
364    except Exception, e:
365        sys.stderr.write(str(e) + os.linesep)
366     
367    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.