Back to index

python-weblib  1.3.9
sslenv.py
Go to the documentation of this file.
00001 """
00002 pyweblib.sslenv.py - retrieve SSL data from environment vars
00003 (C) by Michael Stroeder
00004 
00005 This module is distributed under the terms of the
00006 GPL (GNU GENERAL PUBLIC LICENSE) Version 2
00007 (see http://www.gnu.org/copyleft/gpl.html)
00008 
00009 $Id: sslenv.py,v 1.11 2011/04/16 13:57:25 michael Exp $
00010 """
00011 
00012 __version__ = '0.6.3'
00013 
00014 from forms import escapeHTML
00015 
00016 import sys,os,re,string
00017 
00018 def GetAllSSLEnviron(env=None):
00019   """
00020   Get all SSL-related environment vars and return mod_ssl
00021   compatible dictionary.
00022 
00023   mod_ssl compatible names are preferred. ApacheSSL names
00024   are used as fallback.
00025   """
00026   env = env or os.environ
00027   if env.get('HTTPS','off')!='on':
00028     return {}
00029   SSLEnv = {}
00030   SSLEnv['SSL_CIPHER_ALGKEYSIZE'] = \
00031     env.get('SSL_CIPHER_ALGKEYSIZE',
00032     env.get('HTTPS_KEYSIZE',
00033     env.get('SSL_KEYSIZE',
00034     env.get('SSL_SERVER_KEY_SIZE',
00035     None))))
00036   SSLEnv['SSL_CIPHER_EXPORT'] = \
00037     env.get('SSL_CIPHER_EXPORT',
00038     env.get('HTTPS_EXPORT',
00039     env.get('SSL_EXPORT',
00040     None)))
00041   SSLEnv['SSL_CIPHER'] = \
00042     env.get('SSL_CIPHER',
00043     env.get('HTTPS_CIPHER',
00044     None))
00045   SSLEnv['SSL_CIPHER_USEKEYSIZE'] = \
00046     env.get('SSL_CIPHER_USEKEYSIZE',
00047     env.get('HTTPS_SECRETKEYSIZE',
00048     env.get('SSL_SECKEYSIZE',
00049     None)))
00050   SSLEnv['SSL_CLIENT_A_SIG'] = \
00051     env.get('SSL_CLIENT_A_SIG',
00052     env.get('SSL_CLIENT_SIGNATURE_ALGORITHM',
00053     None))
00054   SSLEnv['SSL_CLIENT_CERT'] = \
00055     env.get('SSL_CLIENT_CERT',
00056     env.get('SSL_CLIENT_CERTIFICATE',
00057     None))
00058   SSLEnv['SSL_CLIENT_I_DN'] = \
00059     env.get('SSL_CLIENT_I_DN',
00060     env.get('SSL_CLIENT_IDN',
00061     None))
00062   SSLEnv['SSL_CLIENT_I_DN_CN'] = \
00063     env.get('SSL_CLIENT_I_DN_CN',
00064     env.get('SSL_CLIENT_ICN',
00065     None))
00066   SSLEnv['SSL_CLIENT_I_DN_C'] = \
00067     env.get('SSL_CLIENT_I_DN_C',
00068     env.get('SSL_CLIENT_IC',
00069     None))
00070   SSLEnv['SSL_CLIENT_I_DN_Email'] = \
00071     env.get('SSL_CLIENT_I_DN_Email',
00072     env.get('SSL_CLIENT_IEMAIL',
00073     None))
00074   SSLEnv['SSL_CLIENT_I_DN_L'] = \
00075     env.get('SSL_CLIENT_I_DN_L',
00076     env.get('SSL_CLIENT_IL',
00077     None))
00078   SSLEnv['SSL_CLIENT_I_DN_O'] = \
00079     env.get('SSL_CLIENT_I_DN_O',
00080     env.get('SSL_CLIENT_IO',
00081     None))
00082   SSLEnv['SSL_CLIENT_I_DN_OU'] = \
00083     env.get('SSL_CLIENT_I_DN_OU',
00084     env.get('SSL_CLIENT_IOU',
00085     None))
00086   SSLEnv['SSL_CLIENT_I_DN_SP'] = \
00087     env.get('SSL_CLIENT_I_DN_SP',
00088     env.get('SSL_CLIENT_ISP',
00089     None))
00090   SSLEnv['SSL_CLIENT_M_SERIAL'] = \
00091     env.get('SSL_CLIENT_M_SERIAL',
00092     env.get('SSL_CLIENT_CERT_SERIAL',
00093     None))
00094   SSLEnv['SSL_CLIENT_S_DN'] = \
00095     env.get('SSL_CLIENT_S_DN',
00096     env.get('SSL_CLIENT_DN',
00097     None))
00098   SSLEnv['SSL_CLIENT_S_DN_CN'] = \
00099     env.get('SSL_CLIENT_S_DN_CN',
00100     env.get('SSL_CLIENT_CN',
00101     None))
00102   SSLEnv['SSL_CLIENT_S_DN_C'] = \
00103     env.get('SSL_CLIENT_S_DN_C',
00104     env.get('SSL_CLIENT_C',
00105     None))
00106   SSLEnv['SSL_CLIENT_S_DN_Email'] = \
00107     env.get('SSL_CLIENT_S_DN_Email',
00108     env.get('SSL_CLIENT_EMAIL',
00109     None))
00110   SSLEnv['SSL_CLIENT_S_DN_L'] = \
00111     env.get('SSL_CLIENT_S_DN_L',
00112     env.get('SSL_CLIENT_L',
00113     None))
00114   SSLEnv['SSL_CLIENT_S_DN_O'] = \
00115     env.get('SSL_CLIENT_S_DN_O',
00116     env.get('SSL_CLIENT_O',
00117     None))
00118   SSLEnv['SSL_CLIENT_S_DN_OU'] = \
00119     env.get('SSL_CLIENT_S_DN_OU',
00120     env.get('SSL_CLIENT_OU',
00121     None))
00122   SSLEnv['SSL_CLIENT_S_DN_SP'] = \
00123     env.get('SSL_CLIENT_S_DN_SP',
00124     env.get('SSL_CLIENT_SP',
00125     None))
00126   SSLEnv['SSL_CLIENT_V_END'] = \
00127     env.get('SSL_CLIENT_V_END',
00128     env.get('SSL_CLIENT_CERT_END',
00129     None))
00130   SSLEnv['SSL_CLIENT_V_START'] = \
00131     env.get('SSL_CLIENT_V_START',
00132     env.get('SSL_CLIENT_CERT_START',
00133     None))
00134   SSLEnv['SSL_PROTOCOL'] = \
00135     env.get('SSL_PROTOCOL',
00136     env.get('SSL_PROTOCOL_VERSION',
00137     None))
00138   SSLEnv['SSL_SERVER_A_SIG'] = \
00139     env.get('SSL_SERVER_A_SIG',
00140     env.get('SSL_SERVER_SIGNATURE_ALGORITHM',
00141     None))
00142   SSLEnv['SSL_SERVER_CERT'] = \
00143     env.get('SSL_SERVER_CERT',
00144     env.get('SSL_SERVER_CERTIFICATE',
00145     None))
00146   SSLEnv['SSL_SERVER_I_DN_CN'] = \
00147     env.get('SSL_SERVER_I_DN_CN',
00148     env.get('SSL_SERVER_ICN',
00149     None))
00150   SSLEnv['SSL_SERVER_I_DN_C'] = \
00151     env.get('SSL_SERVER_I_DN_C',
00152     env.get('SSL_SERVER_IC',
00153     None))
00154   SSLEnv['SSL_SERVER_I_DN_Email'] = \
00155     env.get('SSL_SERVER_I_DN_Email',
00156     env.get('SSL_SERVER_IEMAIL',
00157     None))
00158   SSLEnv['SSL_SERVER_I_DN_L'] = \
00159     env.get('SSL_SERVER_I_DN_L',
00160     env.get('SSL_SERVER_IL',
00161     None))
00162   SSLEnv['SSL_SERVER_I_DN_O'] = \
00163     env.get('SSL_SERVER_I_DN_O',
00164     env.get('SSL_SERVER_IO',
00165     None))
00166   SSLEnv['SSL_SERVER_I_DN'] = \
00167     env.get('SSL_SERVER_I_DN',
00168     env.get('SSL_SERVER_IDN',
00169     None))
00170   SSLEnv['SSL_SERVER_I_DN_OU'] = \
00171     env.get('SSL_SERVER_I_DN_OU',
00172     env.get('SSL_SERVER_IOU',
00173     None))
00174   SSLEnv['SSL_SERVER_I_DN_SP'] = \
00175     env.get('SSL_SERVER_I_DN_SP',
00176     env.get('SSL_SERVER_ISP',
00177     None))
00178   SSLEnv['SSL_SERVER_M_SERIAL'] = \
00179     env.get('SSL_SERVER_M_SERIAL',
00180     env.get('SSL_SERVER_CERT_SERIAL',
00181     None))
00182   SSLEnv['SSL_SERVER_S_DN'] = \
00183     env.get('SSL_SERVER_S_DN',
00184     env.get('SSL_SERVER_DN',
00185     None))
00186   SSLEnv['SSL_SERVER_S_DN_CN'] = \
00187     env.get('SSL_SERVER_S_DN_CN',
00188     env.get('SSL_SERVER_CN',
00189     None))
00190   SSLEnv['SSL_SERVER_S_DN_C'] = \
00191     env.get('SSL_SERVER_S_DN_C',
00192     env.get('SSL_SERVER_C',
00193     None))
00194   SSLEnv['SSL_SERVER_S_DN_Email'] = \
00195     env.get('SSL_SERVER_S_DN_Email',
00196     env.get('SSL_SERVER_EMAIL',
00197     None))
00198   SSLEnv['SSL_SERVER_S_DN_L'] = \
00199     env.get('SSL_SERVER_S_DN_L',
00200     env.get('SSL_SERVER_L',
00201     None))
00202   SSLEnv['SSL_SERVER_S_DN_O'] = \
00203     env.get('SSL_SERVER_S_DN_O',
00204     env.get('SSL_SERVER_O',
00205     None))
00206   SSLEnv['SSL_SERVER_S_DN_OU'] = \
00207     env.get('SSL_SERVER_S_DN_OU',
00208     env.get('SSL_SERVER_OU',
00209     None))
00210   SSLEnv['SSL_SERVER_S_DN_SP'] = \
00211     env.get('SSL_SERVER_S_DN_SP',
00212     env.get('SSL_SERVER_SP',
00213     None))
00214   SSLEnv['SSL_SERVER_V_END'] = \
00215     env.get('SSL_SERVER_V_END',
00216     env.get('SSL_SERVER_CERT_END',
00217     None))
00218   SSLEnv['SSL_SERVER_V_START'] = \
00219     env.get('SSL_SERVER_V_START',
00220     env.get('SSL_SERVER_CERT_START',
00221     None))
00222   SSLEnv['SSL_VERSION_LIBRARY'] = \
00223     env.get('SSL_VERSION_LIBRARY',
00224     env.get('SSL_SSLEAY_VERSION',
00225     None))
00226   return SSLEnv
00227 
00228 
00229 def SecLevel(env,acceptedciphers,valid_dn_regex='',valid_idn_regex=''):
00230   """
00231   Determine Security Level of SSL session.
00232 
00233   Returns:
00234   0  no SSL at all
00235   1  SSL-connection and cipher used is in acceptedciphers
00236   2  like 1 but client also has sent client certificate
00237      matching valid_dn_regex and valid_idn_regex.
00238   """
00239   https_env = GetAllSSLEnviron(env)
00240   if https_env and https_env.get('SSL_CIPHER','') in acceptedciphers:
00241     ssl_client_s_dn = https_env.get('SSL_CLIENT_S_DN','')
00242     if ssl_client_s_dn:
00243       ssl_client_i_dn = https_env.get('SSL_CLIENT_I_DN','')
00244       dn_rm = re.compile(valid_dn_regex).match(ssl_client_s_dn)
00245       idn_rm = re.compile(valid_idn_regex).match(ssl_client_i_dn)
00246       if (dn_rm) and (idn_rm):
00247         return 2
00248       else:
00249         return 1
00250     else:
00251       return 1
00252   else:
00253     return 0
00254 
00255 
00256 def PrintSecInfo(env,acceptedciphers,valid_dn_regex='',valid_idn_regex='',f=sys.stdout):
00257   """
00258   Print the SSL data in HTML format
00259   """
00260   seclevel = SecLevel(env,acceptedciphers,valid_dn_regex,valid_idn_regex)
00261   https_env = GetAllSSLEnviron(env)
00262   f.write("""<h3>Security level</h3>
00263 <p>Current security level is: <strong>%d</strong></p>
00264 <table cellspacing="5%%" summary="Possible SSL/TLS security levels">
00265 <tr>
00266   <td align=center width=10%%>0</td>
00267   <td>no encryption at all</td>
00268 </tr>
00269 <tr>
00270   <td align=center>1</td>
00271   <td>Session is encrypted with SSL and cipher is accepted</td>
00272 </tr>
00273 <tr>
00274   <td align=center>2</td>
00275   <td>
00276     Client presented valid certificate,
00277     the DN of the certified object matches &quot;<code>%s</code>&quot;
00278     and the DN of the certifier matches &quot;<code>%s</code>&quot;
00279   </td>
00280 </tr>
00281 </table>
00282    """ % (seclevel,valid_dn_regex,valid_idn_regex))
00283 
00284   if seclevel>=1:
00285     SSL_PROTOCOL = https_env.get('SSL_PROTOCOL')
00286     SSL_CIPHER_ALGKEYSIZE = https_env.get('SSL_CIPHER_ALGKEYSIZE')
00287     SSL_CIPHER = https_env.get('SSL_CIPHER')
00288     SSL_CIPHER_USEKEYSIZE = https_env.get('SSL_CIPHER_USEKEYSIZE')
00289     SSL_SERVER_S_DN = https_env.get('SSL_SERVER_S_DN')
00290     SSL_SERVER_I_DN = https_env.get('SSL_SERVER_I_DN')
00291 
00292     f.write("""<p><strong>%s</strong> connection with cipher <strong>%s</strong>,
00293 key size <strong>%s Bit</strong>, actually used key size <strong>%s Bit</strong>.</p>
00294 <h3>Server certificate</h3>
00295 <dl>
00296   <dt>Subject-DN:</dt>
00297   <dd>%s</dd>
00298   <dt>Issuer-DN:</dt>
00299   <dd>%s</dd>
00300 </dl>
00301 """ % (
00302   SSL_PROTOCOL,
00303   SSL_CIPHER,
00304   SSL_CIPHER_ALGKEYSIZE,
00305   SSL_CIPHER_USEKEYSIZE,
00306   escapeHTML(SSL_SERVER_S_DN),
00307   escapeHTML(SSL_SERVER_I_DN),
00308 ))
00309 
00310   if seclevel>=2:
00311 
00312     SSL_CLIENT_I_DN = https_env.get('SSL_CLIENT_I_DN',https_env.get('SSL_CLIENT_IDN','')
00313     )
00314     SSL_CLIENT_S_DN = https_env.get('SSL_CLIENT_S_DN',https_env.get('SSL_CLIENT_DN',''))
00315 
00316     f.write("""<h3>Your client certificate</h3>
00317 <dl>
00318   <dt>Subject-DN:</dt>
00319   <dd>%s</dd>
00320   <dt>Issuer-DN:</dt>
00321   <dd>%s</dd>
00322 </dl>
00323 """ % (
00324   escapeHTML(SSL_CLIENT_S_DN),
00325   escapeHTML(SSL_CLIENT_I_DN),
00326 ))
00327