~ubuntu-branches/ubuntu/jaunty/pyca/jaunty

« back to all changes in this revision

Viewing changes to cgi-bin/client-enroll.py

  • Committer: Bazaar Package Importer
  • Author(s): Lars Bahner
  • Date: 2003-12-02 19:39:35 UTC
  • Revision ID: james.westby@ubuntu.com-20031202193935-fzzt289mntvy6a8q
Tags: upstream-20031118
ImportĀ upstreamĀ versionĀ 20031118

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
"""
 
4
client-enroll.py - certificate enrollment with mainstream web browsers
 
5
(c) by Michael Stroeder <michael@stroeder.com>
 
6
"""
 
7
 
 
8
Version='0.6.6'
 
9
 
 
10
########################################################################
 
11
# CGI-BIN for creating certificate requests
 
12
########################################################################
 
13
 
 
14
import os, sys, types, string, re, socket, \
 
15
       pycacnf, \
 
16
       cgiforms, cgihelper, charset, ipadr, htmlbase, certhelper
 
17
 
 
18
from pycacnf import opensslcnf, pyca_section
 
19
from charset import iso2utf, iso2html4
 
20
from cgihelper import BrowserType,known_browsers,known_browsers_rev
 
21
 
 
22
########################################################################
 
23
# "Internet"-Funktionen
 
24
########################################################################
 
25
 
 
26
# Aus einer Mailadresse die Domain herausloesen
 
27
# Ergebnis ist Teilstring hinter letztem(!) @
 
28
# falls kein @ vorhanden, dann Leerstring
 
29
def DomainAdr(MailAdr=""):
 
30
  splitted=string.split(MailAdr,'@')
 
31
  if len(splitted)>1:
 
32
    return splitted[-1]
 
33
  else:
 
34
    return ''
 
35
 
 
36
# String der Hilfe-URL zu bestimmtem Parameter zurueckgeben
 
37
def HelpURL(HelpUrl,name,text):
 
38
  return '<A HREF="%s.html#%s">%s</A>' % \
 
39
         (HelpUrl,name,iso2html4(text))
 
40
 
 
41
# Print list of possible cert types
 
42
def PrintCertTypes(ca_names):
 
43
  htmlbase.PrintHeader('Start enrollment for certificate request')
 
44
  htmlbase.PrintHeading('Start enrollment for certificate request')
 
45
  print """This certificate authority issues several types
 
46
of client certificates.<BR>Please choose the appropriate certificate
 
47
type below:<P>
 
48
<TABLE CELLSPACING=10%%>"""
 
49
  for ca_name in ca_names:
 
50
    ca = opensslcnf.getcadata(ca_name)
 
51
    if ca.isclientcert():
 
52
      if ca.nsCaPolicyUrl:
 
53
        nsCaPolicyUrlStr = '<A HREF="%s%s">(view policy)' % (ca.nsBaseUrl,ca.nsCaPolicyUrl)
 
54
      else:
 
55
        nsCaPolicyUrlStr = '&nbsp;'
 
56
      print '<TR><TD><A HREF="%s/%s">%s</A></TD><TD>%s</TD><TD>%s</TD></TR>' % (os.environ.get('SCRIPT_NAME','client-enroll.py'),ca_name,ca_name,ca.nsComment,nsCaPolicyUrlStr)
 
57
  print '</TABLE>'
 
58
  htmlbase.PrintFooter()
 
59
 
 
60
# Ausgabe eines leeren Eingabeformulars
 
61
def PrintEmptyForm(form,ca_name,scriptmethod='POST'):
 
62
  print '<FORM ACTION="%s/%s" METHOD="%s" ACCEPT-CHARSET="iso-8859-1">' % (os.environ.get('SCRIPT_NAME','client-enroll.py'),ca_name,scriptmethod)
 
63
  print '<TABLE WIDTH=100% BORDER>'
 
64
  for i in form.keys:
 
65
    for j in form.field[i]:
 
66
      print '<TR><TD>%s%s</TD><TD>%s</TD></TR>' % (HelpURL(HelpUrlBase,j.name,j.text),' <FONT SIZE="+2">*</FONT>'*j.required,j.inputfield())
 
67
  print '</TABLE>'
 
68
  print '<INPUT TYPE="submit" VALUE="Send">'
 
