1 | #!/usr/local/bin/python |
---|
2 | |
---|
3 | import sys |
---|
4 | import os |
---|
5 | |
---|
6 | from M2Crypto import SSL |
---|
7 | from M2Crypto.SSL import SSLError |
---|
8 | from xmlrpclib import ServerProxy, dumps, loads, Fault, Error, Binary |
---|
9 | |
---|
10 | # This disables server hostname checking in SSL as a side effect. |
---|
11 | from cred_printer.util import ssl_context, SSLTransport |
---|
12 | |
---|
13 | from string import join |
---|
14 | from optparse import OptionParser |
---|
15 | |
---|
16 | |
---|
17 | class OptParser(OptionParser): |
---|
18 | """ |
---|
19 | Option parsing for clients. Should be self-explanatory. |
---|
20 | """ |
---|
21 | def __init__(self): |
---|
22 | OptionParser.__init__(self) |
---|
23 | if 'CRED_URL' in os.environ: default_url = os.environ['CRED_URL'] |
---|
24 | else: default_url = 'http://localhost:13232' |
---|
25 | |
---|
26 | self.add_option('--url', dest='url', default=default_url, |
---|
27 | help='URL of the server') |
---|
28 | self.add_option('--cert', dest='cert', default=None, |
---|
29 | help='My identity certificate (and key)') |
---|
30 | self.add_option('--verbose', dest='verbose', default=False, |
---|
31 | action='store_true') |
---|
32 | |
---|
33 | def print_attr(a, label): |
---|
34 | ''' |
---|
35 | Print the fields of an attribute dict |
---|
36 | ''' |
---|
37 | print '\t%s:' % label |
---|
38 | for an in ('pretty_principal', 'principal', 'role', 'linked_role'): |
---|
39 | if an in a: print '\t\t%s: %s' % (an, a[an]) |
---|
40 | |
---|
41 | def print_cred(e, verbose=False): |
---|
42 | ''' |
---|
43 | Print the credential (e), either as one line of |
---|
44 | id type string auxstring |
---|
45 | or |
---|
46 | id Error, code n |
---|
47 | |
---|
48 | If verbose is True, print the head and tail components of valid attribute |
---|
49 | credentials indented. |
---|
50 | ''' |
---|
51 | |
---|
52 | if e['errcode'] == 0: |
---|
53 | print "%s: %s %s %s" % (e['id'], e['type'], e['str'], e['auxstr']) |
---|
54 | if verbose and e['type'] == 'attribute': |
---|
55 | for en in ('head', 'tail'): |
---|
56 | if en in e: print_attr(e[en], en) |
---|
57 | else: |
---|
58 | print "%s: Error, code %d" % (e['id'], e['errcode']) |
---|
59 | |
---|
60 | |
---|
61 | # Parse the args |
---|
62 | parser = OptParser() |
---|
63 | opts, args = parser.parse_args() |
---|
64 | |
---|
65 | if opts.cert: |
---|
66 | # If a certificate is given, use an SSL-protected connection |
---|
67 | try: |
---|
68 | ctx = ssl_context(opts.cert) |
---|
69 | except SSLError, e: |
---|
70 | sys.exit("Cannot load %s: %s" % (opts.cert, e)) |
---|
71 | |
---|
72 | transport=SSLTransport(ctx) |
---|
73 | else: |
---|
74 | transport=None |
---|
75 | |
---|
76 | |
---|
77 | creds = [] |
---|
78 | for fn in args: |
---|
79 | # Collect the contents of the filenames into the creds list |
---|
80 | try: |
---|
81 | # The list comprehension and join are a compact way to read the whole |
---|
82 | # file into a string. |
---|
83 | creds.append(join([l for l in open(fn)], '')) |
---|
84 | except EnvironmentError, e: |
---|
85 | # warn if there's an error reading one of the files |
---|
86 | print >>sys.stderr, "Cannot read %s: %s" % (fn, e.strerror) |
---|
87 | |
---|
88 | # This builds a list of structs with the ID (an integer printed to 3 places) |
---|
89 | # and the contents of the file as an XMLRPC binary. |
---|
90 | req = [ {'id': "%03d" % i, 'credential': Binary(c) } |
---|
91 | for i, c in enumerate(creds)] |
---|
92 | |
---|
93 | # Call the server |
---|
94 | proxy = ServerProxy(opts.url, transport=transport) |
---|
95 | try: |
---|
96 | resp = proxy.translate(req) |
---|
97 | except SSLError, e: |
---|
98 | sys.exit("SSL error: %s" %e) |
---|
99 | except EnvironmentError, e: |
---|
100 | sys.exit("IOError: %s" %e) |
---|
101 | except: |
---|
102 | t, e = sys.exc_info()[0:2] |
---|
103 | sys.exit('Unexpected error: %s %s' % (t,e)) |
---|
104 | |
---|
105 | # Sort by ID |
---|
106 | resp.sort(key=lambda x: x['id']) |
---|
107 | |
---|
108 | # Output the response |
---|
109 | for e in resp: |
---|
110 | print_cred(e, opts.verbose) |
---|