Thread: Authenticate with hash instead of plaintext password?

Authenticate with hash instead of plaintext password?

From
Murray Cumming
Date:
libpq lets me open a connection by specifying a password:
http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS

Is there any way to specify a hash of the password when connecting, instead of
providing the password itself? My Web UI asks the user for a PostgreSQL
username and password, and I want to avoid asking the user for the
password again later, as long as they have the browser cookie that I set.

I've looked at the source of phpPgAdmin, which should deal with the same issue,
but that seems to store the plaintext password in the session, which might even
mean that the plaintext password ends up on disk, though I don't know enough about
PHP to be sure.

I understand that libpq already sends only an MD5 hash to the
PostgreSQL server, when it's configured to use MD5 authentication.
But I don't want to have to provide a plaintext password to libpq.


--
murrayc@murrayc.com
www.murrayc.com
www.openismus.com





Re: Authenticate with hash instead of plaintext password?

From
Peter Bex
Date:
On Sun, Dec 16, 2012 at 04:54:30PM +0100, Murray Cumming wrote:
> libpq lets me open a connection by specifying a password:
> http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS
>
> Is there any way to specify a hash of the password when connecting, instead of
> providing the password itself?

What's the use of that?  It won't buy you any extra protection if the
hash would be accepted as-is instead of the password.  In fact, now
you would have *two* strings (instead of one) that are accepted as
equally valid passwords.

> My Web UI asks the user for a PostgreSQL
> username and password, and I want to avoid asking the user for the
> password again later, as long as they have the browser cookie that I set.

Perhaps you can encrypt it in the cookie, to prevent casual onlookers
from discovering the password.  However, if anyone can obtain the cookie
(eg via the Firesheep plugin) they can still use that to login even if
they don't know the actual password - they can just reuse the encrypted
blob.

> I've looked at the source of phpPgAdmin, which should deal with the same issue,
> but that seems to store the plaintext password in the session, which might even
> mean that the plaintext password ends up on disk, though I don't know enough about
> PHP to be sure.

The session is slightly safer than storing it directly in the cookie
because one would have to break into the server rather than access
the cookie store in the client.  However, if anyone can recover the
session id, they can connect with this user's credentials as well.

> I understand that libpq already sends only an MD5 hash to the
> PostgreSQL server, when it's configured to use MD5 authentication.

I would think that's challenge-response based, but I'm not sure.  The
documentation seems to hint that it's just the password, but hashed.

> But I don't want to have to provide a plaintext password to libpq.

Why not?  If the script lives on the server, there shouldn't be a way
for the user to recover the password even if it's put in the string.

Unfortunately, I'm not aware of any truly secure method of doing this.
Sorry!  Maybe someone else knows of a good approach.

Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
                            -- Donald Knuth


Re: Authenticate with hash instead of plaintext password?

From
Murray Cumming
Date:
On Sun, 2012-12-16 at 17:24 +0100, Peter Bex wrote:
> On Sun, Dec 16, 2012 at 04:54:30PM +0100, Murray Cumming wrote:
> > libpq lets me open a connection by specifying a password:
> > http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-PARAMKEYWORDS
> >
> > Is there any way to specify a hash of the password when connecting, instead of
> > providing the password itself?
>
> What's the use of that?
[snip]

I would not be storing the plaintext password anywhere. That makes it
harder for someone get the plaintext password if they break into the
server, and therefore harder for someone to use that password to break
into another account if the user has used the same password.

There have been plenty of high profile cases recently of password
databases being stolen, with those passwords being in plaintext, or
hashed without a salt, making user accounts on other systems vulnerable.
I'd like to avoid making the same embarrassing mistake.

murrayc@murrayc.com
www.murrayc.com
www.openismus.com




Re: Authenticate with hash instead of plaintext password?