69
  print '<INPUT TYPE="reset" VALUE="Reset">'
 
70
  print '</FORM>'
 
71
  return
 
72
 
 
73
def PrintInput(form,cellpadding=5,width=100):
 
74
  print '<TABLE BORDER CELLPADDING=%d%% WIDTH=%d%%>' % (cellpadding,width)
 
75
  formKeys = form.inputkeys[:]
 
76
  try:
 
77
    formKeys.remove('challenge')
 
78
  except ValueError:
 
79
    pass
 
80
 
 
81
  for i in formKeys:
 
82
    for j in form.field[i]:
 
83
      print '<TR><TD WIDTH=35%%>%s</TD><TD>%s</TD></TR>' % \
 
84
             (HelpURL(HelpUrlBase,j.name,j.text),j.contentprint())
 
85
  print '</TABLE>'
 
86
  return
 
87
 
 
88
# Ausgabe eines Formulars zur Schuesselerzeugung
 
89
def PrintKeygenForm(form,ca_name,ca,browsertype,scriptmethod='POST'):
 
90
 
 
91
  print """Content-type: text/html\n
 
92
<HTML>
 
93
  <HEAD>
 
94
    <TITLE>Create key pair and certificate request</TITLE>
 
95
"""
 
96
  if browsertype=='MSIE':
 
97
    import vbs
 
98
    vbs.PrintVBSXenrollObject()
 
99
    print '<SCRIPT Language=VBSCRIPT>\n<!-- '
 
100
    vbs.PrintVBSCryptoProvider()
 
101
    vbs.PrintVBSKeyGenCode(form)
 
102
    print ' -->\n</SCRIPT>'
 
103
  print '</HEAD><BODY onLoad=KeySizeSelectList() %s>' % htmlbase.bodyPARAM
 
104
  htmlbase.PrintHeading('Create key pair and certificate request')
 
105
  print 'Your key pair and certificate request can be generated now.<BR>'
 
106
  print 'Please have a look below to check if your input data was correct.<P>'
 
107
  # Print input given by user as readable table and hidden input fields
 
108
  PrintInput(form)
 
109
  print '<FORM name="KeyGenForm" ACTION="%s/%s" METHOD=%s ACCEPT-CHARSET="iso-8859-1">' % (os.environ.get('SCRIPT_NAME','client-enroll.py'),ca_name,scriptmethod)
 
110
  for i in form.inputkeys:
 
111
    for j in form.field[i]:
 
112
      print '<INPUT TYPE="hidden" NAME="%s" VALUE="%s">' % (j.name,j.content)
 
113
 
 
114
  # Print hint about minimum key size
 
115
  if ca.min_key_size>0:
 
116
    print """Please note:<BR>
 
117
The certificate type <STRONG>%s</STRONG> requires a minimum key size of <STRONG>%d</STRONG> bits!
 
118
If you are not able to choose a key length equal or greater than <STRONG>%d</STRONG> the
 
119
certificate authority will refuse to issue a certificate for your certificate request!<P>
 
120
""" % (ca_name,ca.min_key_size,ca.min_key_size)
 
121
 
 
122
  if browsertype=='MSIE':
 
123
    print '<P>Key size: <SELECT NAME="KeySize"></SELECT></P><INPUT TYPE="hidden" NAME="PKCS10" VALUE="">'
 
124
    print '<INPUT TYPE="BUTTON" onClick="GenTheKeyPair()" VALUE="Generate key pair"></FORM>'
 
125
  else:
 
126
    print '<P>%s:%s</P><INPUT TYPE="submit" VALUE="Generate key pair"></FORM>' % ( \
 
127
      HelpURL(HelpUrlBase,form.field['SPKAC'][0].name,form.field['SPKAC'][0].text),\
 
128
      form.field['SPKAC'][0].inputfield(form.field['challenge'][0].content) \
 
129
    )
 
130
  htmlbase.PrintFooter()
 
131
 
 
132
########################################################################
 
133
# Main
 
134
########################################################################
 
135
 
 
136
# Read several parameters from config
 
137
 
 
138
MailRelay           = pyca_section.get('MailRelay','localhost')
 
139
TmpDir              = pyca_section.get('TmpDir','/tmp')
 
