Issue Details (XML | Word | Printable)

Key: CORE-6038
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Alexander Peshkov
Reporter: Artyom Smirnov
Votes: 0
Watchers: 4
Operations

If you were logged in you would be able to see more operations.
Firebird Core

Srp user manager sporadically creates users which can not attach

Created: 29/Mar/19 12:07 PM   Updated: 11/Jun/19 05:36 PM
Component/s: Engine
Affects Version/s: 3.0.4
Fix Version/s: 3.0.5, 4.0 Beta 2

Environment: Ubuntu 18.10 x86_64, Cent OS 6/7 x86_64

QA Status: Done successfully


 Description  « Hide
To reproduce this bug enough to create user/try to login/drop user many times.

I digged into Srp manager and found it happen with some "magic" salts. For example: AE7A9732FB795098A4ECE3CE28BD01C4363E870F9AD399AFBEE2CBC6FBB30580

If you try to set this constant salt in SrpManagement.cpp all newly created users will be unable to authenticate (SrpServer.cpp: SrpServer::authenticate "if (clientProof == serverProof)" always false).

Reproducing script:

#!/bin/bash

BIN=/opt/firebird/bin/
DBPATH=/tmp/test
DB=localhost:$DBPATH

cat << EOF > /tmp/prepare
create database '$DB' user sysdba password 'masterkey';
drop user test;
EOF

cat << EOF > /tmp/sql
connect '$DB' user sysdba password 'masterkey';
create user test password 'test';
connect '$DB' user test password 'test';
connect '$DB' user sysdba password 'masterkey';
drop user test;
EOF

rm $DBPATH
$BIN/isql -i /tmp/prepare

set -e

while true; do
$BIN/isql -b -i /tmp/sql
done


 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Artyom Smirnov added a comment - 04/Apr/19 01:00 PM
Looks I've found root of problem:

In some cases verifier (SrpManager.cpp: server.computeVerifier(user->userName()->get(), s1, user->password()->get()).getBytes(s);) which is should be 128 bit number generated as 127 bit.

When selecting (SrpServer.cpp: "SELECT PLG$VERIFIER, PLG$SALT FROM PLG$SRP WHERE PLG$USER_NAME = ? AND PLG$ACTIVE";) it casted to array of 128 bits (SrpServer.cpp: verifier.assign(reinterpret_cast<const UCHAR*>((const char*)verify), RemotePassword::SRP_VERIFIER_SIZE);) and padded with extra zero bytes at right. So after this casting we will get wrong verifier.

For example if we pad verifier from left when selecting it will be casted properly:
SELECT LPAD(PLG$VERIFIER, 128), PLG$SALT FROM PLG$SRP WHERE PLG$USER_NAME = ? AND PLG$ACTIVE"

The question is it always should be 128 bit or not?

Alexander Peshkov added a comment - 04/Apr/19 03:58 PM
You've meant 128 bytes I suppose.
No - it should not. Treat verifier as a very big integer. When upper byte is 0 it's just omitted and this looks like 127-byte verifier.
If you have any DB with such verifier please send it to me - want to fix.

Artyom Smirnov added a comment - 04/Apr/19 06:51 PM
Yep, bytes of course.

Here backup and original security3.fdb database. User/password are test/test

https://www.dropbox.com/s/0qc79m69fix0byi/security3.bak?dl=1
https://www.dropbox.com/s/1wej7tbiphm2any/security3.fdb?dl=1

Alexander Peshkov added a comment - 14/Apr/19 06:08 PM
Slightly offtopic - never used to notice that effect myself, great that you've found relatively stable case.