From
Peter Bex
Date:
On Sun, Dec 16, 2012 at 05:38:37PM +0100, Murray Cumming wrote:
> On Sun, 2012-12-16 at 17:24 +0100, Peter Bex wrote:
> > What's the use of that?
> [snip]
>
> I would not be storing the plaintext password anywhere. That makes it
> harder for someone get the plaintext password if they break into the
> server, and therefore harder for someone to use that password to break
> into another account if the user has used the same password.

If they do break in and are able to retrieve the password hash, they
can still break in with that hash.  Hashes (if properly salted and
stretched) are only useful if they are only ever checked against the
password itself.  Storing a hash of any kind and comparing that directly
with user input is equivalent to storing the password and comparing that
with user input.

> There have been plenty of high profile cases recently of password
> databases being stolen, with those passwords being in plaintext, or
> hashed without a salt, making user accounts on other systems vulnerable.
> I'd like to avoid making the same embarrassing mistake.

Please also avoid the mistake outlined above.

Unless I'm overlooking something, then if there's a way to directly
mediate between the browser client and the postgres server, you've
effectively created a man-in-the-middle.  This shouldn't be possible
with a truly secure authentication mechanism.

The best solution I can come up with is not provide a web UI at all
but let the user connect directly to the database using a secure
method (e.g. SSL client certs, GSSAPI etc).

Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
                            -- Donald Knuth


Re: Authenticate with hash instead of plaintext password?

From
Peter Bex
Date:
On Sun, Dec 16, 2012 at 05:51:23PM +0100, Peter Bex wrote:
> The best solution I can come up with is not provide a web UI at all
> but let the user connect directly to the database using a secure
> method (e.g. SSL client certs, GSSAPI etc).

Speaking of which, a custom implementation of the GSSAPI might be
feasible.  I don't have experience with the API, but presumably you
can accept a password once, generate a GSSAPI ticket and store *that*
in the user's session file or cookie.  Any succesful attack will only
be able to get that one ticket.  If the server is compromised you can
revoke all currently active tickets.

Assuming you're using HTTPS and store cookies with the "secure"
attribute, this could be a safe way to do things.  It's probably not
easy or available out-of-the-box though!

I think the Postgres docs could use some improvement on how to
use GSSAPI; they're pretty terse!  If I understand the Kerberos
section correctly, it's even possible to avoid passwords altogether
by using mod_auth_kerb and a browser extension that allows talking
to this module.  That would be even better, but might not be acceptable
if you want to allow users to connect using vanilla webbrowsers.

Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
                            -- Donald Knuth


Re: Authenticate with hash instead of plaintext password?

From
Tom Lane
Date:
Peter Bex <Peter.Bex@xs4all.nl> writes:
> On Sun, Dec 16, 2012 at 05:38:37PM +0100, Murray Cumming wrote:
>> I would not be storing the plaintext password anywhere. That makes it
>> harder for someone get the plaintext password if they break into the
>> server, and therefore harder for someone to use that password to break
>> into another account if the user has used the same password.

> If they do break in and are able to retrieve the password hash, they
> can still break in with that hash.

Right, they can break into *this account*.  But Murray is worrying about
the all-too-common case where a user has used the same or similar
password for multiple sites.  I think his goal of not having the
original password stored anywhere is laudable.

Perhaps I'm missing the context here, but it seems unlikely that the
users have any direct access to the database.  If they can only get to
it through the website, then what about the idea of hashing the original
text, and then using that hashed string as the database password?  IOW
I don't see why this must be implemented inside libpq rather than in
the website logic.

            regards, tom lane


Re: Authenticate with hash instead of plaintext password?

From
Peter Bex
Date:
On Sun, Dec 16, 2012 at 12:51:08PM -0500, Tom Lane wrote:
> Peter Bex <Peter.Bex@xs4all.nl> writes:
> > If they do break in and are able to retrieve the password hash, they
> > can still break in with that hash.
>
> Right, they can break into *this account*.

Not *just* this one, but any account on any service that uses this
same algorithm.  Even if this is a completely custom algorithm
that no other service is going to use, there's still the risk that
when one of his servers is cracked, if a customer has multiple
accounts they are all compromised even if they are on servers that
weren't compromised. (of course, assuming they use the same password
- but that's a reality we'll have to face, hence his original
request)

