Changeset 150 for etherws


Ignore:
Timestamp:
05/16/12 07:21:24 (13 years ago)
Author:
atzm
Message:
  • add basic auth support to server
File:
1 edited

Legend:

Unmodified
Added
Removed
  • etherws/trunk/etherws.py

    r143 r150  
    4545import sys 
    4646import time 
     47import base64 
     48import hashlib 
    4749import argparse 
    4850import threading 
     
    138140 
    139141def server_main(args): 
     142    def may_auth_required(cls, users): 
     143        if not users: 
     144            return cls 
     145 
     146        orig_execute = cls._execute 
     147 
     148        def _execute(self, transforms, *args, **kwargs): 
     149            def auth_required(): 
     150                self.stream.write(tornado.escape.utf8( 
     151                    'HTTP/1.1 401 Authorization Required\r\n' 
     152                    'WWW-Authenticate: Basic realm=etherws\r\n\r\n' 
     153                )) 
     154                self.stream.close() 
     155 
     156            try: 
     157                creds = self.request.headers.get('Authorization') 
     158 
     159                if not creds or not creds.startswith('Basic '): 
     160                    return auth_required() 
     161 
     162                creds = base64.b64decode(creds[6:]) 
     163 
     164                if creds.find(':') < 0: 
     165                    return auth_required() 
     166 
     167                name, passwd = creds.split(':', 2) 
     168                passwd = base64.b64encode(hashlib.sha1(passwd).digest()) 
     169 
     170                if name not in users or users[name] != passwd: 
     171                    return auth_required() 
     172 
     173                return orig_execute(self, transforms, *args, **kwargs) 
     174 
     175            except: 
     176                return auth_required() 
     177 
     178        cls._execute = _execute 
     179        return cls 
     180 
     181    def load_htpasswd(path): 
     182        users = {} 
     183        try: 
     184            with open(path) as fp: 
     185                for line in fp: 
     186                    line = line.strip() 
     187                    if 0 <= line.find(':'): 
     188                        name, passwd = line.split(':', 2) 
     189                        if passwd.startswith('{SHA}'): 
     190                            users[name] = passwd[5:] 
     191        except TypeError: 
     192            pass 
     193        return users 
     194 
     195    handler = may_auth_required(EtherWebSocket, load_htpasswd(args.htpasswd)) 
    140196    ssl_options = {} 
    141197 
     
    163219    tap = TapHandler(args.device, debug=args.debug) 
    164220    app = tornado.web.Application([ 
    165         (args.path, EtherWebSocket, {'tap': tap, 'debug': args.debug}), 
     221        (args.path, handler, {'tap': tap, 'debug': args.debug}), 
    166222    ]) 
    167223    server = tornado.httpserver.HTTPServer(app, ssl_options=ssl_options) 
     
    211267    parser_server.add_argument('--port', action='store', type=int) 
    212268    parser_server.add_argument('--path', action='store', default='/') 
     269    parser_server.add_argument('--htpasswd', action='store') 
    213270    parser_server.add_argument('--keyfile', action='store') 
    214271    parser_server.add_argument('--certfile', action='store') 
Note: See TracChangeset for help on using the changeset viewer.