140
 
 
141
caCertReqMailAdr    = pyca_section.get('caCertReqMailAdr','')
 
142
caPendCertReqValid  = string.atoi(pyca_section.get('caPendCertReqValid','0'))
 
143
 
 
144
caInternalCertTypes = pyca_section.get('caInternalCertTypes',[])
 
145
if type(caInternalCertTypes)!=types.ListType:
 
146
  caInternalCertTypes = [caInternalCertTypes]
 
147
 
 
148
caInternalIPAdr     = pyca_section.get('caInternalIPAdr',['127.0.0.1/255.255.255.255'])
 
149
if type(caInternalIPAdr)!=types.ListType:
 
150
  caInternalIPAdr = [caInternalIPAdr]
 
151
 
 
152
caInternalDomains   = pyca_section.get('caInternalDomains','')
 
153
if type(caInternalDomains)!=types.ListType:
 
154
  caInternalDomains = [caInternalDomains]
 
155
 
 
156
ScriptMethod        = pyca_section.get('ScriptMethod','POST')
 
157
 
 
158
# Read wanted certificate type from PATH_INFO
 
159
ca_name = os.environ.get('PATH_INFO','')[1:]
 
160
 
 
161
# Get list of possible certificate type from config
 
162
ca_names = opensslcnf.sectionkeys.get('ca',[])
 
163
 
 
164
# Check for valid certificate type
 
165
if not ca_names:
 
166
  htmlbase.PrintErrorMsg('No certificate authorities found.')
 
167
  sys.exit(0)
 
168
if not ca_name:
 
169
  PrintCertTypes(ca_names)
 
170
  sys.exit(0)
 
171
if not ca_name in ca_names:
 
172
  # CA-Definition nicht in openssl-Konfiguration enthalten
 
173
  htmlbase.PrintErrorMsg('Unknown certificate authority "%s".' % ca_name)
 
174
  sys.exit(0)
 
175
 
 
176
# Check for "internal" IP address of client
 
177
if (ca_name in caInternalCertTypes) and \
 
178
   not ipadr.MatchIPAdrList(os.environ.get('REMOTE_ADDR',''),caInternalIPAdr):
 
179
  htmlbase.PrintErrorMsg('This type of certificate request is restricted to internal hosts!')
 
180
  sys.exit(0)
 
181
 
 
182
ca = opensslcnf.getcadata(ca_name)
 
183
 
 
184
HelpUrlBase = '%s%s%s' % ( \
 
185
                ca.nsBaseUrl, \
 
186
                pyca_section.get('HelpUrl',''), \
 
187
                os.path.splitext(os.path.basename(os.environ.get('SCRIPT_NAME','')))[0] \
 
188
              )
 
189
 
 
190
policy_section = opensslcnf.data.get(ca.policy,{})
 
191
req_section = opensslcnf.data.get(ca.req,{})
 
192
 
 
193
if req_section and req_section.has_key('distinguished_name'):
 
194
  req_distinguished_name_section = opensslcnf.data.get(req_section['distinguished_name'],{})
 
195
  req_distinguished_name_keys = opensslcnf.sectionkeys.get(req_section['distinguished_name'],[])
 
196
else:
 
197
  htmlbase.PrintErrorMsg('Request section for "%s" not found.' % ca_name)
 
198
  sys.exit(0)
 
199
 
 
200
# Hier Verwendungszweck der Zertifikate pruefen
 
201
if not ca.isclientcert():
 
202
  htmlbase.PrintErrorMsg('Certificate authority "%s" does not issue client certificates.' % ca_name)
 
203
  sys.exit(0)
 
204
 
 
205
# form initialisieren
 
206
form = cgiforms.formClass(charset='iso-8859-1')
 
207
 
 
208
# Die gueltigen Inputattribute setzen
 
209
alphanumregex = r'[0-9a-zA-Z\344\366\374\304\326\334\337ļæ½/\'"._ -]*'
 
210
# telephoneregex = r'^\+[0-9][0-9]-[0-9]*-[0-9]*'
 
211
 
 
212
# Check which browser is used
 
213
http_browsertype,http_browserversion = BrowserType(os.environ.get('HTTP_USER_AGENT',''))
 