Finally, if it's a naive implementation of calculating a single hash
run, the password can be easily retrieved.  Either by brute-force
(with eg Hashcat or John the Ripper), or even common search engines.
See for example http://tools.benramsey.com/md5/

> But Murray is worrying about the all-too-common case where a user
> has used the same or similar password for multiple sites.  I think
> his goal of not having the original password stored anywhere is laudable.

Absolutely, I completely agree.  I wasn't trying to put down this
important goal.  There have been too many incidents of hacked password
databases.  This has to end.  That's why I'm so keen on trying to warn
against doing it in the way he originally proposed.

> Perhaps I'm missing the context here, but it seems unlikely that the
> users have any direct access to the database.  If they can only get to
> it through the website, then what about the idea of hashing the original
> text, and then using that hashed string as the database password?

See above; the password can be easily retrieved.

> IOW I don't see why this must be implemented inside libpq rather than
> in the website logic.

I'm not sure this is necessary either.

Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
                            -- Donald Knuth


Re: Authenticate with hash instead of plaintext password?

From
Tom Lane
Date:
Peter Bex <Peter.Bex@xs4all.nl> writes:
> On Sun, Dec 16, 2012 at 12:51:08PM -0500, Tom Lane wrote:
>> Right, they can break into *this account*.

> Not *just* this one, but any account on any service that uses this
> same algorithm.

That's easily fixed.  I'd be inclined to make the "password" hash be a
hash of the actual password plus the user's name plus some
web-site-specific random salt string.  All of these should be readily
available anytime you need to compute the hash, and the inclusion of the
latter two components will make it difficult to use precomputed rainbow
tables to extract the actual password.  With a little more work, he
could also have a per-user random salt added to the hash input --- but
that would require an additional lookup step during login.

            regards, tom lane


Re: Authenticate with hash instead of plaintext password?

From
Murray Cumming
Date:
On Sun, 2012-12-16 at 17:51 +0100, Peter Bex wrote:
> On Sun, Dec 16, 2012 at 05:38:37PM +0100, Murray Cumming wrote:
> > On Sun, 2012-12-16 at 17:24 +0100, Peter Bex wrote:
> > > What's the use of that?
> > [snip]
> >
> > I would not be storing the plaintext password anywhere. That makes it
> > harder for someone get the plaintext password if they break into the
> > server, and therefore harder for someone to use that password to break
> > into another account if the user has used the same password.
>
> If they do break in and are able to retrieve the password hash, they
> can still break in with that hash.

Yes, but in that case they've already broken in. And this is about
making it much harder to discover the plaintext password in that case.

>   Hashes (if properly salted and
> stretched) are only useful if they are only ever checked against the
> password itself.  Storing a hash of any kind and comparing that directly
> with user input is equivalent to storing the password and comparing that
> with user input.

So PostgresQL, for instance, stores the actual plaintext password (or an
encrypted, but not hashed) password? And compares that with the hash
that it receives from libpq.

If so, then I just shouldn't be using that password for any kind of web
login.

[snip]
> The best solution I can come up with is not provide a web UI at all
> but let the user connect directly to the database using a secure
> method (e.g. SSL client certs, GSSAPI etc).

That's not an option in this case. My system
( http://www.glom.org/wiki/index.php?title=Development/OnlineGlom )
is meant to provide access to databases and I don't wish to implement all
of it on the client side.)

I do have the option of creating a different set of user/password logins
for the web UI and then either
- Using one username/password for all web users' databases, with no
  PostgreSQL-level separation. But this would have to be in a config file
  at least. I guess this is what most web systems do, though they
  generally deal with only one database.
- Generating PostgreSQL username/passwords for each web user's database,
  but never exposing these to the web user. But I'd have to store them
  somewhere.


murrayc@murrayc.com
www.murrayc.com
www.openismus.com




