Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
Changeset 8168 – NDG Security Search: Login Preferences Help/Guide About Trac Wiki Timeline Roadmap Browse Source View Tickets Search Context Navigation ← Previous Changeset Next Changeset → Changeset 8168 View differences inline side by side Show lines around each change Show the changes in full context Ignore: Blank lines Case changes White space changes Timestamp: 04/10/12 17:18:32 (10 years ago) Author: pjkersha Message: Completed refactoring of middleware module subject to tests added factory module for instantiating CA class Location: trunk/online_ca_service/onlineca/server Files: 1 added 1 edited factory.py (added) wsgi/middleware.py (modified) (7 diffs) Legend: Unmodified Added Removed trunk/online_ca_service/onlineca/server/wsgi/middleware.py r8167 r8168   14 14   15 15 import httplib  16   import socket    16 import os  17 17 import base64  18   import traceback  19 18   20 19 from webob import Request  21 20 from OpenSSL import crypto  22 21     22 from onlineca.server.interfaces import OnlineCaInterface    23 from onlineca.server.factory import call_module_object  23 24 from onlineca.server.wsgi.httpbasicauth import HttpBasicAuthResponseException  24 25   … …   29 30   30 31 class OnlineCaMiddleware(object):  31       """Build on MyClientMiddleware to expose a special logon Web Service method  32         33       TODO: possible refactor to NOT inherit from MyProxyClientMiddleware but   34       instead receive a MyProxyClient instance via environ set from an upstream   35       MyProxyClientMiddleware object  36         37       @cvar LOGON_FUNC_ENV_KEYNAME_OPTNAME: ini file option name to set the key   38       name in WSGI environ dict to assign to the Logon function created by this  39       middleware  40       @type LOGON_FUNC_ENV_KEYNAME_OPTNAME: string  41         42       @cvar DEFAULT_LOGON_FUNC_ENV_KEYNAME: default value for the key name in     32     """Web service interface for issuing certificates and providing CA trust     33     roots    34         35     @cvar CA_CLASS_FACTORY_OPTNAME: config file option name for Python path to function     36     or class constructor to make a CA instance.  CA instance must implement CA     37     interface class as defined in the interfaces module -     38     onlineca.server.interfaces import OnlineCaInterface    39     @type CA_CLASS_FACTORY_OPTNAME: string    40         41     @cvar DEFAULT_CA_CLASS_FACTORY: default value for the key name in   43 42     WSGI environ dict to assign to the Logon function created by this  44 43     middleware  45       @type DEFAULT_ LOGON_FUNC_ENV_KEYNAME: string    44     @type DEFAULT_ CA_CLASS_FACTORY: string  46 45       47 46     @cvar CERT_REQ_POST_PARAM_KEYNAME: HTTP POST field name for the   … …   49 48     @type CERT_REQ_POST_PARAM_KEYNAME: string  50 49       51       @ivar __ logonFuncEnvironKeyName:   52       @type __ logonFuncEnvironKeyName: string    50     @ivar __ ca_class_factory_path:     51     @type __ ca_class_factory_path: string  53 52       54 53     @cvar PARAM_PREFIX: prefix for ini file option names   … …   57 56       58 57     # Options for ini file  59       LOGON_FUNC_ENV_KEYNAME_OPTNAME = 'logonFuncEnvKeyName'  60       DEFAULT_GLOBAL_PASSWD_OPTNAME = 'global_passwd'    58     CA_CLASS_FACTORY_OPTNAME = 'ca_class_factory_path'  61 59   62 60     # Default environ key names  63       DEFAULT_LOGON_FUNC_ENV_KEYNAME = ('myproxy.server.wsgi.middleware.'  64                                         'MyProxyClientMiddleware.logon')    61     DEFAULT_CA_CLASS_FACTORY = 'ca.impl.CertificateAuthority'  65 62       66 63     CERT_REQ_POST_PARAM_KEYNAME = 'certificate_request'  67 64       68 65     __slots__ = (  69           '__logonFuncEnvironKeyName',   70           '__global_passwd'    66         '__ca',    67         '__ca_class_factory_path',    68         '__issue_cert_path',    69         '__trustroots_path',    70         '__trustroots_dir'  71 71     )  72       PARAM_PREFIX = 'myproxy.ws.server.logon.'    72     PARAM_PREFIX = 'onlineca.server.'    73     CA_PARAM_PREFIX = CA_CLASS_FACTORY_OPTNAME + '.'  73 74       74 75     def __init__(self, app):  … …   78 79         @param app: WSGI callable for next application in stack  79 80         '''  80           super(OnlineCaMiddleware, self).__init__(app)  81           self.__logonFuncEnvironKeyName = None  82           self.__global_passwd = None      81         self._app = None    82         self.__ca_class_factory_path = None    83         self.__issue_cert_path = None    84         self.__trustroots_path = None    85         self.__ca = None  83 86             84       def parse_config(self, prefix=PARAM_PREFIX, myProxyClientPrefix=None,  85                       **app_conf):    87     def parse_config(self, prefix=PARAM_PREFIX, ca_prefix=CA_PARAM_PREFIX,    88                      **app_conf):  86 89         """Parse dictionary of configuration items updating the relevant   87 90         attributes of this instance  … …   97 100         """  98 101           99           # Call parent version  100           super(OnlineCaMiddleware, self).parse_config(prefix=prefix,   101                               myProxyClientPrefix=myProxyClientPrefix, **app_conf)    102                 103 102         # Extract additional parameters  104           logonFuncEnvKeyOptName = prefix + \  105                           self.__class__.LOGON_FUNC_ENV_KEYNAME_OPTNAME  106     107           self.logonFuncEnvironKeyName = app_conf.get(logonFuncEnvKeyOptName,  108                           self.__class__.DEFAULT_LOGON_FUNC_ENV_KEYNAME)  109             110           global_passwd_optname = prefix + \  111                           self.__class__.DEFAULT_GLOBAL_PASSWD_OPTNAME  112                             113           self.__global_passwd = app_conf.get(global_passwd_optname)  114     115       @property  116       def logonFuncEnvironKeyName(self):  117           """Get MyProxyClient logon function environ key name  118               103         cls = self.__class__    104         ca_class_factory_path_optname = prefix + cls.CA_CLASS_FACTORY_OPTNAME    105     106         self.ca_class_factory_path = app_conf.get(ca_class_factory_path_optname,    107                                                   cls.DEFAULT_CA_CLASS_FACTORY)    108             109         ca_opt_prefix = prefix + ca_prefix    110         ca_opt_offset = len(ca_opt_prefix)    111         ca_opt = {}    112         for optname, optval in app_conf.items():    113             if optname.startswith(ca_opt_prefix):    114                 ca_optname = optname[ca_opt_offset:]    115                 ca_opt[ca_optname] = optval    116                     117         self.instantiate_ca(**ca_opt)    118             119     def instantiate_ca(self, **ca_object_kwargs):    120         '''Create CA class instance    121         @param ca_object_kwargs: keywords to CA class constructor    122         '''    123         self.__ca = call_module_object(self.ca_class_factory_path,     124                                        object_properties=ca_object_kwargs)    125         if not isinstance(self.__ca, OnlineCaInterface):    126             raise TypeError('%r CA class factory must return a %r derived '    127                             'type' % (self.ca_class_factory_path,     128                                       type(OnlineCaInterface)))    129             130     @property    131     def ca_class_factory_path(self):    132         return self.__ca_class_factory_path    133     134     @ca_class_factory_path.setter    135     def ca_class_factory_path(self, value):    136         if not isinstance(value, basestring):    137             raise TypeError('Expecting string type for "ca_class_factory_path"'    138                             '; got %r type' % type(value))    139                 140         self.__ca_class_factory_path = value    141     142     @property    143     def issue_cert_path(self):    144         """Get URI path for get trust roots method  119 145         @rtype: basestring  120           @return: MyProxyClient logon function environ key name  121           """  122           return self.__logonFuncEnvironKeyName  123     124       @logonFuncEnvironKeyName.setter  125       def logonFuncEnvironKeyName(self, value):  126           """Set MyProxyClient environ key name  127               146         @return: path for get trust roots method    147         """    148         return self.__issue_cert_path    149     150     @issue_cert_path.setter    151     def issue_cert_path(self, value):    152         """Set URI path for get trust roots method  128 153         @type value: basestring  129           @param value: MyProxyClient logon function environ key name  130           """  131           if not isinstance(value, basestring):  132               raise TypeError('Expecting string type for '  133                               '"logonFuncEnvironKeyName"; got %r type' %     154         @param value: path for get trust roots method    155         """    156         if not isinstance(value, basestring):    157             raise TypeError('Expecting string type for "path"; got %r' %   134 158                             type(value))  135           self.__logonFuncEnvironKeyName = value  136           159             160         self.__issue_cert_path = value    161     162     @property    163     def trustroots_path(self):    164         """Get URI path for get trust roots method    165         @rtype: basestring    166         @return: path for get trust roots method    167         """    168         return self.__trustroots_path    169     170     @trustroots_path.setter    171     def trustroots_path(self, value):    172         """trust roots path    173         """    174         if not isinstance(value, basestring):    175             raise TypeError('Expecting string type for "path"; got %r' %     176                             type(value))    177             178         self.__trustroots_path = value     179     180     @property    181     def trustroots_dir(self):    182         """Get trust roots dir    183         """    184         return self.__trustroots_dir    185     186     @trustroots_dir.setter    187     def trustroots_dir(self, value):    188         """trust roots dir    189         """    190         if not isinstance(value, basestring):    191             raise TypeError('Expecting string type for "path"; got %r' %     192                             type(value))    193             194         self.__trustroots_dir = value     195                      137 196     def __call__(self, environ, start_response):  138 197         '''Set MyProxy logon method in environ  … …   143 202         @param start_response: standard WSGI start response function  144 203         '''  145           log.debug("MyProxyClientMiddleware.__call__ ...")  146           environ[self.logonFuncEnvironKeyName] = self.myProxyLogon  147             148           return super(OnlineCaMiddleware, self).__call__(environ,   149                                                                 start_response)  150             151       @property  152       def myProxyLogon(self):  153           """Return the MyProxy logon method wrapped as a HTTP Basic Auth   154           authenticate interface function  155             156           @rtype: function  157           @return: MyProxy logon HTTP Basic Auth Callback  158           """  159           def _myProxylogon(environ, start_response, username, password):  160               """Wrap MyProxy logon method as a WSGI app  161               @type environ: dict  162               @param environ: WSGI environment variables dictionary  163               @type start_response: function  164               @param start_response: standard WSGI start response function  165               @type username: basestring  166               @param username: username credential to MyProxy logon  167               @type password: basestring  168               @param password: pass-phrase for MyProxy logon call  169               @raise HttpBasicAuthResponseException: invalid client request  170               @raise MyProxyClientMiddlewareError: socket error for backend  171               MyProxy server  172               """    173               request = Request(environ)  174                 175               requestMethod = environ.get('REQUEST_METHOD')                           176               if requestMethod != 'POST':  177                   response = "HTTP Request method not recognised"  178                   log.error("HTTP Request method %r not recognised",   179                             requestMethod)  180                   raise HttpBasicAuthResponseException(response,   181                                                        httplib.METHOD_NOT_ALLOWED)  182                     183               # Extract cert request and convert to standard string - SSL library  184               # will not accept unicode  185               cert_req_key = self.__class__.CERT_REQ_POST_PARAM_KEYNAME  186               pem_cert_req = str(request.POST.get(cert_req_key))  187               if pem_cert_req is None:  188                   response = ("No %r form variable set in POST message" %   189                               cert_req_key)  190                   log.error(response)  191                   raise HttpBasicAuthResponseException(response,   192                                                        httplib.BAD_REQUEST)  193             194               log.debug("cert req = %r", pem_cert_req)  195                 196               # Expecting PEM encoded request  197               try:  198                   cert_req = crypto.load_certificate_request(crypto.FILETYPE_PEM,  199                                                              pem_cert_req)  200               except crypto.Error, e:  201                   log.error("Error loading input certificate request: %r",   202                             pem_cert_req)  203                   raise HttpBasicAuthResponseException("Error loading input "  204                                                        "certificate request",  205                                                        httplib.BAD_REQUEST)  206                 207               # Convert to ASN1 format expect by logon client call  208               asn1CertReq = crypto.dump_certificate_request(crypto.FILETYPE_ASN1,   209                                                             cert_req)  210     211               # A global password can be set for the MyProxy call.  This is used  212               # for the special case where this service is providing delegation  213               # The MyProxyCA uses a special PAM with a single password set for  214               # all usernames.  Clients to this service must be protected by  215               # SSL client authentication  216               if self.__global_passwd is not None:  217                   password_ = self.__global_passwd  218               else:  219                   password_ = password  220                     221               try:  222                   credentials = self.myProxyClient.logon(username,   223                                                          password_,  224                                                          certReq=asn1CertReq)  225                   status = self.getStatusMessage(httplib.OK)  226                   response = '\n'.join(credentials)  227                     228                   start_response(status,  229                                  [('Content-length', str(len(response))),  230                                   ('Content-type', 'text/plain')])  231                   return [response]  232                            233               except MyProxyClientError, e:  234                   raise HttpBasicAuthResponseException(str(e),  235                                                        httplib.UNAUTHORIZED)  236               except socket.error, e:  237                   raise OnlineCaMiddlewareError("Socket error "  238                                           "with MyProxy server %r: %s" %   239                                           (self.myProxyClient.hostname, e))  240               except Exception, e:  241                   log.error("MyProxyClient.logon raised an unknown exception "  242                             "calling %r: %s",   243                             self.myProxyClient.hostname,  244                             traceback.format_exc())  245                   raise # Trigger 500 Internal Server Error  246                 247           return _myProxylogon  248         249         250   class OnlineCaGetTrustRootsMiddlewareError(Exception):  251       """OnlineCaGetTrustRootsMiddleware exception class"""  252         253         254   class OnlineCaGetTrustRootsMiddleware(MyProxyClientMiddlewareBase):  255       """HTTP client interface for MyProxy server Get Trust Roots method  256         257       It relies on a myproxy.server.wsgi.MyProxyClientMiddleware instance called   258       upstream in the WSGI stack to set up a MyProxyClient instance and make it   259       available in the environ to call its getTrustRoots method.  260         261       @cvar PATH_OPTNAME: ini file option to set the URI path for this service  262       @type PATH_OPTNAME: string  263         264       @cvar DEFAULT_PATH: default URI path setting  265       @type DEFAULT_PATH: string  266     267       @cvar PARAM_PREFIX: prefix for ini file option names   268       @type PARAM_PREFIX: string  269         270       @ivar __path: URI path setting for this service  271       @type __path: basestring  272       """  273             274       PATH_OPTNAME = 'path'       275       DEFAULT_PATH = '/myproxy/get-trustroots'  276         277       # Option prefixes  278       PARAM_PREFIX = 'myproxy.getTrustRoots.'  279         280       __slots__ = (  281           '__path',  282       )  283         284       def __init__(self, app):  285           '''Create attributes  286             287           @type app: function  288           @param app: WSGI callable for next application in stack  289           '''  290           super(OnlineCaGetTrustRootsMiddleware, self).__init__(app)  291           self.__path = None  292             293       @classmethod  294       def filter_app_factory(cls, app, global_conf, prefix=PARAM_PREFIX,   295                              **app_conf):  296           """Function following Paste filter app factory signature  297             298           @type app: callable following WSGI interface  299           @param app: next middleware/application in the chain        300           @type global_conf: dict          301           @param global_conf: PasteDeploy global configuration dictionary  302           @type prefix: basestring  303           @param prefix: prefix for configuration items  304           @type app_conf: dict          305           @param app_conf: PasteDeploy application specific configuration   306           dictionary  307             308           @rtype: myproxy.server.wsgi.middleware.OnlineCaGetTrustRootsMiddleware  309           @return: an instance of this middleware  310           """  311           app = cls(app)  312           app.parse_config(prefix=prefix, **app_conf)  313           return app  314         315       def parse_config(self, prefix=PARAM_PREFIX, **app_conf):  316           """Parse dictionary of configuration items updating the relevant   317           attributes of this instance  318             319           @type prefix: basestring  320           @param prefix: prefix for configuration items  321           @type app_conf: dict          322           @param app_conf: PasteDeploy application specific configuration   323           dictionary  324           """  325           clientEnvKeyOptName = prefix + self.__class__.CLIENT_ENV_KEYNAME_OPTNAME  326                         327           self.clientEnvironKeyName = app_conf.get(clientEnvKeyOptName,  328                                       self.__class__.DEFAULT_CLIENT_ENV_KEYNAME)  329             330           pathOptName = prefix + self.__class__.PATH_OPTNAME  331           self.path = app_conf.get(pathOptName, self.__class__.DEFAULT_PATH)  332     333       def _getPath(self):  334           """Get URI path for get trust roots method  335           @rtype: basestring  336           @return: path for get trust roots method  337           """  338           return self.__path  339     340       def _setPath(self, value):  341           """Set URI path for get trust roots method  342           @type value: basestring  343           @param value: path for get trust roots method  344           """  345           if not isinstance(value, basestring):  346               raise TypeError('Expecting string type for "path"; got %r' %   347                               type(value))  348             349           self.__path = value  350     351       path = property(fget=_getPath, fset=_setPath,   352                       doc="environ SCRIPT_NAME path which invokes the "  353                           "getTrustRoots method on this middleware")  354         355       def __call__(self, environ, start_response):  356           '''Get MyProxyClient instance from environ and call MyProxy   357           getTrustRoots method returning the response.  358             359           MyProxyClientMiddleware must be in place upstream in the WSGI stack  360             361           @type environ: dict  362           @param environ: WSGI environment variables dictionary  363           @type start_response: function  364           @param start_response: standard WSGI start response function  365             366           @rtype: list  367           @return: get trust roots response  368           '''  369           # Skip if path doesn't match  370           if environ['PATH_INFO'] != self.path:  371               return self.app(environ, start_response)  372             373           log.debug("OnlineCaGetTrustRootsMiddleware.__call__ ...")  374             375           # Check method  376           requestMethod = environ.get('REQUEST_METHOD')               377           if requestMethod != 'GET':  378               response = "HTTP Request method not recognised"  379               log.error("HTTP Request method %r not recognised", requestMethod)  380               status = self.__class__.getStatusMessage(httplib.BAD_REQUEST)  381               start_response(status,  382                              [('Content-type', 'text/plain'),  383                               ('Content-length', str(len(response)))])  384               return [response]  385             386           myProxyClient = environ[self.clientEnvironKeyName]  387           if not isinstance(myProxyClient, MyProxyClient):  388               raise TypeError('Expecting %r type for "myProxyClient" environ[%r] '  389                               'attribute got %r' % (MyProxyClient,   390                                                     self.clientEnvironKeyName,  391                                                     type(myProxyClient)))  392             393           response = self._getTrustRoots(myProxyClient)  394           start_response(self.getStatusMessage(httplib.OK),    204         log.debug("OnlineCaMiddleware.__call__ ...")    205     206         path_info = environ['PATH_INFO']    207         if path_info == self.__issue_cert_path:    208             response = self._issue_certificate(environ)    209                        210         elif path_info == self.__trustroots_path:    211             response = self._get_trustroots()    212                 213         else:                  214             return self._app(environ, start_response)    215                 216         start_response('200 OK',  395 217                        [('Content-length', str(len(response))),  396 218                         ('Content-type', 'text/plain')])  397     398 219         return [response]  399         400       @classmethod  401       def _getTrustRoots(cls, myProxyClient):    220                 221     def _issue_certificate(self, environ):    222         request = Request(environ)    223             224         request_method = environ.get('REQUEST_METHOD')                             225         if request_method != 'POST':    226             response = "HTTP Request method not recognised"    227             log.error("HTTP Request method %r not recognised", request_method)    228             raise HttpBasicAuthResponseException(response,     229                                                  httplib.METHOD_NOT_ALLOWED)    230                 231         # Extract cert request and convert to standard string - SSL library    232         # will not accept unicode    233         cert_req_key = self.__class__.CERT_REQ_POST_PARAM_KEYNAME    234         pem_cert_req = str(request.POST.get(cert_req_key))    235         if pem_cert_req is None:    236             response = ("No %r form variable set in POST message" %     237                         cert_req_key)    238             log.error(response)    239             raise HttpBasicAuthResponseException(response,     240                                                  httplib.BAD_REQUEST)    241         242         log.debug("certificate request = %r", pem_cert_req)    243             244         # Expecting PEM encoded request    245         try:    246             cert_req = crypto.load_certificate_request(crypto.FILETYPE_PEM,    247                                                        pem_cert_req)    248         except crypto.Error:    249             log.error("Error loading input certificate request: %r",     250                       pem_cert_req)    251             raise HttpBasicAuthResponseException("Error loading input "    252                                                  "certificate request",    253                                                  httplib.BAD_REQUEST)    254                 255         cert = self.__ca.issue_certificate(cert_req)    256         return cert    257     258     def _get_trustroots(self):  402 259         """Call getTrustRoots method on MyProxyClient instance retrieved from  403 260         environ and format and return a HTTP response  404 261           405           @type myProxyClient: myproxy.client.MyProxyClient  406           @param myProxyClient: MyProxyClient instance on which to call   407           getTrustRoots method  408             409 262         @rtype: basestring  410 263         @return: trust roots base64 encoded and concatenated together  411           @raise OnlineCaGetTrustRootsMiddlewareError: socket error with backend  412           MyProxy server  413           @raise MyProxyClientError: error response received by MyProxyClient  414           instance  415           """  416           try:  417               trustRoots = myProxyClient.getTrustRoots()  418                 419               # Serialise dict response  420               response = "\n".join(["%s=%s" % (k, base64.b64encode(v))  421                                     for k,v in trustRoots.items()])  422                 423               return response  424                        425           except MyProxyClientError, e:  426               log.error("MyProxyClient.getTrustRoots raised an "  427                         "MyProxyClientError exception calling %r: %s",   428                         myProxyClient.hostname,  429                         traceback.format_exc())  430               raise  431                 432           except socket.error, e:  433               raise OnlineCaGetTrustRootsMiddlewareError("Socket error with "  434                                                         "MyProxy server %r: %s" %   435                                                         (myProxyClient.hostname,   436                                                          e))  437           except Exception, e:  438               log.error("MyProxyClient.getTrustRoots raised an unknown exception "  439                         "calling %r: %s",   440                         myProxyClient.hostname,  441                         traceback.format_exc())  442               raise # Trigger 500 Internal Server Error  443              264         """    265         trust_roots = ''    266         for filename in os.listdir(self.trustroots_dir):    267             file_content = open(filename).read()    268                 269             trust_roots += "%s=%s\n" % (filename,     270                                         base64.b64encode(file_content))    271             272         return trust_roots  Note: See TracChangeset for help on using the changeset viewer. Download in other formats: Unified Diff Zip Archive Powered by Trac 0.12.2 By Edgewall Software. Visit the Trac open source project at http://trac.edgewall.org/