214
key_gen_browsers = {'Microsoft Internet Explorer':('PKCS10','pem'),'Netscape Navigator':('SPKAC','spkac'),'Opera':('SPKAC','spkac')}
 
215
if not known_browsers.get(http_browsertype,http_browsertype) in key_gen_browsers.keys():
 
216
  http_browsertype=''
 
217
 
 
218
form.add(cgiforms.formSelectClass('browsertype','Browser Software',key_gen_browsers.keys(),known_browsers.get(http_browsertype,''),required=1))
 
219
form.add(cgiforms.formPasswordClass('challenge','Initial Master Secret',30,alphanumregex,required=1))
 
220
 
 
221
# The form is build by looking at a [req] section in openssl.cnf
 
222
 
 
223
dn_attr_keys = []
 
224
dn_attr = {}
 
225
for i in req_distinguished_name_keys:
 
226
  l = string.split(i,'_')
 
227
  attr_name = string.strip(l[0])
 
228
  if not attr_name in dn_attr_keys:
 
229
    dn_attr_keys.append(attr_name)
 
230
    dn_attr[attr_name]={'comment':'','max':'40','regex':alphanumregex,'default':''}
 
231
  if len(l)>1:
 
232
    dn_attr[attr_name][l[1]]=req_distinguished_name_section.get(i,'')
 
233
  elif len(l)==1:
 
234
    dn_attr[attr_name]['comment']=req_distinguished_name_section.get(i,attr_name)
 
235
 
 
236
for i in dn_attr_keys:
 
237
  imaxlength=string.atoi(dn_attr[i].get('max','40'))
 
238
  if imaxlength>40:
 
239
    isize=40
 
240
  else:
 
241
    isize=imaxlength
 
242
  policy_field = policy_section.get(i,'optional')
 
243
  if policy_field=='match':
 
244
    if type(dn_attr[i]['default'])==types.ListType:
 
245
      dn_attr[i]['default']=dn_attr[i]['default'][0]
 
246
    form.add(cgiforms.formHiddenInputClass(i,dn_attr[i]['comment'],imaxlength,dn_attr[i]['regex'],dn_attr[i]['default'],required=1,show=1))
 
247
  else:
 
248
    if type(dn_attr[i]['default'])==types.ListType:
 
249
      dn_attr[i]['default'].sort()
 
250
      form.add(cgiforms.formSelectClass(i,dn_attr[i]['comment'],dn_attr[i]['default'],required=policy_field=='supplied'))
 
251
    else:
 
252
      form.add(cgiforms.formInputClass(i,dn_attr[i]['comment'],imaxlength,dn_attr[i]['regex'],dn_attr[i]['default'],required=policy_field=='supplied',size=isize))
 
253
 
 
254
# Schon Parameter vorhanden?
 
255
if not form.contentlength:
 
256
 
 
257
  import time
 
258
 
 
259
  # Aufruf erfolgte ohne Parameter =>
 
260
  # 0. Schritt: leeres Eingabeformular ausgeben
 
261
 
 
262
  if not ca.nsComment:
 
263
    ca.nsComment = 'No comment'
 
264
  if ca.nsCaPolicyUrl:
 
265
    nsCommentStr = '<A HREF="%s%s">%s</A>' % (ca.nsBaseUrl,ca.nsCaPolicyUrl,ca.nsComment)
 
266
  else:
 
267
    nsCommentStr = ca.nsComment
 
268
 
 
269
  htmlbase.PrintHeader('Input form for certificate request')
 
270
  htmlbase.PrintHeading('Input form for certificate request')
 
271
 
 
272
  if not http_browsertype:
 
273
    print '<P><STRONG>Your browser type could not be automatically determined.<BR>Please choose the browser you are using.</STRONG></P>'
 
274
 
 
275
  print """<TABLE>
 
276
<TR><TD>Certificate authority:</TD><TD><STRONG>%s</STRONG></TD></TR>
 
277
<TR><TD>Certificate type:</TD><TD><STRONG>%s</STRONG></TD></TR>
 
278
<TR><TD>Certificate comment:</TD><TD><STRONG>%s</STRONG></TD></TR>
 
279
</TABLE>
 
280
<P>
 
281
  Certificates of this type will be valid for <STRONG>%d days</STRONG>, approximately until <STRONG>%s</STRONG>.
 
282
</P>
 
283
""" % (ca_name,
 
284
       ca.nsCertTypeStr,
 
285
       nsCommentStr,
 
286
       ca.default_days,
 
287
       time.strftime('%Y-%m-%d',time.gmtime(time.time()+86400*ca.default_days))
 
288
      )
 
