can you please email it to me?

On Oct 18, 10:30 am, Josh J <jjaq...@seccuris.com> wrote:
> Hey Massimo,
>
> I've taken the initiative and built a patch to allow encoded
> credentials in database URIs.
>
> The following patch adds an additional boolean argument to the SQLDB
> initializer called decode_credentials (defaults to False). The
> decode_credentials argument is used to build the 'credential_decoder'
> lambda. If decode_credentials is False then the lambda doesn't do
> anything, but if decode_credentials is True then the lambda will pass
> the credential through urllib.unquote.
>
> Anytime a username or password is parsed from the URI, it will be
> passed through the credential_decoder lambda before being used with
> the underlying database connection.
>
> Let me know what you think, or if you want me to change anything about
> it before you'll add it into trunk.
>
> =====BEGIN PATCH=====
>
> --- sql.py      2010-10-18 14:44:44.096823600 +0000
> +++ sql_patched.py      2010-10-18 15:09:06.141587000 +0000
> @@ -898,7 +898,13 @@
>
>      def __init__(self, uri='sqlite://dummy.db', pool_size=0,
>                   folder=None, db_codec='UTF-8', check_reserved=None,
> -                 migrate=True, fake_migrate=False):
> +                 migrate=True, fake_migrate=False,
> decode_credentials=False):
> +        if not decode_credentials:
> +            credential_decoder = lambda cred: cred
> +        else:
> +            import urllib
> +            credential_decoder = lambda cred: urllib.unquote(cred)
> +
>          self._uri = str(uri) # NOTE: assuming it is in utf8!!!
>          self._pool_size = pool_size
>          self._db_codec = db_codec
> @@ -957,10 +963,10 @@
>              if not m:
>                  raise SyntaxError, \
>                      "Invalid URI string in SQLDB: %s" % self._uri
> -            user = m.group('user')
> +            user = credential_decoder(m.group('user'))
>              if not user:
>                  raise SyntaxError, 'User required'
> -            passwd = m.group('passwd')
> +            passwd = credential_decoder(m.group('passwd'))
>              if not passwd:
>                  passwd = ''
>              host = m.group('host')
> @@ -992,10 +998,10 @@
>                             ).match(self._uri[11:])
>              if not m:
>                  raise SyntaxError, "Invalid URI string in SQLDB"
> -            user = m.group('user')
> +            user = credential_decoder(m.group('user'))
>              if not user:
>                  raise SyntaxError, 'User required'
> -            passwd = m.group('passwd')
> +            passwd = credential_decoder(m.group('passwd'))
>              if not passwd:
>                  passwd = ''
>              host = m.group('host')
> @@ -1067,10 +1073,10 @@
>                  if not m:
>                      raise SyntaxError, \
>                          "Invalid URI string in SQLDB: %s" % self._uri
> -                user = m.group('user')
> +                user = credential_decoder(m.group('user'))
>                  if not user:
>                      raise SyntaxError, 'User required'
> -                passwd = m.group('passwd')
> +                passwd = credential_decoder(m.group('passwd'))
>                  if not passwd:
>                      passwd = ''
>                  host = m.group('host')
> @@ -1108,10 +1114,10 @@
>              if not m:
>                  raise SyntaxError, \
>                      "Invalid URI string in SQLDB: %s" % self._uri
> -            user = m.group('user')
> +            user = credential_decoder(m.group('user'))
>              if not user:
>                  raise SyntaxError, 'User required'
> -            passwd = m.group('passwd')
> +            passwd = credential_decoder(m.group('passwd'))
>              if not passwd:
>                  passwd = ''
>              host = m.group('host')
> @@ -1137,10 +1143,10 @@
>              if not m:
>                  raise SyntaxError, \
>                      "Invalid URI string in SQLDB: %s" % self._uri
> -            user = m.group('user')
> +            user = credential_decoder(m.group('user'))
>              if not user:
>                  raise SyntaxError, 'User required'
> -            passwd = m.group('passwd')
> +            passwd = credential_decoder(m.group('passwd'))
>              if not passwd:
>                  passwd = ''
>              pathdb = m.group('path')
> @@ -1165,10 +1171,10 @@
>              if not m:
>                  raise SyntaxError, \
>                      "Invalid URI string in SQLDB: %s" % self._uri
> -            user = m.group('user')
> +            user = credential_decoder(m.group('user'))
>              if not user:
>                  raise SyntaxError, 'User required'
> -            passwd = m.group('passwd')
> +            passwd = credential_decoder(m.group('passwd'))
>              if not passwd:
>                  passwd = ''
>              host = m.group('host')
> @@ -1205,10 +1211,10 @@
>                             ).match(self._uri[11:])
>              if not m:
>                  raise SyntaxError, "Invalid URI string in SQLDB"
> -            user = m.group('user')
> +            user = credential_decoder(m.group('user'))
>              if not user:
>                  raise SyntaxError, 'User required'
> -            passwd = m.group('passwd')
> +            passwd = credential_decoder(m.group('passwd'))
>              if not passwd:
>                  passwd = ''
>              host = m.group('host')
>
> ====END PATCH====
>
> On Sep 30, 2:31 pm, Josh J <jjaq...@seccuris.com> wrote:
>
> > Sure I can provide the patch if you want,
>
> > Would basically just have to change
>
> > user = m.group("user")
> > passwd = m.group("passwd")
>
> > to
>
> > user = urllib.unquote(m.group("user"))
> > passwd = urllib.unquote(m.group("passwd"))
>
> > everywhere you parse the credentials.
>
> > On Sep 29, 11:35 am, mdipierro <mdipie...@cs.depaul.edu> wrote:
>
> > > Ignore my previous email... there is no need with a patch for what you
> > > are suggestion...let me think about this some more.
>
> > > On Sep 29, 11:01 am, Josh J <jjaq...@seccuris.com> wrote:
>
> > > > Hey all,
>
> > > >         I've found an issue with SQLDB when developing my application. 
> > > > The
> > > > URI handling does not allow special characters in database passwords.
> > > > Unfortunately, I must connect to the database from my application
> > > > using a password with special characters.
> > > > eg. Consider the URI for a database with has an @ in the password:
> > > > postgres://username:p...@ssword@localhost:5432/database
>
> > > >         That is the simplest way to break the current URI handling. 
> > > > Consider
> > > > a more complex password like �...@b:3/c”, which is a valid postgres
> > > > password and probably valid in other DBMS as well. It would build a
> > > > URI that looks something like:
> > > > postgres://username:a...@b:3/c...@host:port/database
>
> > > >         The regular expression CAN be carefully modified to allow all of
> > > > these characters in the password, but what about if you had special
> > > > characters in your username too? Imagine if you had a (valid but
> > > > contrived) postgres username like “u...@host/group:subgroup”  with the
> > > > same �...@b:3/c” password as before. Then your URI would look something
> > > > like:
> > > > postgres://u...@host/group:subgroup:a...@b:3/c...@host:port/database
>
> > > >         I think this exposes a problem in general with parsing username 
> > > > and
> > > > passwords from a URI, in that if you have these special characters you
> > > > can no longer parse them with a simple regular expression. If you look
> > > > at Section 3.1 of RFC 1738 - Uniform Resource Locators they already
> > > > thought of this, and they say that within the user and password field
> > > > you should encode any ":",  "@", or "/".
>
> > > >         I have tried modifying SQLDB to pass the username and password
> > > > through the urllib.unquote function as follows:
> > > >    user = urllib.unquote(m.group("user"))
> > > >    passwd = urllib.unquote(m.group("passwd"))
>
> > > >         Then when opening the database do something like this:
> > > > SQLDB("postgres://%(user)s:%(pass)s...@localhost:5432/database" % \
> > > >       ({'user': urllib.quote("test"),
> > > > 'pass':urllib.quote("p...@ssword"})))
>
> > > >         This works fine for me. And, passwords without special 
> > > > characters
> > > > will be unmodified by urllib.unquote().  In this way backwards
> > > > compatibility is mostly intact. However consider a user who currently
> > > > has a password with a % character. Even though it works fine now, if
> > > > you were to pass the password through urllib.unquote then it would
> > > > assume the % was an escape sequence and produce unexpected results for
> > > > them.
>
> > > >         What do you think?
>
> > > > Regards,
>
> > > > Josh Jaques
> > > > Seccuris Inc.
>
>

Reply via email to