Re: Authenticate with hash instead of plaintext password?

From
Peter Bex
Date:
On Sun, Dec 16, 2012 at 01:30:29PM -0500, Tom Lane wrote:
> Peter Bex <Peter.Bex@xs4all.nl> writes:
> > On Sun, Dec 16, 2012 at 12:51:08PM -0500, Tom Lane wrote:
> >> Right, they can break into *this account*.
>
> > Not *just* this one, but any account on any service that uses this
> > same algorithm.
>
> That's easily fixed.  I'd be inclined to make the "password" hash be a
> hash of the actual password plus the user's name plus some
> web-site-specific random salt string.

That could work, provided the hashing algorithm is one of the stronger
varieties (eg bcrypt, scrypt, pbkdf2).  If it's a simple hash, you
still run the risk of having the password recovered through one of the
methods pointed out in my other post.

However, if the hash is going to be stored as-is in postgres and
immediately used as the password, the user will also need to put the
hash in their web scripts (assuming it's an interface to manage shared
hosting accounts), and *if* the postgres port can be accessed directly
for client programs they'll need to use this hash there as well.
This may or may not be desirable.

Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
                            -- Donald Knuth


Re: Authenticate with hash instead of plaintext password?

From
Peter Bex
Date:
On Sun, Dec 16, 2012 at 07:42:40PM +0100, Murray Cumming wrote:
> On Sun, 2012-12-16 at 17:51 +0100, Peter Bex wrote:
> > Hashes (if properly salted and
> > stretched) are only useful if they are only ever checked against the
> > password itself.  Storing a hash of any kind and comparing that directly
> > with user input is equivalent to storing the password and comparing that
> > with user input.
>
> So PostgresQL, for instance, stores the actual plaintext password (or an
> encrypted, but not hashed) password? And compares that with the hash
> that it receives from libpq.

Hm, that's a good point, I hadn't considered that.  I don't know how
Postgres stores its passwords internally or how its authentication works
exactly.  Maybe one of the developers can shine a light on this.

> [snip]
> > The best solution I can come up with is not provide a web UI at all
> > but let the user connect directly to the database using a secure
> > method (e.g. SSL client certs, GSSAPI etc).
>
> That's not an option in this case. My system
> ( http://www.glom.org/wiki/index.php?title=Development/OnlineGlom )
> is meant to provide access to databases and I don't wish to implement all
> of it on the client side.)
>
> I do have the option of creating a different set of user/password logins
> for the web UI and then either
> - Using one username/password for all web users' databases, with no
>   PostgreSQL-level separation. But this would have to be in a config file
>   at least. I guess this is what most web systems do, though they
>   generally deal with only one database.

I've been wondering about how to do this correctly.  I think I've asked
before on this list.  I think one way to do it is to create a "master"
user which can do nothing but use "set role" to switch to each account.

Then this user would have access to one table of its own which stores
the usernames and password hashes you have made yourself.  When a user
logs in, you can create a one-time random value (a "ticket") that you
store in a mappings table.  Then you can check whether the user really
is logged in before switching to their database role.

> - Generating PostgreSQL username/passwords for each web user's database,
>   but never exposing these to the web user. But I'd have to store them
>   somewhere.

I think the GSSAPI might really be a good way to do it, if rather
difficult and labor-intensive.  You could just get a ticket and store
that in the cookie.  No need to do any double bookkeeping.

Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
                            -- Donald Knuth


Re: Authenticate with hash instead of plaintext password?

From
Adrian Klaver
Date:
On 12/16/2012 11:07 AM, Peter Bex wrote:
> On Sun, Dec 16, 2012 at 07:42:40PM +0100, Murray Cumming wrote:
>> On Sun, 2012-12-16 at 17:51 +0100, Peter Bex wrote:
>>> Hashes (if properly salted and
>>> stretched) are only useful if they are only ever checked against the
>>> password itself.  Storing a hash of any kind and comparing that directly
>>> with user input is equivalent to storing the password and comparing that
>>> with user input.
>>
>> So PostgresQL, for instance, stores the actual plaintext password (or an
>> encrypted, but not hashed) password? And compares that with the hash
>> that it receives from libpq.
>
> Hm, that's a good point, I hadn't considered that.  I don't know how
> Postgres stores its passwords internally or how its authentication works
> exactly.  Maybe one of the developers can shine a light on this.
>