289
  print """You can apply for a certificate by filling out the input form below.
 
290
Click on the names of the parameters to get further informations about the
 
291
usage and format restrictions of the input data.<P>
 
292
Required input parameters are marked with *.
 
293
"""
 
294
  PrintEmptyForm(form,ca_name)
 
295
  htmlbase.PrintFooter()
 
296
  sys.exit(0)
 
297
 
 
298
# 1. und 2. Schritt haben Schluesselfeld
 
299
form.add(cgiforms.formInputClass('KeySize','Key Size',100,alphanumregex))
 
300
form.add(
 
301
  cgiforms.formInputClass(
 
302
    'PKCS10',
 
303
    'PKCS#10 Request',
 
304
    2000,
 
305
    (
 
306
      r'[ \w+/=\r\n]+',
 
307
      re.S+re.M)
 
308
  )
 
309
)
 
310
form.add(cgiforms.formKeygenClass('SPKAC','Public Key and Challenge',6000))
 
311
 
 
312
# Aufruf erfolgte mit Parametern
 
313
try:
 
314
  form.getparams(ignoreemptyparams=1)
 
315
except cgiforms.formContentLengthException,e:
 
316
  htmlbase.PrintErrorMsg('Content length invalid.')
 
317
  sys.exit(0)
 
318
except cgiforms.formParamNameException,e:
 
319
  htmlbase.PrintErrorMsg('Unknown parameter "%s".' % (e.name))
 
320
  sys.exit(0)
 
321
except cgiforms.formParamsMissing,e:
 
322
  htmlbase.PrintHeader('Error')
 
323
  htmlbase.PrintHeading('Error')
 
324
  print """The following parameter(s) is/are missing:<P>
 
325
<UL>
 
326
  <LI>%s
 
327
</UL><P>
 
328
Required input parameters are marked with *.
 
329
""" % (string.join(map(lambda x: x[1],e.missing),'<LI>'))
 
330
  for k in ['PKCS10','KeySize','SPKAC']:
 
331
    try:
 
332
      form.keys.remove(k)
 
333
    except ValueError:
 
334
      pass
 
335
  for i in form.inputkeys:
 
336
    form.field[i][0].default=form.field[i][0].content
 
337
  PrintEmptyForm(form,ca_name)
 
338
  htmlbase.PrintFooter()
 
339
  sys.exit(0)
 
340
except cgiforms.formParamContentException,e:
 
341
  htmlbase.PrintHeader('Error')
 
342
  htmlbase.PrintHeading('Error')
 
343
  print 'Content of field "%s" has invalid format.<P>' % (e.text)
 
344
  form.keys.remove(RequestDataKey)
 
345
  for i in form.inputkeys:
 
346
    form.field[i][0].default=form.field[i][0].content
 
347
  PrintEmptyForm(form,ca_name)
 
348
  htmlbase.PrintFooter()
 
349
  sys.exit(0)
 
350
except cgiforms.formParamStructException,e:
 
351
  htmlbase.PrintErrorMsg('Too many (%d) parameters for field "%s".' % (e.count,e.name))
 
352
  sys.exit(0)
 
353
except cgiforms.formParamLengthException,e:
 
354
  htmlbase.PrintErrorMsg('Content too long. Field "%s" has %d characters.' % (e.text,e.length))
 
355
  sys.exit(0)
 
356
 
 
357
if 'browsertype' in form.inputkeys and \
 
358
  form.field['browsertype'][0].content in key_gen_browsers.keys():
 
359
  browsertype = known_browsers_rev[form.field['browsertype'][0].content]
 
360
else:
 
361
  browsertype = http_browsertype
 
362
 
 
363
RequestDataKey,request_filenamesuffix = key_gen_browsers[known_browsers[browsertype]]
 
364
 
 
365
##############################################################################
 
366
# Zusaetzliche Ueberpruefungen diverser Parameter
 
367
##############################################################################
 
368
 
 
369
if 'commonName' in form.inputkeys:
 
