From: <ale...@us...> - 2011-12-23 12:44:08
|
Revision: 53739 http://firebird.svn.sourceforge.net/firebird/?rev=53739&view=rev Author: alexpeshkoff Date: 2011-12-23 12:43:58 +0000 (Fri, 23 Dec 2011) Log Message: ----------- Fixed CORE-1898: Increase the password length from 8 characters, CORE-3372: Simplify process of non-default security database creation Modified Paths: -------------- firebird/trunk/builds/install/arch-specific/linux/misc/linuxLibrary.sh.in firebird/trunk/builds/install/arch-specific/linux/misc/postinstall.sh.in firebird/trunk/builds/install/misc/posixLibrary.sh.in firebird/trunk/builds/posix/Makefile.in firebird/trunk/builds/posix/make.defaults firebird/trunk/builds/posix/make.shared.variables firebird/trunk/configure.in firebird/trunk/lang_helpers/gds_codes.ftn firebird/trunk/lang_helpers/gds_codes.pas firebird/trunk/src/auth/AuthDbg.cpp firebird/trunk/src/auth/AuthDbg.h firebird/trunk/src/auth/SecurityDatabase/LegacyClient.cpp firebird/trunk/src/auth/SecurityDatabase/LegacyClient.h firebird/trunk/src/auth/SecurityDatabase/LegacyHash.h firebird/trunk/src/auth/SecurityDatabase/LegacyManagement.epp firebird/trunk/src/auth/SecurityDatabase/LegacyManagement.h firebird/trunk/src/auth/SecurityDatabase/LegacyServer.cpp firebird/trunk/src/auth/SecurityDatabase/LegacyServer.h firebird/trunk/src/auth/trusted/AuthSspi.cpp firebird/trunk/src/auth/trusted/AuthSspi.h firebird/trunk/src/common/Auth.cpp firebird/trunk/src/common/Auth.h firebird/trunk/src/common/classes/ClumpletReader.cpp firebird/trunk/src/common/classes/ClumpletReader.h firebird/trunk/src/common/classes/ClumpletWriter.cpp firebird/trunk/src/common/classes/ClumpletWriter.h firebird/trunk/src/common/classes/GetPlugins.h firebird/trunk/src/common/classes/array.h firebird/trunk/src/common/common.h firebird/trunk/src/common/config/config.cpp firebird/trunk/src/common/security.h firebird/trunk/src/common/sha.cpp firebird/trunk/src/common/sha.h firebird/trunk/src/common/thd.cpp firebird/trunk/src/common/utils.cpp firebird/trunk/src/common/utils_proto.h firebird/trunk/src/include/consts_pub.h firebird/trunk/src/include/firebird/Plugin.h firebird/trunk/src/include/firebird/Provider.h firebird/trunk/src/include/gen/codetext.h firebird/trunk/src/include/gen/iberror.h firebird/trunk/src/include/gen/msgs.h firebird/trunk/src/include/gen/sql_code.h firebird/trunk/src/include/gen/sql_state.h firebird/trunk/src/jrd/SysFunction.cpp firebird/trunk/src/jrd/UserManagement.h firebird/trunk/src/jrd/jrd.cpp firebird/trunk/src/jrd/svc.cpp firebird/trunk/src/jrd/tra.cpp firebird/trunk/src/jrd/trace/TraceCmdLine.cpp firebird/trunk/src/jrd/trace/TraceManager.h firebird/trunk/src/msgs/facilities2.sql firebird/trunk/src/msgs/messages2.sql firebird/trunk/src/msgs/system_errors2.sql firebird/trunk/src/remote/client/interface.cpp firebird/trunk/src/remote/inet.cpp firebird/trunk/src/remote/inet_proto.h firebird/trunk/src/remote/os/win32/wnet.cpp firebird/trunk/src/remote/protocol.cpp firebird/trunk/src/remote/protocol.h firebird/trunk/src/remote/remot_proto.h firebird/trunk/src/remote/remote.cpp firebird/trunk/src/remote/remote.h firebird/trunk/src/remote/server/os/posix/inet_server.cpp firebird/trunk/src/remote/server/server.cpp firebird/trunk/src/utilities/gsec/gsec.cpp firebird/trunk/src/utilities/gsec/gsec_proto.h firebird/trunk/src/utilities/gstat/dba.epp firebird/trunk/src/yvalve/DistributedTransaction.cpp firebird/trunk/src/yvalve/PluginManager.cpp firebird/trunk/src/yvalve/PluginManager.h firebird/trunk/src/yvalve/why.cpp Added Paths: ----------- firebird/trunk/src/auth/SecureRemotePassword/ firebird/trunk/src/auth/SecureRemotePassword/BigInteger.cpp firebird/trunk/src/auth/SecureRemotePassword/BigInteger.h firebird/trunk/src/auth/SecureRemotePassword/Message.h firebird/trunk/src/auth/SecureRemotePassword/client/ firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.cpp firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.h firebird/trunk/src/auth/SecureRemotePassword/manage/ firebird/trunk/src/auth/SecureRemotePassword/manage/SrpManagement.cpp firebird/trunk/src/auth/SecureRemotePassword/misc/ firebird/trunk/src/auth/SecureRemotePassword/misc/prime.cpp firebird/trunk/src/auth/SecureRemotePassword/misc/test.sh firebird/trunk/src/auth/SecureRemotePassword/misc/test_srp.cpp firebird/trunk/src/auth/SecureRemotePassword/server/ firebird/trunk/src/auth/SecureRemotePassword/server/SrpServer.cpp firebird/trunk/src/auth/SecureRemotePassword/server/SrpServer.h firebird/trunk/src/auth/SecureRemotePassword/srp.cpp firebird/trunk/src/auth/SecureRemotePassword/srp.h firebird/trunk/src/include/firebird/Auth.h firebird/trunk/src/plugins/crypt/ firebird/trunk/src/plugins/crypt/arc4/ Removed Paths: ------------- firebird/trunk/src/auth/AuthInterface.h Modified: firebird/trunk/builds/install/arch-specific/linux/misc/linuxLibrary.sh.in =================================================================== --- firebird/trunk/builds/install/arch-specific/linux/misc/linuxLibrary.sh.in 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/builds/install/arch-specific/linux/misc/linuxLibrary.sh.in 2011-12-23 12:43:58 UTC (rev 53739) @@ -178,35 +178,40 @@ } #------------------------------------------------------------------------ -# Generate new sysdba password - this routine is used only in the -# rpm file not in the install script. +# Create new password string - this routine is used only in +# silent mode of the install script. -generateNewDBAPassword() { +createNewPassword() { # openssl generates random data. openssl </dev/null >/dev/null 2&>/dev/null if [ $? -eq 0 ] then - # We generate 20 random chars, strip any '/''s and get the first 8 - NewPasswd=`openssl rand -base64 20 | tr -d '/' | cut -c1-8` + # We generate 40 random chars, strip any '/''s and get the first 20 + NewPasswd=`openssl rand -base64 40 | tr -d '/' | cut -c1-20` fi - # mkpasswd is a bit of a hassle, but check to see if it's there - if [ -z "$NewPasswd" ] - then - if [ -f /usr/bin/mkpasswd ] - then - NewPasswd=`/usr/bin/mkpasswd -l 8` - fi - fi + # If openssl is missing... + if [ -z "$NewPasswd" ] + then + NewPasswd=`dd if=/dev/urandom bs=10 count=1 2>/dev/null | od -x | head -n 1 | tr -d ' ' | cut -c8-27` + fi - # On some systems the mkpasswd program doesn't appear and on others - # there is another mkpasswd which does a different operation. So if + # On some systems even this routines may be missing. So if # the specific one isn't available then keep the original password. if [ -z "$NewPasswd" ] then NewPasswd="masterkey" fi + echo "$NewPasswd" +} + +#------------------------------------------------------------------------ +# Generate new sysdba password - this routine is used only in +# silent mode of the install script. + +generateNewDBAPassword() { + NewPasswd=`createNewPassword` writeNewPassword $NewPasswd } Modified: firebird/trunk/builds/install/arch-specific/linux/misc/postinstall.sh.in =================================================================== --- firebird/trunk/builds/install/arch-specific/linux/misc/postinstall.sh.in 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/builds/install/arch-specific/linux/misc/postinstall.sh.in 2011-12-23 12:43:58 UTC (rev 53739) @@ -40,16 +40,6 @@ addFirebirdUser fi -# Create the fbmgr shell script. -if [ -x @FB_SBINDIR@/fbmgr.bin ]; then - cat > @FB_SBINDIR@/fbmgr <<EOF -#!/bin/sh -FIREBIRD=@FB_CONFDIR@ -export FIREBIRD -exec @FB_SBINDIR@/fbmgr.bin \$@ -EOF -fi - # Update ownership and SUID bits for files. fixFilePermissions @@ -65,11 +55,11 @@ # Update the /etc/inetd.conf or xinetd entry updateInetdServiceEntry +# Change sysdba password (use embedded access) +setDBAPassword + # Get inetd to reread new init files. resetInetdServer -# start the db server so we can change the password +# start the RDBMS server startService @FIREBIRD_ARCH_TYPE@ - -# Change sysdba password -changeDBAPassword Modified: firebird/trunk/builds/install/misc/posixLibrary.sh.in =================================================================== --- firebird/trunk/builds/install/misc/posixLibrary.sh.in 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/builds/install/misc/posixLibrary.sh.in 2011-12-23 12:43:58 UTC (rev 53739) @@ -297,6 +297,17 @@ #------------------------------------------------------------------------ +# Ask user to enter new DBA password string +# !! This routine is interactive !! + +getNewDBAPasswordFromUser() +{ + AskQuestion "Please enter new password for SYSDBA user: " + echo $Answer +} + + +#------------------------------------------------------------------------ # Modify DBA password to value, asked from user. # $1 may be set to original DBA password # !! This routine is interactive !! @@ -313,8 +324,7 @@ NewPasswd="" while [ -z "$NewPasswd" ] do - AskQuestion "Please enter new password for SYSDBA user: " - NewPasswd=$Answer + NewPasswd=`getNewDBAPasswordFromUser` if [ ! -z "$NewPasswd" ] then if ! runSilent "@FB_BINDIR@/gsec -user sysdba -password $OrigPasswd -modify sysdba -pw $NewPasswd" @@ -438,6 +448,26 @@ #------------------------------------------------------------------------ +# Set sysdba password. + +setDBAPassword() { + if [ -z "$InteractiveInstall" ] + then + passwd=`createNewPassword` + else + passwd=`getNewDBAPasswordFromUser` + fi + + if [ ! -z "$passwd" ] + then + passwd=masterkey + fi + + runSilent "@FB_BINDIR@/gsec -add sysdba -pw $passwd" +} + + +#------------------------------------------------------------------------ # buildUninstallFile # This will work only for the .tar.gz install and it builds an # uninstall shell script. The RPM system, if present, takes care of it's own. Modified: firebird/trunk/builds/posix/Makefile.in =================================================================== --- firebird/trunk/builds/posix/Makefile.in 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/builds/posix/Makefile.in 2011-12-23 12:43:58 UTC (rev 53739) @@ -359,10 +359,11 @@ # plugins - some of them are required to build examples, use separate entry for them # -.PHONY: udr legacy_user_management trace auth_debug +.PHONY: udr legacy_user_management trace auth_debug makePluginName= $(PLUGINS)/$(LIB_PREFIX)$(1).$(SHRLIB_EXT) UDR_PLUGIN = $(call makePluginName,udr_engine) LEGACY_USER_MANAGER = $(call makePluginName,Legacy_UserManager) +SRP_USER_MANAGER = $(call makePluginName,Srp) AUTH_DEBUGGER = $(call makePluginName,Auth_Debug) BUILD_DEBUG:= @@ -370,7 +371,7 @@ BUILD_DEBUG:=auth_debug endif -plugins: udr legacy_user_management trace $(BUILD_DEBUG) +plugins: udr legacy_user_management srp_user_management trace $(BUILD_DEBUG) udr: $(UDR_PLUGIN) $(PLUGINS)/udr_engine.conf @@ -395,7 +396,11 @@ $(AUTH_DEBUGGER): $(AUTH_DEBUGGER_Objects) $(COMMON_LIB) $(LINK_PLUGIN) $(call LIB_LINK_SONAME,$(notdir $@).0) -o $@ $^ $(LINK_PLUG_LIBS) $(FIREBIRD_LIBRARY_LINK) +srp_user_management: $(SRP_USER_MANAGER) +$(SRP_USER_MANAGER): $(SRP_USERS_MANAGE_Objects) $(COMMON_LIB) + $(LINK_PLUGIN) $(call LIB_LINK_SONAME,$(notdir $@).0) -o $@ $^ $(LINK_PLUG_LIBS) $(FIREBIRD_LIBRARY_LINK) $(MATHLIB) + #___________________________________________________________________________ # codes - developers change them sometimes # Modified: firebird/trunk/builds/posix/make.defaults =================================================================== --- firebird/trunk/builds/posix/make.defaults 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/builds/posix/make.defaults 2011-12-23 12:43:58 UTC (rev 53739) @@ -128,6 +128,9 @@ # needed at least for solaris inline assembly routines CAS_OPTIONS=@CAS_OPTIONS@ +# multiple-precision integer library +MATHLIB=@MATHLIB@ + # Default programs and tools to be used in the build process SH= sh -c @@ -307,7 +310,7 @@ LINK_FIREBIRD = $(LIB_LINK) $(LINK_FIREBIRD_SYMBOLS) $(LIB_LINK_OPTIONS) $(LIB_FIREBIRD_OPTIONS) $(UNDEF_FLAGS)\ $(call LIB_LINK_SONAME,$(LibrarySoName)) $(call LIB_LINK_RPATH,lib) -LINK_FIREBIRD_LIBS = -L$(LIB) $(LIB_GUI) $(SO_LINK_LIBS) +LINK_FIREBIRD_LIBS = -L$(LIB) $(LIB_GUI) $(SO_LINK_LIBS) $(MATHLIB) LINK_ENGINE = $(LIB_LINK) $(LINK_PLUGIN_SYMBOLS) $(LIB_LINK_OPTIONS) $(LIB_FIREBIRD_OPTIONS) $(UNDEF_FLAGS)\ $(call LIB_LINK_SONAME,$(EngineSoName)) $(call LIB_LINK_RPATH,lib) Modified: firebird/trunk/builds/posix/make.shared.variables =================================================================== --- firebird/trunk/builds/posix/make.shared.variables 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/builds/posix/make.shared.variables 2011-12-23 12:43:58 UTC (rev 53739) @@ -49,10 +49,12 @@ # Remote -Remote_Common:= $(call dirObjects,remote) -Remote_Server:= $(call dirObjects,remote/server) $(call makeObjects,auth/SecurityDatabase,LegacyServer.cpp) - # legacy security database LegacyServer.cpp should become SA plugin -Remote_Client:= $(call dirObjects,remote/client) $(call makeObjects,auth/SecurityDatabase,LegacyClient.cpp) +Remote_Common:= $(call dirObjects,remote) $(call dirObjects,auth/SecureRemotePassword) +Remote_Server:= $(call dirObjects,remote/server) $(call dirObjects,auth/SecureRemotePassword/server) \ + $(call makeObjects,auth/SecurityDatabase,LegacyServer.cpp) + # legacy security database LegacyServer.cpp should become plugin soon +Remote_Client:= $(call dirObjects,remote/client) $(call dirObjects,auth/SecureRemotePassword/client) \ + $(call makeObjects,auth/SecurityDatabase,LegacyClient.cpp) Remote_Server_Objects:= $(Remote_Common) $(Remote_Server) Remote_Client_Objects:= $(Remote_Common) $(Remote_Client) @@ -165,6 +167,13 @@ AllObjects += $(LEGACY_USERS_MANAGE_Objects) +# SRP-based users management in security database +SRP_USERS_MANAGE_Objects:= $(call dirObjects,auth/SecureRemotePassword/manage) \ + $(call dirObjects,auth/SecureRemotePassword) + +AllObjects += $(SRP_USERS_MANAGE_Objects) + + # Multihop authentication debugger AUTH_DEBUGGER_Objects:= $(call makeObjects,auth,AuthDbg.cpp) Modified: firebird/trunk/configure.in =================================================================== --- firebird/trunk/configure.in 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/configure.in 2011-12-23 12:43:58 UTC (rev 53739) @@ -43,6 +43,18 @@ AC_SUBST([$3]) ]) +define([XE_SAVE_ENV], [ +pre_save_restore_cflags=$CFLAGS +pre_save_restore_cxxflags=$CXXFLAGS +pre_save_restore_libs=$LIBS +]) + +define([XE_RESTORE_ENV], [ +CFLAGS=$pre_save_restore_cflags +CXXFLAGS=$pre_save_restore_cxxflags +LIBS=$pre_save_restore_libs +]) + sinclude(acx_pthread.m4) sinclude(binreloc.m4) @@ -458,14 +470,11 @@ fi dnl Find out how to use threads on this platform -pre_acx_pthread_cflags=$CFLAGS -pre_acx_pthread_cxxflags=$CXXFLAGS -pre_acx_pthread_libs=$LIBS +XE_SAVE_ENV() ACX_PTHREAD([ AC_DEFINE(HAVE_MULTI_THREAD, 1, [Define this if multi-threading should be supported])]) -CFLAGS=$pre_acx_pthread_cflags -LIBS=$pre_acx_pthread_libs +XE_RESTORE_ENV() AC_SUBST(PTHREAD_LIBS) AC_SUBST(PTHREAD_CFLAGS) @@ -507,7 +516,7 @@ # not need editline in default libs, but need to test for its presence READLINE=edit # builtin default -saveLIBS=$LIBS +XE_SAVE_ENV() if test "$STD_EDITLINE" = "true"; then AC_CHECK_LIB(edit, readline, [READLINE=edit EDITLINE_FLG=Y], AC_CHECK_LIB(editline, readline, [READLINE=editline EDITLINE_FLG=Y], @@ -517,7 +526,7 @@ AC_MSG_WARN([[[--with-system-editline specified, not found. Using bundled editline]]])]))) fi fi -LIBS=$saveLIBS +XE_RESTORE_ENV() AC_SUBST(READLINE) AC_SUBST(STD_EDITLINE) @@ -671,6 +680,14 @@ dnl setting ICU_OK here is done to only avoid default action AC_CHECK_LIB(icuuc, main, ICU_OK=yes, AC_MSG_ERROR(ICU support not found - please install development ICU package)) +dnl check for tommath presence +XE_SAVE_ENV() +LIBS= +AC_CHECK_HEADER(tommath.h,,AC_MSG_ERROR(Include file for tommath not found - please install development tommath package)) +AC_CHECK_LIB(tommath, mp_init, MATHLIB=-ltommath, AC_MSG_ERROR(Library tommath not found - please install development tommath package)) +XE_RESTORE_ENV() +AC_SUBST(MATHLIB) + dnl Check for libraries AC_SEARCH_LIBS(dlopen, dl) AC_CHECK_LIB(m, main) @@ -990,12 +1007,12 @@ esac dnl Detect support for ISO syntax for thread-locals -pre_tls_cxxflags=$CXXFLAGS +XE_SAVE_ENV() CXXFLAGS=$TLS_OPTIONS AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[__thread int a = 42;]],[[a = a + 1;]])], AC_DEFINE(HAVE___THREAD, 1, [Define it if compiler supports ISO syntax for thread-local storage]),) -CXXFLAGS=$pre_tls_cxxflags +XE_RESTORE_ENV() AC_SUBST(TLS_OPTIONS) AC_SUBST(ATOMIC_OPTIONS) AC_SUBST(CAS_OPTIONS) Modified: firebird/trunk/lang_helpers/gds_codes.ftn =================================================================== --- firebird/trunk/lang_helpers/gds_codes.ftn 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/lang_helpers/gds_codes.ftn 2011-12-23 12:43:58 UTC (rev 53739) @@ -1468,6 +1468,8 @@ PARAMETER (GDS__ee_blr_mismatch_length = 335545027) INTEGER*4 GDS__ss_out_of_bounds PARAMETER (GDS__ss_out_of_bounds = 335545028) + INTEGER*4 GDS__missing_data_structures + PARAMETER (GDS__missing_data_structures = 335545029) INTEGER*4 GDS__gfix_db_name PARAMETER (GDS__gfix_db_name = 335740929) INTEGER*4 GDS__gfix_invalid_sw Modified: firebird/trunk/lang_helpers/gds_codes.pas =================================================================== --- firebird/trunk/lang_helpers/gds_codes.pas 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/lang_helpers/gds_codes.pas 2011-12-23 12:43:58 UTC (rev 53739) @@ -741,6 +741,7 @@ gds_ee_blr_mismatch_null = 335545026; gds_ee_blr_mismatch_length = 335545027; gds_ss_out_of_bounds = 335545028; + gds_missing_data_structures = 335545029; gds_gfix_db_name = 335740929; gds_gfix_invalid_sw = 335740930; gds_gfix_incmp_sw = 335740932; Modified: firebird/trunk/src/auth/AuthDbg.cpp =================================================================== --- firebird/trunk/src/auth/AuthDbg.cpp 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/src/auth/AuthDbg.cpp 2011-12-23 12:43:58 UTC (rev 53739) @@ -56,10 +56,10 @@ : str(getPool()) { } -Result FB_CARG DebugServer::startAuthentication(Firebird::IStatus* status, const AuthTags* tags, - IClumplets* dpb, IWriter* writerInterface) +Result FB_CARG DebugServer::authenticate(Firebird::IStatus* status, IServerBlock* sBlock, + IWriter* writerInterface) { - try +/* try { Firebird::MasterInterfacePtr()->upgradeInterface(dpb, FB_AUTH_CLUMPLETS_VERSION, upInfo); str.erase(); @@ -86,10 +86,10 @@ catch (const Firebird::Exception& ex) { ex.stuffException(status); - return AUTH_FAILED; - } + } */ + return AUTH_FAILED; } - +/* Result FB_CARG DebugServer::contAuthentication(Firebird::IStatus* status, const unsigned char* data, unsigned int size, IWriter* writerInterface) { @@ -108,16 +108,8 @@ return AUTH_FAILED; } } + */ -void FB_CARG DebugServer::getData(const unsigned char** data, unsigned short* dataSize) -{ - *data = reinterpret_cast<const unsigned char*>(str.c_str()); - *dataSize = str.length(); -#ifdef AUTH_VERBOSE - fprintf(stderr, "DebugServer::getData: %.*s\n", *dataSize, *data); -#endif -} - int FB_CARG DebugServer::release() { if (--refCounter == 0) @@ -133,8 +125,9 @@ : str(getPool()) { } -Result FB_CARG DebugClient::startAuthentication(Firebird::IStatus* status, const AuthTags* tags, IClumplets* dpb) +Result FB_CARG DebugClient::authenticate(Firebird::IStatus* status, IClientBlock* cBlock) { +/* try { str = "HAND"; @@ -155,10 +148,11 @@ catch (const Firebird::Exception& ex) { ex.stuffException(status); - return AUTH_FAILED; } + */ + return AUTH_FAILED; } - +/* Result FB_CARG DebugClient::contAuthentication(Firebird::IStatus* status, const unsigned char* data, unsigned int size) { try @@ -180,16 +174,8 @@ return AUTH_FAILED; } } +*/ -void FB_CARG DebugClient::getData(const unsigned char** data, unsigned short* dataSize) -{ - *data = reinterpret_cast<const unsigned char*>(str.c_str()); - *dataSize = str.length(); -#ifdef AUTH_VERBOSE - fprintf(stderr, "DebugClient::getData: %.*s\n", *dataSize, *data); -#endif -} - int FB_CARG DebugClient::release() { if (--refCounter == 0) @@ -201,6 +187,22 @@ return 1; } +Result DebugServer::getSessionKey(Firebird::IStatus*, + const unsigned char** key, unsigned int* keyLen) +{ + *key = NULL; + *keyLen = 0; + return AUTH_CONTINUE; +} + +Result DebugClient::getSessionKey(Firebird::IStatus*, + const unsigned char** key, unsigned int* keyLen) +{ + *key = NULL; + *keyLen = 0; + return AUTH_CONTINUE; +} + } // namespace Auth #endif // AUTH_DEBUG Modified: firebird/trunk/src/auth/AuthDbg.h =================================================================== --- firebird/trunk/src/auth/AuthDbg.h 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/src/auth/AuthDbg.h 2011-12-23 12:43:58 UTC (rev 53739) @@ -34,7 +34,7 @@ #ifdef AUTH_DEBUG -#include "../auth/AuthInterface.h" +#include "firebird/Auth.h" #include "../common/classes/ImplementHelper.h" #include "../common/classes/ClumpletWriter.h" #include "../common/classes/init.h" @@ -51,11 +51,10 @@ public: DebugServer(Firebird::IPluginConfig*); - Result startAuthentication(Firebird::IStatus* status, const AuthTags* tags, IClumplets* dpb, + Result authenticate(Firebird::IStatus* status, IServerBlock* sBlock, IWriter* writerInterface); - Result contAuthentication(Firebird::IStatus* status, const unsigned char* data, - unsigned int size, IWriter* writerInterface); - void getData(const unsigned char** data, unsigned short* dataSize); + Result getSessionKey(Firebird::IStatus* status, + const unsigned char** key, unsigned int* keyLen); int release(); private: @@ -67,9 +66,9 @@ public: DebugClient(Firebird::IPluginConfig*); - Result startAuthentication(Firebird::IStatus* status, const AuthTags* tags, IClumplets* dpb); - Result contAuthentication(Firebird::IStatus* status, const unsigned char* data, unsigned int size); - void getData(const unsigned char** data, unsigned short* dataSize); + Result authenticate(Firebird::IStatus* status, IClientBlock* sBlock); + Result getSessionKey(Firebird::IStatus* status, + const unsigned char** key, unsigned int* keyLen); int release(); private: Deleted: firebird/trunk/src/auth/AuthInterface.h =================================================================== --- firebird/trunk/src/auth/AuthInterface.h 2011-12-23 03:21:38 UTC (rev 53738) +++ firebird/trunk/src/auth/AuthInterface.h 2011-12-23 12:43:58 UTC (rev 53739) @@ -1,166 +0,0 @@ -/* - * PROGRAM: Firebird authentication - * MODULE: AuthInterface.h - * DESCRIPTION: Interfaces, used by authentication plugins - * - * The contents of this file are subject to the Initial - * Developer's Public License Version 1.0 (the "License"); - * you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. - * - * Software distributed under the License is distributed AS IS, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. - * See the License for the specific language governing rights - * and limitations under the License. - * - * The Original Code was created by Alex Peshkov - * for the Firebird Open Source RDBMS project. - * - * Copyright (c) 2010 Alex Peshkov <peshkoff at mail.ru> - * and all contributors signed below. - * - * All Rights Reserved. - * Contributor(s): ______________________________________. - * - * - */ - -#ifndef FB_AUTH_INTERFACE -#define FB_AUTH_INTERFACE - -#include "firebird/Plugin.h" - -namespace Firebird { -class IStatus; -} - -namespace Auth { - -enum Result {AUTH_SUCCESS, AUTH_CONTINUE, AUTH_FAILED, AUTH_MORE_DATA}; - -class IWriter : public Firebird::IVersioned -{ -public: - virtual void FB_CARG reset() = 0; - virtual void FB_CARG add(const char* name) = 0; - virtual void FB_CARG setAttribute(unsigned char tag, const char* value) = 0; -}; -#define FB_AUTH_WRITER_VERSION (FB_VERSIONED_VERSION + 3) - -class IClumplets : public Firebird::IVersioned -{ -public: - virtual int FB_CARG find(UCHAR tag) = 0; - virtual void FB_CARG add(UCHAR tag, const void* bytes, unsigned int count) = 0; - virtual void FB_CARG drop() = 0; - virtual const unsigned char* FB_CARG get(unsigned int* cntPtr) = 0; -}; -#define FB_AUTH_CLUMPLETS_VERSION (FB_VERSIONED_VERSION + 4) - -// This struct defines auth-related tags (including legacy ones) in parameter blocks -struct AuthTags -{ - UCHAR authBlock, trustedAuth, trustedRole; - UCHAR service; // non-zero if we work with service connection -}; - -class IServer : public Firebird::IPluginBase -{ -public: - virtual Result FB_CARG startAuthentication(Firebird::IStatus* status, const AuthTags* tags, IClumplets* dpb, - IWriter* writerInterface) = 0; - virtual Result FB_CARG contAuthentication(Firebird::IStatus* status, const unsigned char* data, - unsigned int size, IWriter* writerInterface) = 0; - virtual void FB_CARG getData(const unsigned char** data, unsigned short* dataSize) = 0; -}; -#define FB_AUTH_SERVER_VERSION (FB_PLUGIN_VERSION + 3) - -class IClient : public Firebird::IPluginBase -{ -public: - virtual Result FB_CARG startAuthentication(Firebird::IStatus* status, const AuthTags* tags, IClumplets* dpb) = 0; - virtual Result FB_CARG contAuthentication(Firebird::IStatus* status, const unsigned char* data, unsigned int size) = 0; - virtual void FB_CARG getData(const unsigned char** data, unsigned short* dataSize) = 0; -}; -#define FB_AUTH_CLIENT_VERSION (FB_PLUGIN_VERSION + 3) - -class IUserField : public Firebird::IVersioned -{ -public: - virtual int FB_CARG entered() = 0; - virtual int FB_CARG specified() = 0; - virtual void FB_CARG setEntered(int newValue) = 0; -}; -#define FB_AUTH_FIELD_VERSION (FB_VERSIONED_VERSION + 3) - -class ICharUserField : public IUserField -{ -public: - virtual const char* FB_CARG get() = 0; - virtual void FB_CARG set(const char* newValue) = 0; -}; -#define FB_AUTH_CHAR_FIELD_VERSION (FB_AUTH_FIELD_VERSION + 2) - -class IIntUserField : public IUserField -{ -public: - virtual int FB_CARG get() = 0; - virtual void FB_CARG set(int newValue) = 0; -}; -#define FB_AUTH_INT_FIELD_VERSION (FB_AUTH_FIELD_VERSION + 2) - -class IUser : public Firebird::IVersioned -{ -public: - virtual int FB_CARG operation() = 0; - - virtual ICharUserField* FB_CARG userName() = 0; - virtual ICharUserField* FB_CARG password() = 0; - - virtual ICharUserField* FB_CARG firstName() = 0; - virtual ICharUserField* FB_CARG lastName() = 0; - virtual ICharUserField* FB_CARG middleName() = 0; - virtual ICharUserField* FB_CARG groupName() = 0; - - virtual IIntUserField* FB_CARG uid() = 0; - virtual IIntUserField* FB_CARG gid() = 0; - virtual IIntUserField* FB_CARG admin() = 0; - - virtual void FB_CARG clear() = 0; -}; -#define FB_AUTH_USER_VERSION (FB_VERSIONED_VERSION + 11) - -class IListUsers : public Firebird::IVersioned -{ -public: - virtual void FB_CARG list(IUser* user) = 0; -}; -#define FB_AUTH_LIST_USERS_VERSION (FB_VERSIONED_VERSION + 1) - -class ILogonInfo : public Firebird::IVersioned -{ -public: - virtual const char* FB_CARG name() = 0; - virtual const char* FB_CARG role() = 0; - virtual int FB_CARG forceAdmin() = 0; - virtual const char* FB_CARG networkProtocol() = 0; - virtual const char* FB_CARG remoteAddress() = 0; - virtual unsigned int FB_CARG authBlock(const unsigned char** bytes) = 0; -}; -#define FB_AUTH_LOGON_INFO_VERSION (FB_VERSIONED_VERSION + 6) - -class IManagement : public Firebird::IPluginBase -{ -public: - virtual void FB_CARG start(Firebird::IStatus* status, ILogonInfo* logonInfo) = 0; - virtual int FB_CARG execute(Firebird::IStatus* status, IUser* user, IListUsers* callback) = 0; - virtual void FB_CARG commit(Firebird::IStatus* status) = 0; - virtual void FB_CARG rollback(Firebird::IStatus* status) = 0; -}; -#define FB_AUTH_MANAGE_VERSION (FB_PLUGIN_VERSION + 4) - -} // namespace Auth - - -#endif // FB_AUTH_INTERFACE Added: firebird/trunk/src/auth/SecureRemotePassword/BigInteger.cpp =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/BigInteger.cpp (rev 0) +++ firebird/trunk/src/auth/SecureRemotePassword/BigInteger.cpp 2011-12-23 12:43:58 UTC (rev 53739) @@ -0,0 +1,212 @@ +/* + * PROGRAM: Firebird interface. + * MODULE: BigInteger.cpp + * DESCRIPTION: Integer of unlimited precision. Uses libtommath. + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2011 Alex Peshkov <peshkoff at mail.ru> + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + * + * + */ + +#include "firebird.h" +#include "gen/iberror.h" + +#include <stdlib.h> + +#include "../auth/SecureRemotePassword/BigInteger.h" +#include "../common/os/guid.h" + +using namespace Firebird; + +#define CHECK_MP(a) check(a, #a) + +namespace Auth +{ + + static inline void check(int rc, const char* function) + { + switch (rc) + { + case MP_OKAY: + return; + case MP_MEM: + BadAlloc::raise(); + default: + // Want fancy "Libtommath error in @1 code @2" + (Arg::Gds(isc_random) << "Libtommath error").raise(); + } + } + + BigInteger::BigInteger() + { + CHECK_MP(mp_init(&t)); + } + + BigInteger::BigInteger(const char* text, unsigned int radix) + { + CHECK_MP(mp_init(&t)); + CHECK_MP(mp_read_radix(&t, text, radix)); + } + + BigInteger::BigInteger(unsigned int count, const unsigned char* bytes) + { + CHECK_MP(mp_init(&t)); + assign(count, bytes); + } + + BigInteger::BigInteger(const Firebird::UCharBuffer& val) + { + CHECK_MP(mp_init(&t)); + assign(val.getCount(), val.begin()); + } + + BigInteger::BigInteger(const BigInteger& val) + { + CHECK_MP(mp_init_copy(const_cast<mp_int*>(&val.t), &t)); + } + + BigInteger::~BigInteger() + { + mp_clear(&t); + } + + BigInteger& BigInteger::operator= (const BigInteger& val) + { + CHECK_MP(mp_copy(const_cast<mp_int*>(&val.t), &t)); + return *this; + } + + void BigInteger::random(int numBytes) + { + Firebird::UCharBuffer b; + Firebird::GenerateRandomBytes(b.getBuffer(numBytes), numBytes); + assign(numBytes, b.begin()); + } + + void BigInteger::assign(unsigned int count, const unsigned char* bytes) + { + CHECK_MP(mp_read_unsigned_bin(&t, bytes, count)); + } + + BigInteger BigInteger::operator+ (const BigInteger& val) const + { + BigInteger rc; + CHECK_MP(mp_add(const_cast<mp_int*>(&t), const_cast<mp_int*>(&val.t), &rc.t)); + return rc; + } + + BigInteger BigInteger::operator- (const BigInteger& val) const + { + BigInteger rc; + CHECK_MP(mp_sub(const_cast<mp_int*>(&t), const_cast<mp_int*>(&val.t), &rc.t)); + return rc; + } + + BigInteger BigInteger::operator* (const BigInteger& val) const + { + BigInteger rc; + CHECK_MP(mp_mul(const_cast<mp_int*>(&t), const_cast<mp_int*>(&val.t), &rc.t)); + return rc; + } + + BigInteger BigInteger::operator/ (const BigInteger& val) const + { + BigInteger rc; + CHECK_MP(mp_div(const_cast<mp_int*>(&t), const_cast<mp_int*>(&val.t), &rc.t, NULL)); + return rc; + } + + BigInteger BigInteger::operator% (const BigInteger& val) const + { + BigInteger rc; + CHECK_MP(mp_mod(const_cast<mp_int*>(&t), const_cast<mp_int*>(&val.t), &rc.t)); + return rc; + } + + BigInteger& BigInteger::operator+= (const BigInteger& val) + { + CHECK_MP(mp_add(&t, const_cast<mp_int*>(&val.t), &t)); + return *this; + } + + BigInteger& BigInteger::operator-= (const BigInteger& val) + { + CHECK_MP(mp_sub(&t, const_cast<mp_int*>(&val.t), &t)); + return *this; + } + + BigInteger& BigInteger::operator*= (const BigInteger& val) + { + CHECK_MP(mp_mul(&t, const_cast<mp_int*>(&val.t), &t)); + return *this; + } + + BigInteger& BigInteger::operator/= (const BigInteger& val) + { + CHECK_MP(mp_div(&t, const_cast<mp_int*>(&val.t), &t, NULL)); + return *this; + } + + BigInteger& BigInteger::operator%= (const BigInteger& val) + { + CHECK_MP(mp_mod(&t, const_cast<mp_int*>(&val.t), &t)); + return *this; + } + + bool BigInteger::operator== (const BigInteger& val) const + { + return mp_cmp(const_cast<mp_int*>(&t), const_cast<mp_int*>(&val.t)) == 0; + } + + void BigInteger::getBytes(Firebird::UCharBuffer& bytes) const + { + CHECK_MP(mp_to_unsigned_bin(const_cast<mp_int*>(&t), bytes.getBuffer(length()))); + } + + unsigned int BigInteger::length() const + { + int rc = mp_unsigned_bin_size(const_cast<mp_int*>(&t)); + if (rc < 0) + { + check(rc, "mp_unsigned_bin_size(&t)"); + } + return static_cast<unsigned int>(rc); + } + + void BigInteger::getText(string& str, unsigned int radix) const + { + int size; + CHECK_MP(mp_radix_size(const_cast<mp_int*>(&t), radix, &size)); + str.resize(size - 1, ' '); + CHECK_MP(mp_toradix(const_cast<mp_int*>(&t), const_cast<char*>(str.c_str()), radix)); + } + + BigInteger BigInteger::modPow(const BigInteger& pow, const BigInteger& mod) const + { + BigInteger rc; + CHECK_MP(mp_exptmod(const_cast<mp_int*>(&t), const_cast<mp_int*>(&pow.t), + const_cast<mp_int*>(&mod.t), &rc.t)); + return rc; + } + +} + +#undef CHECK_MP Property changes on: firebird/trunk/src/auth/SecureRemotePassword/BigInteger.cpp ___________________________________________________________________ Added: svn:mime-type + text/x-c++src Added: svn:eol-style + native Added: firebird/trunk/src/auth/SecureRemotePassword/BigInteger.h =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/BigInteger.h (rev 0) +++ firebird/trunk/src/auth/SecureRemotePassword/BigInteger.h 2011-12-23 12:43:58 UTC (rev 53739) @@ -0,0 +1,80 @@ +/* + * PROGRAM: Firebird interface. + * MODULE: BigInteger.h + * DESCRIPTION: Integer of unlimited precision. Uses libtommath. + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2010 Alex Peshkov <peshkoff at mail.ru> + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + * + * + */ + +#ifndef FB_COMMON_CLASSES_BIG_INTEGER +#define FB_COMMON_CLASSES_BIG_INTEGER + +#include <tommath.h> + +#include "../common/classes/fb_string.h" +#include "../common/classes/array.h" + +namespace Auth { + +class BigInteger +{ +public: + BigInteger(); + BigInteger(const char* text, unsigned int radix = 16u); + BigInteger(unsigned int count, const unsigned char* bytes); + BigInteger(const Firebird::UCharBuffer& val); + BigInteger(const BigInteger& val); +// BigInteger(int numBits, Random& r); + ~BigInteger(); + + BigInteger& operator= (const BigInteger& val); + void random(int numBytes); + void assign(unsigned int count, const unsigned char* bytes); + + BigInteger operator+ (const BigInteger& val) const; + BigInteger operator- (const BigInteger& val) const; + BigInteger operator* (const BigInteger& val) const; + BigInteger operator/ (const BigInteger& val) const; + BigInteger operator% (const BigInteger& val) const; + + BigInteger& operator+= (const BigInteger& val); + BigInteger& operator-= (const BigInteger& val); + BigInteger& operator*= (const BigInteger& val); + BigInteger& operator/= (const BigInteger& val); + BigInteger& operator%= (const BigInteger& val); + + bool operator== (const BigInteger& val) const; + + void getBytes(Firebird::UCharBuffer& bytes) const; + unsigned int length() const; + void getText(Firebird::string& str, unsigned int radix = 16u) const; + + BigInteger modPow(const BigInteger& pow, const BigInteger& mod) const; + +private: + mp_int t; +}; + +} // namespace Firebird + +#endif // FB_COMMON_CLASSES_BIG_INTEGER Property changes on: firebird/trunk/src/auth/SecureRemotePassword/BigInteger.h ___________________________________________________________________ Added: svn:mime-type + text/x-chdr Added: svn:eol-style + native Added: firebird/trunk/src/auth/SecureRemotePassword/Message.h =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/Message.h (rev 0) +++ firebird/trunk/src/auth/SecureRemotePassword/Message.h 2011-12-23 12:43:58 UTC (rev 53739) @@ -0,0 +1,157 @@ +#include "../jrd/align.h" +#include "../common/classes/alloc.h" + +// This class helps to fill FbMessage with correct values +class Message : public Firebird::FbMessage, public Firebird::GlobalStorage +{ +public: + Message() + : blrBuf(getPool()), dataBuf(getPool()) + { + blrLength = 0; + blr = NULL; + bufferLength = 0; + buffer = NULL; + + // start message BLR + blrBuf.add(blr_version5); + blrBuf.add(blr_begin); + blrBuf.add(blr_message); + blrBuf.add(0); + countOffset = blrBuf.getCount(); + blrBuf.add(0); + blrBuf.add(0); + + varCount = 0; + } + + template <typename T> + unsigned genBlr() + { + // for special types call type-specific BLR generator + // for generic types use specialization of whole call + return T::genBlr(blrBuf); + } + + template <typename T> + void add(unsigned& pos, unsigned& null) + { + if (blr) + { + (Firebird::Arg::Gds(isc_random) << "This is already constructed message").raise(); + } + + // generate code for variable + unsigned align = genBlr<T>(); + if (align) + { + bufferLength = FB_ALIGN(bufferLength, align); + } + pos = bufferLength; + bufferLength += sizeof(T); + + // generate code for null flag + blrBuf.add(blr_short); + blrBuf.add(0); + align = type_alignments[dtype_short]; + if (align) + { + bufferLength = FB_ALIGN(bufferLength, align); + } + null = bufferLength; + bufferLength += sizeof(short); + + ++varCount; + } + + void ready() + { + if (blr) + return; + + // Adjust number of variables + blrBuf[countOffset] = (varCount * 2) & 0xFF; + blrBuf[countOffset + 1] = ((varCount * 2) >> 8) & 0xFF; + + // Complete blr + blrBuf.add(blr_end); + blrBuf.add(blr_eoc); + blrLength = blrBuf.getCount(); + blr = blrBuf.begin(); + + // Allocate buffer + buffer = dataBuf.getBuffer(bufferLength); + } + + Firebird::UCharBuffer blrBuf, dataBuf; + unsigned countOffset, varCount; +}; + +template <> +unsigned Message::genBlr<SLONG>() +{ + blrBuf.add(blr_long); + blrBuf.add(0); // scale + return type_alignments[dtype_long]; +} + +// With template magic, we make the fields strongly-typed. +template <class T> +class Field +{ +public: + Field(Message& m) + : msg(m), pos(~0), nullPos(~0) + { + msg.add<T>(pos, nullPos); + } + + T& operator()() + { + msg.ready(); + return *(T*) (msg.buffer + pos); + } + + short& null() + { + msg.ready(); + return *(short*) (msg.buffer + nullPos); + } + +private: + Message& msg; + unsigned pos, nullPos; +}; + +template <short N> +class VarChar +{ +public: + short len; + char data[N]; // This guarantees N > 0 + + static unsigned genBlr(Firebird::UCharBuffer& blr) + { + blr.add(blr_varying); + blr.add(N & 0xFF); + blr.add((N >> 8) & 0xFF); + return type_alignments[dtype_varying]; + } + + const VarChar& operator=(const char* str) + { + strncpy(data, str, N); + len = strlen(str); + if (len > N) + len = N; + return *this; + } + + void set(unsigned short l, void* bytes) + { + if (l > (unsigned short) N) + l = N; + memcpy(data, bytes, l); + len = l; + } +}; Property changes on: firebird/trunk/src/auth/SecureRemotePassword/Message.h ___________________________________________________________________ Added: svn:mime-type + text/x-chdr Added: svn:eol-style + native Added: firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.cpp =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.cpp (rev 0) +++ firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.cpp 2011-12-23 12:43:58 UTC (rev 53739) @@ -0,0 +1,173 @@ +/* + * PROGRAM: Firebird authentication. + * MODULE: SrpClient.cpp + * DESCRIPTION: SPR authentication plugin. + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2011 Alex Peshkov <peshkoff at mail.ru> + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include "firebird.h" + +#include "../auth/SecureRemotePassword/client/SrpClient.h" +#include "../auth/SecureRemotePassword/srp.h" +#include "../common/classes/ImplementHelper.h" + +using namespace Firebird; + +namespace Auth { + +class SrpClient : public Firebird::StdPlugin<IClient, FB_AUTH_CLIENT_VERSION> +{ +public: + explicit SrpClient(Firebird::IPluginConfig*) + : client(NULL), data(getPool()), + sessionKey(getPool()) + { } + + // IClient implementation + Result FB_CARG authenticate(Firebird::IStatus*, IClientBlock* cb); + Result FB_CARG getSessionKey(Firebird::IStatus* status, + const unsigned char** key, unsigned int* keyLen); + int FB_CARG release(); + +private: + RemotePassword* client; + string data; + UCharBuffer sessionKey; +}; + +Result SrpClient::authenticate(Firebird::IStatus* status, IClientBlock* cb) +{ + try + { + if (sessionKey.hasData()) + { + // Why are we called when auth is completed? + (Firebird::Arg::Gds(isc_random) << "Auth sync failure - SRP's authenticate called more times than supported").raise(); + } + + if (!client) + { + HANDSHAKE_DEBUG(fprintf(stderr, "Cln SRP1: %s %s\n", cb->getLogin(), cb->getPassword())); + if (!(cb->getLogin() && cb->getPassword())) + { + return AUTH_CONTINUE; + } + + client = new RemotePassword; + client->genClientKey(data); + dumpIt("Clnt: clientPubKey", data); + cb->putData(data.length(), data.begin()); + return AUTH_MORE_DATA; + } + + HANDSHAKE_DEBUG(fprintf(stderr, "Cln SRP2\n")); + unsigned int length; + const unsigned char* saltAndKey = cb->getData(&length); + if (length > (RemotePassword::SRP_SALT_SIZE + RemotePassword::SRP_KEY_SIZE + 2) * 2) + { + string msg; + msg.printf("Wrong length (%d) of data from server", length); + (Arg::Gds(isc_random) << msg).raise(); + } + + string salt, key; + unsigned charSize = *saltAndKey++; + charSize += ((unsigned)*saltAndKey++) << 8; + if (charSize > RemotePassword::SRP_SALT_SIZE * 2) + { + string msg; + msg.printf("Wrong length (%d) of salt from server", charSize); + (Arg::Gds(isc_random) << msg).raise(); + } + salt.assign(saltAndKey, charSize); + dumpIt("Clnt: salt", salt); + saltAndKey += charSize; + length -= (charSize + 2); + + charSize = *saltAndKey++; + charSize += ((unsigned)*saltAndKey++) << 8; + if (charSize + 2 != length) + { + string msg; + msg.printf("Wrong length (%d) of key from server", charSize); + (Arg::Gds(isc_random) << msg).raise(); + } + + key.assign(saltAndKey, charSize); + dumpIt("Clnt: key(srvPub)", key); + + dumpIt("Clnt: login", string(cb->getLogin())); + dumpIt("Clnt: pass", string(cb->getPassword())); + client->clientSessionKey(sessionKey, cb->getLogin(), salt.c_str(), cb->getPassword(), key.c_str()); + dumpIt("Clnt: sessionKey", sessionKey); + + BigInteger cProof = client->clientProof(cb->getLogin(), salt.c_str(), sessionKey); + cProof.getText(data); + + cb->putData(data.length(), data.c_str()); + } + catch(const Exception& ex) + { + ex.stuffException(status); + return AUTH_FAILED; + } + + return AUTH_SUCCESS; +} + + +Result SrpClient::getSessionKey(Firebird::IStatus*, + const unsigned char** key, unsigned int* keyLen) +{ + if (!sessionKey.hasData()) + { + return AUTH_MORE_DATA; + } + + *key = sessionKey.begin(); + *keyLen = sessionKey.getCount(); + + return AUTH_SUCCESS; +} + +int SrpClient::release() +{ + if (--refCounter == 0) + { + delete this; + return 0; + } + return 1; +} + +namespace +{ + Firebird::SimpleFactory<SrpClient> factory; +} + +void registerSrpClient(Firebird::IPluginManager* iPlugin) +{ + iPlugin->registerPluginFactory(PluginType::AuthClient, RemotePassword::plugName, &factory); +} + +} // namespace Auth + Property changes on: firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.cpp ___________________________________________________________________ Added: svn:mime-type + text/x-c++src Added: svn:eol-style + native Added: firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.h =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.h (rev 0) +++ firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.h 2011-12-23 12:43:58 UTC (rev 53739) @@ -0,0 +1,38 @@ +/* + * PROGRAM: Firebird authentication. + * MODULE: SrpClient.h + * DESCRIPTION: SPR authentication plugin. + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2011 Alex Peshkov <peshkoff at mail.ru> + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#ifndef AUTH_SRP_CLIENT_H +#define AUTH_SRP_CLIENT_H + +#include "firebird/Auth.h" + +namespace Auth { + +void registerSrpClient(Firebird::IPluginManager* iPlugin); + +} // namespace Auth + +#endif // AUTH_SRP_CLIENT_H Property changes on: firebird/trunk/src/auth/SecureRemotePassword/client/SrpClient.h ___________________________________________________________________ Added: svn:mime-type + text/x-chdr Added: svn:eol-style + native Added: firebird/trunk/src/auth/SecureRemotePassword/manage/SrpManagement.cpp =================================================================== --- firebird/trunk/src/auth/SecureRemotePassword/manage/SrpManagement.cpp (rev 0) +++ firebird/trunk/src/auth/SecureRemotePassword/manage/SrpManagement.cpp 2011-12-23 12:43:58 UTC (rev 53739) @@ -0,0 +1,633 @@ +/* + * PROGRAM: Firebird authentication + * MODULE: SrpManagement.cpp + * DESCRIPTION: Manages security database with SRP + * + * The contents of this file are subject to the Initial + * Developer's Public License Version 1.0 (the "License"); + * you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. + * + * Software distributed under the License is distributed AS IS, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + * See the License for the specific language governing rights + * and limitations under the License. + * + * The Original Code was created by Alex Peshkov + * for the Firebird Open Source RDBMS project. + * + * Copyright (c) 2011 Alex Peshkov <peshkoff at mail.ru> + * and all contributors signed below. + * + * All Rights Reserved. + * Contributor(s): ______________________________________. + */ + +#include "firebird.h" + +#include "../common/classes/ImplementHelper.h" +#include "../common/classes/ClumpletWriter.h" +#include "../common/StatusHolder.h" +#include "firebird/Auth.h" +#include "../auth/SecureRemotePassword/srp.h" +#include "../jrd/constants.h" +#include "../utilities/gsec/gsec.h" +#include "../auth/SecureRemotePassword/Message.h" +#include "../common/classes/auto.h" + +namespace { + +Firebird::MakeUpgradeInfo<> upInfo; +const unsigned int INIT_KEY = ((~0) - 1); +unsigned int secDbKey = INIT_KEY; + +const unsigned int SZ_LOGIN = 31; +const unsigned int SZ_NAME = 31; + +template <short N> +void setField(Field<VarChar<N> >& to, Auth::ICharUserField* from) +{ + if (from->entered()) + { + to() = from->get(); + to.null() = 0; + } + else + { + to.null() = -1; + } +} + +// Domains +typedef Field<VarChar<SZ_LOGIN> > Login; +typedef Field<VarChar<Auth::RemotePassword::SRP_VERIFIER_SIZE> > Verifier; +typedef Field<VarChar<Auth::RemotePassword::SRP_SALT_SIZE> > Salt; +typedef Field<VarChar<SZ_NAME> > Name; + +void allocField(Firebird::AutoPtr<Name>& field, Message& up, Auth::ICharUserField* value, Firebird::string& update, const char* name) +{ + if (value->entered() || value->specified()) + { + field = new Name(up); + update += ' '; + update += name; + update += "=?,"; + } +} + +void assignField(Firebird::AutoPtr<Name>& field, Auth::ICharUserField* name) +{ + if (field.hasData()) + { + if (name->entered()) + { + (*field)() = name->get(); + field->null() = 0; + } + else + { + fb_assert(name->specified()); + field->null() = -1; + } + } +} + +template <short N> +void listField(Auth::ICharUserField* to, Field<VarChar<N> >& from) +{ + to->set(from().data); + to->setEntered(from.null() == 0 ? 1 : 0); +} + +} + +namespace Auth { + +class SrpManagement : public Firebird::StdPlugin<IManagement, FB_AUTH_MANAGE_VERSION> +{ +public: + explicit SrpManagement(Firebird::IPluginConfig* par) + : config(par->getFirebirdConf()) + { + config->release(); + } + + void prepareDataStructures() + { + const char* script[] = { +"CREATE TABLE PLG$SRP (PLG$USER_NAME SEC$USER_NAME NOT NULL PRIMARY KEY, " +"PLG$VERIFIER VARCHAR(128) CHARACTER SET OCTETS NOT NULL, " +"PLG$SALT VARCHAR(32) CHARACTER SET OCTETS NOT NULL, " +"PLG$COMMENT RDB$DESCRIPTION, PLG$FIRST SEC$NAME_PART, " +"PLG$MIDDLE SEC$NAME_PART, PLG$LAST SEC$NAME_PART)" , + +"CREATE VIEW PLG$SRP_VIEW AS " +"SELECT PLG$USER_NAME, PLG$VERIFIER, PLG$SALT, PLG$COMMENT, PLG$FIRST, PLG$MIDDLE, PLG$LAST " +"FROM PLG$SRP WHERE CURRENT_USER = 'SYSDBA' OR CURRENT_ROLE = 'RDB$ADMIN' OR CURRENT_USER = PLG$SRP.PLG$USER_NAME", + +"GRANT ALL ON PLG$SRP to VIEW PLG$SRP_VIEW", + +"GRANT SELECT ON PLG$SRP_VIEW to PUBLIC", + +"GRANT UPDATE(PLG$VERIFIER, PLG$SALT, PLG$FIRST, PLG$MIDDLE, PLG$LAST) ON PLG$SRP_VIEW TO PUBLIC", + NULL }; + + Firebird::LocalStatus s; + Firebird::RefPtr<Firebird::ITransaction> ddlTran(att->startTransaction(&s, 0, NULL)); + if (!s.isSuccess()) + { + Firebird::status_exception::raise(s.get()); + } + + try + { + for (const char** sql = script; *sql; ++sql) + { + att->execute(&s, ddlTran, 0, *sql, 3, 0, NULL, NULL); + if (!s.isSuccess()) + { + Firebird::status_exception::raise(s.get()); + } + } + + ddlTran->commit(&s); + if (!s.isSuccess()) + { + Firebird::status_exception::raise(s.get()); + } + } + catch (const Firebird::Exception&) + { + if (ddlTran) + { + ddlTran->rollback(&s); + } + throw; + } + } + + // IManagement implementation + void FB_CARG start(Firebird::IStatus* status, ILogonInfo* logonInfo) + { + try + { + Firebird::MasterInterfacePtr()->upgradeInterface(logonInfo, FB_AUTH_LOGON_INFO_VERSION, upInfo); + + status->init(); + + if (att) + { + (Firebird::Arg::Gds(isc_random) << "Database is already attached in SRP").raise(); + } + + if (secDbKey == INIT_KEY) + { + secDbKey = config->getKey("SecurityDatabase"); + } + const char* secDbName = config->asString(secDbKey); + + if (!(secDbName && secDbName[0])) + { + (Firebird::Arg::Gds(isc_random) << "Error getting security database name").raise(); + } + + Firebird::ClumpletWriter dpb(Firebird::ClumpletReader::dpbList, MAX_DPB_SIZE); + dpb.insertByte(isc_dpb_gsec_attach, TRUE); + + const unsigned char* authBlock; + unsigned int authBlockSize = logonInfo->authBlock(&authBlock); + + if (authBlockSize) + dpb.insertBytes(isc_dpb_auth_block, authBlock, authBlockSize); + else + { + const char* str = logonInfo->name(); + if (str && str[0]) + dpb.insertString(isc_dpb_trusted_auth, str, strlen(str)); + + str = logonInfo->role(); + + if (str && str[0]) + dpb.insertString(isc_dpb_sql_role_name, str, strlen(str)); + else if (logonInfo->forceAdmin()) + dpb.insertString(isc_dpb_trusted_role, ADMIN_ROLE, strlen(ADMIN_ROLE)); + } + + Firebird::RefPtr<Firebird::IProvider> p(Firebird::MasterInterfacePtr()->getDispatcher()); + p->release(); + att = p->attachDatabase(status, secDbName, dpb.getBufferLength(), dpb.getBuffer()); + if (!status->isSuccess()) + { + Firebird::status_exception::raise(status->get()); + } + + tra = att->startTransaction(status, 0, NULL); + if (!status->isSuccess()) + { + Firebird::status_exception::raise(status->get()); + } + } + catch (const Firebird::Exception& ex) + { + ex.stuffException(status); + + if (att) + { + // detach from database + Firebird::LocalStatus lStatus; + att->detach(&lStatus); + att = NULL; + } + } + } + + int FB_CARG execute(Firebird::IStatus* status, IUser* user, IListUsers* callback) + { + try + { + Firebird::MasterInterfacePtr()->upgradeInterface(callback, FB_AUTH_LIST_USERS_VERSION, upInfo); + Firebird::MasterInterfacePtr()->upgradeInterface(user, FB_AUTH_USER_VERSION, upInfo); + + status->init(); + + fb_assert(att); + fb_assert(tra); + + switch(user->operation()) + { + case MAP_DROP_OPER: + case MAP_SET_OPER: + { + Firebird::string sql; + sql.printf("ALTER ROLE RDB$ADMIN %s AUTO ADMIN MAPPING", + user->operation() == MAP_SET_OPER ? "SET" : "DROP"); + att->execute(status, tra, sql.length(), sql.c_str(), 3, 0, NULL, NULL); + if (!status->isSuccess()) + { + Firebird::status_exception::raise(status->get()); + } + } + break; + + case ADD_OPER: + { + const char* insert = + "INSERT INTO plg$srp_view(PLG$USER_NAME, PLG$VERIFIER, PLG$SALT, PLG$FIRST, PLG$MIDDLE, PLG$LAST) " + "VALUES(?, ?, ?, ?, ?, ?)"; + + Message add; + Login login(add); + Verifier verifier(add); + Salt slt(add); + Name first(add), middle(add), last(add); + + setField(login, user->userName()); + setField(first, user->firstName()); + setField(middle, user->middleName()); + setField(last, user->lastName()); + +#if SRP_DEBUG > 1 + BigInteger salt("02E268803000000079A478A700000002D1A6979000000026E1601C000000054F"); +#else + BigInteger salt; + salt.random(RemotePassword::SRP_SALT_SIZE); +#endif + Firebird::UCharBuffer s; + salt.getBytes(s); + slt().set(s.getCount(), s.begin()); + slt.null() = 0; + + dumpIt("salt", s); +#if SRP_DEBUG > 0 + fprintf(stderr, ">%s< >%s<\n", user->userName()->get(), user->password()->get()); +#endif + Firebird::string s1; + salt.getText(s1); + server.computeVerifier(user->userName()->get(), s1, user->password()->get()).getBytes(s); + dumpIt("verifier", s); + verifier().set(s.getCount(), s.begin()); + verifier.null() = 0; + + for (unsigned repeat = 0; ; ++repeat) + { + att->execute(status, tra, 0, insert, 3, 0, &add, NULL); + if (status->isSuccess() || repeat > 0) + { + break; + } + + const ISC_STATUS* v = status->get(); + while (v[0] == isc_arg_gds) + { + if (v[1] == isc_dsql_relation_err) + { + prepareDataStructures(); + tra->commit(status); + if (!status->isSuccess()) + { + Firebird::status_exception::raise(status->get()); + } + tra = att->startTransaction(status, 0, NULL); + if (!status->isSuccess()) + { + Firebird::status_exception::raise(status->get()); + } + break; + } + do + { + v += 2; + } while (v[0] != isc_arg_warning && v[0] != isc_arg_gds && v[0] != isc_arg_end); + } + } + if (!status->isSuccess()) + { + Firebird::status_exception::raise(status->get()); + } + } + break; + + case MOD_OPER: + { + Message up; + + Firebird::string update = "UPDATE plg$srp_view SET "; + + Firebird::AutoPtr<Verifier> verifier; + Firebird::AutoPtr<Salt> slt; + if (user->password()->entered()) + { + verifier = new Verifier(up); + slt = new Salt(up); + update += "PLG$VERIFIER=?,PLG$SALT=?,"; + } + + Firebird::AutoPtr<Name> first, middle, last; + allocField(first, up, user->firstName(), update, "PLG$FIRST"); + allocField(middle, up, user->middleName(), update, "PLG$MIDDLE"); + allocField(last, up, user->lastName(), update, "PLG$LAST"); + + if (update[update.length() - 1] != ',') + { + return 0; + } + update.rtrim(","); + + update += " WHERE PLG$USER_NAME=?"; + Login login(up); + + if (verifier.hasData()) + { +#if SRP_DEBUG > 1 + BigInteger salt("02E268803000000079A478A700000002D1A6979000000026E1601C000000054F"); +#else + BigInteger salt; + salt.random(RemotePassword::SRP_SALT_SIZE); +#endif + Firebird::UCharBuffer s; + salt.getBytes(s); + (*slt)().set(s.getCount(), s.begin()); + slt->null() = 0; + + dumpIt("salt", s); +#if SRP_DEBUG > 0 + fprintf(stderr, ">%s< >%s<\n", user->userName()->get(), user->password()->get()); +#endif + Firebird::string s1; + salt.getText(s1); + server.computeVerifier(user->userName()->get(), s1, user->password()->get()).getBytes(s); + dumpIt("verifier", s); + (*verifier)().set(s.getCount(), s.begin()); + verifier->null() = 0; + } + + assignField(first, user->firstName()); + assignField(middle, user->middleName()); + assignField(last, user->lastName()); + setField(login, user->userName()); + + att->execute(status, tra, 0, update.c_str(), 3, 0, &up, NULL); + if (!status->isSuccess()) + { + Firebird::status_exception::raise(status->get()); + } + } + break; + + case DEL_OPER: + { + Message dl; + const char* d... [truncated message content] |