http://www.postgresql.org/docs/9.2/static/encryption-options.html
"
Password Storage Encryption
By default, database user passwords are stored as MD5 hashes, so the
administrator cannot determine the actual password assigned to the user.
If MD5 encryption is used for client authentication, the unencrypted
password is never even temporarily present on the server because the
client MD5-encrypts it before being sent across the network.
"


--
Adrian Klaver
adrian.klaver@gmail.com


Re: Authenticate with hash instead of plaintext password?

From
Peter Bex
Date:
On Sun, Dec 16, 2012 at 11:17:25AM -0800, Adrian Klaver wrote:
> On 12/16/2012 11:07 AM, Peter Bex wrote:
> > I don't know how Postgres stores its passwords internally or how
> > its authentication works exactly.  Maybe one of the developers
> > can shine a light on this.
>
> http://www.postgresql.org/docs/9.2/static/encryption-options.html

Thanks for the link; must've missed it somehow.  I now also see
the topic of improving the password hashing has been discussed before.
For others reading along, I've found these two threads from this year:
http://archives.postgresql.org/pgsql-general/2012-02/msg00334.php
http://archives.postgresql.org/pgsql-hackers/2012-10/msg00462.php

Like the poster in the first URL says, password hashing is *not*
encryption.  It's advisable not to refer to it as such - this
will only help increase the widespread confusion about the subject.

A good treatise on password hashing after the explosion of blog
posts about "rainbow tables" is this one:
http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html
Note how it deprecates (salted) MD5 as insecure because they can
be brute-forced too easily/quickly.

I understand that it would take a lot for a database to be compromised
and that the used passwords generally aren't going to be used on other
sites.  On the other hand, there's no guarantee of either, and it's
not *that* complicated to improve the way passwords are stored.
IMO, the simplest way to implement a good hashing system that can be
easily upgraded in a backwards-compatible way when the need arises
is to use modular Unix crypt().  Modern libc implementations provide
a variety of decent ways of storing password hashes.

I've collected some more information about UNIX crypt() in the
documentation for a library I wrote for Chicken Scheme:
http://wiki.call-cc.org/eggref/4/crypt
All the fallback crypt() implementations this library provides are
public domain, so they could be used in Postgres.  If public domain
is not acceptable for legal reasons, there are also plenty of
BSD-licensed implementations to be found elsewhere; bcrypt was first
implemented by OpenBSD.

I could try my hand at providing a patch to switch to, say, bcrypt,
but I'm pretty unfamiliar with the PostgreSQL source code.  If
nobody else is interested in working on it I can give it a try
during the holidays.

I'm not sure how to deal with the md5 authentication method.
There is a good point in the -hackers thread above that eavesdroppers
are probably able to hijack existing connections, but there's no reason
to take any risks.

One solution would be to point out in the manual that it's not secure
and advise people to use SSL.  Another would be to implement something
like SCRAM, as pointed out in the -hackers thread I posted above or
some other challenge-response system.  However, this could be done
separately, either before or after the password storage itself has
been improved.

Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
                            -- Donald Knuth


Re: Authenticate with hash instead of plaintext password?

From
Stephen Frost
Date:
* Murray Cumming (murrayc@murrayc.com) wrote:
> I do have the option of creating a different set of user/password logins
> for the web UI and then either
> - Using one username/password for all web users' databases, with no
>   PostgreSQL-level separation. But this would have to be in a config file
>   at least. I guess this is what most web systems do, though they
>   generally deal with only one database.