370
  commonName   = form.field.get('commonName',[''])[0].content
 
371
else:
 
372
  commonName = ''
 
373
if 'emailAddress' in form.inputkeys:
 
374
  emailAddress   = form.field.get('emailAddress',[''])[0].content
 
375
else:
 
376
  emailAddress = ''
 
377
 
 
378
# Check for "internal" mail domain
 
379
if (ca_name in caInternalCertTypes) and \
 
380
   not (DomainAdr(emailAddress) in caInternalDomains):
 
381
  htmlbase.PrintErrorMsg('This type of certificate request is restricted to internal address domains!')
 
382
  sys.exit(0)
 
383
 
 
384
if not (RequestDataKey in form.inputkeys and form.field[RequestDataKey][0].content):
 
385
 
 
386
  # Aufruf erfolgte mit Parametern ohne Schluessel =>
 
387
  # 1. Schritt: Eingegebene Daten anzeigen und
 
388
  # Benutzer zur Schluesselerzeugung auffordern
 
389
 
 
390
  PrintKeygenForm(form,ca_name,ca,browsertype)
 
391
  sys.exit(0)
 
392
 
 
393
# Aufruf erfolgte mit Parametern inkl. Schluessel =>
 
394
# 2. Schritt: Forminhalt bearbeiten
 
395
 
 
396
# Check the required key length if min_key_size was defined
 
397
if ca.min_key_size>0:
 
398
  # FIX ME!!!
 
399
  # This is a very primitive and falsy key length checking!!!
 
400
  # Only useful for SPKAC
 
401
  minbytes={512:200,768:300,1024:400}
 
402
  if minbytes.has_key(ca.min_key_size) and len(form.field[RequestDataKey][0].content)<minbytes[ca.min_key_size]:
 
403
    htmlbase.PrintErrorMsg('The key length you submitted was too weak!<BR>The certificate type <STRONG>%s</STRONG> requires a minimum key size of <STRONG>%d</STRONG> bits!' % (ca_name,ca.min_key_size))
 
404
    sys.exit(0)
 
405
 
 
406
# Zufaellige ChallengeID erzeugen und daraus eindeutige, noch nicht
 
407
# existierende Dateinamen mittels MD5-Hash basteln
 
408
 
 
409
import random, md5, binascii
 
410
 
 
411
# Zufaellige ID fuer Antwort vom Benutzer
 
412
caChallengeId = md5.new('%d' % random.randint(0,99999999))
 
413
formKeys = form.inputkeys[:]
 
414
for i in formKeys:
 
415
  for j in form.field[i]:
 
416
    caChallengeId.update(j.content)
 
417
 
 
418
# ca_name und ChallengeId fuer Mail-Subjects und Dateinamen
 
419
camailSubject    = 'cert-req-%s.%s.%s' % (RequestDataKey,ca_name,string.replace(binascii.b2a_base64(caChallengeId.digest()),'/','_')[:-1])
 
420
request_filename = os.path.join(ca.pend_reqs_dir,'%s.%s' % (camailSubject,request_filenamesuffix))
 
421
 
 
422
if os.path.exists(request_filename):
 
423
  # Versuch nicht existierenden Dateinamen zu basteln schlug fehl.
 
424
  # Duerfte eigentlich nicht passieren.
 
425
  htmlbase.PrintErrorMsg('Error generating a random ID or creating temporary files.')
 
426
  sys.exit(0)
 
427
 
 
428
##############################################################################
 
429
# Request erzeugen
 
430
##############################################################################
 
431
 
 
432
request_file = open(request_filename,'w')
 
433
 
 
434
if RequestDataKey=='PKCS10':
 
435
 
 
436
  request_file.write("""-----BEGIN CERTIFICATE REQUEST-----
 
437
  %s
 
438
-----END CERTIFICATE REQUEST-----
 
439
""" % (form.field['PKCS10'][0].content))
 
440
 
 
441
elif RequestDataKey=='SPKAC':
 
442
 
 
443
  # FIX ME! This won't work with additional parameters of [ new_oids ] section
 
444
#  CertRequestKeys = ['countryName','stateOrProvinceName','localityName','organizationName','organizationalUnitName','commonName','initials','uid','emailAddress','SPKAC']
 
