def _parse_db_str(db_str): scheme, rest = db_str.split(':', 1) if not rest.startswith('/'): if scheme == 'sqlite': # Support for relative and in-memory SQLite connection strings host = None path = rest else: raise TracError( _( 'Unknown scheme "%(scheme)s"; database ' 'connection string must start with {scheme}:/', scheme=scheme)) else: if not rest.startswith('//'): host = None rest = rest[1:] elif rest.startswith('///'): host = None rest = rest[3:] else: rest = rest[2:] if '/' not in rest: host = rest rest = '' else: host, rest = rest.split('/', 1) path = None if host and '@' in host: user, host = host.split('@', 1) if ':' in user: user, password = user.split(':', 1) else: password = None if user: user = urllib.unquote(user) if password: password = unicode_passwd(urllib.unquote(password)) else: user = password = None if host and ':' in host: host, port = host.split(':') port = int(port) else: port = None if not path: path = '/' + rest if os.name == 'nt': # Support local paths containing drive letters on Win32 if len(rest) > 1 and rest[1] == '|': path = "%s:%s" % (rest[0], rest[2:]) params = {} if '?' in path: path, qs = path.split('?', 1) qs = qs.split('&') for param in qs: name, value = param.split('=', 1) value = urllib.unquote(value) params[name] = value args = zip(('user', 'password', 'host', 'port', 'path', 'params'), (user, password, host, port, path, params)) return scheme, dict([(key, value) for key, value in args if value])
def parse_connection_uri(db_str): """Parse the database connection string. The database connection string for an environment is specified through the `database` option in the `[trac]` section of trac.ini. :return: a tuple containing the scheme and a dictionary of attributes: `user`, `password`, `host`, `port`, `path`, `params`. :since: 1.1.3 """ if not db_str: section = tag.a("[trac]", title=_("TracIni documentation"), class_='trac-target-new', href='https://trac.edgewall.org/wiki/TracIni' '#trac-section') raise ConfigurationError( tag_( "Database connection string is empty. Set the %(option)s " "configuration option in the %(section)s section of " "trac.ini. Please refer to the %(doc)s for help.", option=tag.code("database"), section=section, doc=_doc_db_str())) try: scheme, rest = db_str.split(':', 1) except ValueError: raise _invalid_db_str(db_str) if not rest.startswith('/'): if scheme == 'sqlite' and rest: # Support for relative and in-memory SQLite connection strings host = None path = rest else: raise _invalid_db_str(db_str) else: if not rest.startswith('//'): host = None rest = rest[1:] elif rest.startswith('///'): host = None rest = rest[3:] else: rest = rest[2:] if '/' in rest: host, rest = rest.split('/', 1) else: host = rest rest = '' path = None if host and '@' in host: user, host = host.split('@', 1) if ':' in user: user, password = user.split(':', 1) else: password = None if user: user = urllib.unquote(user) if password: password = unicode_passwd(urllib.unquote(password)) else: user = password = None if host and ':' in host: host, port = host.split(':', 1) try: port = int(port) except ValueError: raise _invalid_db_str(db_str) else: port = None if not path: path = '/' + rest if os.name == 'nt': # Support local paths containing drive letters on Win32 if len(rest) > 1 and rest[1] == '|': path = "%s:%s" % (rest[0], rest[2:]) params = {} if '?' in path: path, qs = path.split('?', 1) qs = qs.split('&') for param in qs: try: name, value = param.split('=', 1) except ValueError: raise _invalid_db_str(db_str) value = urllib.unquote(value) params[name] = value args = zip(('user', 'password', 'host', 'port', 'path', 'params'), (user, password, host, port, path, params)) return scheme, {key: value for key, value in args if value}
def _parse_db_str(db_str): scheme, rest = db_str.split(':', 1) if not rest.startswith('/'): if scheme == 'sqlite': # Support for relative and in-memory SQLite connection strings host = None path = rest else: raise TracError('Unknown scheme "%s"; database connection string ' 'must start with {scheme}:/' % scheme) else: if not rest.startswith('//'): host = None rest = rest[1:] elif rest.startswith('///'): host = None rest = rest[3:] else: rest = rest[2:] if '/' not in rest: host = rest rest = '' else: host, rest = rest.split('/', 1) path = None if host and '@' in host: user, host = host.split('@', 1) if ':' in user: user, password = user.split(':', 1) else: password = None if user: user = urllib.unquote(user) if password: password = unicode_passwd(urllib.unquote(password)) else: user = password = None if host and ':' in host: host, port = host.split(':') port = int(port) else: port = None if not path: path = '/' + rest if os.name == 'nt': # Support local paths containing drive letters on Win32 if len(rest) > 1 and rest[1] == '|': path = "%s:%s" % (rest[0], rest[2:]) params = {} if '?' in path: path, qs = path.split('?', 1) qs = qs.split('&') for param in qs: name, value = param.split('=', 1) value = urllib.unquote(value) params[name] = value args = zip(('user', 'password', 'host', 'port', 'path', 'params'), (user, password, host, port, path, params)) return scheme, dict([(key, value) for key, value in args if value])
def parse_connection_uri(db_str): """Parse the database connection string. The database connection string for an environment is specified through the `database` option in the `[trac]` section of trac.ini. :return: a tuple containing the scheme and a dictionary of attributes: `user`, `password`, `host`, `port`, `path`, `params`. :since: 1.1.3 """ if not db_str: section = tag.a("[trac]", title=_("TracIni documentation"), class_='trac-target-new', href='http://trac.edgewall.org/wiki/TracIni' '#trac-section') raise ConfigurationError( tag_("Database connection string is empty. Set the %(option)s " "configuration option in the %(section)s section of " "trac.ini. Please refer to the %(doc)s for help.", option=tag.code("database"), section=section, doc=_doc_db_str())) try: scheme, rest = db_str.split(':', 1) except ValueError: raise _invalid_db_str(db_str) if not rest.startswith('/'): if scheme == 'sqlite' and rest: # Support for relative and in-memory SQLite connection strings host = None path = rest else: raise _invalid_db_str(db_str) else: if not rest.startswith('//'): host = None rest = rest[1:] elif rest.startswith('///'): host = None rest = rest[3:] else: rest = rest[2:] if '/' in rest: host, rest = rest.split('/', 1) else: host = rest rest = '' path = None if host and '@' in host: user, host = host.split('@', 1) if ':' in user: user, password = user.split(':', 1) else: password = None if user: user = urllib.unquote(user) if password: password = unicode_passwd(urllib.unquote(password)) else: user = password = None if host and ':' in host: host, port = host.split(':', 1) try: port = int(port) except ValueError: raise _invalid_db_str(db_str) else: port = None if not path: path = '/' + rest if os.name == 'nt': # Support local paths containing drive letters on Win32 if len(rest) > 1 and rest[1] == '|': path = "%s:%s" % (rest[0], rest[2:]) params = {} if '?' in path: path, qs = path.split('?', 1) qs = qs.split('&') for param in qs: try: name, value = param.split('=', 1) except ValueError: raise _invalid_db_str(db_str) value = urllib.unquote(value) params[name] = value args = zip(('user', 'password', 'host', 'port', 'path', 'params'), (user, password, host, port, path, params)) return scheme, dict([(key, value) for key, value in args if value])
class RadiusAuthStore(Component): """[extra] Provides RADIUS authentication support. Custom configuration is mandatory. Provide IP address and authentication port of your RADIUS server. RADIUS uses UDP port 1812 for authentication as per IETF RFC2865, but old servers may still use 1645. You must also supply a shared secret, which the RADIUS server admin must disclose to you. """ implements(IPasswordStore) radius_server = Option('account-manager', 'radius_server', doc="RADIUS server IP address, required.") radius_authport = IntOption( 'account-manager', 'radius_authport', 1812, doc="RADIUS server authentication port, defaults to 1812.") # Conceal shared secret. radius_secret = unicode_passwd( Option('account-manager', 'radius_secret', doc="RADIUS server shared secret, required.")) def get_users(self): """Returns an iterable of the known usernames.""" return [] def has_user(self, user): """Returns whether the user account exists.""" # DEVEL: Shall we really deny knowing a specified user? return False def check_password(self, username, password): """Checks if the password is valid for the user.""" # Handle pyrad lib absence and upstream incompatibilities gracefully. try: import pyrad.packet from pyrad.client import Client, Timeout from pyrad.dictionary import Dictionary except ImportError, e: self.log.error( "RADIUS auth store could not import pyrad, " "need to install the egg: %s", e) return self.log.debug("RADIUS server=%s:%s (authport), secret='%s'", self.radius_server, self.radius_authport, self.radius_secret) self.log.debug("RADIUS auth callenge for username=%s password=%s", username, unicode_passwd(password)) client = Client( server=self.radius_server, authport=self.radius_authport, secret=self.radius_secret.encode('utf-8'), dict=Dictionary(StringIO(DICTIONARY)), ) req = client.CreateAuthPacket(code=pyrad.packet.AccessRequest, User_Name=username.encode('utf-8')) req['User-Password'] = req.PwCrypt(password) self.log.debug("RADIUS auth sending packet req=%s", req) try: reply = client.SendPacket(req) except Timeout, e: self.log.error("RADIUS timeout contacting server=%s:%s (%s)", self.radius_server, self.radius_authport, e) return