Actually, you could provide PG-level separation through the use of
roles.  Create a role in the database which is 'noinherit' but which is
granted all the user roles.  Then create a role for the web server to
log in as and then grant the 'noinherit' role to the web server role.
When the web server logs in and does whatever user verification it
needs, it can issue a 'set role userX;'.

Through that mechanism you could support client-side SSL certificates
(have Apache validate the user's client-side cert and then you can have
a mapping from DN to PG role for that user).  With GSSAPI, as mentioned
up-thread, you could support Kerberos credentials and, with
mod_auth_kerb, could actually proxy those credentials to allow access to
the database as the user with GSSAPI.  That requires setting up a
Kerberos environment, joining the client system to the Kerberos realm,
etc.

With the common web-server role method above, you could also implement
your own poor-man's GSSAPI using simple session ids, like a ton of web
sites out there do, and then have a mapping server-side between the
session ID and user role, along with first-issued time, last-used time,
etc, etc.  If no session ID is present, go through the normal
authentication process and then have a security definer function be
used, upon successful login of that user, to set up the session.

    Thanks,

        Stephen

Attachment

Re: Authenticate with hash instead of plaintext password?

From
Stephen Frost
Date:
* Peter Bex (Peter.Bex@xs4all.nl) wrote:
> Hm, that's a good point, I hadn't considered that.  I don't know how
> Postgres stores its passwords internally or how its authentication works
> exactly.  Maybe one of the developers can shine a light on this.

PG stores a hash which is salted with the username.  The client takes
the username and password provided by the user and creates the same hash
to send to the server.  There is a challenge/response mechanism used for
the communication between the client and server to avoid the hash
actually being seen on the wire.

> I've been wondering about how to do this correctly.  I think I've asked
> before on this list.  I think one way to do it is to create a "master"
> user which can do nothing but use "set role" to switch to each account.
>
> Then this user would have access to one table of its own which stores
> the usernames and password hashes you have made yourself.  When a user
> logs in, you can create a one-time random value (a "ticket") that you
> store in a mappings table.  Then you can check whether the user really
> is logged in before switching to their database role.

Right, I described this in another email just now, but you don't
necessairly need to have your own username/password hash table, as I
point out in my other email.

> I think the GSSAPI might really be a good way to do it, if rather
> difficult and labor-intensive.  You could just get a ticket and store
> that in the cookie.  No need to do any double bookkeeping.

GSSAPI isn't hard at all, really, if you have some notion of control
over the client (if this is an "Enterprise" solution, where your users
are members of the enterprise, they're probably already using Kerberos
through Microsoft Active Directory, and supporting that is very easily
done with PG...).

    Thanks,

        Stephen

Attachment

Re: Authenticate with hash instead of plaintext password?

From
Stephen Frost
Date:
* Peter Bex (Peter.Bex@xs4all.nl) wrote:
> I could try my hand at providing a patch to switch to, say, bcrypt,
> but I'm pretty unfamiliar with the PostgreSQL source code.  If
> nobody else is interested in working on it I can give it a try
> during the holidays.

The code, in general, is very clean.  The issues you're going to run
into are questions about protocol support (the hash, in some ways, is
currently part of our PG protocol and so changing that would be a break
in the protocol which would be frowned upon greatly...) and making sure
that things don't break internally.  Note that not everything uses libpq
to talk to PG (the JDBC driver, for example, has a completely seperate
implementation of the protocol, as I recall).  You'll also need to
address the upgrade path.

If this is implemented as an optional capability, that's more likely to
be acceptable but at the same time might not really 'fix' things.

I, for one, would love to see some work done in this area and would be
happy to help you with any questions you have regarding the code.

> I'm not sure how to deal with the md5 authentication method.
> There is a good point in the -hackers thread above that eavesdroppers
> are probably able to hijack existing connections, but there's no reason
> to take any risks.

We do support SSL also, of course, and we do encourage people to use it
whenever possible and definitely if going across untrusted networks.

    Thanks,

        Stephen

Attachment