445
  CertRequestKeys = filter(
 
446
    lambda i: not i in ['challenge','browsertype'],
 
447
    form.keys
 
448
  )
 
449
  for i in CertRequestKeys:
 
450
    if (i in form.inputkeys) and form.field[i][0].content:
 
451
      request_file.write('%s = %s\n' % (i,form.field[i][0].content))
 
452
 
 
453
request_file.close()
 
454
os.chmod(request_filename,0444)
 
455
 
 
456
##############################################################################
 
457
# Send a nice e-mail with random ID to user to initiate mail dialogue
 
458
##############################################################################
 
459
 
 
460
if caCertReqMailAdr and emailAddress:
 
461
 
 
462
  import smtplib, mimify
 
463
 
 
464
  if commonName:
 
465
    to_addr = '%s <%s>' % (mimify.mime_encode_header(commonName),emailAddress)
 
466
  else:
 
467
    to_addr = '%s' % (emailAddress)
 
468
 
 
469
  # Mailbody erzeugen
 
470
  mail_msg = """From: %s
 
471
To: %s
 
472
Subject: %s
 
473
 
 
474
Someone (maybe you) has sent a certificate request
 
475
to our certificate authority.
 
476
 
 
477
Please answer this e-mail with the same subject
 
478
if this was really you and the data below is correct.
 
479
 
 
480
If someone abused your name / e-mail address simply
 
481
forget about this message and delete it. %s
 
482
 
 
483
------------- Identity Information -------------
 
484
""" % (caCertReqMailAdr,\
 
485
       to_addr,\
 
486
       camailSubject,\
 
487
       (caPendCertReqValid>0)*(' The certificate\nrequest will be removed automatically after %d hours.' % caPendCertReqValid)
 
488
      )
 
489
  # Hier den eigentlichen Cert-Req an Mailbody anhaengen
 
490
  formKeys = form.keys[:]
 
491
  for unwantedkey in ['challenge','browsertype',RequestDataKey]:
 
492
    try:
 
493
      formKeys.remove(unwantedkey)
 
494
    except ValueError:
 
495
      pass
 
496
 
 
497
  mail_msg_paramlist = []
 
498
  for i in formKeys:
 
499
    if (i in form.inputkeys) and form.field[i][0].content:
 
500
      mail_msg_paramlist.append('%s = %s' % (i,form.field[i][0].content))
 
501
  mail_msg = '%s%s' % (mail_msg,string.join(mail_msg_paramlist,'\n'))
 
502
 
 
503
  try:
 
504
    smtpconn=smtplib.SMTP(MailRelay)
 
505
    smtpconn.set_debuglevel(0)
 
506
    try:
 
507
      smtpconn.sendmail(caCertReqMailAdr,[to_addr],mail_msg)
 
508
    except:
 
509
      htmlbase.PrintErrorMsg(
 
510
        'Unable to send an e-mail to <B>%s</B>!<BR>Please provide your correct and valid %s or ask your system administrator.' % \
 
511
        (
 
512
          charset.escapeHTML(to_addr),
 
513
          HelpURL(HelpUrlBase,'emailAddress','e-mail address')
 
514
        )
 
515
      )
 
516
      sys.exit(0)
 
517
    smtpconn.quit()
 
518
  except socket.error:
 
519
    htmlbase.PrintErrorMsg('Unable to contact default mail server!')
 
520
    sys.exit(0)
 
521
 
 
522
# Schliesslich und endlich...
 
523
htmlbase.PrintHeader('Certificate request stored.')
 
524
htmlbase.PrintHeading('Certificate request is stored.')
 
525
print """Your certificate request was stored for
 
526
further processing."""
 
527
 
 
528
if caCertReqMailAdr and emailAddress:
 
529
  print """<P>You will get an e-mail message with a random ID.
 
530
Please answer this e-mail to confirm your certificate request."""
 
531
 
 
532
if caPendCertReqValid:
 
533
  print """Otherwise your certificate request will be
 
534
removed automatically after %d hour(s).<P>""" % (caPendCertReqValid)
 
535
 
 
536
print '<P>Once again the data you gave to us:<P>'
 
537
PrintInput(form)
 
538
htmlbase.PrintFooter()
 
539
 
 
540
sys.exit(0)
 
541