summaryrefslogtreecommitdiffstats
path: root/base/tps/src
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2012-03-24 02:27:47 -0500
committerEndi Sukma Dewata <edewata@redhat.com>2012-03-26 11:43:54 -0500
commit621d9e5c413e561293d7484b93882d985b3fe15f (patch)
tree638f3d75761c121d9a8fb50b52a12a6686c5ac5c /base/tps/src
parent40d3643b8d91886bf210aa27f711731c81a11e49 (diff)
downloadpki-621d9e5c413e561293d7484b93882d985b3fe15f.tar.gz
pki-621d9e5c413e561293d7484b93882d985b3fe15f.tar.xz
pki-621d9e5c413e561293d7484b93882d985b3fe15f.zip
Removed unnecessary pki folder.
Previously the source code was located inside a pki folder. This folder was created during svn migration and is no longer needed. This folder has now been removed and the contents have been moved up one level. Ticket #131
Diffstat (limited to 'base/tps/src')
-rw-r--r--base/tps/src/CMakeLists.txt148
-rw-r--r--base/tps/src/apdu/APDU.cpp331
-rw-r--r--base/tps/src/apdu/APDU_Response.cpp111
-rw-r--r--base/tps/src/apdu/Create_Object_APDU.cpp121
-rw-r--r--base/tps/src/apdu/Create_Pin_APDU.cpp73
-rw-r--r--base/tps/src/apdu/Delete_File_APDU.cpp59
-rw-r--r--base/tps/src/apdu/External_Authenticate_APDU.cpp76
-rw-r--r--base/tps/src/apdu/Format_Muscle_Applet_APDU.cpp107
-rw-r--r--base/tps/src/apdu/Generate_Key_APDU.cpp68
-rw-r--r--base/tps/src/apdu/Get_Data_APDU.cpp59
-rw-r--r--base/tps/src/apdu/Get_IssuerInfo_APDU.cpp80
-rw-r--r--base/tps/src/apdu/Get_Status_APDU.cpp59
-rw-r--r--base/tps/src/apdu/Get_Version_APDU.cpp59
-rw-r--r--base/tps/src/apdu/Import_Key_APDU.cpp79
-rw-r--r--base/tps/src/apdu/Import_Key_Enc_APDU.cpp70
-rw-r--r--base/tps/src/apdu/Initialize_Update_APDU.cpp66
-rw-r--r--base/tps/src/apdu/Install_Applet_APDU.cpp112
-rw-r--r--base/tps/src/apdu/Install_Load_APDU.cpp91
-rw-r--r--base/tps/src/apdu/Lifecycle_APDU.cpp50
-rw-r--r--base/tps/src/apdu/List_Objects_APDU.cpp61
-rw-r--r--base/tps/src/apdu/List_Pins_APDU.cpp63
-rw-r--r--base/tps/src/apdu/Load_File_APDU.cpp52
-rw-r--r--base/tps/src/apdu/Put_Key_APDU.cpp53
-rw-r--r--base/tps/src/apdu/Read_Buffer_APDU.cpp63
-rw-r--r--base/tps/src/apdu/Read_Object_APDU.cpp88
-rw-r--r--base/tps/src/apdu/Select_APDU.cpp49
-rw-r--r--base/tps/src/apdu/Set_IssuerInfo_APDU.cpp76
-rw-r--r--base/tps/src/apdu/Set_Pin_APDU.cpp76
-rw-r--r--base/tps/src/apdu/Unblock_Pin_APDU.cpp50
-rw-r--r--base/tps/src/apdu/Write_Object_APDU.cpp103
-rw-r--r--base/tps/src/authentication/CMakeLists.txt52
-rw-r--r--base/tps/src/authentication/LDAP_Authentication.cpp424
-rw-r--r--base/tps/src/channel/Channel.cpp69
-rw-r--r--base/tps/src/channel/Secure_Channel.cpp2550
-rw-r--r--base/tps/src/cms/CertEnroll.cpp725
-rw-r--r--base/tps/src/cms/ConnectionInfo.cpp78
-rw-r--r--base/tps/src/cms/HttpConnection.cpp245
-rw-r--r--base/tps/src/engine/RA.cpp3624
-rw-r--r--base/tps/src/httpClient/Cache.cpp496
-rw-r--r--base/tps/src/httpClient/engine.cpp775
-rw-r--r--base/tps/src/httpClient/http.cpp307
-rw-r--r--base/tps/src/httpClient/httpClient.cpp130
-rw-r--r--base/tps/src/httpClient/nscperror.cpp358
-rw-r--r--base/tps/src/httpClient/request.cpp431
-rw-r--r--base/tps/src/httpClient/response.cpp1115
-rw-r--r--base/tps/src/include/apdu/APDU.h116
-rw-r--r--base/tps/src/include/apdu/APDU_Response.h66
-rw-r--r--base/tps/src/include/apdu/Create_Object_APDU.h57
-rw-r--r--base/tps/src/include/apdu/Create_Pin_APDU.h57
-rw-r--r--base/tps/src/include/apdu/Delete_File_APDU.h57
-rw-r--r--base/tps/src/include/apdu/External_Authenticate_APDU.h62
-rw-r--r--base/tps/src/include/apdu/Format_Muscle_Applet_APDU.h65
-rw-r--r--base/tps/src/include/apdu/Generate_Key_APDU.h60
-rw-r--r--base/tps/src/include/apdu/Get_Data_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Get_IssuerInfo_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Get_Status_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Get_Version_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Import_Key_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Import_Key_Enc_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Initialize_Update_APDU.h60
-rw-r--r--base/tps/src/include/apdu/Install_Applet_APDU.h59
-rw-r--r--base/tps/src/include/apdu/Install_Load_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Lifecycle_APDU.h57
-rw-r--r--base/tps/src/include/apdu/List_Objects_APDU.h59
-rw-r--r--base/tps/src/include/apdu/List_Pins_APDU.h60
-rw-r--r--base/tps/src/include/apdu/Load_File_APDU.h57
-rw-r--r--base/tps/src/include/apdu/Put_Key_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Read_Buffer_APDU.h61
-rw-r--r--base/tps/src/include/apdu/Read_Object_APDU.h57
-rw-r--r--base/tps/src/include/apdu/Select_APDU.h58
-rw-r--r--base/tps/src/include/apdu/Set_IssuerInfo_APDU.h59
-rw-r--r--base/tps/src/include/apdu/Set_Pin_APDU.h59
-rw-r--r--base/tps/src/include/apdu/Unblock_Pin_APDU.h54
-rw-r--r--base/tps/src/include/apdu/Write_Object_APDU.h57
-rw-r--r--base/tps/src/include/authentication/AuthParams.h64
-rw-r--r--base/tps/src/include/authentication/Authentication.h80
-rw-r--r--base/tps/src/include/authentication/LDAP_Authentication.h85
-rw-r--r--base/tps/src/include/channel/Channel.h55
-rw-r--r--base/tps/src/include/channel/Secure_Channel.h158
-rw-r--r--base/tps/src/include/cms/CertEnroll.h75
-rw-r--r--base/tps/src/include/cms/ConnectionInfo.h66
-rw-r--r--base/tps/src/include/cms/HttpConnection.h88
-rw-r--r--base/tps/src/include/engine/RA.h374
-rw-r--r--base/tps/src/include/engine/audit.h90
-rw-r--r--base/tps/src/include/httpClient/httpc/AccessLogger.h105
-rw-r--r--base/tps/src/include/httpClient/httpc/Auth.h155
-rw-r--r--base/tps/src/include/httpClient/httpc/ByteBuffer.h194
-rw-r--r--base/tps/src/include/httpClient/httpc/CERTUtil.h65
-rw-r--r--base/tps/src/include/httpClient/httpc/Cache.h226
-rw-r--r--base/tps/src/include/httpClient/httpc/Connection.h117
-rw-r--r--base/tps/src/include/httpClient/httpc/ConnectionListener.h58
-rw-r--r--base/tps/src/include/httpClient/httpc/DebugLogger.h185
-rw-r--r--base/tps/src/include/httpClient/httpc/Defines.h219
-rw-r--r--base/tps/src/include/httpClient/httpc/ErrorLogger.h93
-rw-r--r--base/tps/src/include/httpClient/httpc/Iterator.h62
-rw-r--r--base/tps/src/include/httpClient/httpc/LogRotationTask.h132
-rw-r--r--base/tps/src/include/httpClient/httpc/Logger.h117
-rw-r--r--base/tps/src/include/httpClient/httpc/NSPRerrs.h160
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddy.h89
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddyCache.h123
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddyList.h373
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddyListener.h78
-rw-r--r--base/tps/src/include/httpClient/httpc/PSBuddyService.h121
-rw-r--r--base/tps/src/include/httpClient/httpc/PSCertExtension.h153
-rw-r--r--base/tps/src/include/httpClient/httpc/PSCommonLib.h52
-rw-r--r--base/tps/src/include/httpClient/httpc/PSConfig.h67
-rw-r--r--base/tps/src/include/httpClient/httpc/PSConfigManager.h66
-rw-r--r--base/tps/src/include/httpClient/httpc/PSConfigReader.h71
-rw-r--r--base/tps/src/include/httpClient/httpc/PSCrypt.h79
-rw-r--r--base/tps/src/include/httpClient/httpc/PSDataSourceListener.h106
-rw-r--r--base/tps/src/include/httpClient/httpc/PSDataSourceManager.h152
-rw-r--r--base/tps/src/include/httpClient/httpc/PSGroup.h97
-rw-r--r--base/tps/src/include/httpClient/httpc/PSGroupCache.h74
-rw-r--r--base/tps/src/include/httpClient/httpc/PSHelper.h70
-rw-r--r--base/tps/src/include/httpClient/httpc/PSListener.h55
-rw-r--r--base/tps/src/include/httpClient/httpc/PSPRUtil.h92
-rw-r--r--base/tps/src/include/httpClient/httpc/PSPlugin.h81
-rw-r--r--base/tps/src/include/httpClient/httpc/PSPluginManager.h102
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServer.h95
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServerLib.h62
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServerListener.h85
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServerManager.h145
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServiceListener.h87
-rw-r--r--base/tps/src/include/httpClient/httpc/PSServiceManager.h145
-rw-r--r--base/tps/src/include/httpClient/httpc/PSUser.h164
-rw-r--r--base/tps/src/include/httpClient/httpc/PSWaspLib.h55
-rw-r--r--base/tps/src/include/httpClient/httpc/Pool.h149
-rw-r--r--base/tps/src/include/httpClient/httpc/PresenceManager.h93
-rw-r--r--base/tps/src/include/httpClient/httpc/PresenceServer.h60
-rw-r--r--base/tps/src/include/httpClient/httpc/PresenceServerImpl.h111
-rw-r--r--base/tps/src/include/httpClient/httpc/SECerrs.h522
-rw-r--r--base/tps/src/include/httpClient/httpc/SSLServerSocket.h93
-rw-r--r--base/tps/src/include/httpClient/httpc/SSLSocket.h132
-rw-r--r--base/tps/src/include/httpClient/httpc/SSLerrs.h392
-rw-r--r--base/tps/src/include/httpClient/httpc/ScheduledTask.h86
-rw-r--r--base/tps/src/include/httpClient/httpc/Scheduler.h103
-rw-r--r--base/tps/src/include/httpClient/httpc/SecurityHeaders.h48
-rw-r--r--base/tps/src/include/httpClient/httpc/ServerConnection.h179
-rw-r--r--base/tps/src/include/httpClient/httpc/ServerHeaderProcessor.h72
-rw-r--r--base/tps/src/include/httpClient/httpc/ServerSocket.h113
-rw-r--r--base/tps/src/include/httpClient/httpc/Socket.h157
-rw-r--r--base/tps/src/include/httpClient/httpc/SocketINC.h163
-rw-r--r--base/tps/src/include/httpClient/httpc/SocketLib.h62
-rw-r--r--base/tps/src/include/httpClient/httpc/StringList.h151
-rw-r--r--base/tps/src/include/httpClient/httpc/StringUtil.h74
-rw-r--r--base/tps/src/include/httpClient/httpc/TaskList.h114
-rw-r--r--base/tps/src/include/httpClient/httpc/ThreadPool.h159
-rw-r--r--base/tps/src/include/httpClient/httpc/URLUtil.h92
-rw-r--r--base/tps/src/include/httpClient/httpc/engine.h77
-rw-r--r--base/tps/src/include/httpClient/httpc/http.h120
-rw-r--r--base/tps/src/include/httpClient/httpc/request.h115
-rw-r--r--base/tps/src/include/httpClient/httpc/response.h148
-rw-r--r--base/tps/src/include/main/AttributeSpec.h68
-rw-r--r--base/tps/src/include/main/AuthenticationEntry.h64
-rw-r--r--base/tps/src/include/main/Base.h63
-rw-r--r--base/tps/src/include/main/Buffer.h196
-rw-r--r--base/tps/src/include/main/ConfigStore.h126
-rw-r--r--base/tps/src/include/main/LogFile.h89
-rw-r--r--base/tps/src/include/main/Login.h55
-rw-r--r--base/tps/src/include/main/Memory.h130
-rw-r--r--base/tps/src/include/main/MemoryMgr.h46
-rw-r--r--base/tps/src/include/main/NameValueSet.h72
-rw-r--r--base/tps/src/include/main/ObjectSpec.h79
-rw-r--r--base/tps/src/include/main/PKCS11Obj.h80
-rw-r--r--base/tps/src/include/main/PublishEntry.h57
-rw-r--r--base/tps/src/include/main/RA_Context.h57
-rw-r--r--base/tps/src/include/main/RA_Msg.h79
-rw-r--r--base/tps/src/include/main/RA_Session.h61
-rw-r--r--base/tps/src/include/main/RA_pblock.h74
-rw-r--r--base/tps/src/include/main/RollingLogFile.h93
-rw-r--r--base/tps/src/include/main/SecureId.h55
-rw-r--r--base/tps/src/include/main/Util.h99
-rw-r--r--base/tps/src/include/modules/tps/AP_Context.h57
-rw-r--r--base/tps/src/include/modules/tps/AP_Session.h56
-rw-r--r--base/tps/src/include/msg/RA_ASQ_Request_Msg.h62
-rw-r--r--base/tps/src/include/msg/RA_ASQ_Response_Msg.h62
-rw-r--r--base/tps/src/include/msg/RA_Begin_Op_Msg.h64
-rw-r--r--base/tps/src/include/msg/RA_End_Op_Msg.h84
-rw-r--r--base/tps/src/include/msg/RA_Extended_Login_Request_Msg.h73
-rw-r--r--base/tps/src/include/msg/RA_Extended_Login_Response_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_Login_Request_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_Login_Response_Msg.h64
-rw-r--r--base/tps/src/include/msg/RA_New_Pin_Request_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_New_Pin_Response_Msg.h62
-rw-r--r--base/tps/src/include/msg/RA_SecureId_Request_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_SecureId_Response_Msg.h64
-rw-r--r--base/tps/src/include/msg/RA_Status_Update_Request_Msg.h65
-rw-r--r--base/tps/src/include/msg/RA_Status_Update_Response_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_Token_PDU_Request_Msg.h63
-rw-r--r--base/tps/src/include/msg/RA_Token_PDU_Response_Msg.h62
-rw-r--r--base/tps/src/include/processor/RA_Enroll_Processor.h300
-rw-r--r--base/tps/src/include/processor/RA_Format_Processor.h57
-rw-r--r--base/tps/src/include/processor/RA_Pin_Reset_Processor.h57
-rw-r--r--base/tps/src/include/processor/RA_Processor.h214
-rw-r--r--base/tps/src/include/processor/RA_Renew_Processor.h57
-rw-r--r--base/tps/src/include/processor/RA_Unblock_Processor.h57
-rw-r--r--base/tps/src/include/publisher/IConnector.h58
-rw-r--r--base/tps/src/include/publisher/IPublish_Data.h56
-rw-r--r--base/tps/src/include/publisher/IPublisher.h74
-rw-r--r--base/tps/src/include/publisher/NetkeyPublisher.h74
-rw-r--r--base/tps/src/include/selftests/SelfTest.h74
-rw-r--r--base/tps/src/include/selftests/TPSPresence.h78
-rw-r--r--base/tps/src/include/selftests/TPSSystemCertsVerification.h76
-rw-r--r--base/tps/src/include/selftests/TPSValidity.h79
-rw-r--r--base/tps/src/include/service/NK_Context.h57
-rw-r--r--base/tps/src/include/service/NK_Session.h58
-rw-r--r--base/tps/src/include/tus/tus_db.h273
-rw-r--r--base/tps/src/main/AttributeSpec.cpp115
-rw-r--r--base/tps/src/main/AuthParams.cpp72
-rw-r--r--base/tps/src/main/Authentication.cpp105
-rw-r--r--base/tps/src/main/AuthenticationEntry.cpp91
-rw-r--r--base/tps/src/main/Buffer.cpp243
-rw-r--r--base/tps/src/main/ConfigStore.cpp893
-rw-r--r--base/tps/src/main/LogFile.cpp298
-rw-r--r--base/tps/src/main/Login.cpp72
-rw-r--r--base/tps/src/main/Memory.cpp268
-rw-r--r--base/tps/src/main/NameValueSet.cpp322
-rw-r--r--base/tps/src/main/ObjectSpec.cpp515
-rw-r--r--base/tps/src/main/PKCS11Obj.cpp491
-rw-r--r--base/tps/src/main/RA_Context.cpp56
-rw-r--r--base/tps/src/main/RA_Msg.cpp45
-rw-r--r--base/tps/src/main/RA_Session.cpp75
-rw-r--r--base/tps/src/main/RA_pblock.cpp176
-rw-r--r--base/tps/src/main/RollingLogFile.cpp493
-rw-r--r--base/tps/src/main/SecureId.cpp71
-rw-r--r--base/tps/src/main/Util.cpp1168
-rw-r--r--base/tps/src/modules/CMakeLists.txt2
-rw-r--r--base/tps/src/modules/tokendb/CMakeLists.txt48
-rw-r--r--base/tps/src/modules/tokendb/mod_tokendb.cpp7756
-rw-r--r--base/tps/src/modules/tps/AP_Context.cpp83
-rw-r--r--base/tps/src/modules/tps/AP_Session.cpp1169
-rw-r--r--base/tps/src/modules/tps/CMakeLists.txt52
-rw-r--r--base/tps/src/modules/tps/mod_tps.cpp732
-rw-r--r--base/tps/src/msg/RA_ASQ_Request_Msg.cpp70
-rw-r--r--base/tps/src/msg/RA_ASQ_Response_Msg.cpp68
-rw-r--r--base/tps/src/msg/RA_Begin_Op_Msg.cpp72
-rw-r--r--base/tps/src/msg/RA_End_Op_Msg.cpp73
-rw-r--r--base/tps/src/msg/RA_Extended_Login_Request_Msg.cpp114
-rw-r--r--base/tps/src/msg/RA_Extended_Login_Response_Msg.cpp65
-rw-r--r--base/tps/src/msg/RA_Login_Request_Msg.cpp71
-rw-r--r--base/tps/src/msg/RA_Login_Response_Msg.cpp85
-rw-r--r--base/tps/src/msg/RA_New_Pin_Request_Msg.cpp70
-rw-r--r--base/tps/src/msg/RA_New_Pin_Response_Msg.cpp68
-rw-r--r--base/tps/src/msg/RA_SecureId_Request_Msg.cpp69
-rw-r--r--base/tps/src/msg/RA_SecureId_Response_Msg.cpp83
-rw-r--r--base/tps/src/msg/RA_Status_Update_Request_Msg.cpp66
-rw-r--r--base/tps/src/msg/RA_Status_Update_Response_Msg.cpp56
-rw-r--r--base/tps/src/msg/RA_Token_PDU_Request_Msg.cpp63
-rw-r--r--base/tps/src/msg/RA_Token_PDU_Response_Msg.cpp68
-rw-r--r--base/tps/src/processor/RA_Enroll_Processor.cpp5194
-rw-r--r--base/tps/src/processor/RA_Format_Processor.cpp70
-rw-r--r--base/tps/src/processor/RA_Pin_Reset_Processor.cpp1013
-rw-r--r--base/tps/src/processor/RA_Processor.cpp3506
-rw-r--r--base/tps/src/processor/RA_Renew_Processor.cpp57
-rw-r--r--base/tps/src/processor/RA_Unblock_Processor.cpp58
-rw-r--r--base/tps/src/selftests/SelfTest.cpp220
-rw-r--r--base/tps/src/selftests/TPSPresence.cpp204
-rw-r--r--base/tps/src/selftests/TPSSystemCertsVerification.cpp149
-rw-r--r--base/tps/src/selftests/TPSValidity.cpp215
-rw-r--r--base/tps/src/test/Test_ConfigStore.cfg28
-rw-r--r--base/tps/src/test/Test_ConfigStore.cpp79
-rw-r--r--base/tps/src/tus/CMakeLists.txt50
-rw-r--r--base/tps/src/tus/tus_db.c4515
263 files changed, 61665 insertions, 0 deletions
diff --git a/base/tps/src/CMakeLists.txt b/base/tps/src/CMakeLists.txt
new file mode 100644
index 000000000..5f588663c
--- /dev/null
+++ b/base/tps/src/CMakeLists.txt
@@ -0,0 +1,148 @@
+project(tps_library CXX)
+
+set(TPS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+add_subdirectory(tus)
+
+set(TPS_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${TPS_INCLUDE_DIR}
+ CACHE INTERNAL "tps public include directories"
+)
+
+set(TPS_PRIVATE_INCLUDE_DIRS
+ ${TPS_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSS_INCLUDE_DIRS}
+ ${NSPR_INCLUDE_DIRS}
+ ${APR_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(TPS_SHARED_LIBRARY
+ tps_library
+ CACHE INTERNAL "tps shared library"
+)
+
+set(TPS_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${APR_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+ ${TOKENDB_SHARED_LIBRARY}
+)
+
+set(tps_library_SRCS
+ main/Buffer.cpp
+ main/NameValueSet.cpp
+ main/ConfigStore.cpp
+ main/Util.cpp
+ main/RA_Msg.cpp
+ main/RA_pblock.cpp
+ main/RA_Session.cpp
+ main/RA_Context.cpp
+ main/Login.cpp
+ main/SecureId.cpp
+ main/Memory.cpp
+ main/AuthenticationEntry.cpp
+ main/AuthParams.cpp
+ main/Authentication.cpp
+ main/AttributeSpec.cpp
+ main/ObjectSpec.cpp
+ main/PKCS11Obj.cpp
+ main/LogFile.cpp
+ main/RollingLogFile.cpp
+ httpClient/httpClient.cpp
+ httpClient/Cache.cpp
+ httpClient/engine.cpp
+ httpClient/http.cpp
+ httpClient/response.cpp
+ httpClient/request.cpp
+ httpClient/nscperror.cpp
+ cms/HttpConnection.cpp
+ cms/ConnectionInfo.cpp
+ cms/CertEnroll.cpp
+ apdu/APDU.cpp
+ apdu/Unblock_Pin_APDU.cpp
+ apdu/Create_Object_APDU.cpp
+ apdu/Set_Pin_APDU.cpp
+ apdu/Set_IssuerInfo_APDU.cpp
+ apdu/Get_IssuerInfo_APDU.cpp
+ apdu/Create_Pin_APDU.cpp
+ apdu/List_Pins_APDU.cpp
+ apdu/Initialize_Update_APDU.cpp
+ apdu/Get_Version_APDU.cpp
+ apdu/Get_Status_APDU.cpp
+ apdu/Get_Data_APDU.cpp
+ apdu/External_Authenticate_APDU.cpp
+ apdu/Generate_Key_APDU.cpp
+ apdu/Read_Buffer_APDU.cpp
+ apdu/Read_Object_APDU.cpp
+ apdu/Write_Object_APDU.cpp
+ apdu/Put_Key_APDU.cpp
+ apdu/Select_APDU.cpp
+ apdu/Delete_File_APDU.cpp
+ apdu/Install_Applet_APDU.cpp
+ apdu/Format_Muscle_Applet_APDU.cpp
+ apdu/Load_File_APDU.cpp
+ apdu/Install_Load_APDU.cpp
+ apdu/Lifecycle_APDU.cpp
+ apdu/List_Objects_APDU.cpp
+ apdu/Import_Key_APDU.cpp
+ apdu/Import_Key_Enc_APDU.cpp
+ apdu/APDU_Response.cpp
+ msg/RA_Begin_Op_Msg.cpp
+ msg/RA_End_Op_Msg.cpp
+ msg/RA_Login_Request_Msg.cpp
+ msg/RA_Login_Response_Msg.cpp
+ msg/RA_SecureId_Request_Msg.cpp
+ msg/RA_SecureId_Response_Msg.cpp
+ msg/RA_ASQ_Request_Msg.cpp
+ msg/RA_ASQ_Response_Msg.cpp
+ msg/RA_New_Pin_Request_Msg.cpp
+ msg/RA_New_Pin_Response_Msg.cpp
+ msg/RA_Token_PDU_Request_Msg.cpp
+ msg/RA_Token_PDU_Response_Msg.cpp
+ msg/RA_Status_Update_Request_Msg.cpp
+ msg/RA_Status_Update_Response_Msg.cpp
+ msg/RA_Extended_Login_Request_Msg.cpp
+ msg/RA_Extended_Login_Response_Msg.cpp
+ channel/Channel.cpp
+ channel/Secure_Channel.cpp
+ engine/RA.cpp
+ processor/RA_Processor.cpp
+ processor/RA_Enroll_Processor.cpp
+ processor/RA_Pin_Reset_Processor.cpp
+ processor/RA_Renew_Processor.cpp
+ processor/RA_Unblock_Processor.cpp
+ processor/RA_Format_Processor.cpp
+ selftests/SelfTest.cpp
+ selftests/TPSPresence.cpp
+ selftests/TPSSystemCertsVerification.cpp
+ selftests/TPSValidity.cpp
+)
+
+include_directories(${TPS_PRIVATE_INCLUDE_DIRS})
+
+add_library(${TPS_SHARED_LIBRARY} SHARED ${tps_library_SRCS})
+target_link_libraries(${TPS_SHARED_LIBRARY} ${TPS_LINK_LIBRARIES})
+
+set_target_properties(
+ ${TPS_SHARED_LIBRARY}
+ PROPERTIES
+ OUTPUT_NAME
+ tps
+)
+
+install(
+ TARGETS
+ ${TPS_SHARED_LIBRARY}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/tps
+)
+
+add_subdirectory(authentication)
+add_subdirectory(modules)
+
diff --git a/base/tps/src/apdu/APDU.cpp b/base/tps/src/apdu/APDU.cpp
new file mode 100644
index 000000000..1ae729cc5
--- /dev/null
+++ b/base/tps/src/apdu/APDU.cpp
@@ -0,0 +1,331 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs an APDU.
+ *
+ * ==============
+ * APDU:
+ * APDU are commands that can be sent from an authorized entity
+ * (such as RA) to the token. It takes the following form:
+ * ---------------------------------------------------
+ * | CLA | INS | P1 | P2 | lc | data...
+ * ---------------------------------------------------
+ *
+ * The values for the APDU header: CLA, INS, P1, P2 and lc are defined
+ * in each individual APDU class.
+ *
+ * ==============
+ * Status Words (response):
+ * When APDUs are sent to the token, a response is returned. The following
+ * is a list of all possible Return Codes (Status Words):
+ *
+ * <I'm hoping not having to type this out...waiting for Bob to get back
+ * to me with an electronic copy of his file...>
+ *
+ * ==============
+ * ObjectID:
+ * byte[0] - an ASCII letter,
+ * 'c' - An object containing PKCS11 attributes for a certificate
+ * 'k' - An object containing PKCS11 attributes for a public or private key
+ * 'r' - An object containing PKCS11 attributes for a "reader"
+ * <upper case letters signify objects containing raw data
+ * corresponding to lower cases objects above
+ * byte[1] - an ASCII numeral, in the range '0' - '9'
+ * byte[2] - binary zero
+ * byte[3] - binary zero
+ *
+ * ==============
+ * ACLs:
+ * Each key or object on the card is associated with an ACL.
+ *
+ * ACL for objects:
+ * [2-byte] Read Permissions;
+ * [2-byte] Write Permissions;
+ * [2-byte] Delete Permissions;
+ *
+ * Each permission is a 2-byte word. A 1 in a bit grants permission
+ * to it's corresponding identity if pass authentication.
+ * permission 2-byte word format:
+ * Bit 15 - reserved
+ * Bit 14 - Identity #14 (strong - Secure Channel required)
+ * Bit 13 - reserved
+ * ...
+ * Bit 7 - Identity #7 (PIN identity)
+ * ...
+ * Bit 1 - Identity #1 (PIN identity)
+ * Bit 0 - Identity #0 (PIN identity)
+ *
+ * All 0 means operation never allowed
+ */
+TPS_PUBLIC APDU::APDU ()
+{
+ m_data = Buffer(0, (BYTE)0);
+ m_mac = Buffer(0, (BYTE)0);
+} /* APDU */
+
+/**
+ * Destroys an APDU.
+ */
+TPS_PUBLIC APDU::~APDU ()
+{
+} /* ~APDU */
+
+/**
+ * Copy constructor.
+ */
+TPS_PUBLIC APDU::APDU (const APDU &cpy)
+{
+ *this = cpy;
+} /* APDU */
+
+/**
+ * Operator for simple assignment.
+ */
+TPS_PUBLIC APDU& APDU::operator=(const APDU &cpy)
+{
+ if (this == &cpy)
+ return *this;
+ m_cla = cpy.m_cla;
+ m_ins = cpy.m_ins;
+ m_p1 = cpy.m_p1;
+ m_p2 = cpy.m_p2;
+ m_data = cpy.m_data;
+ return *this;
+} /* operator= */
+
+TPS_PUBLIC APDU_Type APDU::GetType()
+{
+ return APDU_UNDEFINED;
+}
+
+/**
+ * Sets APDU's CLA parameter.
+ */
+TPS_PUBLIC void APDU::SetCLA(BYTE cla)
+{
+ m_cla = cla;
+} /* SetCLA */
+
+/**
+ * Sets APDU's INS parameter.
+ */
+TPS_PUBLIC void APDU::SetINS(BYTE ins)
+{
+ m_ins = ins;
+} /* SetINS */
+
+/**
+ * Sets APDU's P1 parameter.
+ */
+TPS_PUBLIC void APDU::SetP1(BYTE p1)
+{
+ m_p1 = p1;
+} /* SetP1 */
+
+/**
+ * Sets APDU's P2 parameter.
+ */
+TPS_PUBLIC void APDU::SetP2(BYTE p2)
+{
+ m_p2 = p2;
+} /* SetP2 */
+
+
+TPS_PUBLIC BYTE APDU::GetCLA()
+{
+ return m_cla;
+}
+
+TPS_PUBLIC BYTE APDU::GetINS()
+{
+ return m_ins;
+}
+
+TPS_PUBLIC BYTE APDU::GetP1()
+{
+ return m_p1;
+}
+
+TPS_PUBLIC BYTE APDU::GetP2()
+{
+ return m_p2;
+}
+
+TPS_PUBLIC Buffer &APDU::GetData()
+{
+ return m_data;
+}
+
+TPS_PUBLIC Buffer &APDU::GetMAC()
+{
+ return m_mac;
+}
+
+/**
+ * Sets APDU's data parameter.
+ */
+TPS_PUBLIC void APDU::SetData(Buffer &data)
+{
+ m_data = data;
+} /* SetData */
+
+TPS_PUBLIC void APDU::SetMAC(Buffer &mac)
+{
+ m_mac = mac;
+} /* SetMAC */
+
+/**
+ * populates "data" with data that's to be mac'd.
+ * note: mac is not handled in here
+ *
+ * @param data results buffer
+ */
+TPS_PUBLIC void APDU::GetDataToMAC(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, (BYTE)m_data.size() + 8);
+ data += Buffer(m_data, m_data.size());
+}
+
+/*
+ * pad the message, if needed, and then
+ * encrypt it with the encryption session key
+ * and then set data
+ *
+ */
+TPS_PUBLIC PRStatus APDU::SecureMessage(PK11SymKey *encSessionKey)
+{
+ PRStatus rv = PR_SUCCESS;
+ Buffer data_to_enc;
+ Buffer padding;
+ Buffer data_encrypted;
+ int pad_needed = 0;
+#ifdef ENC_DEBUG
+ m_plainText = m_data;
+ // developer debugging only, not for production
+// RA::DebugBuffer("APDU::SecureMessage", "plaintext (pre padding) = ", &m_plainText);
+#endif
+
+ if (encSessionKey == NULL) {
+ // RA::Debug("APDU::SecureMessage", "no encryption session key");
+ rv = PR_FAILURE;
+ goto done;
+ }
+// RA::Debug(LL_ALL_DATA_IN_PDU, "APDU::SecureMessage", "plaintext data length = %d", m_data.size());
+
+ data_to_enc += (BYTE)m_data.size();
+ data_to_enc += m_data;
+
+ if ((data_to_enc.size() % 8) == 0)
+ pad_needed = 0;
+ else if (data_to_enc.size() < 8) {
+ pad_needed = 8 - data_to_enc.size();
+ } else { // data size > 8 and not divisible by 8
+ pad_needed = 8 - (data_to_enc.size() % 8);
+ }
+ if (pad_needed) {
+// RA::Debug(LL_ALL_DATA_IN_PDU, "APDU::SecureMessage", "padding needed =%d", pad_needed);
+ data_to_enc += Buffer(1, 0x80);
+ pad_needed --;
+
+ if (pad_needed) {
+// RA::Debug(LL_ALL_DATA_IN_PDU, "APDU::SecureMessage", "padding needed =%d", pad_needed);
+ padding = Buffer(pad_needed, (BYTE)0);
+ for (int i = 0; i < pad_needed; i++) {
+ ((BYTE*)padding)[i] = 0x00;
+ } /* for */
+ } // pad needed
+
+ } else {
+ // RA::Debug(LL_ALL_DATA_IN_PDU, "APDU::SecureMessage", "padding not needed");
+ }
+
+ if (padding.size() > 0) {
+ data_to_enc += Buffer(padding, padding.size());
+ }
+
+#ifdef ENC_DEBUG
+// RA::DebugBuffer("APDU::SecureMessage", "data to encrypt (post padding)= ",&data_to_enc);
+#endif
+
+ // now, encrypt "data_to_enc"
+ rv = Util::EncryptData(encSessionKey, data_to_enc, data_encrypted);
+ if (rv == PR_FAILURE) {
+ // RA::Error("APDU::SecureMessage", "encryption failed");
+ goto done;
+ } else {
+ // RA::Debug(LL_PER_PDU, "APDU::SecureMessage", "encryption succeeded");
+ // RA::Debug(LL_PER_PDU, "APDU::SecureMessage", "encrypted data length = %d",
+// data_encrypted.size());
+ // set "m_data"
+ m_data = data_encrypted;
+ }
+
+ // lc should be automatically set correctly when getEncoding is called
+
+ done:
+ return rv;
+
+}
+
+
+/**
+ * Retrieves APDU's encoding.
+ * The encoding of APDU is as follows:
+ *
+ * CLA 1 byte
+ * INS 1 byte
+ * P1 1 byte
+ * P2 1 byte
+ * <Data Size> 1 byte
+ * <Data> <Data Size> byte(s)
+ * 0 1 byte
+ *
+ * @param data the result buffer which will contain the actual data
+ * including the APDU header, data, and pre-calculated mac.
+ */
+TPS_PUBLIC void APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, (BYTE)m_data.size() + m_mac.size());
+ data += Buffer(m_data, m_data.size());
+ if (m_mac.size() > 0) {
+ data += Buffer(m_mac, m_mac.size());
+ }
+} /* Encode */
diff --git a/base/tps/src/apdu/APDU_Response.cpp b/base/tps/src/apdu/APDU_Response.cpp
new file mode 100644
index 000000000..fac9b1ff4
--- /dev/null
+++ b/base/tps/src/apdu/APDU_Response.cpp
@@ -0,0 +1,111 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU_Response.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a response object.
+ */
+APDU_Response::APDU_Response ()
+{
+}
+
+TPS_PUBLIC APDU_Response::APDU_Response (Buffer &data)
+{
+ m_data = data;
+}
+
+/**
+ * Destroys a response object.
+ */
+APDU_Response::~APDU_Response ()
+{
+}
+
+/**
+ * Copy constructor.
+ */
+APDU_Response::APDU_Response (const APDU_Response &cpy)
+{
+ *this = cpy;
+}
+
+/**
+ * Operator for simple assignment.
+ */
+APDU_Response& APDU_Response::operator=(const APDU_Response &cpy)
+{
+ if (this == &cpy)
+ return *this;
+ m_data = cpy.m_data;
+ return *this;
+}
+
+
+
+/**
+ * Retrieves the byte encoding of the response
+ * object including the last 2 state bytes.
+ */
+TPS_PUBLIC Buffer &APDU_Response::GetData()
+{
+ return m_data;
+}
+
+/**
+ * Retrieves the 1st status byte.
+ */
+BYTE APDU_Response::GetSW1()
+{
+ if (m_data == NULL) {
+ return 0x0;
+ } else {
+ if (m_data.size() < 2) {
+ return 0x0;
+ } else {
+ return ((BYTE*)m_data)[((int)m_data.size())-2];
+ }
+ }
+}
+
+
+/**
+ * Retrieves the 2nd status byte.
+ */
+BYTE APDU_Response::GetSW2()
+{
+ if (m_data == NULL) {
+ return 0x0;
+ } else {
+ if (m_data.size() < 2) {
+ return 0x0;
+ } else {
+ return ((BYTE*)m_data)[((int)m_data.size())-1];
+ }
+ }
+}
diff --git a/base/tps/src/apdu/Create_Object_APDU.cpp b/base/tps/src/apdu/Create_Object_APDU.cpp
new file mode 100644
index 000000000..2da9f20d3
--- /dev/null
+++ b/base/tps/src/apdu/Create_Object_APDU.cpp
@@ -0,0 +1,121 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Create Object APDU. This APDU is usually sent right
+ * before Write_Buffer_APDU is sent. This APDU only creates an Object
+ * on token, but does not actually writes object content until
+ * Write_Buffer_APDU is sent.
+ *
+ * CreateObject APDU format:
+ * CLA 0x84
+ * INS 0x5a
+ * P1 0x00
+ * P2 0x00
+ * lc 0x0e
+ * DATA <Object Parameters>
+ *
+ * [DATA] Object Parameters are:
+ * Long Object ID;
+ * Long Object Size;
+ * ObjectACL ObjectACL;
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ * 9C 08 - object already exists
+ * 9C 01 - insufficient memory on card to complete the operation
+ *
+ * NOTE:
+ * Observe that the PIN identity is hard-coded at n.2 for each
+ * permission. In Housekey, this is probably a non-issue, however,
+ * in housekey, do we not allow multiple people (presumably closely
+ * -related) to share one token with individual certs? We should
+ * consider exposing this as an input param.
+ *
+ * @param object_id as defined in APDU
+ * @param len length of object
+ * @see APDU
+ */
+TPS_PUBLIC Create_Object_APDU::Create_Object_APDU (BYTE *object_id, BYTE *permissions, int len)
+{
+ SetCLA(0x84);
+ SetINS(0x5a);
+ SetP1(0x00);
+ SetP2(0x00);
+ Buffer data;
+ data =
+ /* Object ID */
+ Buffer(1, (BYTE)object_id[0]) +
+ Buffer(1, (BYTE)object_id[1]) +
+ Buffer(1, (BYTE)object_id[2]) +
+ Buffer(1, (BYTE)object_id[3]) +
+ /* data length */
+ Buffer(1, (BYTE)(len >> 24)) +
+ Buffer(1, (BYTE)((len >> 16) & 0xff)) +
+ Buffer(1, (BYTE)((len >> 8) & 0xff)) +
+ Buffer(1, (BYTE)(len & 0xff)) +
+ /* ACLs */
+
+ /* should take from caller
+ // read permission
+ Buffer(1, (BYTE)0xFF) + // means "read" never allowed
+ Buffer(1, (BYTE)0xFF) +
+
+ // write permission
+ Buffer(1, (BYTE)0x40) + //means "write" for identity n.2 (PIN required)
+ Buffer(1, (BYTE)0x00) +
+
+ // delete permission
+ Buffer(1, (BYTE)0x40) + //means "delete" for identity n.2 (PIN) required
+ Buffer(1, (BYTE)0x00);
+ */
+
+ Buffer(1, (BYTE) permissions[0]) +
+ Buffer(1, (BYTE) permissions[1]) +
+ Buffer(1, (BYTE) permissions[2]) +
+ Buffer(1, (BYTE) permissions[3]) +
+ Buffer(1, (BYTE) permissions[4]) +
+ Buffer(1, (BYTE) permissions[5]);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Create_Object_APDU::~Create_Object_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Create_Object_APDU::GetType()
+{
+ return APDU_CREATE_OBJECT;
+}
diff --git a/base/tps/src/apdu/Create_Pin_APDU.cpp b/base/tps/src/apdu/Create_Pin_APDU.cpp
new file mode 100644
index 000000000..db2ad3d0a
--- /dev/null
+++ b/base/tps/src/apdu/Create_Pin_APDU.cpp
@@ -0,0 +1,73 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs CreatePIN APDU.
+ * CLA 0x80
+ * INS 0x40
+ * P1 <Pin number>
+ * P2 <Max # of allowed attempts>
+ * lc <data length>
+ * DATA <Pin Value>
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ * 9C 10 - incorrect p1
+ * 9C 0E - invalid parameter (data)
+ *
+ * @param p1 Pin number: 0x00 - 0x07
+ * @param p2 Max # of consecutive unsuccessful verifications
+ * before the PIN blocks.
+ * @param data pin
+ * @see APDU
+ */
+TPS_PUBLIC Create_Pin_APDU::Create_Pin_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+// SetCLA(0xB0);
+ SetCLA(0x84);
+ SetINS(0x40);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Create_Pin_APDU::~Create_Pin_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Create_Pin_APDU::GetType()
+{
+ return APDU_CREATE_PIN;
+}
diff --git a/base/tps/src/apdu/Delete_File_APDU.cpp b/base/tps/src/apdu/Delete_File_APDU.cpp
new file mode 100644
index 000000000..2306f0255
--- /dev/null
+++ b/base/tps/src/apdu/Delete_File_APDU.cpp
@@ -0,0 +1,59 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Delete_File_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Delete File APDU.
+ */
+TPS_PUBLIC Delete_File_APDU::Delete_File_APDU (Buffer &AID)
+{
+ SetCLA(0x84);
+ SetINS(0xE4);
+ SetP1(0x00);
+ SetP2(0x00);
+
+ Buffer AIDTLV(AID.size() + 2);
+ ((BYTE*)AIDTLV)[0] = 0x4F;
+ ((BYTE*)AIDTLV)[1] = AID.size();
+ for(unsigned int i=0; i < AID.size(); ++i ) {
+ ((BYTE*)AIDTLV)[i+2] = ((BYTE*)AID)[i];
+ }
+
+ SetData(AIDTLV);
+}
+
+TPS_PUBLIC Delete_File_APDU::~Delete_File_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Delete_File_APDU::GetType()
+{
+ return APDU_DELETE_FILE;
+}
diff --git a/base/tps/src/apdu/External_Authenticate_APDU.cpp b/base/tps/src/apdu/External_Authenticate_APDU.cpp
new file mode 100644
index 000000000..32c414584
--- /dev/null
+++ b/base/tps/src/apdu/External_Authenticate_APDU.cpp
@@ -0,0 +1,76 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "channel/Secure_Channel.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs External Authenticate APDU. This allows
+ * setting of the security level.
+ */
+TPS_PUBLIC External_Authenticate_APDU::External_Authenticate_APDU (Buffer &data,
+ SecurityLevel sl)
+{
+ SetCLA(0x84);
+ SetINS(0x82);
+ SetP1(0x01);
+
+ if (sl == SECURE_MSG_MAC_ENC) {
+ SetP1(0x03);
+// RA::Debug("External_Authenticate_APDU::External_Authenticate_APDU",
+ // "Security level set to 3 - attempted =%d", (int)sl);
+ } else if (sl == SECURE_MSG_NONE) {
+ SetP1(0x00);
+// RA::Debug("External_Authenticate_APDU::External_Authenticate_APDU",
+// "Security level set to 0 - attempted =%d", (int)sl);
+ } else { // default
+ SetP1(0x01);
+ // RA::Debug("External_Authenticate_APDU::External_Authenticate_APDU",
+// "Security level set to 1 - attempted =%d", (int)sl);
+ }
+
+ SetP2(0x00);
+ SetData(data);
+}
+
+TPS_PUBLIC External_Authenticate_APDU::~External_Authenticate_APDU ()
+{
+}
+
+TPS_PUBLIC Buffer &External_Authenticate_APDU::GetHostCryptogram()
+{
+ return GetData();
+}
+
+TPS_PUBLIC APDU_Type External_Authenticate_APDU::GetType()
+{
+ return APDU_EXTERNAL_AUTHENTICATE;
+}
+
diff --git a/base/tps/src/apdu/Format_Muscle_Applet_APDU.cpp b/base/tps/src/apdu/Format_Muscle_Applet_APDU.cpp
new file mode 100644
index 000000000..dff95b8cd
--- /dev/null
+++ b/base/tps/src/apdu/Format_Muscle_Applet_APDU.cpp
@@ -0,0 +1,107 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Format Muscle Applet APDU.
+ */
+TPS_PUBLIC Format_Muscle_Applet_APDU::Format_Muscle_Applet_APDU (
+ unsigned short memSize,
+ Buffer &PIN0, BYTE pin0Tries,
+ Buffer &unblockPIN0, BYTE unblock0Tries,
+ Buffer &PIN1, BYTE pin1Tries,
+ Buffer &unblockPIN1, BYTE unblock1Tries,
+ unsigned short objCreationPermissions,
+ unsigned short keyCreationPermissions,
+ unsigned short pinCreationPermissions)
+{
+ SetCLA(0xB0);
+ SetINS(0x2A);
+ SetP1(0x00);
+ SetP2(0x00);
+
+ Buffer data; data.reserve(100);
+ Buffer pin((BYTE *)"Muscle00", 8);
+ data += pin.size();
+ data += pin;
+
+ pin = Buffer((BYTE*) PIN0, PIN0.size());
+ data += pin0Tries; // pin tries
+ data += unblock0Tries; // unblock tries
+ data += pin.size();
+ data += pin;
+
+ pin = Buffer((BYTE*)unblockPIN0, unblockPIN0.size());
+ data += pin.size();
+ data += pin;
+
+ pin = Buffer((BYTE*)PIN1, PIN1.size());
+ data += pin1Tries; // pin tries
+ data += unblock1Tries; // unblock tries
+ data += pin.size();
+ data += pin;
+
+ pin = Buffer((BYTE*)unblockPIN1, unblockPIN1.size());
+ data += pin.size();
+ data += pin;
+
+ data += (BYTE)0; data += (BYTE)0; // fluff
+
+ data += (memSize >> 8) & 0xff;
+ data += memSize & 0xff;
+
+ data += (BYTE)(objCreationPermissions >> 8);
+ data += (BYTE)(objCreationPermissions & 0xFF);
+ data += (BYTE)(keyCreationPermissions >> 8);
+ data += (BYTE)(keyCreationPermissions & 0xFF);
+ data += (BYTE)(pinCreationPermissions >> 8);
+ data += (BYTE)(pinCreationPermissions & 0xFF);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Format_Muscle_Applet_APDU::~Format_Muscle_Applet_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Format_Muscle_Applet_APDU::GetType()
+{
+ return APDU_FORMAT_MUSCLE_APPLET;
+}
+
+TPS_PUBLIC void Format_Muscle_Applet_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, (BYTE)m_data.size());
+ data += Buffer(m_data, m_data.size());
+} /* Encode */
diff --git a/base/tps/src/apdu/Generate_Key_APDU.cpp b/base/tps/src/apdu/Generate_Key_APDU.cpp
new file mode 100644
index 000000000..7d78b5513
--- /dev/null
+++ b/base/tps/src/apdu/Generate_Key_APDU.cpp
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Generate Key APDU.
+ */
+TPS_PUBLIC Generate_Key_APDU::Generate_Key_APDU (BYTE p1, BYTE p2, BYTE alg, int keysize, BYTE option,
+BYTE type, Buffer &wrapped_challenge, Buffer &key_check)
+{
+ SetCLA(0x84);
+ SetINS(0x0C);
+ SetP1(p1);
+ SetP2(p2);
+ Buffer data;
+ data =
+ Buffer(1,alg) +
+ Buffer(1,(BYTE)(keysize/256)) +
+ Buffer(1,(BYTE)(keysize%256)) +
+ Buffer(1,option) +
+ Buffer(1,type) +
+ Buffer(1,(BYTE)wrapped_challenge.size()) +
+ Buffer(wrapped_challenge) +
+
+ Buffer(1,(BYTE)key_check.size());
+
+ if(key_check.size() > 0)
+ data = data + Buffer(key_check);
+
+ SetData(data);
+
+}
+
+TPS_PUBLIC Generate_Key_APDU::~Generate_Key_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Generate_Key_APDU::GetType()
+{
+ return APDU_GENERATE_KEY;
+}
diff --git a/base/tps/src/apdu/Get_Data_APDU.cpp b/base/tps/src/apdu/Get_Data_APDU.cpp
new file mode 100644
index 000000000..1cb4d9a5b
--- /dev/null
+++ b/base/tps/src/apdu/Get_Data_APDU.cpp
@@ -0,0 +1,59 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Get_Data_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Get Data APDU.
+ */
+TPS_PUBLIC Get_Data_APDU::Get_Data_APDU ()
+{
+ SetCLA(0x80);
+ SetINS(0xCA);
+ SetP1(0x9F);
+ SetP2(0x7F);
+}
+
+TPS_PUBLIC Get_Data_APDU::~Get_Data_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Get_Data_APDU::GetType()
+{
+ return APDU_GET_DATA;
+}
+
+TPS_PUBLIC void Get_Data_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 0x2D);
+} /* Encode */
diff --git a/base/tps/src/apdu/Get_IssuerInfo_APDU.cpp b/base/tps/src/apdu/Get_IssuerInfo_APDU.cpp
new file mode 100644
index 000000000..c83d920df
--- /dev/null
+++ b/base/tps/src/apdu/Get_IssuerInfo_APDU.cpp
@@ -0,0 +1,80 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Get_IssuerInfo_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs GetIssuer APDU.
+ *
+ * SecureGetIssuer APDU format:
+ * CLA 0x84
+ * INS 0xF6
+ * P1 0x00
+ * P2 0x00
+ * lc 0xE0
+ * DATA <Issuer Info>
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ *
+ * @param p1 always 0x00
+ * @param p2 always 0x00
+ * @param data issuer info
+ * @see APDU
+ */
+TPS_PUBLIC Get_IssuerInfo_APDU::Get_IssuerInfo_APDU ()
+{
+ SetCLA(0x84);
+ SetINS(0xF6);
+ SetP1(0x00);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Get_IssuerInfo_APDU::~Get_IssuerInfo_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Get_IssuerInfo_APDU::GetType()
+{
+ return APDU_GET_ISSUERINFO;
+}
+
+TPS_PUBLIC void Get_IssuerInfo_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 0xe0);
+} /* Encode */
+
diff --git a/base/tps/src/apdu/Get_Status_APDU.cpp b/base/tps/src/apdu/Get_Status_APDU.cpp
new file mode 100644
index 000000000..dcf7c9fac
--- /dev/null
+++ b/base/tps/src/apdu/Get_Status_APDU.cpp
@@ -0,0 +1,59 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Get_Status_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Get Status APDU.
+ */
+TPS_PUBLIC Get_Status_APDU::Get_Status_APDU ()
+{
+ SetCLA(0xB0);
+ SetINS(0x3C);
+ SetP1(0x00);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Get_Status_APDU::~Get_Status_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Get_Status_APDU::GetType()
+{
+ return APDU_GET_STATUS;
+}
+
+TPS_PUBLIC void Get_Status_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 16);
+} /* Encode */
diff --git a/base/tps/src/apdu/Get_Version_APDU.cpp b/base/tps/src/apdu/Get_Version_APDU.cpp
new file mode 100644
index 000000000..eb7e53728
--- /dev/null
+++ b/base/tps/src/apdu/Get_Version_APDU.cpp
@@ -0,0 +1,59 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Get_Version_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Get Version APDU.
+ */
+TPS_PUBLIC Get_Version_APDU::Get_Version_APDU ()
+{
+ SetCLA(0xB0);
+ SetINS(0x70);
+ SetP1(0x00);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Get_Version_APDU::~Get_Version_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Get_Version_APDU::GetType()
+{
+ return APDU_GET_VERSION;
+}
+
+TPS_PUBLIC void Get_Version_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 4);
+} /* Encode */
diff --git a/base/tps/src/apdu/Import_Key_APDU.cpp b/base/tps/src/apdu/Import_Key_APDU.cpp
new file mode 100644
index 000000000..18c6c886f
--- /dev/null
+++ b/base/tps/src/apdu/Import_Key_APDU.cpp
@@ -0,0 +1,79 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "apdu/Import_Key_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Import Key APDU.
+ *
+ * CLA 0x84
+ * INS 0x32
+ * P1 Key Number (0x00 -0x0F) - key slot number defined in CS.cfg
+ * P2 0x00
+ * P3 Import Parameters Length (6 bytes: 3 shorts if just for ACL)
+ * DATA Import Parameters
+ *
+ * This function allows th eimport of a key into the card by (over)-writing the Cardlet memory. Object ID 0xFFFFFFFE needs to be initialized with a key blob before invocation of this function so tha tit can retrieve the key from this object. The exact key blob contents depend on th ekey's algorithm, type and actual import parameters. The key's number, algorithm type, and parameters are specified by argumetns P1, P2, P3, and DATA. Appropriate values for these are specified below:
+
+[DATA]
+Import Parameters:
+KeyACL ACL for the imported key;
+Byte[] Additional parameters; // Optional
+If KeyBlob's Encoding is BLOB_ENC_PLAIN(0x00), there are no additional parameters.
+ */
+TPS_PUBLIC Import_Key_APDU::Import_Key_APDU (BYTE p1)
+{
+ SetCLA(0x84);
+ SetINS(0x32);
+ SetP1(p1);
+ SetP2(0x00);
+ // SetP3(p3);
+
+ Buffer data;
+ data =
+ Buffer(1, (BYTE)0xFF) + // means "read allowed" by anyone
+ Buffer(1, (BYTE) 0xFF) +
+ Buffer(1, (BYTE) 0x40) + // means "write" allowed for RA only
+ Buffer(1, (BYTE) 0x00) +
+ Buffer(1, (BYTE) 0xFF) + // means "use" allowed for everyone
+ Buffer(1, (BYTE) 0xFF);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Import_Key_APDU::~Import_Key_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Import_Key_APDU::GetType()
+{
+ return APDU_IMPORT_KEY;
+}
diff --git a/base/tps/src/apdu/Import_Key_Enc_APDU.cpp b/base/tps/src/apdu/Import_Key_Enc_APDU.cpp
new file mode 100644
index 000000000..6df161157
--- /dev/null
+++ b/base/tps/src/apdu/Import_Key_Enc_APDU.cpp
@@ -0,0 +1,70 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "apdu/Import_Key_Enc_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Import Key Encrypted APDU.
+ *
+ * CLA 0x80
+ * INS 0x0A
+ * P1 private Key Number (0x00 -0x0F) - key slot number defined in CMS.cfg
+ * P2 public Key Number (0x00 -0x0F) - key slot number defined in CMS.cfg
+ * DATA:
+ * Wrapped Key DesKey
+ * Byte IV_Length
+ * Byte IV_Data
+ *
+ * This function allows the import of a key into the card by (over)-writing the Cardlet memory. Object ID 0xFFFFFFFE needs to be initialized with a key blob before invocation of this function so that it can retrieve the key from this object. The exact key blob contents depend on the key's algorithm, type and actual import parameters. The key's number, algorithm type, and parameters are specified by argumetns P1, P2, P3, and DATA. Appropriate values for these are specified below:
+
+[DATA]
+Import Parameters:
+...to be provided
+ */
+TPS_PUBLIC Import_Key_Enc_APDU::Import_Key_Enc_APDU (BYTE p1, BYTE p2,
+ Buffer& data)
+{
+ SetCLA(0x84);
+ SetINS(0x0A);
+ SetP1(p1);
+ SetP2(p2);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Import_Key_Enc_APDU::~Import_Key_Enc_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Import_Key_Enc_APDU::GetType()
+{
+ return APDU_IMPORT_KEY_ENC;
+}
diff --git a/base/tps/src/apdu/Initialize_Update_APDU.cpp b/base/tps/src/apdu/Initialize_Update_APDU.cpp
new file mode 100644
index 000000000..a87091122
--- /dev/null
+++ b/base/tps/src/apdu/Initialize_Update_APDU.cpp
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Initialize Update APDU.
+ */
+TPS_PUBLIC Initialize_Update_APDU::Initialize_Update_APDU (BYTE key_version, BYTE key_index, Buffer &data)
+{
+ SetCLA(0x80);
+ SetINS(0x50);
+ SetP1(key_version);
+ SetP2(key_index);
+ SetData(data);
+}
+
+TPS_PUBLIC Initialize_Update_APDU::~Initialize_Update_APDU ()
+{
+}
+
+TPS_PUBLIC Buffer &Initialize_Update_APDU::GetHostChallenge()
+{
+ return GetData();
+}
+
+TPS_PUBLIC APDU_Type Initialize_Update_APDU::GetType()
+{
+ return APDU_INITIALIZE_UPDATE;
+}
+
+TPS_PUBLIC void Initialize_Update_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, (BYTE)m_data.size());
+ data += Buffer(m_data, m_data.size());
+} /* Encode */
diff --git a/base/tps/src/apdu/Install_Applet_APDU.cpp b/base/tps/src/apdu/Install_Applet_APDU.cpp
new file mode 100644
index 000000000..0a6b9b7c1
--- /dev/null
+++ b/base/tps/src/apdu/Install_Applet_APDU.cpp
@@ -0,0 +1,112 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Install_Applet_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Install Applet APDU.
+ */
+TPS_PUBLIC Install_Applet_APDU::Install_Applet_APDU (Buffer &packageAID, Buffer &appletAID,
+ BYTE appPrivileges, unsigned int instanceSize, unsigned int appletMemorySize)
+{
+ SetCLA(0x84);
+ SetINS(0xE6);
+ SetP1(0x0C);
+ SetP2(0x00);
+
+ Buffer data;
+ data.reserve(32); // pre-allocate
+ data += packageAID.size();
+ data += packageAID;
+ data += appletAID.size();
+ data += appletAID;
+ data += appletAID.size();
+ data += appletAID;
+
+ data += 0x01; // length of application privileges byte
+ data += appPrivileges;
+
+ Buffer installParams; installParams.reserve(6);
+ installParams += 0xEF;
+ installParams += 0x04;
+ installParams += 0xC8;
+ installParams += 0x02;
+
+ installParams += (instanceSize>>8) & 0xff;
+ installParams += instanceSize & 0xff;
+ installParams += 0xC9;
+
+
+ //installParams += 0x01;
+ //installParams += (BYTE)0x00;
+
+ //Now add some applet specific init data that the applet supports
+ //Length of applet specific data
+
+ installParams += 0x04;
+
+ //Issuer info length.
+ //Leave this to zero since TPS already writes phone home info to card.
+ installParams += (BYTE)0x00;
+
+ //Length of applet memory size
+ installParams += (BYTE)0x02;
+
+ // Applet memory block size
+
+ installParams += (appletMemorySize>>8) & 0xff;
+ installParams += appletMemorySize & 0xff;
+
+ data += installParams.size();
+ data += installParams;
+ data += (BYTE) 0x00; // size of token return data
+
+ SetData(data);
+}
+
+/**
+ * Constructs Install Applet APDU.
+ */
+TPS_PUBLIC Install_Applet_APDU::Install_Applet_APDU (Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0xE6);
+ SetP1(0x0C);
+ SetP2(0x00);
+ SetData(data);
+}
+
+TPS_PUBLIC Install_Applet_APDU::~Install_Applet_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Install_Applet_APDU::GetType()
+{
+ return APDU_INSTALL_APPLET;
+}
diff --git a/base/tps/src/apdu/Install_Load_APDU.cpp b/base/tps/src/apdu/Install_Load_APDU.cpp
new file mode 100644
index 000000000..6169538e5
--- /dev/null
+++ b/base/tps/src/apdu/Install_Load_APDU.cpp
@@ -0,0 +1,91 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Install Load APDU.
+ */
+TPS_PUBLIC Install_Load_APDU::Install_Load_APDU (Buffer& packageAID, Buffer& sdAID,
+ unsigned int fileLen)
+{
+ SetCLA(0x84);
+ SetINS(0xE6);
+ SetP1(0x02);
+ SetP2(0x00);
+
+ Buffer inputData(packageAID.size() + sdAID.size() + 11);
+
+ unsigned int i = 0; // offset
+ ((BYTE*)inputData)[i++] = packageAID.size();
+ inputData.replace(i, packageAID, packageAID.size());
+ i += packageAID.size();
+
+ ((BYTE*)inputData)[i++] = sdAID.size();
+ inputData.replace(i, sdAID, sdAID.size());
+ i += sdAID.size();
+
+ ((BYTE*)inputData)[i++] = 0;
+
+ ((BYTE*)inputData)[i++] = 6;
+
+ ((BYTE*)inputData)[i++] = 0xEF;
+ ((BYTE*)inputData)[i++] = 0x04;
+ ((BYTE*)inputData)[i++] = 0xC6;
+ ((BYTE*)inputData)[i++] = 0x02;
+ fileLen += 24 + sdAID.size(); // !!! XXX
+
+ ((BYTE*)inputData)[i++] = ((fileLen) >> 8) & 0xff;
+ ((BYTE*)inputData)[i++] = fileLen & 0xff;
+
+ ((BYTE*)inputData)[i++] = 0;
+
+ SetData(inputData);
+}
+
+/**
+ * Constructs Install Load APDU. Used when data was pre-constructed
+ */
+TPS_PUBLIC Install_Load_APDU::Install_Load_APDU (Buffer& data)
+{
+ SetCLA(0x84);
+ SetINS(0xE6);
+ SetP1(0x02);
+ SetP2(0x00);
+ SetData(data);
+}
+
+TPS_PUBLIC Install_Load_APDU::~Install_Load_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Install_Load_APDU::GetType()
+{
+ return APDU_INSTALL_LOAD;
+}
diff --git a/base/tps/src/apdu/Lifecycle_APDU.cpp b/base/tps/src/apdu/Lifecycle_APDU.cpp
new file mode 100644
index 000000000..e7236147e
--- /dev/null
+++ b/base/tps/src/apdu/Lifecycle_APDU.cpp
@@ -0,0 +1,50 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Lifecycle APDU.
+ */
+TPS_PUBLIC Lifecycle_APDU::Lifecycle_APDU (BYTE lifecycle)
+{
+ SetCLA(0x84);
+ SetINS(0xf0);
+ SetP1(lifecycle);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Lifecycle_APDU::~Lifecycle_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Lifecycle_APDU::GetType()
+{
+ return APDU_LIFECYCLE;
+}
diff --git a/base/tps/src/apdu/List_Objects_APDU.cpp b/base/tps/src/apdu/List_Objects_APDU.cpp
new file mode 100644
index 000000000..86ae570d9
--- /dev/null
+++ b/base/tps/src/apdu/List_Objects_APDU.cpp
@@ -0,0 +1,61 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/List_Objects_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Set Pin APDU.
+ */
+TPS_PUBLIC List_Objects_APDU::List_Objects_APDU (BYTE seq)
+{
+ SetCLA(0xB0);
+ SetINS(0x58);
+ SetP1(seq);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC List_Objects_APDU::~List_Objects_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type List_Objects_APDU::GetType()
+{
+ return APDU_LIST_OBJECTS;
+}
+
+TPS_PUBLIC void List_Objects_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, 0x0E);
+} /* Encode */
+
diff --git a/base/tps/src/apdu/List_Pins_APDU.cpp b/base/tps/src/apdu/List_Pins_APDU.cpp
new file mode 100644
index 000000000..218072f21
--- /dev/null
+++ b/base/tps/src/apdu/List_Pins_APDU.cpp
@@ -0,0 +1,63 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Set Pin APDU.
+ */
+TPS_PUBLIC List_Pins_APDU::List_Pins_APDU (BYTE ret_size)
+{
+ SetCLA(0xB0);
+// SetCLA(0x84);
+ SetINS(0x48);
+ SetP1(0x00);
+ SetP2(0x00);
+ m_ret_size = ret_size;
+}
+
+TPS_PUBLIC List_Pins_APDU::~List_Pins_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type List_Pins_APDU::GetType()
+{
+ return APDU_LIST_PINS;
+}
+
+TPS_PUBLIC void List_Pins_APDU::GetEncoding(Buffer &data)
+{
+ data += Buffer(1, m_cla);
+ data += Buffer(1, m_ins);
+ data += Buffer(1, m_p1);
+ data += Buffer(1, m_p2);
+ data += Buffer(1, m_ret_size);
+} /* Encode */
+
diff --git a/base/tps/src/apdu/Load_File_APDU.cpp b/base/tps/src/apdu/Load_File_APDU.cpp
new file mode 100644
index 000000000..c41f0ec73
--- /dev/null
+++ b/base/tps/src/apdu/Load_File_APDU.cpp
@@ -0,0 +1,52 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Load_File_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Load File APDU.
+ */
+TPS_PUBLIC Load_File_APDU::Load_File_APDU (BYTE refControl, BYTE blockNum, Buffer& data)
+{
+ SetCLA(0x84);
+ SetINS(0xE8);
+ SetP1(refControl);
+ SetP2(blockNum);
+
+ SetData(data);
+}
+
+TPS_PUBLIC Load_File_APDU::~Load_File_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Load_File_APDU::GetType()
+{
+ return APDU_LOAD_FILE;
+}
diff --git a/base/tps/src/apdu/Put_Key_APDU.cpp b/base/tps/src/apdu/Put_Key_APDU.cpp
new file mode 100644
index 000000000..0a061394f
--- /dev/null
+++ b/base/tps/src/apdu/Put_Key_APDU.cpp
@@ -0,0 +1,53 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Put Key APDU.
+ */
+TPS_PUBLIC Put_Key_APDU::Put_Key_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0xd8);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Put_Key_APDU::~Put_Key_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Put_Key_APDU::GetType()
+{
+ return APDU_PUT_KEY;
+}
diff --git a/base/tps/src/apdu/Read_Buffer_APDU.cpp b/base/tps/src/apdu/Read_Buffer_APDU.cpp
new file mode 100644
index 000000000..22f23fe1f
--- /dev/null
+++ b/base/tps/src/apdu/Read_Buffer_APDU.cpp
@@ -0,0 +1,63 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Read Buffer APDU.
+ */
+TPS_PUBLIC Read_Buffer_APDU::Read_Buffer_APDU (int len, int offset)
+{
+ SetCLA(0x84);
+ SetINS(0x08);
+ SetP1(len);
+ SetP2(0x00);
+ Buffer data;
+ data = Buffer(1,(BYTE)(offset/256)) + Buffer(1,(BYTE)(offset%256));
+ SetData(data);
+}
+
+TPS_PUBLIC Read_Buffer_APDU::~Read_Buffer_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Read_Buffer_APDU::GetType()
+{
+ return APDU_READ_BUFFER;
+}
+
+TPS_PUBLIC int Read_Buffer_APDU::GetLen()
+{
+ return m_p1;
+}
+
+TPS_PUBLIC int Read_Buffer_APDU::GetOffset()
+{
+ return (((int)((BYTE*)m_data)[0]) << 8) + ((int)((BYTE*)m_data)[1]);
+}
diff --git a/base/tps/src/apdu/Read_Object_APDU.cpp b/base/tps/src/apdu/Read_Object_APDU.cpp
new file mode 100644
index 000000000..21722d331
--- /dev/null
+++ b/base/tps/src/apdu/Read_Object_APDU.cpp
@@ -0,0 +1,88 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Read_Object_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Read Object APDU.
+ *
+ * ReadObject APDU format:
+ * CLA 0x84
+ * INS 0x56
+ * P1 0x00
+ * P2 0x00
+ * lc 0x09
+ * DATA <Data Parameters>
+ *
+ * [DATA] Parameters are:
+ * Long Object ID;
+ * Long Offset
+ * Byte Data Size;
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ * 9C 07 - object not found
+ *
+ * @param object_id as defined in APDU
+ * @param offset
+ * @param data
+ * @see APDU
+ */
+TPS_PUBLIC Read_Object_APDU::Read_Object_APDU (BYTE *object_id, int offset, int len)
+{
+ SetCLA(0x84);
+ SetINS(0x56);
+ SetP1(0x00);
+ SetP2(0x00);
+ Buffer data;
+ data =
+ Buffer(1, (BYTE)object_id[0]) +
+ Buffer(1, (BYTE)object_id[1]) +
+ Buffer(1, (BYTE)object_id[2]) +
+ Buffer(1, (BYTE)object_id[3]) +
+ Buffer(1,(BYTE)((offset>>24) & 0xff)) +
+ Buffer(1,(BYTE)((offset>>16) & 0xff)) +
+ Buffer(1,(BYTE)((offset>>8) & 0xff)) +
+ Buffer(1,(BYTE)(offset & 0xff)) +
+ Buffer(1, (BYTE)len);
+ SetData(data);
+}
+
+TPS_PUBLIC Read_Object_APDU::~Read_Object_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Read_Object_APDU::GetType()
+{
+ return APDU_READ_OBJECT;
+}
+
diff --git a/base/tps/src/apdu/Select_APDU.cpp b/base/tps/src/apdu/Select_APDU.cpp
new file mode 100644
index 000000000..4f5917b29
--- /dev/null
+++ b/base/tps/src/apdu/Select_APDU.cpp
@@ -0,0 +1,49 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Select_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC Select_APDU::Select_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+ SetCLA(0x00);
+ SetINS(0xa4);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Select_APDU::~Select_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Select_APDU::GetType()
+{
+ return APDU_SELECT;
+}
diff --git a/base/tps/src/apdu/Set_IssuerInfo_APDU.cpp b/base/tps/src/apdu/Set_IssuerInfo_APDU.cpp
new file mode 100644
index 000000000..77b1d0f8d
--- /dev/null
+++ b/base/tps/src/apdu/Set_IssuerInfo_APDU.cpp
@@ -0,0 +1,76 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Set_IssuerInfo_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs SetIssuer APDU.
+ *
+ * SecureSetIssuer APDU format:
+ * CLA 0x84
+ * INS 0xF4
+ * P1 0x00
+ * P2 0x00
+ * lc 0xE0
+ * DATA <Issuer Info>
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ *
+ * @param p1 always 0x00
+ * @param p2 always 0x00
+ * @param data issuer info
+ * @see APDU
+ */
+TPS_PUBLIC Set_IssuerInfo_APDU::Set_IssuerInfo_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0xF4);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Set_IssuerInfo_APDU::~Set_IssuerInfo_APDU ()
+{
+}
+
+TPS_PUBLIC Buffer &Set_IssuerInfo_APDU::GetIssuerInfo()
+{
+ return GetData();
+}
+
+TPS_PUBLIC APDU_Type Set_IssuerInfo_APDU::GetType()
+{
+ return APDU_SET_ISSUERINFO;
+}
diff --git a/base/tps/src/apdu/Set_Pin_APDU.cpp b/base/tps/src/apdu/Set_Pin_APDU.cpp
new file mode 100644
index 000000000..3faaa89ed
--- /dev/null
+++ b/base/tps/src/apdu/Set_Pin_APDU.cpp
@@ -0,0 +1,76 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "apdu/APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs SetPin APDU.
+ *
+ * SecureSetPIN APDU format:
+ * CLA 0x80
+ * INS 0x04
+ * P1 <Pin number>
+ * P2 0x00
+ * lc <data length>
+ * DATA <New Pin Value>
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ *
+ * @param p1 Pin number: 0x00 - 0x07
+ * @param p2 always 0x00
+ * @param data pin
+ * @see APDU
+ */
+TPS_PUBLIC Set_Pin_APDU::Set_Pin_APDU (BYTE p1, BYTE p2, Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0x04);
+ SetP1(p1);
+ SetP2(p2);
+ SetData(data);
+}
+
+TPS_PUBLIC Set_Pin_APDU::~Set_Pin_APDU ()
+{
+}
+
+TPS_PUBLIC Buffer &Set_Pin_APDU::GetNewPIN()
+{
+ return GetData();
+}
+
+TPS_PUBLIC APDU_Type Set_Pin_APDU::GetType()
+{
+ return APDU_SET_PIN;
+}
diff --git a/base/tps/src/apdu/Unblock_Pin_APDU.cpp b/base/tps/src/apdu/Unblock_Pin_APDU.cpp
new file mode 100644
index 000000000..c580dc9f2
--- /dev/null
+++ b/base/tps/src/apdu/Unblock_Pin_APDU.cpp
@@ -0,0 +1,50 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Unblock_Pin_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Unblock Pin APDU.
+ */
+TPS_PUBLIC Unblock_Pin_APDU::Unblock_Pin_APDU ()
+{
+ SetCLA(0x84);
+ SetINS(0x02);
+ SetP1(0x00);
+ SetP2(0x00);
+}
+
+TPS_PUBLIC Unblock_Pin_APDU::~Unblock_Pin_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Unblock_Pin_APDU::GetType()
+{
+ return APDU_UNBLOCK_PIN;
+}
diff --git a/base/tps/src/apdu/Write_Object_APDU.cpp b/base/tps/src/apdu/Write_Object_APDU.cpp
new file mode 100644
index 000000000..958ee4384
--- /dev/null
+++ b/base/tps/src/apdu/Write_Object_APDU.cpp
@@ -0,0 +1,103 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include "apdu/APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs Write Buffer APDU. This APDU is usually sent right after
+ * the Create_Object_APDU is sent. This APDU writes the actual object
+ * content into the object that was created with Create_Object_APDU.
+ * This APDU is used for both write and re-writes of data.
+ * The object data is stored starting from the byte specified by the
+ * offset parameter.
+ * Up to 240 bytes can be transferred with a single APDU. If more bytes
+ * need to be transferred, then multiple WriteObject commands must be
+ * used with different offsets.
+ *
+ * WriteObject APDU format:
+ * CLA 0x84
+ * INS 0x54
+ * P1 0x00
+ * P2 0x00
+ * lc Data Size + 9
+ * DATA <Data Parameters>
+ *
+ * [DATA] Parameters are:
+ * Long Object ID;
+ * Long Offset
+ * Byte Data Size;
+ * Byte[] Object Data
+ *
+ * Connection requirement:
+ * Secure Channel
+ *
+ * Possible error Status Codes:
+ * 9C 06 - unauthorized
+ * 9C 07 - object not found
+ *
+ * @param object_id as defined in APDU
+ * @param offset
+ * @param data
+ * @see APDU
+ */
+TPS_PUBLIC Write_Object_APDU::Write_Object_APDU (BYTE *object_id, int offset, Buffer &data)
+{
+ SetCLA(0x84);
+ SetINS(0x54);
+ SetP1(0x00);
+ SetP2(0x00);
+ Buffer data1;
+ data1 =
+ Buffer(1, (BYTE)object_id[0]) +
+ Buffer(1, (BYTE)object_id[1]) +
+
+ Buffer(1, (BYTE)object_id[2]) +
+ Buffer(1, (BYTE)object_id[3]) +
+ /*
+ Buffer(1, (BYTE)0x00) +
+ Buffer(1, (BYTE)0x00) +
+ */
+ Buffer(1,(BYTE)((offset>>24) & 0xff)) +
+ Buffer(1,(BYTE)((offset>>16) & 0xff)) +
+ Buffer(1,(BYTE)((offset>>8) & 0xff)) +
+ Buffer(1,(BYTE)(offset & 0xff)) +
+ Buffer(1, (BYTE)data.size()) +
+ Buffer(data);
+ SetData(data1);
+}
+
+TPS_PUBLIC Write_Object_APDU::~Write_Object_APDU ()
+{
+}
+
+TPS_PUBLIC APDU_Type Write_Object_APDU::GetType()
+{
+ return APDU_WRITE_OBJECT;
+}
+
diff --git a/base/tps/src/authentication/CMakeLists.txt b/base/tps/src/authentication/CMakeLists.txt
new file mode 100644
index 000000000..ba8ca07dc
--- /dev/null
+++ b/base/tps/src/authentication/CMakeLists.txt
@@ -0,0 +1,52 @@
+project(ldapauth_library CXX)
+
+set(LDAPAUTH_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${TPS_INCLUDE_DIR}
+ CACHE INTERNAL "ldapauth public include directories"
+)
+
+set(LDAPAUTH_PRIVATE_INCLUDE_DIRS
+ ${LDAPAUTH_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(LDAPAUTH_SHARED_LIBRARY
+ ldapauth_library
+ CACHE INTERNAL "ldapauth shared library"
+)
+
+set(LDAPAUTH_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+ ${TOKENDB_SHARED_LIBRARY}
+ ${TPS_SHARED_LIBRARY}
+)
+
+set(ldapauth_library_SRCS
+ LDAP_Authentication.cpp
+)
+
+include_directories(${LDAPAUTH_PRIVATE_INCLUDE_DIRS})
+
+add_library(${LDAPAUTH_SHARED_LIBRARY} SHARED ${ldapauth_library_SRCS})
+target_link_libraries(${LDAPAUTH_SHARED_LIBRARY} ${LDAPAUTH_LINK_LIBRARIES})
+
+set_target_properties(${LDAPAUTH_SHARED_LIBRARY}
+ PROPERTIES
+ OUTPUT_NAME
+ ldapauth
+)
+
+install(
+ TARGETS
+ ${LDAPAUTH_SHARED_LIBRARY}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/tps
+)
diff --git a/base/tps/src/authentication/LDAP_Authentication.cpp b/base/tps/src/authentication/LDAP_Authentication.cpp
new file mode 100644
index 000000000..3e073dfff
--- /dev/null
+++ b/base/tps/src/authentication/LDAP_Authentication.cpp
@@ -0,0 +1,424 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "engine/RA.h"
+#include "ldap.h"
+#include "authentication/LDAP_Authentication.h"
+#include "authentication/Authentication.h"
+#include "main/Memory.h"
+#include "main/Util.h"
+
+/**
+ * Constructs a base processor.
+ */
+LDAP_Authentication::LDAP_Authentication ()
+{
+ m_hostport = NULL;
+ m_baseDN = NULL;
+ m_connInfo = NULL;
+ m_attributes = NULL;
+ m_ssl = NULL;
+ m_bindDN = NULL;
+ m_bindPwd = NULL;
+}
+
+/**
+ * Destructs processor.
+ */
+LDAP_Authentication::~LDAP_Authentication ()
+{
+ if( m_hostport != NULL ) {
+ PL_strfree( m_hostport );
+ m_hostport = NULL;
+ }
+
+ if( m_baseDN != NULL ) {
+ PL_strfree( m_baseDN );
+ m_baseDN = NULL;
+ }
+
+ if( m_connInfo != NULL ) {
+ delete m_connInfo;
+ m_connInfo = NULL;
+ }
+}
+
+/*
+ * Search for password name "name" in the password file "filepath"
+ */
+static char *get_pwd_from_conf(char *filepath, const char *name)
+{
+ PRFileDesc *fd;
+ char line[1024];
+ int removed_return;
+ char *val= NULL;
+
+ fd= PR_Open(filepath, PR_RDONLY, 400);
+ if (fd == NULL) {
+ return NULL;
+ }
+
+ while (1) {
+ int n = Util::ReadLine(fd, line, 1024, &removed_return);
+ if (n > 0) {
+ /* handle comment line */
+ if (line[0] == '#')
+ continue;
+ int c = 0;
+ while ((c < n) && (line[c] != ':')) {
+ c++;
+ }
+ if (c < n) {
+ line[c] = '\0';
+ } else {
+ continue; /* no ':', skip this line */
+ }
+ if (!PL_strcmp (line, name)) {
+ val = PL_strdup(&line[c+1]);
+ break;
+ }
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+ return val;
+
+}
+
+void LDAP_Authentication::Initialize(int instanceIndex) {
+ char configname[256];
+ const char *prefix="auth.instance";
+
+ m_index = instanceIndex;
+ PR_snprintf((char *)configname, 256, "%s.%d.hostport", prefix, instanceIndex);
+ m_hostport = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ PR_snprintf((char *)configname, 256, "%s.%d.SSLOn", prefix, instanceIndex);
+ m_isSSL = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+ PR_snprintf((char *)configname, 256, "%s.%d.retries", prefix, instanceIndex);
+ m_retries = RA::GetConfigStore()->GetConfigAsInt(configname, 1);
+ PR_snprintf((char *)configname, 256, "%s.%d.retryConnect", prefix, instanceIndex);
+ m_connectRetries = RA::GetConfigStore()->GetConfigAsInt(configname, 3);
+ m_connInfo = new ConnectionInfo();
+ m_connInfo->BuildFailoverList(m_hostport);
+ PR_snprintf((char *)configname, 256, "%s.%d.baseDN", prefix, instanceIndex);
+ m_baseDN = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ PR_snprintf((char *)configname, 256, "%s.%d.attributes", prefix, instanceIndex);
+ m_attributes = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ /* support of SSL */
+ PR_snprintf((char *)configname, 256, "%s.%d.ssl", prefix, instanceIndex);
+ m_ssl = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ PR_snprintf((char *)configname, 256, "%s.%d.bindDN", prefix, instanceIndex);
+ m_bindDN = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ PR_snprintf((char *)configname, 256, "%s.%d.bindPWD", prefix, instanceIndex);
+ char *m_bindPwdPath = PL_strdup(RA::GetConfigStore()->GetConfigAsString(configname));
+ m_bindPwd = get_pwd_from_conf(m_bindPwdPath, "tokendbBindPass");
+}
+
+/**
+ * @return (0:login correct) (-1:LDAP error) (-2:User not found) (-3:Password error)
+ */
+
+#define TPS_AUTH_OK 0
+#define TPS_AUTH_ERROR_LDAP -1
+#define TPS_AUTH_ERROR_USERNOTFOUND -2
+#define TPS_AUTH_ERROR_PASSWORDINCORRECT -3
+
+int LDAP_Authentication::Authenticate(AuthParams *params)
+{
+ char buffer[500];
+ char ldapuri[1024];
+ char *host = NULL;
+ char *portStr = NULL;
+ int port = 0;
+ LDAP *ld = NULL;
+ int status = TPS_AUTH_ERROR_LDAP;
+ int version = LDAP_VERSION3;
+ LDAPMessage *result = NULL, *e = NULL;
+ char *dn = NULL;
+ char *uid = NULL;
+ char *password = NULL;
+ int retries = 0;
+ int rc =0;
+
+ if (params == NULL) {
+ status = TPS_AUTH_ERROR_USERNOTFOUND;
+ goto loser;
+ }
+
+ uid = params->GetUID();
+ password = params->GetPassword();
+
+ GetHostPort(&host, &portStr);
+ port = atoi(portStr);
+
+ if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) {
+ /* handling of SSL */
+ snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port);
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", host, port);
+ }
+ status = ldap_initialize(&ld, ldapuri);
+
+ while ((ld == NULL) && (retries < m_connectRetries)) {
+ RA::IncrementAuthCurrentIndex(m_connInfo->GetHostPortListLen());
+ GetHostPort(&host, &portStr);
+ port = atoi(portStr);
+ if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) {
+ /* handling of SSL */
+ snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port);
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", host, port);
+ }
+ status = ldap_initialize(&ld, ldapuri);
+ retries++;
+ }
+
+ if (ld == NULL) {
+ status = TPS_AUTH_ERROR_LDAP;
+ goto loser;
+ }
+
+ PR_snprintf((char *)buffer, 500, "(uid=%s)", uid);
+
+ while (retries < m_connectRetries) {
+ RA::IncrementAuthCurrentIndex(m_connInfo->GetHostPortListLen());
+ GetHostPort(&host, &portStr);
+ port = atoi(portStr);
+ RA::Debug("ldap auth:"," host=%s, portstr=%s, port=%d", host, portStr, port);
+ if ((m_ssl != NULL) && (strcmp(m_ssl, "true")==0)) {
+ /* handling of SSL */
+ snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port);
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", host, port);
+ }
+ status = ldap_initialize(&ld, ldapuri);
+
+ if (ld == NULL) {
+ RA::Debug("LDAP_Authentication::Authenticate:", "ld null. Trying failover...");
+ retries++;
+ continue;
+ }
+
+ if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) {
+ status = TPS_AUTH_ERROR_LDAP;
+ goto loser;
+ }
+
+ if (m_bindDN != NULL && strlen(m_bindDN) > 0) {
+ RA::Debug("LDAP_Authentication::Authenticate", "Simple bind required '%s'", m_bindDN);
+ struct berval credential;
+ credential.bv_val = m_bindPwd;
+ credential.bv_len= strlen(m_bindPwd);
+ rc = ldap_sasl_bind_s(ld, m_bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ }
+
+ int ldap_status = LDAP_OTHER;
+ if ((ldap_status = ldap_search_ext_s(ld, m_baseDN, LDAP_SCOPE_SUBTREE, buffer, NULL, 0, NULL, NULL, NULL, 0, &result)) != LDAP_SUCCESS) {
+ if (ldap_status != LDAP_NO_SUCH_OBJECT) {
+ RA::Debug("LDAP_Authentication::Authenticate:", "LDAP_UNAVAILABLE. Trying failover...");
+ retries++;
+ continue; // do failover
+ }
+ status = TPS_AUTH_ERROR_USERNOTFOUND;
+ } else {
+ for (e = ldap_first_entry(ld, result); e != NULL; e = ldap_next_entry(ld, e)) {
+ if ((dn = ldap_get_dn(ld, e)) != NULL) {
+ RA::Debug("LDAP_Authentication::Authenticate", "User bind required '%s' '(sensitive)'", dn );
+ struct berval credential;
+ credential.bv_val = password;
+ credential.bv_len= strlen(password);
+ rc = ldap_sasl_bind_s(ld, dn, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc == LDAP_SUCCESS) {
+ /* retrieve attributes and, */
+ /* put them into the auth parameters */
+ if (m_attributes != NULL) {
+ RA::Debug("LDAP_Authentication::Authenticate", "Attributes %s", m_attributes);
+ char *m_dup_attributes = strdup(m_attributes);
+ char *token = NULL;
+ token = strtok(m_dup_attributes, ",");
+ while( token != NULL ) {
+ struct berval **v = NULL;
+ v = ldap_get_values_len(ld, e, token);
+ if ((v != NULL) && (v[0]!= NULL) && (v[0]->bv_val != NULL)) {
+ RA::Debug("LDAP_Authentication::Authenticate", "Exposed %s=%s", token, v[0]->bv_val);
+ params->Add(token, PL_strdup(v[0]->bv_val));
+ RA::Debug("LDAP_Authentication::Authenticate", "Size %d", params->Size());
+ }
+ token = strtok( NULL, "," );
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+
+ }
+ free(m_dup_attributes);
+ }
+ status = TPS_AUTH_OK; // SUCCESS - PASSWORD VERIFIED
+ } else {
+ status = TPS_AUTH_ERROR_PASSWORDINCORRECT;
+ goto loser;
+ }
+ } else {
+ status = TPS_AUTH_ERROR_USERNOTFOUND;
+ goto loser;
+ }
+ }
+ RA::Debug("LDAP_Authentication::Authenticate:", " authentication completed for %s",uid);
+ break;
+ }
+ } //while
+
+ if (dn == NULL) {
+ status = TPS_AUTH_ERROR_USERNOTFOUND;
+ goto loser;
+ }
+
+loser:
+
+ if (result != NULL) {
+ ldap_msgfree(result);
+ }
+
+ if (dn != NULL) {
+ ldap_memfree(dn);
+ }
+
+ if (ld != NULL) {
+ ldap_unbind_ext_s(ld, NULL, NULL);
+ ld = NULL;
+ }
+ return status;
+}
+
+void LDAP_Authentication::GetHostPort(char **p, char **q) {
+ int num=0;
+ int auth_curr = RA::GetAuthCurrentIndex();
+ char *hp = (m_connInfo->GetHostPortList())[auth_curr];
+ char *host_port = PL_strdup(hp);
+
+ char *lasts = NULL;
+ char *tok = PL_strtok_r((char *)host_port, ":", &lasts);
+ while (tok != NULL) {
+ if (num == 0)
+ *p = PL_strdup(tok);
+ else
+ *q = PL_strdup(tok);
+ tok = PL_strtok_r(NULL, ":", &lasts);
+ num++;
+ }
+
+ PR_Free(host_port);
+}
+
+bool LDAP_Authentication::IsSSL() {
+ return m_isSSL;
+}
+
+char *LDAP_Authentication::GetHostPort() {
+ return m_hostport;
+}
+
+Authentication *GetAuthentication() {
+ LDAP_Authentication *auth = new LDAP_Authentication();
+ return (Authentication *)auth;
+}
+
+const char *LDAP_Authentication::GetTitle(char *locale)
+{
+ char configname[256];
+ const char *prefix="auth.instance";
+ PR_snprintf((char *)configname, 256, "%s.%d.ui.title.%s",
+ prefix, m_index, locale);
+RA::Debug("LDAP_Authentication::GetTitle", "%s", configname);
+ return RA::GetConfigStore()->GetConfigAsString(configname);
+}
+
+const char *LDAP_Authentication::GetDescription(char *locale)
+{
+ char configname[256];
+ const char *prefix="auth.instance";
+ PR_snprintf((char *)configname, 256, "%s.%d.ui.description.%s",
+ prefix, m_index, locale);
+RA::Debug("LDAP_Authentication::GetDescription", "%s", configname);
+RA::Debug("LDAP_Authentication::GetDescription", "%s", RA::GetConfigStore()->GetConfigAsString(configname));
+ return RA::GetConfigStore()->GetConfigAsString(configname);
+}
+
+int LDAP_Authentication::GetNumOfParamNames()
+{
+ return 2;
+}
+
+char *LDAP_Authentication::GetParamID(int index)
+{
+ if (index == 0)
+ return ( char * ) "UID";
+ else if (index == 1)
+ return ( char * ) "PASSWORD";
+ else
+ return NULL;
+}
+
+const char *LDAP_Authentication::GetParamName(int index, char *locale)
+{
+ char configname[256];
+ const char *prefix="auth.instance";
+ PR_snprintf((char *)configname, 256, "%s.%d.ui.id.%s.name.%s",
+ prefix, m_index, GetParamID(index), locale);
+
+RA::Debug("LDAP_Authentication::GetParamName", "%s", configname);
+
+ return RA::GetConfigStore()->GetConfigAsString(configname);
+}
+
+char *LDAP_Authentication::GetParamType(int index)
+{
+ if (index == 0)
+ return ( char * ) "string";
+ else if (index == 1)
+ return ( char * ) "password";
+ else
+ return NULL;
+}
+
+const char *LDAP_Authentication::GetParamDescription(int index, char *locale)
+{
+ char configname[256];
+ const char *prefix="auth.instance";
+ PR_snprintf((char *)configname, 256, "%s.%d.ui.id.%s.description.%s",
+ prefix, m_index, GetParamID(index), locale);
+ return RA::GetConfigStore()->GetConfigAsString(configname);
+}
+
+char *LDAP_Authentication::GetParamOption(int index)
+{
+ return ( char * ) "";
+}
+
diff --git a/base/tps/src/channel/Channel.cpp b/base/tps/src/channel/Channel.cpp
new file mode 100644
index 000000000..6b77d3a19
--- /dev/null
+++ b/base/tps/src/channel/Channel.cpp
@@ -0,0 +1,69 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+#include "channel/Channel.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "apdu/Delete_File_APDU.h"
+#include "apdu/Load_File_APDU.h"
+#include "apdu/Install_Applet_APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/APDU_Response.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a secure channel between the RA and the
+ * token key directly.
+ */
+Channel::Channel()
+{
+} /* Channel */
+
+/**
+ * Destroys this secure channel.
+ */
+Channel::~Channel ()
+{
+} /* ~Channel */
+
+/**
+ * Closes secure channel.
+ */
+int Channel::Close()
+{
+ /* currently do not have anything to terminate here */
+ return 1;
+}
diff --git a/base/tps/src/channel/Secure_Channel.cpp b/base/tps/src/channel/Secure_Channel.cpp
new file mode 100644
index 000000000..50b24ae99
--- /dev/null
+++ b/base/tps/src/channel/Secure_Channel.cpp
@@ -0,0 +1,2550 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+#include "channel/Secure_Channel.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "apdu/Set_IssuerInfo_APDU.h"
+#include "apdu/Get_IssuerInfo_APDU.h"
+#include "apdu/Import_Key_APDU.h"
+#include "apdu/Import_Key_Enc_APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "apdu/Read_Object_APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "apdu/Delete_File_APDU.h"
+#include "apdu/Load_File_APDU.h"
+#include "apdu/Install_Applet_APDU.h"
+#include "apdu/Install_Load_APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/APDU_Response.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a secure channel between the RA and the
+ * token key directly. APDUs that are sent via this channel
+ * will be mac'ed using the session key calculated by
+ * TKS which maintains all the user keys.
+ */
+
+Secure_Channel::Secure_Channel(RA_Session *session, PK11SymKey *session_key,
+ PK11SymKey *enc_session_key,
+ char *drm_des_key_s,
+ char *kek_des_key_s, char *keycheck_s,
+ Buffer &key_diversification_data, Buffer &key_info_data,
+ Buffer &card_challenge, Buffer &card_cryptogram,
+ Buffer &host_challenge, Buffer &host_cryptogram)
+{
+ m_icv = Buffer(8,(BYTE)0);
+ m_session = session;
+ m_session_key = session_key;
+ m_enc_session_key = enc_session_key;
+ m_drm_wrapped_des_key_s = drm_des_key_s;
+ m_kek_wrapped_des_key_s = kek_des_key_s;
+ m_keycheck_s = keycheck_s;
+ m_key_diversification_data = key_diversification_data;
+ m_key_info_data = key_info_data;
+ m_card_challenge = card_challenge;
+ m_card_cryptogram = card_cryptogram;
+ m_host_challenge = host_challenge;
+ m_host_cryptogram = host_cryptogram;
+} /* Secure_Channel */
+
+/**
+ * Destroys this secure channel.
+ */
+Secure_Channel::~Secure_Channel ()
+{
+ /* m_session (RA_Session) should not be destroyed at this level. */
+ if( m_session_key != NULL ) {
+ PK11_FreeSymKey( m_session_key );
+ m_session_key = NULL;
+ }
+ if( m_enc_session_key != NULL ) {
+ PK11_FreeSymKey( m_enc_session_key );
+ m_enc_session_key = NULL;
+ }
+ if (m_drm_wrapped_des_key_s != NULL) {
+ PR_Free(m_drm_wrapped_des_key_s);
+ m_drm_wrapped_des_key_s = NULL;
+ }
+ if (m_kek_wrapped_des_key_s != NULL) {
+ PR_Free(m_kek_wrapped_des_key_s);
+ m_kek_wrapped_des_key_s = NULL;
+ }
+ if (m_keycheck_s != NULL) {
+ PR_Free(m_keycheck_s);
+ m_keycheck_s = NULL;
+ }
+} /* ~Secure_Channel */
+
+/**
+ * Closes secure channel.
+ */
+int Secure_Channel::Close()
+{
+ /* currently do not have anything to terminate here */
+ return 1;
+}
+
+/*
+ * to be called by all token request types
+ * it resets m_data if security level is to do encryption
+ */
+int Secure_Channel::ComputeAPDU(APDU *apdu)
+{
+ int rc = -1;
+ Buffer *mac = NULL;
+
+ if (apdu == NULL) {
+ goto loser;
+ }
+ RA::Debug(LL_PER_PDU, "Secure_Channel::ComputeAPDU", "apdu type = %d",
+ apdu->GetType());
+
+ mac = ComputeAPDUMac(apdu);
+ if (mac == NULL)
+ goto loser;
+
+ if (m_security_level == SECURE_MSG_MAC_ENC) {
+ PRStatus status = apdu->SecureMessage(m_enc_session_key);
+ if (status == PR_FAILURE) {
+ goto loser;
+ }
+ }
+
+ rc = 1;
+ loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Calculates MAC for the given APDU.
+ */
+Buffer *Secure_Channel::ComputeAPDUMac(APDU *apdu)
+{
+ Buffer data;
+ Buffer *mac = new Buffer(8, (BYTE)0);
+
+ if (apdu == NULL) {
+ RA::Error("Secure_Channel::ComputeAPDUMac", "apdu NULL");
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ return NULL;
+ }
+ apdu->GetDataToMAC(data);
+
+ // developer debugging only - not for deployment
+ // RA::DebugBuffer("Secure_Channel::ComputeAPDUMac", "Data To MAC'ed",
+ // &data);
+
+ // Compute MAC will padd the data if it is
+ // not in 8 byte multiples
+ Util::ComputeMAC(m_session_key, data, m_icv, *mac);
+ apdu->SetMAC(*mac);
+ m_icv = *mac;
+
+ return mac;
+} /* EncodeAPDUMac */
+
+/**
+ * Sends the token an external authenticate APDU.
+ */
+int Secure_Channel::ExternalAuthenticate()
+{
+ int rc = -1;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ External_Authenticate_APDU *external_auth_apdu = NULL;
+ APDU_Response *response = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::ExternalAuthenticate",
+ "Secure_Channel::ExternalAuthenticate");
+
+ // This command is very strange
+ external_auth_apdu =
+ new External_Authenticate_APDU(m_host_cryptogram, m_security_level);
+
+ // Need to update APDU length to include 8-bytes MAC
+ // before mac'ing the data
+ mac = ComputeAPDUMac(external_auth_apdu);
+ external_auth_apdu->SetMAC(*mac);
+
+ token_pdu_request_msg =
+ new RA_Token_PDU_Request_Msg(external_auth_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ExternalAuthenticate",
+ "Sent external_auth_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ExternalAuthenticate",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::ExternalAuthenticate",
+ "Invalid Msg Type");
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ExternalAuthenticate",
+ "No Response From Token");
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ExternalAuthenticate",
+ "Invalid Response From Token");
+ goto loser;
+ }
+
+ // must return 0x90 0x00
+ if (!(response->GetSW1() == 0x90 && response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ExternalAuthenticate",
+ "Bad Response %x %x", response->GetSW1(), response->GetSW2());
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ExternalAuthenticate */
+
+int Secure_Channel::DeleteFileX(RA_Session *session, Buffer *aid)
+{
+ int rc = 0;
+ APDU_Response *delete_response = NULL;
+ RA_Token_PDU_Request_Msg *delete_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *delete_response_msg = NULL;
+ Delete_File_APDU *delete_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug("RA_Processor::DeleteFile",
+ "RA_Processor::DeleteFile");
+
+ delete_apdu = new Delete_File_APDU(*aid);
+ rc = ComputeAPDU(delete_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(delete_apdu);
+ delete_apdu->SetMAC(*mac);
+ */
+ delete_request_msg =
+ new RA_Token_PDU_Request_Msg(delete_apdu);
+ session->WriteMsg(delete_request_msg);
+
+ RA::Debug("RA_Processor::DeleteFile",
+ "Sent delete_request_msg");
+
+ delete_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (delete_response_msg == NULL)
+ {
+ RA::Error("RA_Processor::DeleteFile",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (delete_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::DeleteFile",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ delete_response = delete_response_msg->GetResponse();
+ if (delete_response == NULL) {
+ RA::Error("Secure_Channel::DeleteFile",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (delete_response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::DeleteFile",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (!(delete_response->GetSW1() == 0x90 &&
+ delete_response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::DeleteFile",
+ "Bad Response %x %x", delete_response->GetSW1(),
+ delete_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+
+loser:
+ if( delete_request_msg != NULL ) {
+ delete delete_request_msg;
+ delete_request_msg = NULL;
+ }
+ if( delete_response_msg != NULL ) {
+ delete delete_response_msg;
+ delete_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+int Secure_Channel::InstallLoad(RA_Session *session,
+ Buffer& packageAID, Buffer& sdAID, unsigned int fileLen)
+{
+ int rc = 0;
+ APDU_Response *install_response = NULL;
+ RA_Token_PDU_Request_Msg *install_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *install_response_msg = NULL;
+ Install_Load_APDU *install_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug("RA_Processor::InstallLoad",
+ "RA_Processor::InstallLoad");
+
+ install_apdu = new Install_Load_APDU(packageAID, sdAID, fileLen);
+ rc = ComputeAPDU(install_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(install_apdu);
+ install_apdu->SetMAC(*mac);
+ */
+ install_request_msg =
+ new RA_Token_PDU_Request_Msg(install_apdu);
+ session->WriteMsg(install_request_msg);
+
+ RA::Debug("RA_Processor::InstallLoad",
+ "Sent install_request_msg");
+
+ install_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (install_response_msg == NULL)
+ {
+ RA::Error("RA_Processor::InstallLoad",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (install_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::InstallLoad",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ install_response = install_response_msg->GetResponse();
+ if (install_response == NULL) {
+ RA::Error("Secure_Channel::InstallLoad",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (install_response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::InstallLoad",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (!(install_response->GetSW1() == 0x90 &&
+ install_response->GetSW2() == 0x00)) {
+ RA::Error("Secure_Channel::InstallLoad",
+ "Error Response from token %2x%2x",
+ install_response->GetSW1(),
+ install_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+
+loser:
+ if( install_request_msg != NULL ) {
+ delete install_request_msg;
+ install_request_msg = NULL;
+ }
+ if( install_response_msg != NULL ) {
+ delete install_response_msg;
+ install_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+int Secure_Channel::InstallApplet(RA_Session *session,
+ Buffer &packageAID, Buffer &appletAID,
+ BYTE appPrivileges, unsigned int instanceSize, unsigned int appletMemorySize)
+{
+ int rc = 0;
+ APDU_Response *install_response = NULL;
+ RA_Token_PDU_Request_Msg *install_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *install_response_msg = NULL;
+ Install_Applet_APDU *install_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug("RA_Processor::InstallApplet",
+ "RA_Processor::InstallApplet");
+
+ install_apdu = new Install_Applet_APDU(packageAID, appletAID, appPrivileges,
+ instanceSize, appletMemorySize );
+ rc = ComputeAPDU(install_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(install_apdu);
+ install_apdu->SetMAC(*mac);
+ */
+ install_request_msg =
+ new RA_Token_PDU_Request_Msg(install_apdu);
+ session->WriteMsg(install_request_msg);
+
+ RA::Debug("RA_Processor::InstallApplet",
+ "Sent install_request_msg");
+
+ install_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (install_response_msg == NULL)
+ {
+ RA::Error("RA_Processor::InstallApplet",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (install_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::InstallApplet",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ install_response = install_response_msg->GetResponse();
+ if (install_response == NULL) {
+ RA::Error("Secure_Channel::InstallApplet",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (install_response->GetData().size() < 2) {
+ RA::Debug("Secure_Channel::InstallApplet",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (!(install_response->GetSW1() == 0x90 &&
+ install_response->GetSW2() == 0x00)) {
+ RA::Error("Secure_Channel::InstallApplet",
+ "Error Response from Token %2x%2x",
+ install_response->GetSW1(),
+ install_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+
+loser:
+ if( install_request_msg != NULL ) {
+ delete install_request_msg;
+ install_request_msg = NULL;
+ }
+ if( install_response_msg != NULL ) {
+ delete install_response_msg;
+ install_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+int Secure_Channel::LoadFile(RA_Session *session, BYTE refControl, BYTE blockNum,
+ Buffer *data)
+{
+ int rc = 0;
+ APDU_Response *load_file_response = NULL;
+ RA_Token_PDU_Request_Msg *load_file_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *load_file_response_msg = NULL;
+ Load_File_APDU *load_file_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::LoadFile",
+ "begin LoadFile");
+
+ load_file_apdu = new Load_File_APDU(refControl, blockNum, *data);
+
+ rc = ComputeAPDU(load_file_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(load_file_apdu);
+ load_file_apdu->SetMAC(*mac);
+ */
+ load_file_request_msg =
+ new RA_Token_PDU_Request_Msg(load_file_apdu);
+
+ session->WriteMsg(load_file_request_msg);
+
+ RA::Debug("RA_Processor::LoadFile",
+ "Sent load_file_request_msg");
+
+ load_file_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (load_file_response_msg == NULL)
+ {
+ RA::Error("RA_Processor::LoadFile",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (load_file_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::LoadFile",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ load_file_response = load_file_response_msg->GetResponse();
+ if (load_file_response == NULL) {
+ RA::Error("Secure_Channel::LoadFile",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (load_file_response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::LoadFile",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(load_file_response->GetSW1() == 0x90 &&
+ load_file_response->GetSW2() == 0x00)) {
+ RA::Error("Secure_Channel::LoadFile",
+ "Error Response from Token %2x%2x",
+ load_file_response->GetSW1(),
+ load_file_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+
+loser:
+ if( load_file_request_msg != NULL ) {
+ delete load_file_request_msg;
+ load_file_request_msg = NULL;
+ }
+ if( load_file_response_msg != NULL ) {
+ delete load_file_response_msg;
+ load_file_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+int Secure_Channel::IsPinPresent(BYTE pin_number)
+{
+ int rc = -1;
+ List_Pins_APDU *list_pins_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Secure_Channel::IsPinPresent");
+ list_pins_apdu = new List_Pins_APDU(2);
+ list_pins_apdu = (List_Pins_APDU *) ComputeAPDU(list_pins_apdu);
+
+ /*
+ mac = ComputeAPDUMac(set_pin_apdu);
+ set_pin_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ list_pins_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::IsPinReset",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::IsPinReset",
+ "Invalid Msg Type");
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::IsPinReset",
+ "No Response From Token");
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Get Issuer Info
+ */
+Buffer Secure_Channel::GetIssuerInfo()
+{
+ Buffer data;
+ int rc = -1;
+ Get_IssuerInfo_APDU *get_issuerinfo_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+
+ RA::Debug("Secure_Channel::GetIssuerInfo",
+ "Secure_Channel::GetIssuerInfo");
+ get_issuerinfo_apdu = new Get_IssuerInfo_APDU();
+ rc = ComputeAPDU(get_issuerinfo_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ get_issuerinfo_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::GetIssuerInfo",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::GetIssuerInfo",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::GetIssuerInfo",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::GetIssuerInfo",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::GetIssuerInfo",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::GetIssuerInfo",
+ "Bad Response");
+ rc = -1;
+ goto loser;
+ }
+
+ data = response->GetData();
+ rc = 1;
+loser:
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return data;
+} /* SetIssuerInfo */
+/**
+ * Set Issuer Info
+ */
+int Secure_Channel::SetIssuerInfo(Buffer *info)
+{
+ int rc = -1;
+ Set_IssuerInfo_APDU *set_issuerinfo_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+
+ RA::Debug("Secure_Channel::SetIssuerInfo",
+ "Secure_Channel::SetIssuerInfo");
+ set_issuerinfo_apdu = new Set_IssuerInfo_APDU(0x0, 0x0, *info);
+ rc = ComputeAPDU(set_issuerinfo_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ set_issuerinfo_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::SetIssuerInfo",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::SetIssuerInfo",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::SetIssuerInfo",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::SetIssuerInfo",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::SetIssuerInfo",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::SetIssuerInfo",
+ "Bad Response");
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* SetIssuerInfo */
+
+/**
+ * Resets token's pin.
+ */
+int Secure_Channel::ResetPin(BYTE pin_number, char *new_pin)
+{
+ int rc = -1;
+ Set_Pin_APDU *set_pin_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+
+ RA::Debug("Secure_Channel::ResetPin",
+ "Secure_Channel::ResetPin");
+ Buffer data = Buffer((BYTE *)new_pin, strlen(new_pin));
+ set_pin_apdu = new Set_Pin_APDU(0x0, 0x0, data);
+ rc = ComputeAPDU(set_pin_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ set_pin_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ResetPin",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ResetPin",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::ResetPin",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ResetPin",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ResetPin",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ResetPin",
+ "Bad Response");
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ResetPin */
+
+/**
+ * inject key (public key, mostly)
+ * @param key_number key slot number (from config file)
+ */
+int Secure_Channel::ImportKey(BYTE key_number)
+{
+ int rc = -1;
+ Import_Key_APDU *import_key_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::ImportKey",
+ "Secure_Channel::ImportKey");
+
+ import_key_apdu = new Import_Key_APDU(key_number);
+ rc = ComputeAPDU(import_key_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ /*
+ mac = ComputeAPDUMac(import_key_apdu);
+ import_key_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ import_key_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ImportKey",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ImportKey",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::ImportKey",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ImportKey",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ImportKey",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ImportKey",
+ "Error Response from Token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ImportKey */
+
+/**
+ * inject an encrypted key (private key, mostly)
+ * @param key_number key slot number (from config file)
+ */
+int Secure_Channel::ImportKeyEnc(BYTE priv_key_number, BYTE pub_key_number, Buffer* data)
+{
+ int rc = -1;
+ Import_Key_Enc_APDU *import_key_enc_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+ BYTE objid[4];
+
+ objid[0] = 0xFF;
+ objid[1] = 0xFF;
+ objid[2] = 0xFF;
+ objid[3] = 0xFE;
+
+
+ RA::Debug("Secure_Channel::ImportKeyEnc",
+ "Secure_Channel::ImportKeyEnc");
+
+ import_key_enc_apdu = new Import_Key_Enc_APDU(priv_key_number, pub_key_number, *data);
+ rc = ComputeAPDU(import_key_enc_apdu);
+ if (rc == -1) {
+ goto loser;
+ }
+
+ /*
+ mac = ComputeAPDUMac(import_key_enc_apdu);
+ import_key_enc_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ import_key_enc_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ImportKeyEnc",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ImportKeyEnc",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::ImportKeyEnc",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ImportKeyEnc",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ImportKeyEnc",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ImportKeyEnc",
+ "Error Response from Token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ /*XXX debuging
+ debugBuf = ReadObject((BYTE*)objid, 0, 16);
+ if (debugBuf != NULL)
+ RA::DebugBuffer("Secure_Channel::ImportKeyEnc(): Error:", "debugBuf=",
+ debugBuf);
+ else
+ RA::Debug("Secure_Channel::ImportKeyEnc(): Error:", "ReadObject for debugging returns none");
+ */
+ rc = -1;
+ goto loser;
+ }
+
+ /* XXX debugging
+ debugBuf = ReadObject((BYTE*)objid, 0, 200);
+ if (debugBuf != NULL)
+ RA::DebugBuffer("Secure_Channel::ImportKeyEnc(): Success:", "debugBuf=",
+ debugBuf);
+ else
+ RA::Debug("Secure_Channel::ImportKeyEnc(): Sucess:", "ReadObject for debugging returns none");
+
+ */
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ImportKeyEnc */
+
+
+/**
+ * Put Keys
+ *
+ * Global Platform Open Platform Card Specification
+ * Version 2.0.1 Page 9-19
+ * Sample Data:
+ *
+ * _____________ CLA
+ * | __________ INS
+ * | | _______ P1
+ * | | | ____ P2
+ * | | | | _ Len
+ * | | | | |
+ * 84 D8 00 81 4B
+ * 01
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (AUTH KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (MAC KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (KEK KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 5E B8 64 3F 73 9D 7D 62
+ *
+ * Data:
+ *
+ * - New key set version
+ * - key set data field (implicit key index P2+0)
+ * - key set data field (implicit key index P2+1)
+ * - key set data field (implicit key index P2+2)
+ *
+ * Key Set Data:
+ *
+ * Length Meaning
+ * ====== =========
+ * 1 Algorithm ID of key
+ * 1-n Length of key
+ * variable Key data value
+ * 0-n Length of Key check value
+ * variable Key check value (if present)
+ */
+int Secure_Channel::PutKeys(RA_Session *session, BYTE key_version,
+ BYTE key_index, Buffer *key_data)
+{
+ int rc = 0;
+ APDU_Response *put_key_response = NULL;
+ RA_Token_PDU_Request_Msg *put_key_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *put_key_response_msg = NULL;
+ Put_Key_APDU *put_key_apdu = NULL;
+ // Buffer *mac = NULL;
+ const char *FN="Secure_Channel::PutKeys";
+
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "RA_Processor::PutKey");
+
+ //For certain keys that require the implicit keyset
+ //00 00
+ //
+ if(key_version == 0xFF)
+ key_version = 0;
+
+ put_key_apdu = new Put_Key_APDU(key_version, 0x80 | key_index,
+ *key_data);
+ rc = ComputeAPDU(put_key_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(put_key_apdu);
+ put_key_apdu->SetMAC(*mac);
+ */
+ put_key_request_msg =
+ new RA_Token_PDU_Request_Msg(put_key_apdu);
+ session->WriteMsg(put_key_request_msg);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "Sent put_key_request_msg");
+
+ put_key_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (put_key_response_msg == NULL)
+ {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (put_key_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ put_key_response =
+ put_key_response_msg->GetResponse();
+ if (put_key_response == NULL) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (put_key_response->GetData().size() < 2) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(put_key_response->GetSW1() == 0x90 &&
+ put_key_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Error Response %2x%2x",
+ put_key_response->GetSW1(),
+ put_key_response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ /* check error */
+ rc = 0;
+
+loser:
+ if( put_key_request_msg != NULL ) {
+ delete put_key_request_msg;
+ put_key_request_msg = NULL;
+ }
+ if( put_key_response_msg != NULL ) {
+ delete put_key_response_msg;
+ put_key_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Sets token's lifecycle state.
+ */
+int Secure_Channel::SetLifecycleState(BYTE flag)
+{
+ int rc = -1;
+ Lifecycle_APDU *lifecycle_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+ const char *FN = "Secure_Channel::SetLifecycleState";
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Begin");
+ lifecycle_apdu = new Lifecycle_APDU(flag);
+ rc = ComputeAPDU(lifecycle_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(lifecycle_apdu);
+ lifecycle_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ lifecycle_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE)
+ {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Invalid Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Error Response from token: %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 0;
+
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* SetLifecycleState */
+
+
+char * Secure_Channel::getDrmWrappedDESKey()
+{
+ return PL_strdup(m_drm_wrapped_des_key_s);
+}
+
+char * Secure_Channel::getKekWrappedDESKey()
+{
+ return PL_strdup(m_kek_wrapped_des_key_s);
+}
+
+char * Secure_Channel::getKeycheck()
+{
+ return PL_strdup(m_keycheck_s);
+}
+
+
+/**
+ * Requests token to generate key in buffer.
+ */
+int Secure_Channel::StartEnrollment(BYTE p1, BYTE p2, Buffer *wrapped_challenge,
+ Buffer *key_check, BYTE alg, int keysize, BYTE option)
+{
+ int rc = -1;
+ Generate_Key_APDU *generate_key_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+ Buffer data;
+
+ RA::Debug("Secure_Channel::GenerateKey",
+ "Secure_Channel::GenerateKey");
+ generate_key_apdu = new Generate_Key_APDU(p1, p2, alg, keysize, option,
+ alg, *wrapped_challenge, *key_check);
+ rc = ComputeAPDU(generate_key_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(generate_key_apdu);
+ generate_key_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ generate_key_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::GenerateKey",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::GenerateKey",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE)
+ {
+ RA::Error("Secure_Channel::GenerateKey",
+ "Invalid Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("SecureChannel::GenerateKey", "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ data = response->GetData();
+ if (data.size() != 4) {
+ RA::Error("SecureChannel::GenerateKey", "Token returned error");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::GenerateKey",
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ /* key length */
+ rc = ((BYTE*)data)[0] * 256 + ((BYTE*)data)[1];
+
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* GenerateKey */
+
+/**
+ * Reads data from token's buffer.
+ */
+int Secure_Channel::ReadBuffer(BYTE *buf, int buf_len)
+{
+ int rc = -1;
+ Read_Buffer_APDU *read_buffer_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ int offset = 0;
+ int wanted = buf_len;
+ int received = 0;
+ int request = 0;
+ int data_len;
+ Buffer data;
+ Buffer *mac = NULL;
+ const char *FN="Secure_Channel::ReadBuffer";
+
+#define MAX_READ_BUFFER_SIZE 0xd0
+ RA::Debug("Secure_Channel::ReadBuffer",
+ "Secure_Channel::ReadBuffer");
+
+ while (1)
+ {
+ if (wanted > MAX_READ_BUFFER_SIZE)
+ {
+ request = MAX_READ_BUFFER_SIZE;
+ }
+ else
+ {
+ request = wanted;
+ }
+ read_buffer_apdu = new Read_Buffer_APDU(request,offset);
+ rc = ComputeAPDU(read_buffer_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(read_buffer_apdu);
+ read_buffer_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ read_buffer_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL)
+ {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+ data = response->GetData();
+ data_len = data.size() - 2;
+ if (data_len == 0)
+ {
+ break;
+ }
+
+// copy data into buffer
+ for (int i = 0; i < data_len; i++)
+ {
+ buf[offset+i] = ((BYTE*)data)[i];
+ }
+
+ received += data_len;
+ wanted -= data_len;
+ offset += data_len;
+
+ if (wanted == 0)
+ {
+ break;
+ }
+
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+ };
+
+ rc = received;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* ReadBuffer */
+
+/**
+ * Writes object to token.
+ */
+int Secure_Channel::CreateObject(BYTE *object_id, BYTE *permissions, int len)
+{
+ int rc = -1;
+ Create_Object_APDU *create_obj_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::CreateObject",
+ "Secure_Channel::CreateObject");
+ create_obj_apdu = new Create_Object_APDU(object_id, permissions, len);
+ rc = ComputeAPDU(create_obj_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(create_obj_apdu);
+ create_obj_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ create_obj_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::CreateObject",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::CreateObject",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::CreateObject",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::CreateObject",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::CreateObject",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::CreateObject",
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+} /* CreateObject */
+
+Buffer *Secure_Channel::ReadObject(BYTE *object_id, int offset, int len)
+{
+ int rc = -1;
+ Buffer data;
+ Read_Object_APDU *read_obj_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+ Buffer *buf = NULL;
+ Buffer result = Buffer();
+
+ RA::Debug("Secure_Channel::ReadObject",
+ "Secure_Channel::ReadObject");
+ int cur_read = 0;
+ int cur_offset = 0;
+ int sum = 0;
+
+#define MAX_READ_BUFFER_SIZE 0xd0
+
+ if (len > MAX_READ_BUFFER_SIZE) {
+ cur_offset = offset;
+ cur_read = MAX_READ_BUFFER_SIZE;
+ } else {
+ cur_offset = offset;
+ cur_read = len;
+ }
+
+ while (sum < len) {
+
+ read_obj_apdu = new Read_Object_APDU(object_id, cur_offset, cur_read);
+ rc = ComputeAPDU(read_obj_apdu);
+ if (rc == -1)
+ goto loser;
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ read_obj_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::ReadObject",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::ReadObject",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE)
+ {
+ RA::Error("Secure_Channel::ReadObject",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::ReadObject",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ if (response->GetData().size() < 2) {
+ RA::Error("Secure_Channel::ReadObject",
+ "Invalid Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::ReadObject",
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+ data = response->GetData();
+ result += Buffer(data.substr(0, data.size() - 2));
+
+ sum += (data.size() - 2);
+ cur_offset += (data.size() - 2);
+
+ if ((len - sum) < MAX_READ_BUFFER_SIZE) {
+ cur_read = len - sum;
+ } else {
+ cur_read = MAX_READ_BUFFER_SIZE;
+ }
+ if (token_pdu_request_msg != NULL) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if (token_pdu_response_msg != NULL) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ }
+
+ buf = new Buffer((BYTE*)result, result.size());
+
+loser:
+ if (mac != NULL)
+ delete mac;
+ if (token_pdu_request_msg != NULL)
+ delete token_pdu_request_msg;
+ if (token_pdu_response_msg != NULL)
+ delete token_pdu_response_msg;
+
+ return buf;
+}
+
+/**
+ * Writes data to token's buffer.
+ */
+int Secure_Channel::WriteObject(BYTE *objid, BYTE *buf, int buf_len)
+{
+ int rc = -1;
+ int i;
+ Write_Object_APDU *write_buffer_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ int offset = 0;
+ int len = 0;
+ int to_send = buf_len;
+ BYTE *data = buf;
+#define MAX_WRITE_BUFFER_SIZE 0xd0
+ Buffer *send_buf = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::WriteObject",
+ "Secure_Channel::WriteObject");
+ while (1)
+ {
+ send_buf = new Buffer(MAX_WRITE_BUFFER_SIZE, (BYTE)0);
+ mac = new Buffer(8, (BYTE)0);
+
+ if (to_send > MAX_WRITE_BUFFER_SIZE)
+ {
+ len = MAX_WRITE_BUFFER_SIZE;
+ }
+ else
+ {
+ len = to_send;
+ }
+ RA::Debug("Secure_Channel::WriteObject",
+ "Sent total=%d len=%d", buf_len, len);
+
+ for (i = 0; i < len; i++)
+ {
+ ((BYTE*)*send_buf)[i] = ((BYTE*)data)[i];
+ }
+ Buffer x_buf = Buffer(*send_buf, len);
+
+ write_buffer_apdu = new Write_Object_APDU(objid, offset, x_buf);
+ rc = ComputeAPDU(write_buffer_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(write_buffer_apdu);
+ write_buffer_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ write_buffer_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::WriteObject",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::WriteObject",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::WriteObject",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::WriteObject",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ RA::Error("RA_Processor::WriteObject",
+ "Error Response from token %2x%2x",
+ response->GetSW1(),
+ response->GetSW2());
+ rc = -1;
+ goto loser;
+ }
+ data += len;
+ to_send -= len;
+ offset += len;
+
+ if (to_send == 0)
+ break; /* done */
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+ if( send_buf != NULL ) {
+ delete send_buf;
+ send_buf = NULL;
+ }
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+ if( send_buf != NULL ) {
+ delete send_buf;
+ send_buf = NULL;
+ }
+
+ return rc;
+} /* WriteObject */
+
+int Secure_Channel::CreatePin(BYTE pin_number,
+ BYTE max_retries, const char *pin)
+{
+ int rc = -1;
+ Create_Pin_APDU *create_pin_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::CreatePin",
+ "Secure_Channel::CreatePin");
+ Buffer pin_buffer = Buffer((BYTE*)pin, strlen(pin));
+ create_pin_apdu = new Create_Pin_APDU(pin_number, max_retries,
+ pin_buffer);
+ rc = ComputeAPDU(create_pin_apdu);
+ if (rc == -1)
+ goto loser;
+
+ /*
+ mac = ComputeAPDUMac(set_pin_apdu);
+ set_pin_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ create_pin_apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::CreatePin",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::CreatePin",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::CreatePin",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::CreatePin",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+APDU_Response *Secure_Channel::SendTokenAPU(APDU *apdu)
+{
+ int rc;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+
+ RA::Debug("Secure_Channel::SendTokenAPDU",
+ "Secure_Channel::SendTokenAPDU");
+ rc = ComputeAPDU(apdu);
+ if (rc == -1)
+ goto loser;
+
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ apdu);
+ m_session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::SendTokenAPDU",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ m_session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::SendTokenAPDU",
+ "No Token PDU Response Msg Received");
+ rc = -1;
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error("Secure_Channel::SendTokenAPDU",
+ "Invalid Msg Type");
+ rc = -1;
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::SendTokenAPDU",
+ "No Response From Token");
+ rc = -1;
+ goto loser;
+ }
+
+loser:
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return response;
+}
+
+
+static void AppendSHORTtoBuffer(Buffer &buf,unsigned short s)
+{
+
+ buf += s/256;
+ buf += s%256;
+}
+
+
+static void AppendLONGtoBuffer(Buffer &buf, unsigned int l)
+{
+ buf += l>>24;
+ buf += (l >> 16) & 0xFF;
+ buf += (l >> 8) & 0xFF;
+ buf += l & 0xFF;
+}
+
+static void AppendAttribute(Buffer &buf, unsigned int type, unsigned int length, BYTE *b)
+{
+ AppendLONGtoBuffer(buf, type);
+ AppendSHORTtoBuffer(buf, length);
+ buf += Buffer(b,length);
+}
+
+static void AppendKeyCapabilities(Buffer &b, const char *opType, const char *tokenType, const char *keyTypePrefix, const char *keyType) {
+ char configname[256];
+
+ bool bvalue = false;
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.encrypt",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_ENCRYPT, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.sign",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_SIGN, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.signRecover",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_SIGN_RECOVER, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.decrypt",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_DECRYPT, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.derive",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_DERIVE, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.unwrap",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_UNWRAP, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.wrap",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_WRAP, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.verifyRecover",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_VERIFY_RECOVER, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.verify",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_VERIFY, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.sensitive",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_SENSITIVE, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.private",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_PRIVATE, 1, Util::bool2byte(bvalue));
+ PR_snprintf((char *)configname, 256, "%s.%s.keyCapabilities.token",
+ keyTypePrefix, keyType);
+ bvalue = RA::GetConfigStore()->GetConfigAsBool(configname);
+ AppendAttribute(b,CKA_TOKEN, 1, Util::bool2byte(bvalue));
+}
+
+static void FinalizeBuffer(Buffer &b, const char* id)
+{
+ ((BYTE*)b)[0] = 0;
+ ((BYTE*)b)[1] = id[0];
+ ((BYTE*)b)[2] = id[1];
+ ((BYTE*)b)[3] = 0;
+ ((BYTE*)b)[4] = 0;
+ ((BYTE*)b)[5] = (b.size()-7) / 256;
+ ((BYTE*)b)[6] = (b.size()-7) % 256;
+}
+
+/**
+ * Creates object on token.
+ */
+int Secure_Channel::CreateObject(BYTE *objid, BYTE *permissions, Buffer *obj)
+{
+ int rc = -1;
+ rc = CreateObject(objid, permissions, obj->size());
+ if (rc == -1)
+ goto loser;
+ rc = WriteObject(objid, (BYTE*)*obj, obj->size());
+ if (rc == -1)
+ goto loser;
+ rc = 1;
+loser:
+ return rc;
+} /* CreateObject */
+
+int Secure_Channel::CreateCertificate(const char *id, Buffer *cert)
+{
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ return CreateObject((BYTE*)id, perms, cert);
+} /* CreateCertificate */
+
+/*
+Cert attrib object (c0):
+CKA_LABEL(0x0003): cert nickname
+CKA_ID (0x0102): 20 bytes same as public key
+CKA_CERTIFICATE_TYPE(0x0080): 00 00 00 00 (CKC_X_509)
+CKA_CLASS(0x0000): 01 00 00 00 (little-endian for CKO_CERTIFICATE)
+CKA_TOKEN(0x0001): true
+
+0000000 0063 3000 0000 6400 0000 0300 294a 616d /Jam
+0000020 6965 204e 6963 6f6c 736f 6e27 7320 416d /ie Nicolson's Am
+0000040 6572 6963 6120 4f6e 6c69 6e65 2049 6e63 /erica Online Inc
+0000060 2049 4420 2332
+ 0000 0102 0014 709b a306 /ID #2
+0000100 3fc8 9ad4 23c6 a1b2 eb04 d8ff f7dd 3f55
+0000120 0000 0080 0004 0000 0000 0000 0000 0004
+0000140 0100 0000 0000 0001 0001 0100 0000 0000
+0000160 0000 0000 0000 0000 0000 0000 0000 0000
+
+mine: (no subject)
+
+
+ 0063 3000 0000 4500 0000 0300 0A74 6861
+ 7965 7330 3939 33
+ 0000 0102 0014 206E 8B36
+ 03A5 568D 266D 51EC 40F0 E35B B55F 8BCC
+ 0000 0080 0004 0000 0000 0000 0000 0004
+ 0100 0000 0000 0001 0001 01
+
+*/
+
+Buffer Secure_Channel::CreatePKCS11CertAttrsBuffer(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid)
+{
+ BYTE type[4] = { 0,0,0,0 };
+ BYTE p11class[4] = { 1,0,0,0 };
+ BYTE tokenflag[1] = { 1 };
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "id=%s", id);
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "keyid", keyid);
+ AppendAttribute(b, CKA_LABEL, strlen(label), (BYTE*)label);
+ // hash of pubk
+ AppendAttribute(b, CKA_ID, keyid->size(), (BYTE*)*keyid);
+ // type of cert
+ AppendAttribute(b, CKA_CERTIFICATE_TYPE, 4, type);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+ AppendAttribute(b, CKA_TOKEN, 1, tokenflag);
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrsBuffer", "buffer", &b);
+
+ return b;
+}
+
+int Secure_Channel::CreatePKCS11CertAttrs(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid)
+{
+ BYTE type[4] = { 0,0,0,0 };
+ BYTE p11class[4] = { 1,0,0,0 };
+ BYTE tokenflag[1] = { 1 };
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "id=%s", id);
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "keyid", keyid);
+ AppendAttribute(b, CKA_LABEL, strlen(label), (BYTE*)label);
+ // hash of pubk
+ AppendAttribute(b, CKA_ID, keyid->size(), (BYTE*)*keyid);
+ // type of cert
+ AppendAttribute(b, CKA_CERTIFICATE_TYPE, 4, type);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+ AppendAttribute(b, CKA_TOKEN, 1, tokenflag);
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "buffer", &b);
+
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ return CreateObject((BYTE*)id, perms, &b);
+} /* CreatePKCS11CertAttrs */
+
+/*
+
+Private Key: (k0)
+CKA_SUBJECT (0x0101): subject name of cert
+CKA_LABEL (0x0003): nickname of cert
+CKA_MODULUS (0x0120)
+ (sha1 hash of spki)
+CKA_ID (0x0102): ?? (20 bytes, 70 9b a3 06 3f c8 9a d4 23 c6 a1 b2 eb 04 d8 ff f7 dd 3f 55)
+CKA_SENSITIVE(0x0103): true
+CKA_PRIVATE(0x0002): true
+CKA_TOKEN(0x0001): true
+CKA_KEY_TYPE(0x0100): 0x00000000 (CKK_RSA)
+cKA_CLASS(0x0000): 03 00 00 00 (little-endian(!) for CKO_PRIVATE_KEY)
+
+
+0000000 006b 3000 0001 8400 0001 0100 8630 8183
+0000020 310b 3009 0603 5504 0613 0255 5331 1b30
+0000040 1906 0355 040a 1312 416d 6572 6963 6120
+0000060 4f6e 6c69 6e65 2049 6e63 3118 3016 060a
+0000100 0992 2689 93f2 2c64 0101 1308 6e69 636f
+0000120 6c73 6f6e 3124 3022 0609 2a86 4886 f70d
+0000140 0109 0116 156e 6963 6f6c 736f 6e40 6e65
+0000160 7473 6361 7065 2e63 6f6d 3117 3015 0603
+0000200 5504 0313 0e4a 616d 6965 204e 6963 6f6c
+0000220 736f 6e00 00
+ 00 0300 294a 616d 6965 204e
+0000240 6963 6f6c 736f 6e27 7320 416d 6572 6963
+0000260 6120 4f6e 6c69 6e65 2049 6e63 2049 4420
+0000300 2332
+ 0000 0120 0080 a70e 07f4 3f51 86c7
+0000320 4f8d 4b64 522d 8c4b 31ae 58f2 f04d a9fd
+0000340 2701 637e 5245 bb48 23ec 2259 742b ddc4
+0000360 e5da f571 78df 07ba b555 6d05 0de5 7329
+0000400 f073 94e2 00a6 f846 d99d d01c 8b62 684c
+0000420 5133 9b16 3c8f ee83 34fc 844d 829b 6fca
+0000440 e694 c432 9532 6413 323c 8b81 bc64 ed30
+0000460 6074 6926 aff5 6b7f cb43 0c40 c039 ba55
+0000500 7d3a 365d bb82 0b49 0000 0102 0014 709b
+0000520 a306 3fc8 9ad4 23c6 a1b2 eb04 d8ff f7dd
+0000540 3f55 0000 0103 0001 0100 0000 0200 0101
+0000560 0000 0001 0001 0100 0001 0000 0400 0000
+0000600 0000 0000 0000 0403 0000 0000 0000 0000
+0000620 0000 0000 0000 0000 0000 0000 0000 0000
+0000640 0000 015e ffff ffff fffe 0002 0002 0002
+0000660 014e 0000 0000 0000 0000 0000 0000 0000
+0000700 0000 0000 0000 0000 0000 0000 0000 0000
+
+mine:
+
+ 006B 3000 0000 D900 0000 0300 0A74 6861
+ 7965 7330 3939 33
+ 0000 0120 0080 DB1F EF
+ 9EEA 63EC F3A9 F831 EDB2 AC38 3957 1917
+ 186D 1CEB 782D 34BA B6DA 4F65 54A5 68B0
+ A08F 7840 FDF8 E115 E8A4 1522 4706 B807
+ 572A 31D2 2BB9 DD9F AF0C 2E0B 8183 ADE2
+ 78C4 B13E 0ED6 92F1 9989 D872 1474 A7A6
+ 2205 7928 1977 075A 5A76 B24D 8FE0 99C1
+ 32BE AE72 5C5D A8FA 3E93 F815 0669 074A
+ 2FF5 99EE 4A29 EDC8 5B79 7B93 5D
+ 0000 0102 0014 206E 8B36 03A5 568D 266D
+ 51EC 40F0 E35B B55F 8BCC
+ 0000 0103 0001 0100 00
+ 00020001010000000100010100000100
+ 00040000000000000000000403000000
+
+ H 00020001010000000100010100000100
+ H 00040000000000000000000403000000
+
+ M 00020001010000000100010100000100
+ M 00040000000000000000000403000000
+*/
+Buffer Secure_Channel::CreatePKCS11PriKeyAttrsBuffer(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+ // BYTE sensitiveflag[1] = { 1 };
+ // BYTE privateflag[1] = { 1 };
+ // BYTE token[1] = { 1 };
+ BYTE keytype[4] = { 0,0,0,0 };
+ BYTE p11class[4] = { 3,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11PriAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "keyid", keyid);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "modulus", modulus);
+ RA::Debug("Secure_Channel::CreatePKCS11PriAttrs", "id=%s",id);
+
+// AppendAttribute(b,CKA_LABEL, strlen(label), (BYTE*)label);
+ AppendAttribute(b,CKA_MODULUS, modulus->size(), (BYTE*)*modulus);
+ AppendAttribute(b,CKA_KEY_TYPE, 4, keytype);
+ AppendAttribute(b,CKA_CLASS, 4, p11class );
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "private");
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrsBuffer", "buffer", &b);
+
+ return b;
+
+} /* CreatePKCS11PriKeyAttrs */
+
+int Secure_Channel::CreatePKCS11PriKeyAttrs(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+ // BYTE sensitiveflag[1] = { 1 };
+ // BYTE privateflag[1] = { 1 };
+ // BYTE token[1] = { 1 };
+ BYTE keytype[4] = { 0,0,0,0 };
+ BYTE p11class[4] = { 3,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11PriAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "keyid", keyid);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "modulus", modulus);
+
+// AppendAttribute(b,CKA_LABEL, strlen(label), (BYTE*)label);
+ AppendAttribute(b,CKA_MODULUS, modulus->size(), (BYTE*)*modulus);
+ AppendAttribute(b,CKA_KEY_TYPE, 4, keytype);
+ AppendAttribute(b,CKA_CLASS, 4, p11class );
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "private");
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PriAttrs", "buffer", &b);
+
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ return CreateObject((BYTE*)id, perms, &b);
+
+} /* CreatePKCS11PriKeyAttrs */
+
+/*
+Public Key: (k1)
+CKA_PUBLIC_EXPONENT(0x0122)
+CKA_MODULUS(0x0120)
+CKA_ID (0x0102): (20 bytes) same as private key
+CKA_CLASS(0x0000): 02 00 00 00 (little-endian for CKO_PUBLIC_KEY)
+
+0000000 006b 3100 0000 b300 0001 2200 0301 0001
+0000020 0000 0120 0080 a70e 07f4 3f51 86c7 4f8d
+0000040 4b64 522d 8c4b 31ae 58f2 f04d a9fd 2701
+0000060 637e 5245 bb48 23ec 2259 742b ddc4 e5da
+0000100 f571 78df 07ba b555 6d05 0de5 7329 f073
+0000120 94e2 00a6 f846 d99d d01c 8b62 684c 5133
+0000140 9b16 3c8f ee83 34fc 844d 829b 6fca e694
+0000160 c432 9532 6413 323c 8b81 bc64 ed30 6074
+0000200 6926 aff5 6b7f cb43 0c40 c039 ba55 7d3a
+0000220 365d bb82 0b49 0000 0102 0014 709b a306
+0000240 3fc8 9ad4 23c6 a1b2 eb04 d8ff f7dd 3f55
+0000260 0000 0000 0004 0200 0000 0000 0000 0000
+0000300 0000 0000 0000 0000 0000 0000 0000 0000
+*
+0000400
+
+mine:
+ 006B 3100 0000 B300 0001 2200 0301 0001
+ 0000 0120 0080 F3E1 1AF0 906D BD35 4792
+ 348A CC4D 6147 CFAC 659A D018 34DD 4621
+ AB57 75F5 B5E0 87D4 F6C2 2B89 3324 D980
+ 2926 4BF1 0F64 A6E5 4368 9DA5 2620 335E
+ ADCD 7540 7CBA B1F9 4ACE EEF8 13FF 6524
+ B76F C7B1 2D21 DD42 5342 EFC3 034E 39DD
+ ACBC 5C43 AC14 974A 45D4 5E66 6FFA BB17
+ 1E98 C177 68CC B51B 1B7E 28C5 38AB 729D
+ 27FD 3077 8C39 0000 0102 0014 815B 6FFE
+ 9B2A 8515 9C76 0F92 4A4E 349F 61EA 521F
+ 0000 0000 0004 0200 0000
+
+
+*/
+Buffer Secure_Channel::CreatePKCS11PubKeyAttrsBuffer(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+#if 0
+ BYTE pubexp[3] = // XXX should I really hardcode this!?
+ {
+ 0x01,0x00,0x01
+ };
+#endif
+ BYTE p11class[4] = { 2,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11PubAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "keyid", keyid);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "modulus", modulus);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "exponent", exponent);
+
+ AppendAttribute(b, CKA_PUBLIC_EXPONENT, exponent->size(),(BYTE*) *exponent);
+ AppendAttribute(b,CKA_MODULUS, modulus->size(), (BYTE*)*modulus);
+ // XXX TUES
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "public");
+
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrsBuffer", "buffer", &b);
+
+ return b;
+} /* CreatePKCS11PubKeyAttrs */
+
+int Secure_Channel::CreatePKCS11PubKeyAttrs(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+#if 0
+ BYTE pubexp[3] = // XXX should I really hardcode this!?
+ {
+ 0x01,0x00,0x01
+ };
+#endif
+ BYTE p11class[4] = { 2,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ RA::Debug("Secure_Channel::CreatePKCS11PubAttrs", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "keyid", keyid);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "modulus", modulus);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "exponent", exponent);
+
+ AppendAttribute(b, CKA_PUBLIC_EXPONENT, exponent->size(),(BYTE*) *exponent);
+ AppendAttribute(b,CKA_MODULUS, modulus->size(), (BYTE*)*modulus);
+ // XXX TUES
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "public");
+
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11PubAttrs", "buffer", &b);
+
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ return CreateObject((BYTE*)id, perms, &b);
+} /* CreatePKCS11PubKeyAttrs */
+
+Buffer &Secure_Channel::GetKeyDiversificationData()
+{
+ return m_key_diversification_data;
+} /* GetKeyDiversificationData */
+
+Buffer &Secure_Channel::GetKeyInfoData()
+{
+ return m_key_info_data;
+} /* GetKeyInfoData */
+
+Buffer &Secure_Channel::GetCardChallenge()
+{
+ return m_card_challenge;
+} /* GetCardChallenge */
+
+Buffer &Secure_Channel::GetCardCryptogram()
+{
+ return m_card_cryptogram;
+} /* GetCardCryptogram */
+
+Buffer &Secure_Channel::GetHostChallenge()
+{
+ return m_host_challenge;
+} /* GetCardCryptogram */
+
+Buffer &Secure_Channel::GetHostCryptogram()
+{
+ return m_host_cryptogram;
+} /* GetHostCryptogram */
+
+SecurityLevel Secure_Channel::GetSecurityLevel()
+{
+ return m_security_level;
+}
+
+void Secure_Channel::SetSecurityLevel(SecurityLevel level)
+{
+ m_security_level = level;
+}
diff --git a/base/tps/src/cms/CertEnroll.cpp b/base/tps/src/cms/CertEnroll.cpp
new file mode 100644
index 000000000..89990d021
--- /dev/null
+++ b/base/tps/src/cms/CertEnroll.cpp
@@ -0,0 +1,725 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+
+#include "main/RA_Session.h"
+#include "main/RA_Msg.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+#include "cms/HttpConnection.h"
+#include "cms/CertEnroll.h"
+
+// for public key processing
+#include "pk11func.h"
+#include "cryptohi.h"
+#include "keyhi.h"
+#include "base64.h"
+#include "nssb64.h"
+#include "prlock.h"
+
+#include "main/Memory.h"
+
+Buffer * parseResponse(char * /*response*/);
+ReturnStatus verifyProof(SECKEYPublicKey* , SECItem* ,
+ unsigned short , unsigned char* ,
+ unsigned char* );
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs handle for Certificate Enrollment
+ */
+TOKENDB_PUBLIC CertEnroll::CertEnroll()
+{
+}
+
+/**
+ * Destructs handle for Certificate Enrollment
+ */
+TOKENDB_PUBLIC CertEnroll::~CertEnroll()
+{
+}
+
+/**
+ * Revokes a certificate in the CA
+ * reason:
+ * 0 = Unspecified
+ * 1 = Key compromised
+ * 2 = CA key compromised
+ * 3 = Affiliation changed
+ * 4 = Certificate superseded
+ * 5 = Cessation of operation
+ * 6 = Certificate is on hold
+ * serialno: serial number in decimal
+ */
+TOKENDB_PUBLIC int CertEnroll::RevokeCertificate(const char *reason, const char *serialno, const char *connid, char *&o_status)
+{
+ char parameters[5000];
+ char configname[5000];
+ int num;
+
+ PR_snprintf((char *)parameters, 5000, "op=revoke&revocationReason=%s&revokeAll=(certRecordId%%3D%s)&totalRecordCount=1", reason, serialno);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.revoke", connid);
+ char *servletID = (char*)RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PSHttpResponse *resp = sendReqToCA(servletID, parameters, connid);
+
+ if (resp != NULL) {
+ char *content = resp->getContent();
+ char *p = strstr(content, "status=");
+ num = *(p+7) - '0';
+ RA::Debug("CertEnroll::RevokeCertificate", "serialno=%s reason=%s connid=%s status=%d", serialno, reason, connid, num);
+ if (num != 0) {
+ char *q = strstr(p, "error=");
+ q = q+6;
+ o_status = PL_strdup(q);
+ RA::Debug("CertEnroll::RevokeCertificate", "status string=%s", q);
+ }
+ if (content != NULL) {
+ resp->freeContent();
+ content = NULL;
+ }
+ delete resp;
+ resp = NULL;
+ } else {
+ RA::Debug("CertEnroll::RevokeCertificate", "serialno=%s reason=%s connid=%s failed: resp is NULL");
+ o_status = PL_strdup("resp from sendReqToCA is NULL");
+ num = 1; //non-zero
+ }
+ return num;
+}
+
+TOKENDB_PUBLIC int CertEnroll::UnrevokeCertificate(const char *serialno, const char *connid,
+ char *&o_status)
+{
+ char parameters[5000];
+ char configname[5000];
+ int num;
+
+ PR_snprintf((char *)parameters, 5000, "serialNumber=%s",serialno);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.unrevoke", connid);
+ char *servletID = (char*)RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PSHttpResponse *resp = sendReqToCA(servletID, parameters, connid);
+ if (resp != NULL) {
+ // XXX - need to parse response
+ char *content = resp->getContent();
+ char *p = strstr(content, "status=");
+ num = *(p+7) - '0';
+ RA::Debug("CertEnroll::UnrevokeCertificate", "status=%d", num);
+
+ if (num != 0) {
+ char *q = strstr(p, "error=");
+ q = q+6;
+ o_status = PL_strdup(q);
+ RA::Debug("CertEnroll::UnrevokeCertificate", "status string=%s", q);
+ }
+
+ if (content != NULL) {
+ resp->freeContent();
+ content = NULL;
+ }
+ delete resp;
+ resp = NULL;
+ } else {
+ RA::Debug("CertEnroll::UnrevokeCertificate", "serialno=%s reason=%s connid=%s failed: resp is NULL");
+ o_status = PL_strdup("resp from sendReqToCA is NULL");
+ num = 1; //non-zero
+ }
+
+ return num;
+}
+
+TOKENDB_PUBLIC Buffer *CertEnroll::RenewCertificate(PRUint64 serialno, const char *connid, const char *profileId, char *error_msg)
+{
+ char parameters[5000];
+ char configname[5000];
+
+ RA::Debug("CertEnroll::RenewCertificate", "begins. profileId=%s",profileId);
+ // on CA, renewal expects parameter "serial_num" if renew by serial number
+ // ahh. need to allow larger serialno...later
+ PR_snprintf((char *)parameters, 5000, "serial_num=%u&profileId=%s&renewal=true",
+ (int)serialno, profileId);
+ RA::Debug("CertEnroll::RenewCertificate", "got parameters =%s", parameters);
+ //e.g. conn.ca1.servlet.renewal=/ca/ee/ca/profileSubmitSSLClient
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.renewal", connid);
+ const char *servlet = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (servlet == NULL) {
+ RA::Debug("CertEnroll::RenewCertificate",
+ "Missing the configuration parameter for %s", configname);
+ PR_snprintf(error_msg, 512, "Missing the configuration parameter for %s", configname);
+ return NULL;
+ }
+
+ // on CA, same profile servlet processes the renewal as well as enrollment
+ PSHttpResponse *resp = sendReqToCA(servlet, parameters, connid);
+ // XXX - need to parse response
+ Buffer * certificate = NULL;
+ if (resp != NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::RenewCertificate",
+ "sendReqToCA done");
+
+ certificate = parseResponse(resp);
+ RA::Debug(LL_PER_PDU, "CertEnroll::RenewCertificate",
+ "parseResponse done");
+
+ if( resp != NULL ) {
+ delete resp;
+ resp = NULL;
+ }
+ } else {
+ RA::Error("CertEnroll::RenewCertificate",
+ "sendReqToCA failure");
+ PR_snprintf(error_msg, 512, "sendReqToCA failure");
+ return NULL;
+ }
+
+ return certificate;
+}
+
+
+/**
+ * Sends certificate request to CA for enrollment.
+ */
+Buffer * CertEnroll::EnrollCertificate(
+ SECKEYPublicKey *pk_parsed,
+ const char *profileId,
+ const char *uid,
+ const char *cuid /*token id*/,
+ const char *connid,
+ char *error_msg,
+ SECItem** encodedPublicKeyInfo)
+{
+ char parameters[5000];
+
+ SECItem* si = SECKEY_EncodeDERSubjectPublicKeyInfo(pk_parsed);
+ if (si == NULL) {
+
+ RA::Error("CertEnroll::EnrollCertificate",
+ "SECKEY_EncodeDERSubjectPublicKeyInfo returns error");
+ PR_snprintf(error_msg, 512, "SECKEY_EncodeDERSubjectPublicKeyInfo returns error");
+ return NULL;
+ }
+
+ // b64 encode it
+ char* pk_b64 = BTOA_ConvertItemToAscii(si);
+
+ if(encodedPublicKeyInfo == NULL)
+ {
+ if( si != NULL ) {
+ SECITEM_FreeItem( si, PR_TRUE );
+ si = NULL;
+ }
+ }
+ else
+ {
+
+ *encodedPublicKeyInfo = si;
+
+ }
+
+ if (pk_b64 == NULL) {
+ RA::Error(LL_PER_PDU, "CertEnroll::EnrollCertificate",
+ "BTOA_ConvertItemToAscii returns error");
+
+ PR_snprintf(error_msg, 512, "BTOA_ConvertItemToAscii returns error");
+ return NULL;
+ }
+ RA::Debug(LL_PER_PDU, "CertEnroll::EnrollCertificate",
+ "after BTOA_ConvertItemToAscii pk_b64=%s",pk_b64);
+
+ char *url_pk = Util::URLEncode(pk_b64);
+ char *url_uid = Util::URLEncode(uid);
+ char *url_cuid = Util::URLEncode(cuid);
+ const char *servlet;
+ char configname[256];
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.enrollment", connid);
+ servlet = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)parameters, 5000, "profileId=%s&tokencuid=%s&screenname=%s&publickey=%s", profileId, url_cuid, url_uid, url_pk);
+
+ PSHttpResponse *resp = sendReqToCA(servlet, parameters, connid);
+ Buffer * certificate = NULL;
+ if (resp != NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::EnrollCertificate",
+ "sendReqToCA done");
+
+ certificate = parseResponse(resp);
+ RA::Debug(LL_PER_PDU, "CertEnroll::EnrollCertificate",
+ "parseResponse done");
+
+ if( resp != NULL ) {
+ delete resp;
+ resp = NULL;
+ }
+ } else {
+ RA::Error("CertEnroll::EnrollCertificate",
+ "sendReqToCA failure");
+ PR_snprintf(error_msg, 512, "sendReqToCA failure");
+ return NULL;
+ }
+
+ if( pk_b64 != NULL ) {
+ PR_Free( pk_b64 );
+ pk_b64 = NULL;
+ }
+ if( url_pk != NULL ) {
+ PR_Free( url_pk );
+ url_pk = NULL;
+ }
+ if( url_uid != NULL ) {
+ PR_Free( url_uid );
+ url_uid = NULL;
+ }
+ if( url_cuid != NULL ) {
+ PR_Free( url_cuid );
+ url_cuid = NULL;
+ }
+
+ return certificate;
+}
+
+/**
+ * Extracts information from the public key blob and verify proof.
+ *
+ * Muscle Key Blob Format (RSA Public Key)
+ * ---------------------------------------
+ *
+ * The key generation operation places the newly generated key into
+ * the output buffer encoding in the standard Muscle key blob format.
+ * For an RSA key the data is as follows:
+ *
+ * Byte Encoding (0 for plaintext)
+ *
+ * Byte Key Type (1 for RSA public)
+ *
+ * Short Key Length (1024 û high byte first)
+ *
+ * Short Modulus Length
+ *
+ * Byte[] Modulus
+ *
+ * Short Exponent Length
+ *
+ * Byte[] Exponent
+ *
+ *
+ * Signature Format (Proof)
+ * ---------------------------------------
+ *
+ * The key generation operation creates a proof-of-location for the
+ * newly generated key. This proof is a signature computed with the
+ * new private key using the RSA-with-MD5 signature algorithm. The
+ * signature is computed over the Muscle Key Blob representation of
+ * the new public key and the challenge sent in the key generation
+ * request. These two data fields are concatenated together to form
+ * the input to the signature, without any other data or length fields.
+ *
+ * Byte[] Key Blob Data
+ *
+ * Byte[] Challenge
+ *
+ *
+ * Key Generation Result
+ * ---------------------------------------
+ *
+ * The key generation command puts the key blob and the signature (proof)
+ * into the output buffer using the following format:
+ *
+ * Short Length of the Key Blob
+ *
+ * Byte[] Key Blob Data
+ *
+ * Short Length of the Proof
+ *
+ * Byte[] Proof (Signature) Data
+ *
+ * @param blob the publickey blob to be parsed
+ * @param challenge the challenge generated by RA
+ * @return
+ * rc is 1 if success, -1 if failure
+ * pk is the public key resulted from parsing the blob.
+ *
+ ******/
+
+SECKEYPublicKey *CertEnroll::ParsePublicKeyBlob(unsigned char *blob,
+ Buffer *challenge)
+{
+ char configname[5000];
+ SECKEYPublicKey *pk = NULL;
+
+ ReturnStatus rs;
+ rs.status = PR_FAILURE;
+ rs.statusNum = ::MSG_INVALID;
+
+ if ((blob == NULL) || (challenge == NULL)) {
+ RA::Error(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob", "invalid input");
+ return NULL;
+ }
+
+ /*
+ * decode blob into structures
+ */
+
+ // offset to the beginning of the public key length. should be 0
+ unsigned short pkeyb_len_offset = 0;
+
+ unsigned short pkeyb_len = 0;
+ unsigned char* pkeyb;
+ unsigned short proofb_len = 0;
+ unsigned char* proofb;
+
+ /*
+ * now, convert lengths
+ */
+ // 1st, keyblob length
+ unsigned char len0 = blob[pkeyb_len_offset];
+ unsigned char len1 = blob[pkeyb_len_offset +1];
+ pkeyb_len = (unsigned short) ((len0 << 8) | (len1 & 0xFF));
+
+ RA::Debug(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob",
+ "pkeyb_len =%d",pkeyb_len);
+
+ if (pkeyb_len <= 0) {
+ RA::Error("CertEnroll::ParsePublicKeyBlob", "public key blob length = %d", pkeyb_len);
+ return NULL;
+ }
+ // 2nd, proofblob length
+ unsigned short proofb_len_offset = pkeyb_len_offset + 2 + pkeyb_len;
+ len0 = blob[proofb_len_offset];
+ len1 = blob[proofb_len_offset +1];
+ proofb_len = (unsigned short) (len0 << 8 | len1 & 0xFF);
+ RA::Debug(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob",
+ "proofb_len =%d", proofb_len);
+
+ // public key blob
+ pkeyb = &blob[pkeyb_len_offset + 2];
+
+ // proof blob
+ proofb = &blob[proofb_len_offset + 2];
+
+ SECItem siProof;
+ siProof.type = (SECItemType) 0;
+ siProof.data = (unsigned char *)proofb;
+ siProof.len = proofb_len;
+
+ // convert pkeyb to pkey
+ // 1 byte encoding, 1 byte key type, 2 bytes key length, then the key
+ unsigned short pkey_offset = 4;
+ // now, convert lengths for modulus and exponent
+ len0 = pkeyb[pkey_offset];
+ len1 = pkeyb[pkey_offset + 1];
+ unsigned short mod_len = (len0 << 8 | len1);
+
+ len0 = pkeyb[pkey_offset + 2 + mod_len];
+ len1 = pkeyb[pkey_offset + 2 + mod_len + 1];
+ unsigned short exp_len = (len0 << 8 | len1);
+
+
+ // public key mod blob
+ unsigned char * modb = &pkeyb[pkey_offset + 2];
+
+ // public key exp blob
+ unsigned char * expb = &pkeyb[pkey_offset + 2 + mod_len + 2];
+
+ // construct SECItem
+ SECItem siMod;
+ siMod.type = (SECItemType) 0;
+ siMod.data = (unsigned char *) modb;
+ siMod.len = mod_len;
+
+ SECItem siExp;
+ siExp.type = (SECItemType) 0;
+ siExp.data = (unsigned char *)expb;
+ siExp.len = exp_len;
+
+ // construct SECKEYRSAPublicKeyStr
+ SECKEYRSAPublicKeyStr rsa_pks;
+ rsa_pks.modulus = siMod;
+ rsa_pks.publicExponent = siExp;
+
+ // construct SECKEYPublicKey
+ // this is to be returned
+ pk = (SECKEYPublicKey *) malloc(sizeof(SECKEYPublicKey));
+ pk->keyType = rsaKey;
+ pk->pkcs11Slot = NULL;
+ pk->pkcs11ID = CK_INVALID_HANDLE;
+ pk->u.rsa = rsa_pks;
+
+ PR_snprintf((char *)configname, 256, "general.verifyProof");
+ int verifyProofEnable = RA::GetConfigStore()->GetConfigAsInt(configname, 0x1);
+ if (verifyProofEnable) {
+ rs = verifyProof(pk, &siProof, pkeyb_len, pkeyb, challenge);
+ if (rs.status == PR_FAILURE) {
+ RA::Error("CertEnroll::ParsePublicKeyBlob",
+ "verify proof failed");
+ free(pk);
+ pk = NULL;
+ }
+ }
+
+ return pk;
+}
+
+
+/**
+ * verify the proof.
+ * @param pk the public key from the input blob
+ * @param siProof the proof from the input blob
+ * @param pkeyb_len the length of the publickey blob
+ * @param pkeyb the public key blob
+ * @param challenge the challenge generated by RA
+ *
+ * @return
+ * returns success indication in case of success
+ * returns error message number as defined in ReturnStatus in Base.h
+ */
+ReturnStatus CertEnroll::verifyProof(SECKEYPublicKey* pk, SECItem* siProof,
+ unsigned short pkeyb_len, unsigned char* pkeyb,
+ Buffer* challenge) {
+
+ ReturnStatus rs;
+ VFYContext * vc = NULL;
+ rs.statusNum = ::VRFY_SUCCESS;
+ rs.status = PR_SUCCESS;
+
+ // verify proof (signature)
+ RA::Debug(LL_PER_PDU, "CertEnroll::verifyProof",
+ "verify proof begins");
+
+ vc = VFY_CreateContext(pk, siProof, SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE, NULL);
+
+ if (vc == NULL) {
+ RA::Error("CertEnroll::verifyProof",
+ "VFY_CreateContext() failed");
+ rs.status = PR_FAILURE;
+ rs.statusNum = ::VFY_BEGIN_FAILURE;
+ return rs;
+ } else {
+ RA::Debug(LL_PER_PDU, "CertEnroll::verifyProof",
+ "VFY_CreateContext() succeeded");
+ }
+
+ unsigned char proof[1024];
+ int i =0;
+ for (i = 0; i<pkeyb_len; i++) {
+ proof[i] = pkeyb[i];
+ }
+ // RA::DebugBuffer("CertEnroll::VerifyProof","VerifyProof:: challenge =", challenge);
+ unsigned char* chal = (unsigned char *)(BYTE *) (*challenge);
+ unsigned int j = 0;
+ for (j=0; j < challenge->size(); i++, j++) {
+ proof[i] = chal[j];
+ // RA::Debug(LL_PER_PDU, "CertEnroll::VerifyProof","proof[%d]= %x",
+ // i, proof[i]);
+ }
+
+ SECStatus vs = VFY_Begin(vc);
+ if (vs == SECSuccess) {
+ vs = VFY_Update(vc, (unsigned char *)proof , pkeyb_len + challenge->size());
+ if (vs == SECSuccess) {
+ vs = VFY_End(vc);
+ if (vs == SECFailure) {
+ RA::Error("CertEnroll::verifyProof",
+ "VFY_End() failed pkeyb_len=%d challenge_size=%d", pkeyb_len, challenge->size());
+ rs.statusNum = ::VFY_UPDATE_FAILURE;
+ rs.status = PR_FAILURE;
+ }
+ } else {
+ RA::Error("CertEnroll::verifyProof",
+ "VFY_Update() failed");
+ rs.statusNum = ::VFY_UPDATE_FAILURE;
+ rs.status = PR_FAILURE;
+ }
+ } else {
+ RA::Error("CertEnroll::verifyProof",
+ "VFY_Begin() failed");
+
+ rs.statusNum = ::VFY_BEGIN_FAILURE;
+ rs.status = PR_FAILURE;
+ }
+
+ if( vc != NULL ) {
+ VFY_DestroyContext( vc, PR_TRUE );
+ vc = NULL;
+ }
+ RA::Debug(LL_PER_PDU, "CertEnroll::verifyProof",
+ " VFY_End() returned %d",vs);
+
+ return rs;
+
+}
+
+/**
+ * sendReqToCA sends cert enrollment request via HTTPS to the CA
+ * @param pk normalized public key
+ * @param uid uid/screenname
+ * @param cuid cud number of the client token
+ * @param timeout timeout value for connection
+ * @return
+ * PSHttpResponse if success
+ * NULL if failure
+ */
+PSHttpResponse * CertEnroll::sendReqToCA(const char *servlet, const char *parameters, const char *connid)
+{
+ // compose http uri
+
+ RA::Debug(LL_PER_PDU, "CertEnroll::sendReqToCA",
+ "begins");
+
+ HttpConnection *caConn = RA::GetCAConn(connid);
+ if (caConn == NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::sendReqToCA", "Failed to get CA Connection %s", connid);
+ RA::Error(LL_PER_PDU, "CertEnroll::sendReqToCA", "Failed to get CA Connection %s", connid);
+ return NULL;
+ }
+ // PRLock *ca_lock = RA::GetCALock();
+ int ca_curr = RA::GetCurrentIndex(caConn);
+ int maxRetries = caConn->GetNumOfRetries();
+ ConnectionInfo *connInfo = caConn->GetFailoverList();
+ char **hostport = connInfo->GetHostPortList();
+ int currRetries = 0;
+
+ RA::Debug(LL_PER_PDU, "Before calling getResponse, caHostPort is %s", hostport[ca_curr]);
+
+ PSHttpResponse * response = caConn->getResponse(ca_curr, servlet, parameters);
+ while (response == NULL) {
+ RA::Failover(caConn, connInfo->GetHostPortListLen());
+ ca_curr = RA::GetCurrentIndex(caConn);
+
+ if (++currRetries >= maxRetries) {
+ RA::Debug(LL_PER_PDU, "Used up all the retries. Response is NULL","");
+ RA::Error("CertEnroll::sendReqToCA", "Failed connecting to CA after %d retries", currRetries);
+ if (caConn != NULL) {
+ RA::ReturnCAConn(caConn);
+ }
+ return NULL;
+ }
+ response = caConn->getResponse(ca_curr, servlet, parameters);
+ }
+
+ if (caConn != NULL) {
+ RA::ReturnCAConn(caConn);
+ }
+ return response;
+}
+
+/**
+ * parse the http response and retrieve the certificate.
+ * @param resp the response returned from http request
+ * @return
+ * The certificate in Buffer if success
+ * NULL if failure
+ */
+Buffer * CertEnroll::parseResponse(PSHttpResponse * resp)
+{
+ unsigned int i;
+ unsigned char blob[8192]; /* cert returned */
+ int blob_len; /* cert length */
+ char *certB64 = NULL;
+ char *certB64End = NULL;
+ unsigned int certB64Len = 0;
+ Buffer *cert = NULL;
+ char * response = NULL;
+ SECItem * outItemOpt = NULL;
+
+ if (resp == NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "no response found");
+ return NULL;
+ }
+ response = resp->getContent();
+ if (response == NULL) {
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "no content found");
+ return NULL;
+ }
+
+ // process result
+ // first look for errorCode="" to look for success clue
+ // and errorReason="..." to extract error reason
+ char pattern[20] = "errorCode=\"0\"";
+ char * err = strstr((char *)response, (char *)pattern);
+
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "begin parsing err: %s", err);
+
+ if (err == NULL) {
+ RA::Error("CertEnroll::parseResponse",
+ "can't find pattern for cert request response");
+ goto endParseResp;
+ }
+
+ // if success, look for "outputList.outputVal=" to extract
+ // the cert
+ certB64 = strstr((char *)response, "outputVal=");
+ certB64 = &certB64[11]; // point pass open "
+
+ certB64End = strstr(certB64, "\";");
+ *certB64End = '\0';
+
+ certB64Len = strlen(certB64);
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "certB64 len = %d", certB64Len);
+
+ for (i=0; i<certB64Len-1 ; i++) {
+ if (certB64[i] == '\\') { certB64[i] = ' '; certB64[i+1] = ' '; }
+ }
+
+ // b64 decode and put back in blob
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "b64 decode received cert");
+
+ outItemOpt = NSSBase64_DecodeBuffer(NULL, NULL, certB64, certB64Len);
+ if (outItemOpt == NULL) {
+ RA::Error("CertEnroll::parseResponse",
+ "b64 decode failed");
+
+ goto endParseResp;
+ }
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "b64 decode len =%d",outItemOpt->len);
+
+ memcpy((char*)blob, (const char*)(outItemOpt->data), outItemOpt->len);
+ blob_len = outItemOpt->len;
+
+ cert = new Buffer((BYTE *) blob, blob_len);
+ if( outItemOpt != NULL ) {
+ SECITEM_FreeItem( outItemOpt, PR_TRUE );
+ outItemOpt = NULL;
+ }
+
+ RA::Debug(LL_PER_PDU, "CertEnroll::parseResponse",
+ "finished");
+
+ endParseResp:
+ resp->freeContent();
+ return cert;
+}
+
diff --git a/base/tps/src/cms/ConnectionInfo.cpp b/base/tps/src/cms/ConnectionInfo.cpp
new file mode 100644
index 000000000..3ab503c5d
--- /dev/null
+++ b/base/tps/src/cms/ConnectionInfo.cpp
@@ -0,0 +1,78 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plstr.h"
+#include "cms/ConnectionInfo.h"
+#include "engine/RA.h"
+#include "httpClient/httpc/engine.h"
+#include "main/Util.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a base processor.
+ */
+TPS_PUBLIC ConnectionInfo::ConnectionInfo ()
+{
+ for( int i = 0; i < HOST_PORT_MEMBERS; i++ ) {
+ m_hostPortList[i] = NULL;
+ }
+}
+
+/**
+ * Destructs processor.
+ */
+TPS_PUBLIC ConnectionInfo::~ConnectionInfo()
+{
+ for (int i=0; i<m_len; i++) {
+ if( m_hostPortList[i] != NULL ) {
+ PL_strfree( m_hostPortList[i] );
+ m_hostPortList[i] = NULL;
+ }
+ }
+}
+
+TPS_PUBLIC void ConnectionInfo::BuildFailoverList(const char *str) {
+ char *lasts = NULL;
+ char *tok = PL_strtok_r((char *)str, " ", &lasts);
+ m_len = 0;
+ while (tok != NULL) {
+ m_hostPortList[m_len] = PL_strdup(tok);
+ tok = PL_strtok_r(NULL, " ", &lasts);
+ m_len++;
+ }
+}
+
+TPS_PUBLIC int ConnectionInfo::GetHostPortListLen() {
+ return m_len;
+}
+
+TPS_PUBLIC char **ConnectionInfo::GetHostPortList() {
+ return m_hostPortList;
+}
+
diff --git a/base/tps/src/cms/HttpConnection.cpp b/base/tps/src/cms/HttpConnection.cpp
new file mode 100644
index 000000000..89f773557
--- /dev/null
+++ b/base/tps/src/cms/HttpConnection.cpp
@@ -0,0 +1,245 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cms/HttpConnection.h"
+#include "main/Memory.h"
+#include "main/NameValueSet.h"
+#include "engine/RA.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a base class for HttpConnection
+ */
+TPS_PUBLIC HttpConnection::HttpConnection(const char *id, ConnectionInfo *cinfo, int retries, int timeout,
+ bool isSSL, const char *nickname, bool keepAlive, NameValueSet *headers)
+{
+ m_failoverList = cinfo;
+ m_retries = retries;
+ m_timeout = timeout;
+ m_Id = PL_strdup(id);
+ m_isSSL = isSSL;
+ m_clientnickname = PL_strdup(nickname);
+ m_keepAlive = keepAlive;
+ m_headers = headers;
+ m_curr = 0;
+ m_lock = PR_NewLock();
+}
+
+/**
+ * Destructs processor.
+ */
+TPS_PUBLIC HttpConnection::~HttpConnection ()
+{
+ if( m_clientnickname != NULL ) {
+ PL_strfree( m_clientnickname );
+ m_clientnickname = NULL;
+ }
+ if( m_Id != NULL ) {
+ PL_strfree( m_Id );
+ m_Id = NULL;
+ }
+ if( m_failoverList != NULL ) {
+ delete m_failoverList;
+ m_failoverList = NULL;
+ }
+ if( m_headers != NULL ) {
+ delete m_headers;
+ m_headers = NULL;
+ }
+ if( m_lock != NULL ) {
+ PR_DestroyLock( m_lock );
+ m_lock = NULL;
+ }
+}
+
+TPS_PUBLIC int HttpConnection::GetNumOfRetries() {
+ return m_retries;
+}
+
+int HttpConnection::GetTimeout() {
+ return m_timeout;
+}
+
+TPS_PUBLIC ConnectionInfo *HttpConnection::GetFailoverList() {
+ return m_failoverList;
+}
+
+TPS_PUBLIC char *HttpConnection::GetId() {
+ return m_Id;
+}
+
+TPS_PUBLIC bool HttpConnection::IsSSL() {
+ return m_isSSL;
+}
+
+TPS_PUBLIC char * HttpConnection::GetClientNickname() {
+ return m_clientnickname;
+}
+
+TPS_PUBLIC bool HttpConnection::IsKeepAlive() {
+ return m_keepAlive;
+}
+
+TPS_PUBLIC PSHttpResponse *HttpConnection::getResponse(int index, const char *servlet, const char *body) {
+ char *host_port;
+ char uri[800];
+ char *nickname;
+ const char *httpprotocol;
+
+ ConnectionInfo *failoverList = GetFailoverList();
+ int len = failoverList->ConnectionInfo::GetHostPortListLen();
+ if (index >= len) {
+ index = len - 1; // use the last one
+ }
+ host_port= (failoverList->GetHostPortList())[index];
+
+ if (IsSSL()) {
+ httpprotocol = "https";
+ } else {
+ httpprotocol = "http";
+ }
+
+ PR_snprintf((char *)uri, 800,
+ "%s://%s/%s",
+ httpprotocol, host_port, servlet);
+
+ RA::Debug("HttpConnection::getResponse", "Send request to host %s servlet %s", host_port, servlet);
+
+ RA::Debug(LL_PER_PDU, "HttpConnection::getResponse", "uri=%s", uri);
+ RA::Debug(LL_PER_PDU, "HttpConnection::getResponse", "host_port=%s", host_port);
+
+ char *pPort = NULL;
+ char *pPortActual = NULL;
+
+
+ char hostName[512];
+
+ /*
+ * Isolate the host name, account for IPV6 numeric addresses.
+ *
+ */
+
+ if(host_port)
+ strncpy(hostName,host_port,512);
+
+ pPort = hostName;
+ while(1) {
+ pPort = strchr(pPort, ':');
+ if (pPort) {
+ pPortActual = pPort;
+ pPort++;
+ } else
+ break;
+ }
+
+ if(pPortActual)
+ *pPortActual = '\0';
+
+
+ /*
+ * Rifle through the values for the host
+ */
+
+ PRAddrInfo *ai;
+ void *iter;
+ PRNetAddr addr;
+ int family = PR_AF_INET;
+
+ ai = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+ if (ai) {
+ printf("%s\n", PR_GetCanonNameFromAddrInfo(ai));
+ iter = NULL;
+ while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+ char buf[512];
+ PR_NetAddrToString(&addr, buf, sizeof buf);
+ RA::Debug( LL_PER_PDU,
+ "HttpConnection::getResponse: ",
+ "Sending addr -- Msg='%s'\n",
+ buf );
+ family = PR_NetAddrFamily(&addr);
+ RA::Debug( LL_PER_PDU,
+ "HttpConnection::getResponse: ",
+ "Sending family -- Msg='%d'\n",
+ family );
+ break;
+ }
+ PR_FreeAddrInfo(ai);
+
+ }
+
+ PSHttpServer httpserver(host_port, family);
+ nickname = GetClientNickname();
+ if (IsSSL())
+ httpserver.setSSL(PR_TRUE);
+ else
+ httpserver.setSSL(PR_FALSE);
+
+ PSHttpRequest httprequest(&httpserver, uri, HTTP11, 0);
+ if (IsSSL()) {
+ httprequest.setSSL(PR_TRUE);
+ if (nickname != NULL) {
+ httprequest.setCertNickName(nickname);
+ } else {
+ return NULL;
+ }
+ } else
+ httprequest.setSSL(PR_FALSE);
+
+ httprequest.setMethod("POST");
+
+ if (body != NULL) {
+ httprequest.setBody( strlen(body), body);
+ }
+
+ httprequest.addHeader( "Content-Type", "application/x-www-form-urlencoded" );
+ if (m_headers != NULL) {
+ for (int i=0; i<m_headers->Size(); i++) {
+ char *name = m_headers->GetNameAt(i);
+ httprequest.addHeader(name, m_headers->GetValue(name));
+ }
+ }
+
+ if (IsKeepAlive())
+ httprequest.addHeader( "Connection", "keep-alive" );
+
+ HttpEngine httpEngine;
+ return httpEngine.makeRequest(httprequest, httpserver, (PRIntervalTime)GetTimeout(),
+ PR_FALSE /*expectChunked*/);
+}
+
+TPS_PUBLIC PRLock * HttpConnection::GetLock() {
+ return m_lock;
+}
+
+TPS_PUBLIC int HttpConnection::GetCurrentIndex() {
+ return m_curr;
+}
+
+TPS_PUBLIC void HttpConnection::SetCurrentIndex(int index) {
+ m_curr = index;
+}
diff --git a/base/tps/src/engine/RA.cpp b/base/tps/src/engine/RA.cpp
new file mode 100644
index 000000000..862b9e105
--- /dev/null
+++ b/base/tps/src/engine/RA.cpp
@@ -0,0 +1,3624 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+//#include <wchar.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "httpd/httpd.h"
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "plhash.h"
+#include "pk11func.h"
+#include "cert.h"
+#include "certt.h"
+#include "secerr.h"
+#include "tus/tus_db.h"
+#include "secder.h"
+#include "nss.h"
+#include "nssb64.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "main/Memory.h"
+#include "main/ConfigStore.h"
+#include "main/RA_Context.h"
+#include "channel/Secure_Channel.h"
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "cms/HttpConnection.h"
+#include "main/RA_pblock.h"
+#include "main/LogFile.h"
+#include "main/RollingLogFile.h"
+#include "selftests/SelfTest.h"
+
+typedef struct
+{
+ enum
+ {
+ PW_NONE = 0,
+ PW_FROMFILE = 1,
+ PW_PLAINTEXT = 2,
+ PW_EXTERNAL = 3
+ } source;
+ char *data;
+} secuPWData;
+
+
+static ConfigStore *m_cfg = NULL;
+static LogFile* m_debug_log = (LogFile *)NULL;
+static LogFile* m_error_log = (LogFile *)NULL;
+static LogFile* m_audit_log = (LogFile *)NULL;
+static LogFile* m_selftest_log = (LogFile *)NULL;
+
+static int tokendbInitialized = 0;
+static int tpsConfigured = 0;
+
+RA_Context *RA::m_ctx = NULL;
+bool RA::m_pod_enable=false;
+int RA::m_pod_curr = 0;
+PRLock *RA::m_pod_lock = NULL;
+int RA::m_auth_curr;
+PRLock *RA::m_verify_lock = NULL;
+PRLock *RA::m_auth_lock = NULL;
+PRLock *RA::m_debug_log_lock = NULL;
+PRLock *RA::m_error_log_lock = NULL;
+PRLock *RA::m_selftest_log_lock = NULL;
+PRLock *RA::m_config_lock = NULL;
+PRMonitor *RA::m_audit_log_monitor = NULL;
+bool RA::m_audit_enabled = false;
+bool RA::m_audit_signed = false;
+SECKEYPrivateKey *RA::m_audit_signing_key = NULL;
+NSSUTF8 *RA::m_last_audit_signature = NULL;
+SECOidTag RA::m_audit_signAlgTag;
+SecurityLevel RA::m_global_security_level;
+char *RA::m_signedAuditSelectedEvents = NULL;
+char *RA::m_signedAuditSelectableEvents = NULL;
+char *RA::m_signedAuditNonSelectableEvents = NULL;
+
+char *RA::m_audit_log_buffer = NULL;
+PRThread *RA::m_flush_thread = (PRThread *) NULL;
+size_t RA::m_bytes_unflushed =0;
+size_t RA::m_buffer_size = 512;
+int RA::m_flush_interval = 5;
+
+int RA::m_audit_log_level = (int) LL_PER_SERVER;
+int RA::m_debug_log_level = (int) LL_PER_SERVER;
+int RA::m_error_log_level = (int) LL_PER_SERVER;
+int RA::m_selftest_log_level = (int) LL_PER_SERVER;
+int RA::m_caConns_len = 0;
+int RA::m_tksConns_len = 0;
+int RA::m_drmConns_len = 0;
+int RA::m_auth_len = 0;
+
+#define MAX_BODY_LEN 4096
+
+#define MAX_CA_CONNECTIONS 20
+#define MAX_TKS_CONNECTIONS 20
+#define MAX_DRM_CONNECTIONS 20
+#define MAX_AUTH_LIST_MEMBERS 20
+HttpConnection* RA::m_caConnection[MAX_CA_CONNECTIONS];
+HttpConnection* RA::m_tksConnection[MAX_TKS_CONNECTIONS];
+AuthenticationEntry* RA::m_auth_list[MAX_AUTH_LIST_MEMBERS];
+HttpConnection* RA::m_drmConnection[MAX_DRM_CONNECTIONS];
+int RA::m_num_publishers = 0;
+PublisherEntry *RA::publisher_list = NULL;
+
+/* TKS response parameters */
+const char *RA::TKS_RESPONSE_STATUS = "status";
+const char *RA::TKS_RESPONSE_SessionKey = "sessionKey";
+const char *RA::TKS_RESPONSE_EncSessionKey = "encSessionKey";
+const char *RA::TKS_RESPONSE_KEK_DesKey = "kek_wrapped_desKey";
+const char *RA::TKS_RESPONSE_DRM_Trans_DesKey = "drm_trans_wrapped_desKey";
+const char *RA::TKS_RESPONSE_HostCryptogram = "hostCryptogram";
+
+const char *RA::CFG_DEBUG_ENABLE = "logging.debug.enable";
+const char *RA::CFG_DEBUG_FILENAME = "logging.debug.filename";
+const char *RA::CFG_DEBUG_LEVEL = "logging.debug.level";
+const char *RA::CFG_AUDIT_ENABLE = "logging.audit.enable";
+const char *RA::CFG_AUDIT_FILENAME = "logging.audit.filename";
+const char *RA::CFG_SIGNED_AUDIT_FILENAME = "logging.audit.signedAuditFilename";
+const char *RA::CFG_AUDIT_LEVEL = "logging.audit.level";
+const char *RA::CFG_AUDIT_SIGNED = "logging.audit.logSigning";
+const char *RA::CFG_AUDIT_SIGNING_CERT_NICK = "logging.audit.signedAuditCertNickname";
+const char *RA::CFG_ERROR_ENABLE = "logging.error.enable";
+const char *RA::CFG_ERROR_FILENAME = "logging.error.filename";
+const char *RA::CFG_ERROR_LEVEL = "logging.error.level";
+const char *RA::CFG_SELFTEST_ENABLE = "selftests.container.logger.enable";
+const char *RA::CFG_SELFTEST_FILENAME = "selftests.container.logger.fileName";
+const char *RA::CFG_SELFTEST_LEVEL = "selftests.container.logger.level";
+const char *RA::CFG_CHANNEL_SEC_LEVEL = "channel.securityLevel";
+const char *RA::CFG_CHANNEL_ENCRYPTION = "channel.encryption";
+const char *RA::CFG_APPLET_CARDMGR_INSTANCE_AID = "applet.aid.cardmgr_instance";
+const char *RA::CFG_APPLET_NETKEY_INSTANCE_AID = "applet.aid.netkey_instance";
+const char *RA::CFG_APPLET_NETKEY_FILE_AID = "applet.aid.netkey_file";
+const char *RA::CFG_APPLET_NETKEY_OLD_INSTANCE_AID = "applet.aid.netkey_old_instance";
+const char *RA::CFG_APPLET_NETKEY_OLD_FILE_AID = "applet.aid.netkey_old_file";
+const char *RA::CFG_APPLET_SO_PIN = "applet.so_pin";
+const char *RA::CFG_APPLET_DELETE_NETKEY_OLD = "applet.delete_old";
+const char *RA::CFG_AUDIT_SELECTED_EVENTS="logging.audit.selected.events";
+const char *RA::CFG_AUDIT_NONSELECTABLE_EVENTS="logging.audit.nonselectable.events";
+const char *RA::CFG_AUDIT_SELECTABLE_EVENTS="logging.audit.selectable.events";
+const char *RA::CFG_AUDIT_BUFFER_SIZE = "logging.audit.buffer.size";
+const char *RA::CFG_AUDIT_FLUSH_INTERVAL = "logging.audit.flush.interval";
+const char *RA::CFG_AUDIT_FILE_TYPE = "logging.audit.file.type";
+const char *RA::CFG_DEBUG_FILE_TYPE = "logging.debug.file.type";
+const char *RA::CFG_ERROR_FILE_TYPE = "logging.error.file.type";
+const char *RA::CFG_SELFTEST_FILE_TYPE = "selftests.container.logger.file.type";
+const char *RA::CFG_AUDIT_PREFIX = "logging.audit";
+const char *RA::CFG_ERROR_PREFIX = "logging.error";
+const char *RA::CFG_DEBUG_PREFIX = "logging.debug";
+const char *RA::CFG_SELFTEST_PREFIX = "selftests.container.logger";
+
+const char *RA::CFG_AUTHS_ENABLE="auth.enable";
+
+/* default values */
+const char *RA::CFG_DEF_CARDMGR_INSTANCE_AID = "A0000000030000";
+const char *RA::CFG_DEF_NETKEY_INSTANCE_AID = "627601FF000000";
+const char *RA::CFG_DEF_NETKEY_FILE_AID = "627601FF0000";
+const char *RA::CFG_DEF_NETKEY_OLD_INSTANCE_AID = "A00000000101";
+const char *RA::CFG_DEF_NETKEY_OLD_FILE_AID = "A000000001";
+const char *RA::CFG_DEF_APPLET_SO_PIN = "000000000000";
+
+typedef IPublisher* (*makepublisher)();
+typedef Authentication* (*makeauthentication)();
+
+extern void BuildHostPortLists(char *host, char *port, char **hostList,
+ char **portList, int len);
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Registration Authority object.
+ */
+RA::RA ()
+{
+}
+
+/**
+ * Destructs a Registration Authority object.
+ */
+RA::~RA ()
+{
+ do_free(m_signedAuditSelectedEvents);
+ do_free(m_signedAuditSelectableEvents);
+ do_free(m_signedAuditNonSelectableEvents);
+
+ if (m_cfg != NULL) {
+ delete m_cfg;
+ m_cfg = NULL;
+ }
+}
+
+TPS_PUBLIC ConfigStore *RA::GetConfigStore()
+{
+ return m_cfg;
+}
+
+PRLock *RA::GetVerifyLock()
+{
+ return m_verify_lock;
+}
+
+PRLock *RA::GetConfigLock()
+{
+ return m_config_lock;
+}
+
+void RA::do_free(char *p)
+{
+ if (p != NULL) {
+ PR_Free(p);
+ p = NULL;
+ }
+}
+
+int RA::InitializeSignedAudit()
+{
+ // cfu
+ RA::Debug("RA:: InitializeSignedAudit", "begins pid: %d",getpid());
+ tpsConfigured = m_cfg->GetConfigAsBool("tps.configured", false);
+ // During installation config, don't do this
+ if (IsTpsConfigured() && (m_audit_signed == true) && (m_audit_signing_key == NULL)) {
+ RA::Debug("RA:: InitializeSignedAudit", "signed audit is on... initializing signing key...");
+ // get audit signing cert
+ const char *audit_signing_cert_nick = m_cfg->GetConfigAsString(CFG_AUDIT_SIGNING_CERT_NICK, "auditSigningCert cert-pki-tps");
+ char certNick[256];
+ PR_snprintf((char *)certNick, 256, audit_signing_cert_nick);
+ RA::Debug("RA:: InitializeSignedAudit", "got audit signing cert nickname: %s", certNick);
+
+ CERTCertDBHandle *cert_handle = 0;
+ cert_handle = CERT_GetDefaultCertDB();
+ if (cert_handle == 0) {
+ RA::Debug("RA:: InitializeSignedAudit", "did not get cert_handle");
+ goto loser;
+ } else {
+ RA::Debug("RA:: InitializeSignedAudit", "got cert_handle");
+ }
+ CERTCertificate *cert = NULL;
+ cert = CERT_FindCertByNickname( cert_handle, (char *) certNick );
+ if (cert != NULL) { // already configed
+ RA::Debug("RA:: InitializeSignedAudit", "got audit signing cert");
+ // get private key from cert
+ m_audit_signing_key =
+ PK11_FindKeyByAnyCert(cert, /*wincx*/ NULL);
+ if (m_audit_signing_key == NULL) {
+ RA::Debug("RA:: InitializeSignedAudit", "audit signing key not initialized...");
+ goto loser;
+ } else {
+ RA::Debug("RA:: InitializeSignedAudit", "got audit signing key");
+ }
+ switch(m_audit_signing_key->keyType) {
+ case rsaKey:
+ m_audit_signAlgTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
+ break;
+ case dsaKey:
+ m_audit_signAlgTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
+ break;
+ default:
+ RA::Debug("RA:: InitializeSignedAudit", "unknown key type for audit signing cert");
+ goto loser;
+ break;
+ } //switch
+ RA::Debug("RA:: InitializeSignedAudit", "audit signing initialized");
+// m_cfg->Add("tps.signedAudit.initialized", "true");
+ } else {
+ RA::Debug("RA:: InitializeSignedAudit", "no audit signing cert found... still configuring...");
+ }
+
+ RA::getLastSignature();
+ if (cert != NULL) {
+ CERT_DestroyCertificate(cert);
+ cert = NULL;
+ }
+ } // if (m_audit_signed == true)
+
+ // Initialize audit flush thread
+ if (IsTpsConfigured() && (m_flush_thread == NULL)) {
+ m_flush_thread = PR_CreateThread( PR_USER_THREAD, RunFlushThread, (void *) NULL,
+ PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */);
+ }
+
+ return 0;
+loser:
+ RA::Debug("RA:: InitializeSignedAudit", "audit function startup failed");
+ return -1;
+//do something
+}
+
+void RA::RunFlushThread(void *arg) {
+ RA::Debug("RA::FlushThread", "Starting audit flush thread");
+ while (m_flush_interval >0) {
+ PR_Sleep(PR_SecondsToInterval(m_flush_interval));
+ if (m_flush_interval ==0)
+ break;
+ if (m_bytes_unflushed > 0)
+ FlushAuditLogBuffer();
+ }
+}
+
+/*
+ * read off the last sig record of the audit file for computing MAC
+ */
+void RA::getLastSignature() {
+ char line[1024];
+ char *sig = NULL;
+
+ RA::Debug("RA:: getLastSignature", "starts");
+ if ((m_audit_log != NULL) && (m_audit_log_monitor != NULL)) {
+ PR_EnterMonitor(m_audit_log_monitor);
+ int removed_return;
+ while (1) {
+ int n = m_audit_log->ReadLine(line, 1024, &removed_return);
+ if (n > 0) {
+ sig = strstr(line, "AUDIT_LOG_SIGNING");
+ if (sig != NULL) {
+ // sig entry found
+ m_last_audit_signature = PL_strdup(line);
+ }
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ RA::Debug("RA:: getLastSignature", "ends");
+ PR_ExitMonitor(m_audit_log_monitor);
+ }
+
+ if (m_last_audit_signature != NULL) {
+ RA::Debug("RA:: getLastSignature", "got last sig from file: %s",
+ m_last_audit_signature);
+ }
+}
+
+TPS_PUBLIC LogFile* RA::GetLogFile(const char *log_type)
+{
+ if (strcmp(log_type, "RollingLogFile") == 0) {
+ return new RollingLogFile();
+ } else {
+ return new LogFile(); // default
+ }
+}
+
+/**
+ * Initializes RA with the given configuration file.
+ */
+TPS_PUBLIC int RA::Initialize(char *cfg_path, RA_Context *ctx)
+{
+ int rc = -1;
+ int i = 0;
+ int status = 0;
+
+ // Authentication *auth;
+ // int secLevel = 0; // for getting config param
+ bool global_enc = false;
+ SecurityLevel security_level = SECURE_MSG_MAC_ENC;
+
+ m_verify_lock = PR_NewLock();
+ m_debug_log_lock = PR_NewLock();
+ m_error_log_lock = PR_NewLock();
+ m_selftest_log_lock = PR_NewLock();
+ m_config_lock = PR_NewLock();
+ m_cfg = ConfigStore::CreateFromConfigFile(cfg_path);
+ if( m_cfg == NULL ) {
+ rc = -2;
+ goto loser;
+ }
+
+ m_ctx = ctx;
+
+ if (m_cfg->GetConfigAsBool(CFG_DEBUG_ENABLE, 0)) {
+ m_debug_log = GetLogFile(m_cfg->GetConfigAsString(CFG_DEBUG_FILE_TYPE, "LogFile"));
+ status = m_debug_log->startup(ctx, CFG_DEBUG_PREFIX,
+ m_cfg->GetConfigAsString(CFG_DEBUG_FILENAME, "/tmp/debug.log"),
+ false);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_debug_log->open();
+ if (status != PR_SUCCESS)
+ goto loser;
+ }
+
+ m_error_log_level = m_cfg->GetConfigAsInt(CFG_ERROR_LEVEL, (int) LL_PER_SERVER);
+ m_debug_log_level = m_cfg->GetConfigAsInt(CFG_DEBUG_LEVEL, (int) LL_PER_SERVER);
+ m_selftest_log_level = m_cfg->GetConfigAsInt(CFG_SELFTEST_LEVEL, (int) LL_PER_SERVER);
+
+ if (m_cfg->GetConfigAsBool(CFG_ERROR_ENABLE, 0)) {
+ m_error_log = GetLogFile(m_cfg->GetConfigAsString(CFG_ERROR_FILE_TYPE, "LogFile"));
+ status = m_error_log->startup(ctx, CFG_ERROR_PREFIX,
+ m_cfg->GetConfigAsString(CFG_ERROR_FILENAME, "/tmp/error.log"),
+ false);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_error_log->open();
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ }
+
+ if (m_cfg->GetConfigAsBool(CFG_SELFTEST_ENABLE, 0)) {
+ m_selftest_log = GetLogFile(m_cfg->GetConfigAsString(CFG_SELFTEST_FILE_TYPE, "LogFile"));
+ status = m_selftest_log->startup(ctx, CFG_SELFTEST_PREFIX,
+ m_cfg->GetConfigAsString(CFG_SELFTEST_FILENAME, "/tmp/selftest.log"),
+ false);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_selftest_log->open();
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ }
+
+
+ RA::Debug("RA:: Initialize", "CS TPS starting...");
+
+ rc = InitializeTokendb(cfg_path);
+ if( rc != LDAP_SUCCESS ) {
+ RA::Debug("RA:: Initialize", "Token DB initialization failed, server continues");
+ ctx->LogError( "RA::Initialize",
+ __LINE__,
+ "The TPS plugin could NOT load the "
+ "Tokendb library! See specific details in the "
+ "TPS plugin log files." );
+ // Since the server hasn't started yet, there is
+ // no need to perform a call to RA::Shutdown()!
+ //goto loser;
+ } else
+ RA::Debug("RA:: Initialize", "Token DB initialization succeeded");
+
+ //testTokendb();
+
+ m_pod_enable = m_cfg->GetConfigAsBool("failover.pod.enable", false);
+ m_pod_curr = 0;
+ m_auth_curr = 0;
+ m_pod_lock = PR_NewLock();
+ m_auth_lock = PR_NewLock();
+
+
+ // make encryption not default for operations globally
+ // individual security levels can override
+ // secLevel = RA::GetConfigAsInt(RA::CFG_CHANNEL_SEC_LEVEL,
+ // SECURE_MSG_MAC);
+
+ global_enc = m_cfg->GetConfigAsBool(RA::CFG_CHANNEL_ENCRYPTION, true);
+ if (global_enc == true)
+ security_level = SECURE_MSG_MAC_ENC;
+ else
+ security_level = SECURE_MSG_MAC;
+
+ RA::SetGlobalSecurityLevel(security_level);
+
+ // Initialize the CA connection pool to be empty
+ for (i=0; i<MAX_CA_CONNECTIONS; i++) {
+ m_caConnection[i] = NULL;
+ }
+
+ // Initialize the TKS connection pool to be empty
+ for (i=0; i<MAX_TKS_CONNECTIONS; i++) {
+ m_tksConnection[i] = NULL;
+ }
+
+ // Initialize the DRM connection pool to be empty
+ for (i=0; i<MAX_DRM_CONNECTIONS; i++) {
+ m_drmConnection[i] = NULL;
+ }
+
+ // Initialize the authentication list to be empty
+ for (i=0; i<MAX_AUTH_LIST_MEMBERS; i++) {
+ m_auth_list[i] = NULL;
+ }
+
+ // even rc != 0, we still go ahead starting up the server.
+ rc = InitializeAuthentication();
+
+ //Initialize Publisher Library
+ InitializePublishers();
+
+ rc = 1;
+loser:
+
+ // Log the status of this TPS plugin into the web server's log:
+ if( rc != 1 ) {
+ ctx->LogError( "RA::Initialize",
+ __LINE__,
+ "The TPS plugin could NOT be "
+ "loaded (rc = %d)! See specific details in the "
+ "TPS plugin log files.", rc );
+ } else {
+ ctx->LogInfo( "RA::Initialize",
+ __LINE__,
+ "The TPS plugin was "
+ "successfully loaded!" );
+ }
+ return rc;
+}
+
+int RA::InitializeInChild(RA_Context *ctx, int nSignedAuditInitCount) {
+
+ int rc = -1;
+ SECStatus rv;
+ int status = 0;
+ char configname[256];
+
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild", "begins: %d pid: %d ppid: %d",
+ nSignedAuditInitCount,getpid(),getppid());
+ if (!NSS_IsInitialized()) {
+
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild", "Initializing NSS");
+
+ PR_snprintf((char *)configname, 256, "%s/alias",
+ m_cfg->GetConfigAsString("service.instanceDir", NULL));
+ rv = NSS_Initialize (configname, "", "", SECMOD_DB, NSS_INIT_READONLY);
+ if (rv != SECSuccess) {
+ RA::Error( LL_PER_SERVER, "RA::InitializeInChild",
+ "NSS not initialized successfully");
+ ctx->InitializationError( "RA::InitializeHttpConnections",
+ __LINE__ );
+ goto loser;
+ }
+ } else {
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild", "NSS already initialized");
+ }
+ //initialize CA Connections
+ status = InitializeHttpConnections("ca", &m_caConns_len,
+ m_caConnection, ctx);
+ if (status != 0) {
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild",
+ "Failed to initialize CA Connection, rc=%i",
+ (int)status);
+ goto loser;
+ }
+ // initialize TKS connections
+ status = InitializeHttpConnections("tks", &m_tksConns_len,
+ m_tksConnection, ctx);
+ if (status != 0) {
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild",
+ "Failed to initialize TKS Connection, rc=%i",
+ (int)status);
+ goto loser;
+ }
+ // initialize DRM connections
+ status = InitializeHttpConnections("drm", &m_drmConns_len,
+ m_drmConnection, ctx);
+ if (status != 0) {
+ RA::Debug( LL_PER_SERVER, "RA::InitializeInChild",
+ "Failed to initialize DRM Connection, rc=%i",
+ (int)status);
+ goto loser;
+ }
+
+ // open audit log
+ m_audit_log_monitor = PR_NewMonitor();
+ m_audit_log_level = m_cfg->GetConfigAsInt(CFG_AUDIT_LEVEL, (int) LL_PER_SERVER);
+
+ // get events for audit signing
+ m_signedAuditSelectedEvents = PL_strdup(m_cfg->GetConfigAsString(
+ CFG_AUDIT_SELECTED_EVENTS, ""));
+ m_signedAuditSelectableEvents = PL_strdup(m_cfg->GetConfigAsString(
+ CFG_AUDIT_SELECTABLE_EVENTS, ""));
+ m_signedAuditNonSelectableEvents= PL_strdup(m_cfg->GetConfigAsString(
+ CFG_AUDIT_NONSELECTABLE_EVENTS, ""));
+ m_audit_enabled = m_cfg->GetConfigAsBool(CFG_AUDIT_ENABLE, false);
+ m_buffer_size = m_cfg->GetConfigAsInt(CFG_AUDIT_BUFFER_SIZE, 512);
+ m_flush_interval = m_cfg->GetConfigAsInt(CFG_AUDIT_FLUSH_INTERVAL, 5);
+
+ if (m_audit_enabled && (nSignedAuditInitCount > 1 )) {
+ // is audit logSigning on?
+ m_audit_signed = m_cfg->GetConfigAsBool(CFG_AUDIT_SIGNED, false);
+ RA::Debug("RA:: InitializeInChild", "Audit signing is %s",
+ m_audit_signed? "true":"false");
+
+ m_audit_log = GetLogFile(m_cfg->GetConfigAsString(CFG_AUDIT_FILE_TYPE, "LogFile"));
+ status = m_audit_log->startup(ctx, CFG_AUDIT_PREFIX,
+ m_cfg->GetConfigAsString((m_audit_signed)?
+ CFG_SIGNED_AUDIT_FILENAME:CFG_AUDIT_FILENAME,
+ "/tmp/audit.log"),
+ m_audit_signed);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_audit_log->open();
+
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ m_audit_log_buffer = (char *) PR_Malloc(m_buffer_size);
+ if (m_audit_log_buffer == NULL) {
+ RA::Debug("RA:: Initialize", "Unable to allocate memory for audit log buffer ..");
+ goto loser;
+ }
+ PR_snprintf((char *) m_audit_log_buffer, m_buffer_size, "");
+ m_bytes_unflushed = 0;
+ }
+
+ RA::Debug("RA::InitializeInChild", "nSignedAuditInitCount=%i",
+ nSignedAuditInitCount);
+ if (NSS_IsInitialized() && (nSignedAuditInitCount >1)) {
+ status = InitializeSignedAudit();
+ if (status == 0) {
+ RA::Audit(EV_AUDIT_LOG_STARTUP, AUDIT_MSG_FORMAT, "System", "Success",
+ "audit function startup");
+ }
+
+ // As per CC requirements, we want to flush the audit log immediately
+ // to ensure that the audit log is not full
+ FlushAuditLogBuffer();
+
+ rc = SelfTest::runStartUpSelfTests(); // run general self tests
+ if (rc != 0) goto loser;
+ }
+
+ if (m_debug_log != NULL) {
+ m_debug_log->child_init();
+ }
+
+ if (m_error_log != NULL) {
+ m_error_log->child_init();
+ }
+
+ if (m_selftest_log != NULL) {
+ m_selftest_log->child_init();
+ }
+
+ if (m_audit_log != NULL) {
+ m_audit_log->child_init();
+ }
+
+ rc =1;
+loser:
+ // Log the status of this TPS plugin into the web server's log:
+ if( rc != 1 ) {
+ ctx->LogError( "RA::InitializeInChild",
+ __LINE__,
+ "The TPS plugin could NOT be "
+ "initialized (rc = %d)! See specific details in the "
+ "TPS plugin log files.", rc );
+ } else {
+ ctx->LogInfo( "RA::InitializeInChild",
+ __LINE__,
+ "The TPS plugin was "
+ "successfully initialized!" );
+ }
+
+ return rc;
+}
+
+int RA::testTokendb() {
+ // try to see if we can talk to the database
+ int st = 0;
+ LDAPMessage *ldapResult = NULL;
+ const char * filter = "(cn=0000000000080000*)";
+
+ if ((st = find_tus_db_entries(filter, 0, &ldapResult)) != LDAP_SUCCESS) {
+ RA::Debug("RA::testing", "response from token DB failed");
+ } else {
+ RA::Debug("RA::testing", "response from token DB succeeded");
+ }
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+
+ return st;
+}
+
+/*
+ * returns true if item is a value in the comma separated list
+ * used by audit logging functions and profile selection functions
+ */
+TPS_PUBLIC bool RA::match_comma_list(const char* item, char *list)
+{
+ char *pList = PL_strdup(list);
+ char *sresult = NULL;
+ char *lasts = NULL;
+
+ sresult = PL_strtok_r(pList, ",", &lasts);
+ while (sresult != NULL) {
+ if (PL_strcmp(sresult, item) == 0) {
+ if (pList != NULL) {
+ PR_Free(pList);
+ pList = NULL;
+ }
+ return true;
+ }
+ sresult = PL_strtok_r(NULL, ",", &lasts);
+ }
+ if (pList != NULL) {
+ PR_Free(pList);
+ pList = NULL;
+ }
+ return false;
+}
+
+/*
+ * return comma separated list with all instances of item removed
+ * must be freed by caller
+ */
+TPS_PUBLIC char* RA::remove_from_comma_list(const char*item, char *list)
+{
+ int len = PL_strlen(list);
+ char *pList=PL_strdup(list);
+ char *ret = (char *) PR_Malloc(len);
+ char *sresult = NULL;
+ char *lasts = NULL;
+
+
+ PR_snprintf(ret, len, "");
+ sresult = PL_strtok_r(pList, ",", &lasts);
+ while (sresult != NULL) {
+ if (PL_strcmp(sresult, item) != 0) {
+ PR_snprintf(ret, len, "%s%s%s", ret, (PL_strlen(ret)>0)? "," : "", sresult);
+ }
+ sresult = PL_strtok_r(NULL, ",",&lasts);
+ }
+ if (pList != NULL) {
+ PR_Free(pList);
+ pList = NULL;
+ }
+ return ret;
+}
+
+
+/*
+ * returns true if an audit event is valid, false if not
+ */
+bool RA::IsValidEvent(const char *auditEvent)
+{
+ return match_comma_list(auditEvent, m_signedAuditNonSelectableEvents) ||
+ match_comma_list(auditEvent, m_signedAuditSelectableEvents);
+}
+
+/*
+ * returns true if an audit event is selected, false if not
+ */
+bool RA::IsAuditEventSelected(const char* auditEvent)
+{
+ return match_comma_list(auditEvent, m_signedAuditNonSelectableEvents) ||
+ match_comma_list(auditEvent, m_signedAuditSelectedEvents);
+}
+
+int RA::IsTokendbInitialized()
+{
+ return tokendbInitialized;
+}
+
+int RA::IsTpsConfigured()
+{
+ return tpsConfigured;
+}
+
+TPS_PUBLIC int RA::Child_Shutdown()
+{
+ RA::Debug("RA::Child_Shutdown", "starts");
+ // clean up connections
+ if (m_caConnection != NULL) {
+ for (int i=0; i<m_caConns_len; i++) {
+ if( m_caConnection[i] != NULL ) {
+ delete m_caConnection[i];
+ m_caConnection[i] = NULL;
+ }
+ }
+ }
+
+ if (m_tksConnection != NULL) {
+ for (int i=0; i<m_tksConns_len; i++) {
+ if( m_tksConnection[i] != NULL ) {
+ delete m_tksConnection[i];
+ m_tksConnection[i] = NULL;
+ }
+ }
+ }
+ if (m_drmConnection != NULL) {
+ for (int i=0; i<m_drmConns_len; i++) {
+ if( m_drmConnection[i] != NULL ) {
+ delete m_drmConnection[i];
+ m_drmConnection[i] = NULL;
+ }
+ }
+ }
+
+ /* log audit log shutdown */
+ PR_EnterMonitor(m_audit_log_monitor);
+ if( (m_audit_log != NULL) && (m_audit_log->isOpen())) {
+ if (m_audit_log_buffer != NULL) {
+ m_flush_interval = 0; // terminate flush thread
+ PR_Interrupt(m_flush_thread);
+ if (m_flush_thread != NULL) {
+ PR_JoinThread(m_flush_thread);
+ }
+ }
+ if ((m_audit_signed) && (m_audit_signing_key != NULL)) {
+ RA::Audit(EV_AUDIT_LOG_SHUTDOWN, AUDIT_MSG_FORMAT, "System", "Success",
+ "audit function shutdown");
+ }
+
+ if (m_bytes_unflushed > 0) {
+ FlushAuditLogBuffer();
+ }
+ }
+
+ if (m_audit_log != NULL) {
+ m_audit_log->shutdown();
+ delete m_audit_log;
+ m_audit_log = NULL;
+ }
+
+ if (m_audit_log_buffer) {
+ PR_Free(m_audit_log_buffer);
+ m_audit_log_buffer = NULL;
+ }
+
+ PR_ExitMonitor(m_audit_log_monitor);
+
+ if( m_audit_log_monitor != NULL ) {
+ PR_DestroyMonitor( m_audit_log_monitor );
+ m_audit_log_monitor = NULL;
+ }
+
+ return 1;
+}
+
+
+/**
+ * Shutdown RA.
+ */
+TPS_PUBLIC int RA::Shutdown()
+{
+ RA::Debug("RA::Shutdown", "starts");
+
+ tus_db_end();
+ tus_db_cleanup();
+
+ if( m_pod_lock != NULL ) {
+ PR_DestroyLock( m_pod_lock );
+ m_pod_lock = NULL;
+ }
+
+ if( m_auth_lock != NULL ) {
+ PR_DestroyLock( m_auth_lock );
+ m_auth_lock = NULL;
+ }
+
+ /* close debug file if opened */
+ if ( m_debug_log != NULL ) {
+ m_debug_log->shutdown();
+ delete m_debug_log;
+ m_debug_log = NULL;
+ }
+
+ /* close error file if opened */
+ if( m_error_log != NULL ) {
+ m_error_log->shutdown();
+ delete m_error_log;
+ m_error_log = NULL;
+ }
+
+ /* close self test file if opened */
+ if( m_selftest_log != NULL ) {
+ m_selftest_log->shutdown();
+ delete m_selftest_log;
+ m_selftest_log = NULL;
+ }
+
+ if( m_verify_lock != NULL ) {
+ PR_DestroyLock( m_verify_lock );
+ m_verify_lock = NULL;
+ }
+
+ if( m_debug_log_lock != NULL ) {
+ PR_DestroyLock( m_debug_log_lock );
+ m_debug_log_lock = NULL;
+ }
+
+ if( m_error_log_lock != NULL ) {
+ PR_DestroyLock( m_error_log_lock );
+ m_error_log_lock = NULL;
+ }
+
+ if( m_selftest_log_lock != NULL ) {
+ PR_DestroyLock( m_selftest_log_lock );
+ m_selftest_log_lock = NULL;
+ }
+
+ if( m_config_lock != NULL ) {
+ PR_DestroyLock( m_config_lock );
+ m_config_lock = NULL;
+ }
+
+ if (m_auth_list != NULL) {
+ for (int i=0; i<m_auth_len; i++) {
+ if( m_auth_list[i] != NULL ) {
+ delete m_auth_list[i];
+ m_auth_list[i] = NULL;
+ }
+ }
+ }
+
+ /* destroy configuration hashtable */
+ if( m_cfg != NULL ) {
+ delete m_cfg;
+ m_cfg = NULL;
+ }
+
+ CleanupPublishers();
+
+ return 1;
+}
+
+HttpConnection *RA::GetTKSConn(const char *id) {
+ HttpConnection *tksconn = NULL;
+ for (int i=0; i<m_tksConns_len; i++) {
+ if (strcmp(m_tksConnection[i]->GetId(), id) == 0) {
+ tksconn = m_tksConnection[i];
+ break;
+ }
+ }
+ return tksconn;
+}
+
+HttpConnection *RA::GetDRMConn(const char *id) {
+ HttpConnection *drmconn = NULL;
+ for (int i=0; i<m_drmConns_len; i++) {
+ if (strcmp(m_drmConnection[i]->GetId(), id) == 0) {
+ drmconn = m_drmConnection[i];
+ break;
+ }
+ }
+ return drmconn;
+}
+
+void RA::ReturnTKSConn(HttpConnection *conn) {
+ // do nothing for now
+}
+
+void RA::ReturnDRMConn(HttpConnection *conn) {
+ // do nothing for now
+}
+
+HttpConnection *RA::GetCAConn(const char *id) {
+ HttpConnection *caconn = NULL;
+ if (id == NULL)
+ return NULL;
+ for (int i=0; i<m_caConns_len; i++) {
+ if (strcmp(m_caConnection[i]->GetId(), id) == 0) {
+ caconn = m_caConnection[i];
+ break;
+ }
+ }
+ return caconn;
+}
+
+AuthenticationEntry *RA::GetAuth(const char *id) {
+ AuthenticationEntry *authEntry = NULL;
+ for (int i=0; i<m_auth_len; i++) {
+ authEntry = m_auth_list[i];
+ if (strcmp(authEntry->GetId(), id) == 0)
+ return authEntry;
+ }
+ return NULL;
+}
+
+void RA::ReturnCAConn(HttpConnection *conn) {
+ // do nothing for now
+}
+
+TPS_PUBLIC PRLock *RA::GetAuthLock() {
+ return m_auth_lock;
+}
+
+int RA::GetPodIndex() {
+ PR_Lock(m_pod_lock);
+ int index = m_pod_curr;
+ PR_Unlock(m_pod_lock);
+ return index;
+}
+
+void RA::SetPodIndex(int index) {
+ PR_Lock(m_pod_lock);
+ m_pod_curr = index;
+ PR_Unlock(m_pod_lock);
+}
+
+void RA::SetCurrentIndex(HttpConnection *&conn, int index) {
+ PRLock *lock = conn->GetLock();
+ PR_Lock(lock);
+ conn->SetCurrentIndex(index);
+ PR_Unlock(lock);
+}
+
+int RA::GetCurrentIndex(HttpConnection *conn) {
+ PRLock *lock = conn->GetLock();
+ PR_Lock(lock);
+ int index = conn->GetCurrentIndex();
+ PR_Unlock(lock);
+ return index;
+}
+
+TPS_PUBLIC int RA::GetAuthCurrentIndex() {
+ PR_Lock(m_auth_lock);
+ int index = m_auth_curr;
+ PR_Unlock(m_auth_lock);
+ return index;
+}
+
+void RA::SetAuthCurrentIndex(int index) {
+ PR_Lock(m_auth_lock);
+ m_auth_curr = index;
+ PR_Unlock(m_auth_lock);
+}
+
+TPS_PUBLIC void RA::IncrementAuthCurrentIndex(int len) {
+ PR_Lock(m_auth_lock);
+ if ((++m_auth_curr) >= len)
+ m_auth_curr = 0;
+ PR_Unlock(m_auth_lock);
+}
+
+void RA::SetGlobalSecurityLevel(SecurityLevel sl) {
+ m_global_security_level = sl;
+ RA::Debug(" RA::SetGlobalSecurityLevel", "global security level set to %d", (int) sl);
+
+}
+
+SecurityLevel RA::GetGlobalSecurityLevel() {
+ return m_global_security_level;
+}
+
+
+/*
+ * recovers user encryption key that was previously archived.
+ * It expects DRM to search its archival db by cert.
+ *
+ * input:
+ * @param cuid (cuid of the recovering key's token)
+ * @param userid (uid of the recovering key owner
+ * @param desKey_s (came from TKS - session key wrapped with DRM transport
+ * @param cert (base64 encoded cert of the recovering key)
+ * @param connId (drm connectoin id)
+ *
+ * output:
+ * @param publickey_s public key provided by DRM
+ * @param wrappedPrivateKey_s encrypted private key provided by DRM
+ * @param ivParam_s returned intialization vector
+ */
+void RA::RecoverKey(RA_Session *session, const char* cuid,
+ const char *userid, char* desKey_s,
+ char *b64cert, char **publicKey_s,
+ char **wrappedPrivateKey_s, const char *connId, char **ivParam_s)
+{
+ int status;
+ PSHttpResponse *response = NULL;
+ HttpConnection *drmConn = NULL;
+ char body[MAX_BODY_LEN];
+ char configname[256];
+ char * cert_s;
+ int drm_curr = 0;
+ long s;
+ char * content = NULL;
+ char ** hostport= NULL;
+ const char* servletID = NULL;
+ char *wrappedDESKey_s= NULL;
+ Buffer *decodeKey = NULL;
+ ConnectionInfo *connInfo = NULL;
+ RA_pblock *ra_pb = NULL;
+ int currRetries = 0;
+ char *p = NULL;
+
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey");
+ if (cuid == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, cuid NULL");
+ goto loser;
+ }
+ if (userid == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, userid NULL");
+ goto loser;
+ }
+ if (b64cert == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, b64cert NULL");
+ goto loser;
+ }
+ if (desKey_s == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, desKey_s NULL");
+ goto loser;
+ }
+ if (connId == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, connId NULL");
+ goto loser;
+ }
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, desKey_s=%s, connId=%s",desKey_s, connId);
+
+ cert_s = Util::URLEncode(b64cert);
+ drmConn = RA::GetDRMConn(connId);
+ if (drmConn == NULL) {
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, failed getting drmconn");
+ goto loser;
+ }
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, got drmconn");
+ connInfo = drmConn->GetFailoverList();
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, got drm failover");
+ decodeKey = Util::URLDecode(desKey_s);
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey,url decoded des");
+ wrappedDESKey_s = Util::SpecialURLEncode(*decodeKey);
+
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, wrappedDESKey_s=%s", wrappedDESKey_s);
+
+ PR_snprintf((char *)body, MAX_BODY_LEN,
+ "CUID=%s&userid=%s&drm_trans_desKey=%s&cert=%s",cuid, userid, wrappedDESKey_s, cert_s);
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, body=%s", body);
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.TokenKeyRecovery", connId);
+ servletID = GetConfigStore()->GetConfigAsString(configname);
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey, configname=%s", configname);
+
+ drm_curr = RA::GetCurrentIndex(drmConn);
+ response = drmConn->getResponse(drm_curr, servletID, body);
+ hostport = connInfo->GetHostPortList();
+ if (response == NULL) {
+ RA::Debug(LL_PER_PDU, "The recoverKey response from DRM ",
+ "at %s is NULL.", hostport[drm_curr]);
+
+ //goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "The recoverKey response from DRM ",
+ "at %s is not NULL.", hostport[drm_curr]);
+ }
+
+ while (response == NULL) {
+ RA::Failover(drmConn, connInfo->GetHostPortListLen());
+
+ drm_curr = RA::GetCurrentIndex(drmConn);
+ RA::Debug(LL_PER_PDU, "RA is reconnecting to DRM ",
+ "at %s for recoverKey.", hostport[drm_curr]);
+
+ if (++currRetries >= drmConn->GetNumOfRetries()) {
+ RA::Debug("Used up all the retries in recoverKey. Response is NULL","");
+ RA::Error("RA::RecoverKey","Failed connecting to DRM after %d retries", currRetries);
+
+ goto loser;
+ }
+ response = drmConn->getResponse(drm_curr, servletID, body);
+ }
+
+ RA::Debug(" RA:: RecoverKey", "in RecoverKey - got response");
+ // XXXskip handling fallback host for prototype
+
+ content = response->getContent();
+ p = strstr(content, "status=");
+ content = p; //skip the HTTP header
+
+ s = response->getStatus();
+
+ if ((content != NULL) && (s == 200)) {
+ RA::Debug("RA::RecoverKey", "response from DRM status ok");
+
+ Buffer* status_b;
+ char* status_s;
+
+ ra_pb = ( RA_pblock * ) session->create_pblock(content);
+ if (ra_pb == NULL)
+ goto loser;
+
+ status_b = ra_pb->find_val("status");
+ if (status_b == NULL) {
+ status = 4;
+ goto loser;
+ }
+ else {
+ status_s = status_b->string();
+ status = atoi(status_s);
+ if (status_s != NULL) {
+ PR_Free(status_s);
+ }
+ }
+
+
+ char * tmp = NULL;
+ tmp = ra_pb->find_val_s("public_key");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_PDU, "RecoverKey"," got no public key");
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RecoverKey", "got public key =%s", tmp);
+ *publicKey_s = PL_strdup(tmp);
+ }
+
+ tmp = NULL;
+ tmp = ra_pb->find_val_s("wrapped_priv_key");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_PDU, "RecoverKey"," got no wrapped private key");
+ //XXX goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RecoverKey", "got wrappedprivate key =%s", tmp);
+ *wrappedPrivateKey_s = PL_strdup(tmp);
+ }
+
+ tmp = ra_pb->find_val_s("iv_param");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_PDU, "RecoverKey",
+ "did not get iv_param for recovered key in DRM response");
+ } else {
+ RA::Debug(LL_PER_PDU, "ServerSideKeyGen", "got iv_param for recovered key =%s", tmp);
+ *ivParam_s = PL_strdup(tmp);
+ }
+
+ } else {// if content is NULL or status not 200
+ if (content != NULL)
+ RA::Debug("RA::RecoverKey", "response from DRM error status %ld", s);
+ else
+ RA::Debug("RA::RecoverKey", "response from DRM no content");
+ }
+ loser:
+ if (desKey_s != NULL)
+ PR_Free(desKey_s);
+
+ if (decodeKey != NULL)
+ PR_Free(decodeKey);
+
+ if (wrappedDESKey_s != NULL)
+ PR_Free(wrappedDESKey_s);
+
+ if (drmConn != NULL)
+ RA::ReturnDRMConn(drmConn);
+
+ if (response != NULL) {
+ if (content != NULL)
+ response->freeContent();
+ delete response;
+ }
+
+ if (ra_pb != NULL) {
+ delete ra_pb;
+ }
+
+}
+
+
+
+/*
+ * input:
+ * @param desKey_s provided for drm to wrap user private
+ * @param publicKey_s returned for key injection back to token
+ *
+ * Output:
+ * @param publicKey_s public key provided by DRM
+ * @param wrappedPrivateKey_s encrypted private key provided by DRM
+ */
+void RA::ServerSideKeyGen(RA_Session *session, const char* cuid,
+ const char *userid, char* desKey_s,
+ char **publicKey_s,
+ char **wrappedPrivateKey_s,
+ char **ivParam_s, const char *connId,
+ bool archive, int keysize)
+{
+
+ const char *FN="RA::ServerSideKeyGen";
+ int status;
+ PSHttpResponse *response = NULL;
+ HttpConnection *drmConn = NULL;
+ char body[MAX_BODY_LEN];
+ char configname[256];
+
+ long s;
+ char * content = NULL;
+ char ** hostport = NULL;
+ const char* servletID = NULL;
+ char *wrappedDESKey_s = NULL;
+ Buffer *decodeKey = NULL;
+ ConnectionInfo *connInfo = NULL;
+ RA_pblock *ra_pb = NULL;
+ int drm_curr = 0;
+ int currRetries = 0;
+ char *p = NULL;
+
+ if ((cuid == NULL) || (strcmp(cuid,"")==0)) {
+ RA::Debug( LL_PER_CONNECTION, FN,
+ "error: passed invalid cuid");
+ goto loser;
+ }
+ if ((userid == NULL) || (strcmp(userid,"")==0)) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "error: passed invalid userid");
+ goto loser;
+ }
+ if ((desKey_s == NULL) || (strcmp(desKey_s,"")==0)) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "error: passed invalid desKey_s");
+ goto loser;
+ }
+ if ((connId == NULL) ||(strcmp(connId,"")==0)) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "error: passed invalid connId");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "desKey_s=%s, connId=%s",desKey_s, connId);
+ drmConn = RA::GetDRMConn(connId);
+
+ if (drmConn == NULL) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "drmconn is null");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "found DRM connection info");
+ connInfo = drmConn->GetFailoverList();
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "got DRM failover list");
+
+ decodeKey = Util::URLDecode(desKey_s);
+ if (decodeKey == NULL) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "url-decoding of des key-transport-key failed");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "successfully url-decoded key-transport-key");
+ wrappedDESKey_s = Util::SpecialURLEncode(*decodeKey);
+
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "wrappedDESKey_s=%s", wrappedDESKey_s);
+
+ PR_snprintf((char *)body, MAX_BODY_LEN,
+ "archive=%s&CUID=%s&userid=%s&keysize=%d&drm_trans_desKey=%s",archive?"true":"false",cuid, userid, keysize, wrappedDESKey_s);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "sending to DRM: query=%s", body);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.GenerateKeyPair", connId);
+ servletID = GetConfigStore()->GetConfigAsString(configname);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "finding DRM servlet info, configname=%s", configname);
+
+ drm_curr = RA::GetCurrentIndex(drmConn);
+ response = drmConn->getResponse(drm_curr, servletID, body);
+ hostport = connInfo->GetHostPortList();
+ if (response == NULL) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "failed to get response from DRM at %s",
+ hostport[drm_curr]);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "failed to get response from DRM at %s",
+ hostport[drm_curr]);
+ } else {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "response from DRM (%s) is not NULL.",
+ hostport[drm_curr]);
+ }
+
+ while (response == NULL) {
+ RA::Failover(drmConn, connInfo->GetHostPortListLen());
+
+ drm_curr = RA::GetCurrentIndex(drmConn);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "RA is failing over to DRM at %s", hostport[drm_curr]);
+
+ if (++currRetries >= drmConn->GetNumOfRetries()) {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "Failed to get response from all DRMs in conn group '%s'"
+ " after %d retries", connId, currRetries);
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Failed to get response from all DRMs in conn group '%s'"
+ " after %d retries", connId, currRetries);
+
+
+ goto loser;
+ }
+ response = drmConn->getResponse(drm_curr, servletID, body);
+ }
+
+ RA::Debug(" RA:: ServerSideKeyGen", "in ServerSideKeyGen - got response");
+ // XXX skip handling fallback host for prototype
+
+ content = response->getContent();
+ p = strstr(content, "status=");
+ content = p; //skip the HTTP header
+ s = response->getStatus();
+
+ if ((content != NULL) && (s == 200)) {
+ RA::Debug("RA::ServerSideKeyGen", "response from DRM status ok");
+
+ Buffer* status_b;
+ char* status_s;
+
+ ra_pb = ( RA_pblock * ) session->create_pblock(content);
+ if (ra_pb == NULL)
+ goto loser;
+
+ status_b = ra_pb->find_val("status");
+ if (status_b == NULL) {
+ status = 4;
+ goto loser;
+ } else {
+ status_s = status_b->string();
+ status = atoi(status_s);
+ if (status_s != NULL) {
+ PR_Free(status_s);
+ }
+ }
+
+ char * tmp = NULL;
+ tmp = ra_pb->find_val_s("public_key");
+ if (tmp == NULL) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Did not get public key in DRM response");
+ } else {
+ RA::Debug(LL_PER_PDU, "ServerSideKeyGen", "got public key =%s", tmp);
+ *publicKey_s = PL_strdup(tmp);
+ }
+
+ tmp = NULL;
+ tmp = ra_pb->find_val_s("wrapped_priv_key");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "did not get wrapped private key in DRM response");
+ } else {
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "got wrappedprivate key =%s", tmp);
+ *wrappedPrivateKey_s = PL_strdup(tmp);
+ }
+
+ tmp = ra_pb->find_val_s("iv_param");
+ if ((tmp == NULL) || (strcmp(tmp,"")==0)) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "did not get iv_param for private key in DRM response");
+ } else {
+ RA::Debug(LL_PER_PDU, "ServerSideKeyGen", "got iv_param for private key =%s", tmp);
+ *ivParam_s = PL_strdup(tmp);
+ }
+
+ } else {// if content is NULL or status not 200
+ if (content != NULL)
+ RA::Debug("RA::ServerSideKeyGen", "response from DRM error status %ld", s);
+ else
+ RA::Debug("RA::ServerSideKeyGen", "response from DRM no content");
+ }
+
+ loser:
+ if (desKey_s != NULL)
+ PR_Free(desKey_s);
+
+ if (decodeKey != NULL) {
+ delete decodeKey;
+ }
+
+ if (wrappedDESKey_s != NULL)
+ PR_Free(wrappedDESKey_s);
+
+ if (drmConn != NULL)
+ RA::ReturnDRMConn(drmConn);
+
+ if (response != NULL) {
+ if (content != NULL)
+ response->freeContent();
+ delete response;
+ }
+
+ if (ra_pb != NULL) {
+ delete ra_pb;
+ }
+
+}
+
+
+#define DES2_WORKAROUND
+#define MAX_BODY_LEN 4096
+
+PK11SymKey *RA::ComputeSessionKey(RA_Session *session,
+ Buffer &CUID,
+ Buffer &keyInfo,
+ Buffer &card_challenge,
+ Buffer &host_challenge,
+ Buffer **host_cryptogram,
+ Buffer &card_cryptogram,
+ PK11SymKey **encSymKey,
+ char** drm_desKey_s,
+ char** kek_desKey_s,
+ char** keycheck_s,
+ const char *connId)
+{
+ PK11SymKey *symKey = NULL;
+ PK11SymKey *symKey24 = NULL;
+ PK11SymKey *encSymKey24 = NULL;
+ PK11SymKey *transportKey = NULL;
+ PK11SymKey *encSymKey16 = NULL;
+ char body[MAX_BODY_LEN];
+ char configname[256];
+ char * cardc = NULL;
+ char * hostc = NULL;
+ char * cardCrypto = NULL;
+ char * cuid = NULL;
+ char * keyinfo = NULL;
+ PSHttpResponse *response = NULL;
+ HttpConnection *tksConn = NULL;
+ RA_pblock *ra_pb = NULL;
+ SECItem *SecParam = PK11_ParamFromIV(CKM_DES3_ECB, NULL);
+ char* transportKeyName = NULL;
+
+ RA::Debug(LL_PER_PDU, "Start ComputeSessionKey", "");
+ tksConn = RA::GetTKSConn(connId);
+ if (tksConn == NULL) {
+ RA::Error(LL_PER_PDU, "RA::ComputeSessionKey", "Failed to get TKSConnection %s", connId);
+ return NULL;
+ } else {
+ int currRetries = 0;
+ ConnectionInfo *connInfo = tksConn->GetFailoverList();
+
+ PR_snprintf((char *) configname, 256, "conn.%s.keySet", connId);
+ const char *keySet = RA::GetConfigStore()->GetConfigAsString(configname, "defKeySet");
+ // is serversideKeygen on?
+ PR_snprintf((char *) configname, 256, "conn.%s.serverKeygen", connId);
+ bool serverKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, false);
+ if (serverKeygen)
+ RA::Debug(LL_PER_PDU, "RA::ComputeSessionKey", "serverKeygen for %s is on", connId);
+ else
+ RA::Debug(LL_PER_PDU, "RA::ComputeSessionKey", "serverKeygen for %s is off", connId);
+
+ cardc = Util::SpecialURLEncode(card_challenge);
+ hostc = Util::SpecialURLEncode(host_challenge);
+ cardCrypto = Util::SpecialURLEncode(card_cryptogram);
+ cuid = Util::SpecialURLEncode(CUID);
+ keyinfo = Util::SpecialURLEncode(keyInfo);
+
+ if ((cardc == NULL) || (hostc == NULL) || (cardCrypto == NULL) ||
+ (cuid == NULL) || (keyinfo == NULL))
+ goto loser;
+
+ PR_snprintf((char *)body, MAX_BODY_LEN,
+ "serversideKeygen=%s&CUID=%s&card_challenge=%s&host_challenge=%s&KeyInfo=%s&card_cryptogram=%s&keySet=%s", serverKeygen? "true":"false", cuid,
+ cardc, hostc, keyinfo, cardCrypto, keySet);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.computeSessionKey", connId);
+ const char *servletID = GetConfigStore()->GetConfigAsString(configname);
+ int tks_curr = RA::GetCurrentIndex(tksConn);
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ char **hostport = connInfo->GetHostPortList();
+ if (response == NULL)
+ RA::Debug(LL_PER_PDU, "The computeSessionKey response from TKS ",
+ "at %s is NULL.", hostport[tks_curr]);
+ else
+ RA::Debug(LL_PER_PDU, "The computeSessionKey response from TKS ",
+ "at %s is not NULL.", hostport[tks_curr]);
+
+ while (response == NULL) {
+ RA::Failover(tksConn, connInfo->GetHostPortListLen());
+
+ tks_curr = RA::GetCurrentIndex(tksConn);
+ RA::Debug(LL_PER_PDU, "RA is reconnecting to TKS ",
+ "at %s for computeSessionKey.", hostport[tks_curr]);
+
+ if (++currRetries >= tksConn->GetNumOfRetries()) {
+ RA::Debug("Used up all the retries in ComputeSessionKey. Response is NULL","");
+ RA::Error("RA::ComputeSessionKey","Failed connecting to TKS after %d retries", currRetries);
+
+ goto loser;
+ }
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ }
+
+ RA::Debug(LL_PER_PDU, "ComputeSessionKey Response is not ","NULL");
+ char * content = response->getContent();
+
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+
+ if (content != NULL) {
+ Buffer *status_b;
+
+ char *status_s, *sessionKey_s, *encSessionKey_s, *hostCryptogram_s;
+ int status;
+
+ /* strip the http header */
+ /* raidzilla 57722: strip the HTTP header and just pass
+ name value pairs into the pblock parsing code.
+ */
+ RA::Debug("RA::Engine", "Pre-processing content '%s", content);
+ char *cx = content;
+ while (cx[0] != '\0' && (!(cx[0] == '\r' && cx[1] == '\n' &&
+ cx[2] == '\r' && cx[3] == '\n')))
+ {
+ cx++;
+ }
+ if (cx[0] != '\0') {
+ cx+=4;
+ }
+ RA::Debug("RA::Engine", "Post-processing content '%s", cx);
+ ra_pb = ( RA_pblock * ) session->create_pblock(cx);
+ if (ra_pb == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no ra_pb");
+ goto loser;
+ }
+
+ status_b = ra_pb->find_val(TKS_RESPONSE_STATUS);
+ if (status_b == NULL) {
+ status = 4;
+ RA::Error(LL_PER_SERVER, "RA:ComputeSessionKey", "Bad TKS Connection. Please make sure TKS is accessible by TPS.");
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no status");
+ goto loser;
+ // return NULL;
+ }
+ else {
+ status_s = status_b->string();
+ status = atoi(status_s);
+ if (status_s != NULL) {
+ PR_Free(status_s);
+ }
+ }
+
+ // Now unwrap the session keys with shared secret transport key
+
+ PR_snprintf((char *)configname, 256, "conn.%s.tksSharedSymKeyName", connId);
+
+ transportKeyName = (char *) m_cfg->GetConfigAsString(configname, TRANSPORT_KEY_NAME);
+
+ RA::Debug(LL_PER_PDU,"RA:ComputeSessionKey","Shared Secret key name: %s.", transportKeyName);
+
+ transportKey = FindSymKeyByName( slot, transportKeyName);
+
+ if ( transportKey == NULL ) {
+ RA::Debug(LL_PER_PDU,"RA::ComputeSessionKey","fail getting transport key");
+ goto loser;
+ }
+
+ sessionKey_s = ra_pb->find_val_s(TKS_RESPONSE_SessionKey);
+ if (sessionKey_s == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no sessionKey_b");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "mac session key=%s", sessionKey_s);
+ Buffer *decodeKey = Util::URLDecode(sessionKey_s);
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "decodekey len=%d",decodeKey->size());
+
+ BYTE *keyData = (BYTE *)*decodeKey;
+ SECItem wrappeditem = {siBuffer , keyData, 16 };
+
+ symKey = PK11_UnwrapSymKey(transportKey,
+ CKM_DES3_ECB,SecParam, &wrappeditem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ if ( symKey ) {
+ symKey24 = CreateDesKey24Byte(slot, symKey);
+ }
+
+ if( decodeKey != NULL ) {
+ delete decodeKey;
+ decodeKey = NULL;
+ }
+ if (symKey24 == NULL)
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "MAC Session key is NULL");
+
+
+ encSessionKey_s = ra_pb->find_val_s(TKS_RESPONSE_EncSessionKey);
+ if (encSessionKey_s == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "fail no encSessionKey_b");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "encSessionKey=%s", encSessionKey_s);
+ Buffer *decodeEncKey = Util::URLDecode(encSessionKey_s);
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey",
+ "decodeEnckey len=%d",decodeEncKey->size());
+
+ BYTE *EnckeyData = (BYTE *)*decodeEncKey;
+ wrappeditem.data = (unsigned char *) EnckeyData;
+ wrappeditem.len = 16;
+
+ encSymKey16 = PK11_UnwrapSymKey(transportKey,
+ CKM_DES3_ECB,SecParam, &wrappeditem,
+ CKM_DES3_ECB,
+ CKA_UNWRAP,
+ 16);
+
+ if ( encSymKey16 ) {
+ encSymKey24 = CreateDesKey24Byte(slot, encSymKey16);
+ }
+
+ *encSymKey = encSymKey24;
+
+ if( decodeEncKey != NULL ) {
+ delete decodeEncKey;
+ decodeEncKey = NULL;
+ }
+
+ if (encSymKey24 == NULL)
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "encSessionKey is NULL");
+
+ if (serverKeygen) {
+ char * tmp= NULL;
+ tmp = ra_pb->find_val_s(TKS_RESPONSE_DRM_Trans_DesKey);
+ if (tmp == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "drm_desKey not retrieved");
+ RA::Error(LL_PER_PDU, "RA:ComputeSessionKey", "drm_desKey not retrieved");
+ goto loser;
+ } else {
+ *drm_desKey_s = PL_strdup(tmp);
+ }
+ // wrapped des key is to be sent to DRM "as is"
+ // thus should not be touched
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "drm_desKey=%s", *drm_desKey_s );
+
+ tmp = ra_pb->find_val_s(TKS_RESPONSE_KEK_DesKey);
+ if (tmp == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "kek-wrapped desKey not retrieved");
+ RA::Error(LL_PER_PDU, "RA:ComputeSessionKey", "kek-wrapped desKey not retrieved");
+ goto loser;
+ } else {
+ *kek_desKey_s = PL_strdup(tmp);
+ }
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "kek_desKey=%s", *kek_desKey_s );
+
+
+ tmp = ra_pb->find_val_s("keycheck");
+ if (tmp == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "keycheck not retrieved");
+ RA::Error(LL_PER_PDU, "RA:ComputeSessionKey", "keycheck not retrieved");
+ goto loser;
+ } else {
+ *keycheck_s = PL_strdup(tmp);
+ }
+ }// serversideKeygen
+
+ hostCryptogram_s = ra_pb->find_val_s(TKS_RESPONSE_HostCryptogram);
+ if (hostCryptogram_s == NULL)
+ goto loser;
+
+ RA::Debug(LL_PER_PDU, "RA:ComputeSessionKey", "hostC=%s", hostCryptogram_s);
+ *host_cryptogram = Util::URLDecode(hostCryptogram_s);
+ } // if content != NULL
+
+ } // else tksConn != NULL
+ RA::Debug(LL_PER_PDU, "finish ComputeSessionKey", "");
+
+
+ loser:
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ if( cardc != NULL ) {
+ PR_Free( cardc );
+ cardc = NULL;
+ }
+ if( hostc != NULL ) {
+ PR_Free( hostc );
+ hostc = NULL;
+ }
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( keyinfo != NULL ) {
+ PR_Free( keyinfo );
+ keyinfo = NULL;
+ }
+ if (cardCrypto != NULL) {
+ PR_Free( cardCrypto );
+ cardCrypto = NULL;
+ }
+
+ if( response != NULL ) {
+ response->freeContent();
+ delete response;
+ response = NULL;
+ }
+
+ if ( SecParam != NULL ) {
+ SECITEM_FreeItem(SecParam, PR_TRUE);
+ SecParam = NULL;
+ }
+
+ if (ra_pb != NULL) {
+ delete ra_pb;
+ }
+
+ if ( symKey != NULL ) {
+ PK11_FreeSymKey( symKey );
+ symKey = NULL;
+ }
+
+ if ( encSymKey16 != NULL ) {
+ PK11_FreeSymKey( encSymKey16 );
+ encSymKey16 = NULL;
+ }
+
+ // in production, if TKS is unreachable, symKey will be NULL,
+ // and this will signal error to the caller.
+ return symKey24;
+}
+
+Buffer *RA::ComputeHostCryptogram(Buffer &card_challenge,
+ Buffer &host_challenge)
+{
+ /* hardcoded enc auth key */
+ BYTE enc_auth_key[16] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+ Buffer input = Buffer(16, (BYTE)0);
+ int i;
+ Buffer icv = Buffer(8, (BYTE)0);
+ Buffer *output = new Buffer(8, (BYTE)0);
+ BYTE *cc = (BYTE*)card_challenge;
+ int cc_len = card_challenge.size();
+ BYTE *hc = (BYTE*)host_challenge;
+ int hc_len = host_challenge.size();
+
+ /* copy card and host challenge into input buffer */
+ for (i = 0; i < 8; i++) {
+ ((BYTE*)input)[i] = cc[i];
+ }
+ for (i = 0; i < 8; i++) {
+ ((BYTE*)input)[8+i] = hc[i];
+ }
+
+ PK11SymKey *key = Util::DeriveKey(
+ Buffer(enc_auth_key, 16), Buffer(hc, hc_len),
+ Buffer(cc, cc_len));
+ Util::ComputeMAC(key, input, icv, *output);
+
+ return output;
+}
+
+TPS_PUBLIC void RA::DebugBuffer(const char *func_name, const char *prefix, Buffer *buf)
+{
+ RA::DebugBuffer(LL_PER_CONNECTION, func_name, prefix, buf);
+}
+
+void RA::DebugBuffer(RA_Log_Level level, const char *func_name, const char *prefix, Buffer *buf)
+{
+ int i;
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ BYTE *data = *buf;
+ int sum = 0;
+ PRThread *ct;
+
+ if ((m_debug_log == NULL) || (!m_debug_log->isOpen()))
+ return;
+ if ((int) level >= m_debug_log_level)
+ return;
+ PR_Lock(m_debug_log_lock);
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ ct = PR_GetCurrentThread();
+ m_debug_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ m_debug_log->printf("%s (length='%d')", prefix, buf->size());
+ m_debug_log->printf("\n");
+ m_debug_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ for (i=0; i<(int)buf->size(); i++) {
+ m_debug_log->printf("%02x ", (unsigned char)data[i]);
+ sum++;
+ if (sum == 10) {
+ m_debug_log->printf("\n");
+ m_debug_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ sum = 0;
+ }
+ }
+ m_debug_log->write("\n");
+ PR_Unlock(m_debug_log_lock);
+}
+
+TPS_PUBLIC void RA::Debug (const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::DebugThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+}
+
+TPS_PUBLIC void RA::Debug (RA_Log_Level level, const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::DebugThis(level, func_name, fmt, ap);
+ va_end(ap);
+}
+
+
+
+void RA::DebugThis (RA_Log_Level level, const char *func_name, const char *fmt, va_list ap)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+
+ if ((m_debug_log == NULL) || (!m_debug_log->isOpen()))
+ return;
+ if ((int) level >= m_debug_log_level)
+ return;
+ PR_Lock(m_debug_log_lock);
+ now = PR_Now();
+ ct = PR_GetCurrentThread();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ m_debug_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ m_debug_log->vfprintf(fmt, ap);
+ m_debug_log->write("\n");
+ PR_Unlock(m_debug_log_lock);
+}
+
+TPS_PUBLIC void RA::Audit (const char *func_name, const char *fmt, ...)
+{
+ if (!RA::IsAuditEventSelected(func_name))
+ return;
+
+ va_list ap;
+ va_start(ap, fmt);
+ RA::AuditThis (LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+// RA::DebugThis (LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+}
+
+TPS_PUBLIC void RA::Audit (RA_Log_Level level, const char *func_name, const char *fmt, ...)
+{
+ if (!RA::IsAuditEventSelected(func_name))
+ return;
+
+ va_list ap;
+ va_start(ap, fmt);
+ RA::AuditThis (level, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis (level, func_name, fmt, ap);
+ va_end(ap);
+}
+
+void RA::AuditThis (RA_Log_Level level, const char *func_name, const char *fmt, va_list ap)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+ char *message_p1 = NULL;
+ char *message_p2 = NULL;
+ int nbytes;
+ int status;
+
+ if (!m_audit_enabled) return;
+
+ if ((m_audit_log == NULL) || (!m_audit_log->isOpen()) || (m_audit_log_buffer == NULL))
+ return;
+ if ((int) level >= m_audit_log_level)
+ return;
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ ct = PR_GetCurrentThread();
+
+ message_p1 = PR_smprintf("[%s] %x [AuditEvent=%s]", datetime, ct, func_name);
+ message_p2 = PR_vsmprintf(fmt, ap);
+
+ /* write out the message first */
+ NSSUTF8 *audit_msg = PR_smprintf("%s%s\n", message_p1, message_p2);
+ nbytes = (unsigned) PL_strlen((const char*) audit_msg);
+ if ((m_bytes_unflushed + nbytes) >= m_buffer_size) {
+ FlushAuditLogBuffer();
+ status = m_audit_log->write(audit_msg);
+ if (status != PR_SUCCESS) {
+ m_audit_log->get_context()->LogError( "RA::AuditThis",
+ __LINE__,
+ "AuditThis: Failure to write to the audit log. Shutting down ...");
+ _exit(APEXIT_CHILDFATAL);
+ }
+ m_audit_log->setSigned(false);
+
+ if (m_audit_signed) SignAuditLog(audit_msg);
+ } else {
+ PL_strcat(m_audit_log_buffer, audit_msg);
+ m_bytes_unflushed += nbytes;
+ }
+
+ PR_Free(message_p1);
+ PR_Free(message_p2);
+
+ if (audit_msg)
+ PR_Free(audit_msg);
+
+ PR_ExitMonitor(m_audit_log_monitor);
+
+}
+
+TPS_PUBLIC void RA::FlushAuditLogBuffer()
+{
+ int status;
+
+ if (!m_audit_enabled) return;
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ if ((m_bytes_unflushed > 0) && (m_audit_log_buffer != NULL) && (m_audit_log != NULL)) {
+ status = m_audit_log->write(m_audit_log_buffer);
+ if (status != PR_SUCCESS) {
+ m_audit_log->get_context()->LogError( "RA::FlushAuditLogBuffer",
+ __LINE__,
+ "RA::FlushAuditLogBuffer: Failure to write to the audit log. Shutting down ...");
+ _exit(APEXIT_CHILDFATAL);
+ }
+ m_audit_log->setSigned(false);
+ if (m_audit_signed) {
+ SignAuditLog((NSSUTF8 *) m_audit_log_buffer);
+ }
+ m_bytes_unflushed=0;
+ PR_snprintf((char *) m_audit_log_buffer, m_buffer_size, "");
+ }
+ PR_ExitMonitor(m_audit_log_monitor);
+}
+
+TPS_PUBLIC void RA::SignAuditLog(NSSUTF8 * audit_msg)
+{
+ char *audit_sig_msg = NULL;
+ char sig[4096];
+ int status;
+
+ if (!m_audit_enabled) return;
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ audit_sig_msg = GetAuditSigningMessage(audit_msg);
+
+ if (audit_sig_msg != NULL) {
+ PR_snprintf(sig, 4096, "%s\n", audit_sig_msg);
+ status = m_audit_log->write(sig);
+ if (status != PR_SUCCESS) {
+ m_audit_log->get_context()->LogError( "RA::SignAuditLog",
+ __LINE__,
+ "SignAuditLog: Failure to write to the audit log. Shutting down ..");
+ _exit(APEXIT_CHILDFATAL);
+ }
+ if (m_last_audit_signature != NULL) {
+ PR_Free( m_last_audit_signature );
+ }
+ m_last_audit_signature = PL_strdup(audit_sig_msg);
+ m_audit_log->setSigned(true);
+
+ PR_Free(audit_sig_msg);
+ }
+ PR_ExitMonitor(m_audit_log_monitor);
+}
+
+TPS_PUBLIC void RA::ra_free_values(struct berval **values)
+{
+ free_values(values, 1);
+}
+
+/* sign audit_msg and last signature
+ returns char* - must be freed by caller */
+TPS_PUBLIC char * RA::GetAuditSigningMessage(const NSSUTF8 * audit_msg)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+ SECStatus rv;
+
+ SECItem signedResult;
+ NSSUTF8 *sig_b64 = NULL;
+ NSSUTF8 *out_sig_b64 = NULL;
+ SGNContext *sign_ctxt=NULL;
+ char *audit_sig_msg = NULL;
+ char sig[4096];
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ ct = PR_GetCurrentThread();
+
+ if (m_audit_signed==true) {
+ sign_ctxt = SGN_NewContext(m_audit_signAlgTag, m_audit_signing_key);
+ if( SGN_Begin(sign_ctxt) != SECSuccess ) {
+ RA::Debug("RA:: SignAuditLog", "SGN_Begin failed");
+ goto loser;
+ }
+
+ if (m_last_audit_signature != NULL) {
+ RA::Debug("RA:: SignAuditLog", "m_last_audit_signature == %s",
+ m_last_audit_signature);
+
+ PR_snprintf(sig, 4096, "%s\n", m_last_audit_signature);
+ rv = SGN_Update( (SGNContext*)sign_ctxt,
+ (unsigned char *) sig,
+ (unsigned)PL_strlen((const char*)sig));
+ if (rv != SECSuccess) {
+ RA::Debug("RA:: SignAuditLog", "SGN_Update failed");
+ goto loser;
+ }
+
+ } else {
+ RA::Debug("RA:: SignAuditLog", "m_last_audit_signature == NULL");
+ }
+
+ /* make sign the UTF-8 bytes later */
+
+ if( SGN_Update( (SGNContext*)sign_ctxt,
+ (unsigned char *) audit_msg,
+ (unsigned)PL_strlen((const char*)audit_msg)) != SECSuccess) {
+ RA::Debug("RA:: SignAuditLog", "SGN_Update failed");
+ goto loser;
+ }
+
+ if( SGN_End(sign_ctxt, &signedResult) != SECSuccess) {
+ RA::Debug("RA:: SignAuditLog", "SGN_End failed");
+ goto loser;
+ }
+
+ sig_b64 = NSSBase64_EncodeItem(NULL, NULL, 0, &signedResult);
+ if (sig_b64 == NULL) {
+ RA::Debug("RA:: SignAuditLog", "NSSBase64_EncodeItem failed");
+ goto loser;
+ }
+
+ /* get rid of the carriage return line feed */
+ int sig_len = PL_strlen(sig_b64);
+ out_sig_b64 = (char *) PORT_Alloc (sig_len);
+ if (out_sig_b64 == NULL) {
+ RA::Debug("RA:: SignAuditLog", "PORT_Alloc for out_sig_b64 failed");
+ goto loser;
+ }
+ int i = 0;
+ char *p = sig_b64;
+ for (i = 0; i< sig_len; i++, p++) {
+ if ((*p!=13) && (*p!= 10)) {
+ out_sig_b64[i] = *p;
+ } else {
+ i--;
+ continue;
+ }
+ }
+
+ /*
+ * write out the signature
+ */
+ audit_sig_msg = PR_smprintf(AUDIT_SIG_MSG_FORMAT,
+ datetime, ct, "AUDIT_LOG_SIGNING",
+ "System", "Success", out_sig_b64);
+
+ }
+
+loser:
+ if (m_audit_signed==true) {
+ if (sign_ctxt)
+ SGN_DestroyContext(sign_ctxt, PR_TRUE);
+ if (sig_b64)
+ PR_Free(sig_b64);
+ if (out_sig_b64)
+ PR_Free(out_sig_b64);
+ if (&signedResult)
+ SECITEM_FreeItem(&signedResult, PR_FALSE);
+ }
+
+ return audit_sig_msg;
+}
+
+TPS_PUBLIC void RA::SetFlushInterval(int interval)
+{
+ char interval_str[512];
+ int status;
+ char error_msg[512];
+
+ RA::Debug("RA::SetFlushInterval", "Setting flush interval to %d seconds", interval);
+ m_flush_interval = interval;
+
+ // Interrupt the flush thread to set new interval
+ // Get monitor so as not to interrupt the flush thread during flushing
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ PR_Interrupt(m_flush_thread);
+ PR_ExitMonitor(m_audit_log_monitor);
+
+ PR_snprintf((char *) interval_str, 512, "%d", interval);
+ m_cfg->Add(CFG_AUDIT_FLUSH_INTERVAL, interval_str);
+ status = m_cfg->Commit(false, error_msg, 512);
+ if (status != 0) {
+ RA::Debug("RA:SetFlushInterval", error_msg);
+ }
+}
+
+TPS_PUBLIC void RA::SetBufferSize(int size)
+{
+ char * new_buffer;
+ char size_str[512];
+ int status;
+ char error_msg[512];
+
+ RA::Debug("RA::SetBufferSize", "Setting buffer size to %d bytes", size);
+
+ PR_EnterMonitor(m_audit_log_monitor);
+ FlushAuditLogBuffer();
+ if (m_audit_log_buffer != NULL) {
+ new_buffer = (char *) PR_Realloc(m_audit_log_buffer, size);
+ m_audit_log_buffer = new_buffer;
+ } else {
+ m_audit_log_buffer = (char *) PR_Malloc(size);
+ }
+ m_buffer_size = size;
+ PR_ExitMonitor(m_audit_log_monitor);
+
+ PR_snprintf((char *) size_str, 512, "%d", size);
+ m_cfg->Add(CFG_AUDIT_BUFFER_SIZE, size_str);
+
+ status = m_cfg->Commit(false, error_msg, 512);
+ if (status != 0) {
+ RA::Debug("RA:SetFlushInterval", error_msg);
+ }
+}
+
+
+TPS_PUBLIC void RA::Error (const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::ErrorThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+}
+
+TPS_PUBLIC void RA::Error (RA_Log_Level level, const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::ErrorThis(level, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis(level, func_name, fmt, ap);
+ va_end(ap);
+}
+
+void RA::ErrorThis (RA_Log_Level level, const char *func_name, const char *fmt, va_list ap)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+
+ if ((m_error_log == NULL) || (!m_error_log->isOpen()))
+ return;
+ if ((int) level >= m_error_log_level)
+ return;
+ PR_Lock(m_error_log_lock);
+ now = PR_Now();
+ ct = PR_GetCurrentThread();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ m_error_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ m_error_log->vfprintf(fmt, ap);
+ m_error_log->write("\n");
+ PR_Unlock(m_error_log_lock);
+}
+
+TPS_PUBLIC void RA::SelfTestLog (const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::SelfTestLogThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis(LL_PER_SERVER, func_name, fmt, ap);
+ va_end(ap);
+}
+
+TPS_PUBLIC void RA::SelfTestLog (RA_Log_Level level, const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ RA::SelfTestLogThis(level, func_name, fmt, ap);
+ va_end(ap);
+ va_start(ap, fmt);
+ RA::DebugThis(level, func_name, fmt, ap);
+ va_end(ap);
+}
+
+void RA::SelfTestLogThis (RA_Log_Level level, const char *func_name, const char *fmt, va_list ap)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ PRThread *ct;
+
+ if ((m_selftest_log == NULL) || (!m_selftest_log->isOpen()))
+ return;
+ if ((int) level >= m_selftest_log_level)
+ return;
+ PR_Lock(m_selftest_log_lock);
+ now = PR_Now();
+ ct = PR_GetCurrentThread();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ m_selftest_log->printf("[%s] %x %s - ", datetime, ct, func_name);
+ m_selftest_log->vfprintf(fmt, ap);
+ m_selftest_log->write("\n");
+ PR_Unlock(m_selftest_log_lock);
+}
+
+PublisherEntry *RA::getPublisherById(const char *publisher_id)
+{
+
+ PublisherEntry *cur = RA::publisher_list;
+
+ if(cur == NULL)
+ {
+ return NULL;
+ }
+
+ while(cur != NULL)
+ {
+ if(!strcmp(publisher_id,cur->id))
+ {
+ break;
+ }
+
+ cur = cur->next;
+ }
+
+ return cur;
+
+}
+
+int RA::InitializePublishers()
+
+{
+ RA::m_num_publishers = 0;
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Attempting to load the configurable list of Publishers.", "");
+
+ const char *pub_prefix = "publisher.instance";
+ const char *pub_suffix = "publisherId";
+
+ const char *publisher_id = NULL;
+ const char *publisher_lib_name = NULL;
+ const char *publisher_lib_factory_name = NULL;
+
+ char config_str[500];
+
+ int i = -1;
+ int res = 0;
+
+ PublisherEntry *new_entry;
+
+ while(1)
+ {
+ i++;
+
+ PR_snprintf((char *)config_str, 256,"%s.%d.%s", pub_prefix,i,pub_suffix);
+ publisher_id = m_cfg->GetConfigAsString(config_str,NULL);
+
+ if(publisher_id != NULL)
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Found publisher id %s ", publisher_id);
+ PR_snprintf((char *)config_str, 256, "%s.%d.%s",pub_prefix,i,"libraryName");
+
+ publisher_lib_name = m_cfg->GetConfigAsString(config_str,NULL);
+
+ if(publisher_lib_name != NULL)
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Found publisher lib name %s ", publisher_lib_name);
+ PR_snprintf((char *)config_str, 256, "%s.%d.%s",pub_prefix,i,"libraryFactory");
+
+ publisher_lib_factory_name = m_cfg->GetConfigAsString(config_str,NULL);
+
+ if(publisher_lib_factory_name)
+ {
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Found publisher lib factory name %s ", publisher_lib_factory_name);
+
+ PRLibrary *pb = PR_LoadLibrary(publisher_lib_name);
+
+ if(pb)
+ {
+ void *sym = PR_FindSymbol(pb,publisher_lib_factory_name);
+
+ if(sym == NULL)
+ {
+
+ RA::Error(LL_PER_PDU, "RA:InitializePublishers",
+ "Failed to find symbol '%s' publisher %s error code: %d",publisher_lib_factory_name,publisher_lib_name,PR_GetError());
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Failed to load publish library.", "");
+
+
+ continue;
+ }
+ makepublisher make_pub = (makepublisher ) sym;
+
+ IPublisher *publisher = (* make_pub )();
+
+ if(publisher == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA:InitializePublishers",
+ "Failed to initialize publisher %s error code: %d",publisher_lib_name,PR_GetError());
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Failed to allocate Netkey publisher.", "");
+ continue;
+ }
+ if(publisher)
+ {
+ res = publisher->init();
+ }
+
+ if(!res)
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Failed to initialize publisher %s.", publisher_lib_name);
+ continue;
+ }
+
+ new_entry = (PublisherEntry *) malloc(sizeof(PublisherEntry));
+
+ if(new_entry == NULL)
+ {
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers: Failed to allocate PublisherEntry structure", "");
+
+ break;
+
+ }
+ new_entry->id = strdup(publisher_id);
+ new_entry->publisher = publisher;
+ new_entry->publisher_lib = pb;
+
+ if(RA::publisher_list == NULL)
+ {
+ RA::publisher_list = new_entry;
+ new_entry->next = NULL;
+
+ }
+
+ else
+ {
+ PublisherEntry *cur = RA::publisher_list;
+
+ while(cur->next != NULL)
+ {
+ cur= cur->next;
+ }
+
+ cur->next = new_entry;
+ new_entry->next = NULL;
+
+ }
+
+ RA::m_num_publishers++;
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Successfully initialized publisher %s.", publisher_lib_name);
+ }
+ else
+ {
+ RA::Error(LL_PER_PDU, "RA:InitializePublishers",
+ "Failed to open library %s error code: %d",publisher_lib_name,PR_GetError());
+
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers"," Failed to load publish library.", "");
+
+ continue;
+
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if(RA::m_num_publishers == 0)
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Did not load any publisher libraries, possibly not configured for publishing. Server continues normally... ");
+ return 0;
+ }
+ else
+ {
+ RA::Debug(LL_PER_PDU, "RA::InitializePublishers:"," Loaded %d Publisher(s).", RA::m_num_publishers);
+
+ return 1;
+ }
+
+}
+
+void RA::CleanupPublishers()
+{
+
+ if(RA::m_num_publishers == 0)
+ return;
+
+ RA::Debug(LL_PER_PDU, "RA::CleanupPublishers:"," Loaded %d publishers.", RA::m_num_publishers);
+
+ PublisherEntry *cur = RA::publisher_list;
+
+ if(cur == NULL)
+ {
+ return ;
+ }
+
+ while(cur != NULL)
+ {
+
+ PublisherEntry *next =cur->next;
+
+ if(cur)
+ {
+
+ RA::Debug(LL_PER_PDU, "RA::CleanupPublishers:"," Cleanup up publisher %s", cur->id);
+ if( cur->id != NULL)
+ {
+ free( cur->id );
+ cur->id = NULL;
+ }
+
+ if( cur->publisher != NULL ) {
+ delete cur->publisher;
+ cur->publisher = NULL;
+ }
+
+ if( cur->publisher_lib != NULL ) {
+ PR_UnloadLibrary( cur->publisher_lib );
+ cur->publisher_lib = NULL;
+ }
+
+ if( cur != NULL ) {
+ free( cur );
+ cur = NULL;
+ }
+
+ cur = next;
+
+ }
+ }
+
+
+}
+
+int RA::InitializeHttpConnections(const char *id, int *len, HttpConnection **conn, RA_Context *ctx) {
+ char configname[256];
+ char connID[100];
+ CERTCertDBHandle *handle = 0;
+ int rc = 0;
+ int i=0;
+
+ *len = 0;
+
+ // Initialize each connection
+ while (1) {
+ i++;
+ PR_snprintf((char *)configname, 256, "conn.%s%d.hostport", id, i);
+ const char *host_port = m_cfg->GetConfigAsString(configname);
+ if (host_port == NULL) {
+ break;
+ }
+ ConnectionInfo *cinfo = new ConnectionInfo();
+ cinfo->BuildFailoverList(host_port);
+ PR_snprintf((char *)configname, 256, "conn.%s%d.retryConnect", id, i);
+ int retries = m_cfg->GetConfigAsInt(configname, 3);
+ PR_snprintf((char *)configname, 256, "conn.%s%d.timeout", id, i);
+ int timeout = m_cfg->GetConfigAsInt(configname, 10);
+ PR_snprintf((char *)connID, 100, "%s%d", id, i);
+ PR_snprintf((char *)configname, 256, "conn.%s%d.clientNickname", id, i);
+ const char *clientnickname = m_cfg->GetConfigAsString(configname);
+
+ handle = CERT_GetDefaultCertDB();
+ if( handle == 0 ) {
+ ctx->InitializationError( "RA::InitializeHttpConnections",
+ __LINE__ );
+ rc = -1;
+ if (cinfo != NULL) {
+ delete cinfo;
+ cinfo = NULL;
+ }
+ goto loser;
+ }
+
+ // (2) Since NSS has been initialized, verify the presence of the
+ // specified certificate:
+ if( ( clientnickname != NULL ) &&
+ ( PL_strcmp( clientnickname, "" ) != 0 ) ) {
+ SelfTest::Initialize(m_cfg);
+
+ rc = SelfTest::runStartUpSelfTests(clientnickname);
+ if (rc != 0) goto loser;
+ } else {
+ RA::Error( LL_PER_SERVER,
+ "RA::InitializeHttpConnections",
+ "An empty or missing %s certificate nickname "
+ "was specified for connection %d!",
+ id,
+ i );
+ rc = -3;
+ if (cinfo != NULL) {
+ delete cinfo;
+ cinfo = NULL;
+ }
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "conn.%s%d.SSLOn", id, i);
+ bool isSSL = m_cfg->GetConfigAsBool(configname, true);
+ PR_snprintf((char *)configname, 256, "conn.%s%d.keepAlive", id, i);
+ bool keepAlive = m_cfg->GetConfigAsBool(configname, true);
+ conn[*len] = new HttpConnection(connID, cinfo, retries, timeout, isSSL, clientnickname, keepAlive, NULL);
+ (*len)++;
+ }
+
+loser:
+
+ return rc;
+}
+
+int RA::InitializeTokendb(char *cfg_path)
+{
+ char *error = NULL;
+ int status;
+
+ if (tokendbInitialized)
+ return 0;
+
+ RA::Debug("RA::InitializeTokendb", "config path = %s", cfg_path);
+
+ if (get_tus_db_config(cfg_path) != 1) {
+ RA::Debug("RA::InitializeTokendb", "get_tus_db_config failed");
+ return -1;
+ }
+
+ tokendbInitialized = 1;
+
+ RA::Debug("RA::InitializeTokendb", "Initializing TUS database");
+ if( ( status = tus_db_init( &error ) ) != LDAP_SUCCESS ) {
+ if( error != NULL ) {
+ RA::Debug( "RA::InitializeTokendb",
+ "Token DB initialization failed: '%s'",
+ error );
+ PR_smprintf_free( error );
+ error = NULL;
+ } else {
+ RA::Debug( "RA::InitializeTokendb",
+ "Token DB initialization failed" );
+ }
+ }
+
+ return status;
+}
+
+TPS_PUBLIC void RA::update_signed_audit_selected_events(char *new_selected)
+{
+ char *tmp = NULL;
+ m_cfg->Add(CFG_AUDIT_SELECTED_EVENTS, new_selected);
+
+ tmp = m_signedAuditSelectedEvents;
+ m_signedAuditSelectedEvents = PL_strdup(new_selected);
+ PL_strfree(tmp);
+}
+
+TPS_PUBLIC void RA::update_signed_audit_enable(const char *enable)
+{
+ m_cfg->Add(CFG_AUDIT_ENABLE, enable);
+}
+
+
+TPS_PUBLIC void RA::update_signed_audit_log_signing(const char *enable)
+{
+ m_cfg->Add(CFG_AUDIT_SIGNED, enable);
+}
+
+TPS_PUBLIC int RA::setup_audit_log(bool enable_signing, bool signing_changed)
+{
+ int status =0;
+ PR_EnterMonitor(m_audit_log_monitor);
+
+ // get buffer if required
+ if (m_audit_log_buffer == NULL) {
+ m_audit_log_buffer = (char *) PR_Malloc(m_buffer_size);
+ if (m_audit_log_buffer == NULL) {
+ RA::Debug(LL_PER_PDU, "RA:: setup_audit_log", "Unable to allocate memory for audit log buffer ..");
+ goto loser;
+ }
+ PR_snprintf((char *) m_audit_log_buffer, m_buffer_size, "");
+ m_bytes_unflushed = 0;
+ }
+
+ // close old log file if signing config changed
+ if (signing_changed && m_audit_log !=NULL) {
+ RA::Debug(LL_PER_PDU, "RA::setup_audit_log","Closing old audit log file");
+ FlushAuditLogBuffer();
+ m_audit_log->shutdown();
+ delete m_audit_log;
+ m_audit_log = NULL;
+ }
+
+ // open new log file if required
+ if (m_audit_log == NULL) {
+ RA::Debug(LL_PER_PDU, "RA::setup_audit_log","Opening audit log file");
+ m_audit_log = GetLogFile(m_cfg->GetConfigAsString(CFG_AUDIT_FILE_TYPE, "LogFile"));
+ status = m_audit_log->startup(m_ctx, CFG_AUDIT_PREFIX,
+ m_cfg->GetConfigAsString((enable_signing)?
+ CFG_SIGNED_AUDIT_FILENAME:CFG_AUDIT_FILENAME,
+ "/tmp/audit.log"),
+ enable_signing);
+ if (status != PR_SUCCESS)
+ goto loser;
+
+ status = m_audit_log->open();
+ if (status != PR_SUCCESS)
+ goto loser;
+ }
+
+ // update variables and CS.cfg
+ m_audit_signed = enable_signing;
+ update_signed_audit_log_signing(enable_signing? "true":"false");
+
+ // initialize signing cert and flush thread, if needed
+ status = InitializeSignedAudit();
+ if (status != 0) {
+ RA::Debug(LL_PER_PDU, "RA::setup_audit_log","Failure in InitializeSignedAudit");
+ goto loser;
+ }
+
+ PR_ExitMonitor(m_audit_log_monitor);
+ return 0;
+
+ loser:
+ RA::Debug(LL_PER_PDU, "RA::setup_audit_log","Failure in audit log setup");
+ PR_ExitMonitor(m_audit_log_monitor);
+ return -1;
+}
+
+TPS_PUBLIC void RA::enable_audit_logging(bool enable)
+{
+ m_audit_enabled = enable;
+ update_signed_audit_enable(enable? "true": "false");
+}
+
+
+TPS_PUBLIC int RA::ra_find_tus_certificate_entries_by_order_no_vlv (char *filter,
+ LDAPMessage **result, int order)
+{
+ return find_tus_certificate_entries_by_order_no_vlv(filter, result, order);
+}
+
+TPS_PUBLIC int RA::ra_find_tus_certificate_entries_by_order (char *filter,
+ int max, LDAPMessage **result, int order)
+{
+ return find_tus_certificate_entries_by_order(filter, max, result, order);
+}
+
+TPS_PUBLIC CERTCertificate **RA::ra_get_certificates(LDAPMessage *e) {
+ return get_certificates(e);
+}
+
+TPS_PUBLIC LDAPMessage *RA::ra_get_first_entry(LDAPMessage *e) {
+ return get_first_entry(e);
+}
+
+TPS_PUBLIC LDAPMessage *RA::ra_get_next_entry(LDAPMessage *e) {
+ return get_next_entry(e);
+}
+
+TPS_PUBLIC struct berval **RA::ra_get_attribute_values(LDAPMessage *e, const char *p) {
+ return get_attribute_values(e, p);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_id(LDAPMessage *e) {
+ return get_token_id(e);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_tokenType(LDAPMessage *entry) {
+ return get_cert_tokenType(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_status(LDAPMessage *entry) {
+ return get_token_status(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_cn(LDAPMessage *entry) {
+ return get_cert_cn(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_attr_byname(LDAPMessage *entry, const char *name) {
+ return get_cert_attr_byname(entry, name);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_status(LDAPMessage *entry) {
+ return get_cert_status(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_type(LDAPMessage *entry) {
+ return get_cert_type(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_serial(LDAPMessage *entry) {
+ return get_cert_serial(entry);
+}
+
+TPS_PUBLIC char *RA::ra_get_cert_issuer(LDAPMessage *entry) {
+ return get_cert_issuer(entry);
+}
+
+TPS_PUBLIC int RA::ra_tus_has_active_tokens(char *userid) {
+ return tus_has_active_tokens(userid);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_reason(LDAPMessage *msg) {
+ return get_token_reason(msg);
+}
+
+TPS_PUBLIC int RA::ra_get_number_of_entries(LDAPMessage *ldapResult) {
+ return get_number_of_entries(ldapResult);
+}
+
+TPS_PUBLIC int RA::ra_find_tus_token_entries_no_vlv(char *filter,
+ LDAPMessage **ldapResult, int num)
+{
+ return find_tus_token_entries_no_vlv(filter, ldapResult, num);
+}
+
+TPS_PUBLIC int RA::ra_find_tus_token_entries(char *filter, int maxReturns,
+ LDAPMessage **ldapResult, int num)
+{
+ return find_tus_token_entries(filter, maxReturns, ldapResult, num);
+}
+
+TPS_PUBLIC int RA::ra_is_tus_db_entry_disabled(char *cuid)
+{
+ return is_tus_db_entry_disabled(cuid);
+}
+
+TPS_PUBLIC int RA::ra_is_token_present(char *cuid)
+{
+ return is_token_present(cuid);
+}
+
+TPS_PUBLIC int RA::ra_is_token_pin_resetable(char *cuid)
+{
+ return is_token_pin_resetable(cuid);
+}
+
+TPS_PUBLIC int RA::ra_is_update_pin_resetable_policy(char *cuid)
+{
+ return is_update_pin_resetable_policy(cuid);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_policy(char *cuid)
+{
+ return get_token_policy(cuid);
+}
+
+TPS_PUBLIC char *RA::ra_get_token_userid(char *cuid)
+{
+ return get_token_userid(cuid);
+}
+
+TPS_PUBLIC int RA::ra_update_token_policy(char *cuid, char *policy)
+{
+ return update_token_policy(cuid, policy);
+}
+
+TPS_PUBLIC int RA::ra_update_cert_status(char *cn, const char *status)
+{
+ return update_cert_status(cn, status);
+}
+
+TPS_PUBLIC int RA::ra_update_token_status_reason_userid(char *userid, char *cuid, const char *status, const char *reason, int modifyDateOfCreate)
+{
+ return update_token_status_reason_userid(userid, cuid, status, reason, modifyDateOfCreate);
+}
+
+TPS_PUBLIC int RA::ra_allow_token_reenroll(char *cuid)
+{
+ return allow_token_reenroll(cuid);
+}
+
+TPS_PUBLIC int RA::ra_allow_token_renew(char *cuid)
+{
+ return allow_token_renew(cuid);
+}
+
+TPS_PUBLIC int RA::ra_force_token_format(char *cuid)
+{
+ return force_token_format(cuid);
+}
+
+TPS_PUBLIC void RA::ra_tus_print_integer(char *out, SECItem *data)
+{
+ tus_print_integer(out, data);
+}
+
+TPS_PUBLIC int RA::ra_delete_certificate_entry(LDAPMessage* e)
+{
+ char *dn = get_dn(e);
+ int rc = LDAP_SUCCESS;
+
+ if (dn != NULL) {
+ rc = delete_tus_general_db_entry(dn);
+ if (rc != LDAP_SUCCESS) {
+ RA::Debug("RA::delete_certificate_entry",
+ "Failed to remove certificate entry: %s", dn);
+ }
+ PL_strfree(dn);
+ dn = NULL;
+ }
+ return rc;
+}
+
+int RA::tdb_activity(const char *ip, const char *cuid, const char *op, const char *result, const char *msg, const char *userid, const char *token_type)
+{
+ return add_activity(ip, cuid, op, result, msg, userid, token_type);
+}
+
+int RA::tdb_update_certificates(char* cuid, char **tokentypes, char *userid, CERTCertificate ** certificates, char **ktypes, char **origins, int numOfCerts)
+{
+ int rc = -1;
+ LDAPMessage *ldapResult = NULL;
+ int k = 0;
+ char serialnumber[512];
+ char filter[512];
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ int i = 0;
+
+ if ((rc = find_tus_db_entry(cuid, 0, &ldapResult)) != LDAP_SUCCESS) {
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates","numOfCerts %d", numOfCerts);
+ /* update certificates */
+ for (i = 0; i < numOfCerts; i++) {
+ if (certificates[i] == NULL) {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "no certificate found at index %d for tokendb entry: %s", i, cuid);
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "cert=%x", certificates[i]);
+
+ k++;
+ }
+ }
+
+ for (i = 0; i < numOfCerts; i++) {
+ if (certificates[i] != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "adding cert=%x", certificates[i]);
+
+ tus_print_integer(serialnumber, &(certificates[i])->serialNumber);
+ PR_snprintf(filter, 512, "tokenSerial=%s", serialnumber);
+
+ int r = find_tus_certificate_entries_by_order_no_vlv(filter, &result, 1);
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "find_tus_certificate_entries_by_order_no_vlv returned %d", r);
+ bool found = false;
+ if (r == LDAP_SUCCESS) {
+ for (e = get_first_entry(result); e != NULL; e = get_next_entry(e)) {
+ struct berval **values = get_attribute_values(e, "tokenID");
+ if ((values == NULL) || (values[0] == NULL)) {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates",
+ "unable to get tokenid");
+ if (values != NULL) {
+ ldap_value_free_len(values);
+ values = NULL;
+ }
+ continue;
+ }
+
+ char *cn = get_cert_cn(e);
+ if (PL_strcmp(cuid, values[0]->bv_val)== 0) found = true;
+ if (cn != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update_certificates", "Updating cert status of %s to active in tokendb", cn);
+ r = update_cert_status(cn, "active");
+ if (r != LDAP_SUCCESS) {
+ RA::Debug("RA::tdb_update_certificates",
+ "Unable to modify cert status to active in tokendb: %s", cn);
+ }
+ PL_strfree(cn);
+ cn = NULL;
+ }
+
+ ldap_value_free_len(values);
+ }
+
+ ldap_msgfree(result);
+ }
+ if (!found)
+ add_certificate(cuid, origins[i], tokentypes[i], userid, certificates[i],
+ ktypes[i], "active");
+ }
+ }
+loser:
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+ return rc;
+}
+
+/*
+ * This adds a brand new token entry to tus.
+ */
+int RA::tdb_add_token_entry(char *userid, char* cuid, const char *status, const char *token_type) {
+ int rc = -1;
+ int r = -1;
+ LDAPMessage *ldapResult = NULL;
+
+ if (tokendbInitialized != 1) {
+ r = 0;
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA::tdb_add_token_entry",
+ "searching for tokendb entry: %s", cuid);
+
+ if ((rc = find_tus_db_entry(cuid, 0, &ldapResult)) != LDAP_SUCCESS) {
+ /* create a new entry */
+ rc = add_default_tus_db_entry(userid, "~tps", cuid, status, NULL, NULL, token_type);
+ if (rc != LDAP_SUCCESS) {
+ RA::Error(LL_PER_PDU, "RA:tdb_add_token_entry",
+ "failed to add tokendb entry");
+ r = -1;
+ goto loser;
+ } else
+ RA::Debug(LL_PER_PDU, "RA::tdb_add_token_entry",
+ "add tokendb entry successful");
+ r = 0;
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::tdb_add_token_entry",
+ "entry in tokendb exists.");
+
+ // try to see if the userid is there
+ LDAPMessage *e = ra_get_first_entry(ldapResult);
+ struct berval **uid = ra_get_attribute_values(e, "tokenUserID");
+
+ if ((uid != NULL) && (uid[0] != NULL)) {
+ if (uid[0]->bv_val != NULL) {
+ if (strlen(uid[0]->bv_val) > 0 && strcmp(uid[0]->bv_val, userid) != 0) {
+ ldap_value_free_len(uid);
+ RA::Debug(LL_PER_PDU, "RA::tdb_add_token_entry",
+ "This token does not belong to this user: %s", userid);
+ r = -1;
+ goto loser;
+ } else {
+ if (strlen(uid[0]->bv_val) > 0 && strcmp(uid[0]->bv_val, userid) == 0) {
+ ldap_value_free_len(uid);
+ r = 0;
+ goto loser;
+ }
+ }
+ }
+ ldap_value_free_len(uid);
+ }
+
+ // this is the recycled token, update userid and dateOfCreate
+ rc = ra_update_token_status_reason_userid(userid, cuid, status, "", 1);
+ r = rc;
+ }
+loser:
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+ return r;
+}
+
+/*
+ * This adds entry to tokendb if entry not found
+ * It is then supposed to modify entry (not yet implemented)
+ */
+int RA::tdb_update(const char *userid, char* cuid, char* applet_version, char *key_info, const char *state, const char *reason, const char *token_type)
+{
+ int rc = -1;
+ LDAPMessage *ldapResult = NULL;
+ // char filter[255];
+
+ if (tokendbInitialized != 1) {
+ rc = 0;
+ goto loser;
+ }
+
+
+ // PR_snprintf(filter, 255, "(cn=%s)", cuid);
+ RA::Debug(LL_PER_PDU, "RA::tdb_update",
+ "searching for tokendb entry: %s", cuid);
+
+ if ((rc = find_tus_db_entry(cuid, 0, &ldapResult)) != LDAP_SUCCESS) {
+ /* create a new entry */
+ rc = add_default_tus_db_entry(userid, "~tps", cuid, state, applet_version,
+ key_info, token_type);
+ if (rc != LDAP_SUCCESS) {
+ RA::Error(LL_PER_PDU, "RA:tdb_update",
+ "failed to add tokendb entry");
+ rc = -1;
+ goto loser;
+ } else
+ RA::Debug(LL_PER_PDU, "RA::tdb_update",
+ "add tokendb entry successful");
+ rc = 0;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::tdb_update",
+ "entry in tokendb exists...should modify entry");
+
+ /* need code to modify things such as applet version ...*/
+ /* ldap modify code to follow...*/
+ rc = update_tus_db_entry ("~tps", cuid, userid, key_info, state,
+ applet_version, reason, token_type);
+ }
+loser:
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+ return rc;
+}
+
+int RA::InitializeAuthentication() {
+ char configname[256];
+ const char *authid;
+ const char *type;
+ const char *authPrefix = "auth.instance";
+ const char *lib = NULL;
+ const char *libfactory = NULL;
+ int i=-1;
+ int rc=0;
+ // AuthenticationEntry *authEntry;
+
+ while (1) {
+ i++;
+ PR_snprintf((char *)configname, 256, "%s.%d.authId", authPrefix, i);
+ authid = m_cfg->GetConfigAsString(configname, NULL);
+ if (authid != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Found authentication id=%s", authid);
+ PR_snprintf((char *)configname, 256, "%s.%d.libraryName", authPrefix, i);
+ lib = m_cfg->GetConfigAsString(configname, NULL);
+ if (lib != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Found authentication library=%s", lib);
+ PR_snprintf((char *)configname, 256, "%s.%d.libraryFactory", authPrefix, i);
+ libfactory = m_cfg->GetConfigAsString(configname, NULL);
+ if (libfactory != NULL) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Found authentication library factory=%s", libfactory);
+ PRLibrary *pb = PR_LoadLibrary(lib);
+ if (pb) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication", "Successfully loaded the library %s", lib);
+ void *sym = PR_FindSymbol(pb, libfactory);
+ if (sym == NULL) {
+ RA::Error(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to find symbol '%s' in '%s' library, error code: %d",
+ libfactory, lib, PR_GetError());
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to load the library symbol");
+ continue;
+ }
+ makeauthentication make_auth = (makeauthentication)sym;
+ Authentication *authentication = (*make_auth)();
+ if (authentication == NULL) {
+ RA::Error(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to create authentication instance with library %s, error code=%d.",
+ lib, PR_GetError());
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to create authentication instance with library %s, error code=%d.",
+ lib, PR_GetError());
+ continue;
+ } else {
+ authentication->Initialize(i);
+ m_auth_list[m_auth_len] = new AuthenticationEntry();
+ m_auth_list[m_auth_len]->SetId(authid);
+ m_auth_list[m_auth_len]->SetLibrary(pb);
+ m_auth_list[m_auth_len]->SetAuthentication(authentication);
+ PR_snprintf((char *)configname, 256, "%s.%d.type", authPrefix, i);
+ type = m_cfg->GetConfigAsString(configname, NULL);
+ m_auth_list[m_auth_len]->SetType(type);
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication:",
+ "Successfully initialized authentication %s.", lib);
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to load the library %s: error=%d", lib, PR_GetError());
+ continue;
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to find the library factory %s", libfactory);
+ continue;
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Failed to find the library %s", lib);
+ continue;
+ }
+ m_auth_len++;
+ } else {
+ break;
+ }
+ }
+
+ if (m_auth_len == 0) {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "No authentication module gets loaded, but server continues starting up...");
+ rc = -1;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA::InitializeAuthentication",
+ "Total number of authentication modules get loaded: %d", m_auth_len);
+ }
+
+ return rc;
+}
+
+int RA::Failover(HttpConnection *&conn, int len) {
+ int rc = 0;
+ if (m_pod_enable) {
+ PR_Lock(m_pod_lock);
+ if (++m_pod_curr >= len)
+ m_pod_curr = 0;
+ HttpConnection *conn = NULL;
+ for (int i=0; i<m_caConns_len; i++) {
+ conn = m_caConnection[i];
+ RA::SetCurrentIndex(conn, m_pod_curr);
+ conn = m_drmConnection[i];
+ RA::SetCurrentIndex(conn, m_pod_curr);
+ conn = m_tksConnection[i];
+ RA::SetCurrentIndex(conn, m_pod_curr);
+ }
+ PR_Unlock(m_pod_lock);
+ } else {
+ if (conn != NULL) {
+ int curr = RA::GetCurrentIndex(conn);
+ if (++curr >= len)
+ curr = 0;
+ RA::SetCurrentIndex(conn, curr);
+ } else
+ rc = -1;
+ }
+ return rc;
+}
+
+TPS_PUBLIC SECCertificateUsage RA::getCertificateUsage(const char *certusage) {
+ SECCertificateUsage cu = -1;
+ if ((certusage == NULL) || *certusage == 0)
+ cu = certificateUsageCheckAllUsages;
+ else if (strcmp(certusage, "CheckAllUsages") == 0)
+ cu = certificateUsageCheckAllUsages;
+ else if (strcmp(certusage, "SSLServer") == 0)
+ cu = certificateUsageSSLServer;
+ else if (strcmp(certusage, "SSLServerWithStepUp") == 0)
+ cu = certificateUsageSSLServerWithStepUp;
+ else if (strcmp(certusage, "SSLClient") == 0)
+ cu = certificateUsageSSLClient;
+ else if (strcmp(certusage, "SSLCA") == 0)
+ cu = certificateUsageSSLCA;
+ else if (strcmp(certusage, "AnyCA") == 0)
+ cu = certificateUsageAnyCA;
+ else if (strcmp(certusage, "StatusResponder") == 0)
+ cu = certificateUsageStatusResponder;
+ else if (strcmp(certusage, "ObjectSigner") == 0)
+ cu = certificateUsageObjectSigner;
+ else if (strcmp(certusage, "UserCertImport") == 0)
+ cu = certificateUsageUserCertImport;
+ else if (strcmp(certusage, "ProtectedObjectSigner") == 0)
+ cu = certificateUsageProtectedObjectSigner;
+ else if (strcmp(certusage, "VerifyCA") == 0)
+ cu = certificateUsageVerifyCA;
+ else if (strcmp(certusage, "EmailSigner") == 0)
+ cu = certificateUsageEmailSigner;
+
+ return cu;
+}
+
+TPS_PUBLIC bool RA::verifySystemCertByNickname(const char *nickname, const char *certusage) {
+ SECStatus rv = SECFailure;
+ CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
+ if (certdb == NULL) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "fatal error:%s", "cert db not found");
+ return false;
+ }
+ CERTCertificate *cert = NULL;
+ PR_ASSERT(certdb != NULL);
+ SECCertificateUsage cu = getCertificateUsage(certusage);
+ if (cu == -1) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "error: invalid certificate usage %s for cert %s", (certusage !=NULL)? certusage:"", nickname);
+ return false;
+ }
+ SECCertificateUsage currUsage = 0;
+
+ cert = CERT_FindCertByNickname(certdb, nickname);
+ if (cert == NULL) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "nickname not found:%s",
+ nickname);
+ } else {
+ rv = CERT_VerifyCertificateNow(certdb, cert, true, cu , NULL, &currUsage);
+ /*
+ * to find actual certificate usage, pass 0 as cu in above call
+ */
+ if (cu == certificateUsageCheckAllUsages) {
+ if (currUsage & certificateUsageSSLServer)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is SSLServer");
+ if (currUsage & certificateUsageSSLServerWithStepUp)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is SSLServerWithStepUp");
+ if (currUsage & certificateUsageSSLClient)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is SSLClient");
+ if (currUsage & certificateUsageAnyCA)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is AnyCA");
+ if (currUsage & certificateUsageSSLCA)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is SSLCA");
+ if (currUsage & certificateUsageEmailSigner)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is EmailSigner");
+ if (currUsage & certificateUsageStatusResponder)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is StatusResponder");
+ if (currUsage & certificateUsageObjectSigner)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is ObjectSigner");
+ if (currUsage & certificateUsageUserCertImport)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is UserCertImport");
+ if (currUsage & certificateUsageProtectedObjectSigner)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is ProtectedObjectSigner");
+ if (currUsage & certificateUsageVerifyCA)
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname", "cert is VerifyCA");
+
+ if (currUsage ==
+ /* 0x0b80 */
+ ( certUsageUserCertImport |
+ certUsageVerifyCA |
+ certUsageProtectedObjectSigner |
+ certUsageAnyCA )) { /* cert is good for nothing */
+
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname() failed:", "cert is good for nothing: %d %s", currUsage, nickname);
+ rv = SECFailure;
+ } else {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCertByNickname() passed:", "%s", nickname);
+ rv = SECSuccess;
+ }
+ }
+ }
+
+ if (cert != NULL) {
+ CERT_DestroyCertificate(cert);
+ }
+ if (rv == SECSuccess)
+ return true;
+ else
+ return false;
+}
+
+/*
+ * tps.cert.list=sslserver,subsystem,audit_signing
+ * tps.cert.sslserver.nickname=xxx
+ * tps.cert.sslserver.certusage=SSLServer
+ * tps.cert.subsystem.nickname=xxx
+ * tps.cert.subsystem.certusage=SSLClient
+ * tps.cert.audit_signing.nickname=xxx
+ * tps.cert.audit_signing.certusage=ObjectSigner
+ */
+TPS_PUBLIC bool RA::verifySystemCerts() {
+ bool verifyResult = false;
+ bool rv = false; /* final return value */
+ char configname[256];
+ char configname_nn[256];
+ char configname_cu[256];
+ char audit_msg[512]="";
+ const char *certList = NULL;
+ ConfigStore *store = RA::GetConfigStore();
+
+ PR_snprintf((char *)configname, 256, "tps.cert.list");
+ certList = store->GetConfigAsString(configname, NULL);
+ if (certList == NULL) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "config not found:%s", configname);
+ PR_snprintf(audit_msg, 512, "%s undefined in CS.cfg", configname);
+ RA::Audit(EV_CIMC_CERT_VERIFICATION, AUDIT_MSG_FORMAT, "System", "Failure", audit_msg);
+ return false;
+ } else {
+ char *certList_x = PL_strdup(certList);
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "found cert list:%s", certList_x);
+ char *sresult = NULL;
+ char *lasts = NULL;
+ const char *nn = NULL;
+ const char *cu = NULL;
+
+ sresult = PL_strtok_r(certList_x, ",", &lasts);
+ while (sresult != NULL) {
+ PR_snprintf((char *)configname_nn, 256, "tps.cert.%s.nickname",
+ sresult);
+ nn = store->GetConfigAsString(configname_nn, NULL);
+ if ((nn == NULL) || *nn==0) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "cert nickname not found for cert tag:%s", sresult);
+ PR_snprintf(audit_msg, 512, "%s undefined in CS.cfg", configname_nn);
+ RA::Audit(EV_CIMC_CERT_VERIFICATION, AUDIT_MSG_FORMAT, "System", "Failure", audit_msg);
+ sresult = PL_strtok_r(NULL, ",", &lasts);
+ rv = false;
+ continue;
+ }
+ PR_snprintf((char *)configname_cu, 256, "tps.cert.%s.certusage",
+ sresult);
+ cu = store->GetConfigAsString(configname_cu, NULL);
+ if ((cu == NULL) || *cu==0) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "certificate usage not found for cert tag:%s. Getting current certificate usage", sresult);
+ } else {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "found certificate usage:%s", cu);
+ }
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "Verifying cert tag: %s, nickname:%s, certificate usage:%s"
+ , sresult, nn, (cu!=NULL)? cu: "");
+
+ verifyResult = verifySystemCertByNickname(nn, cu);
+ if (verifyResult == true) {
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "cert verification passed on cert nickname:%s", nn);
+ PR_snprintf(audit_msg, 512, "Certificate verification succeeded:%s",
+ nn);
+ RA::Audit(EV_CIMC_CERT_VERIFICATION, AUDIT_MSG_FORMAT, "System", "Success", audit_msg);
+ } else {
+ rv = false;
+ RA::Debug(LL_PER_SERVER, "RA::verifySystemCerts",
+ "cert verification failed on cert nickname:%s", nn);
+ PR_snprintf(audit_msg, 512, "Certificate verification failed:%s",
+ nn);
+ RA::Audit(EV_CIMC_CERT_VERIFICATION, AUDIT_MSG_FORMAT, "System", "Failure", audit_msg);
+ }
+ sresult = PL_strtok_r(NULL, ",", &lasts);
+ }
+
+ if (certList_x != NULL) {
+ PL_strfree(certList_x);
+ }
+ }
+
+ return rv;
+}
+
+PK11SymKey *RA::FindSymKeyByName( PK11SlotInfo *slot, char *keyname) {
+char *name = NULL;
+ PK11SymKey *foundSymKey= NULL;
+ PK11SymKey *firstSymKey= NULL;
+ PK11SymKey *sk = NULL;
+ PK11SymKey *nextSymKey = NULL;
+ secuPWData pwdata;
+
+ pwdata.source = secuPWData::PW_NONE;
+ pwdata.data = (char *) NULL;
+ if (keyname == NULL)
+ {
+ goto cleanup;
+ }
+ if (slot== NULL)
+ {
+ goto cleanup;
+ }
+ /* Initialize the symmetric key list. */
+ firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata );
+ /* scan through the symmetric key list for a key matching our nickname */
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ /* get the nickname of this symkey */
+ name = PK11_GetSymKeyNickname( sk );
+
+ /* if the name matches, make a 'copy' of it */
+ if ( name != NULL && !strcmp( keyname, name ))
+ {
+ if (foundSymKey == NULL)
+ {
+ foundSymKey = PK11_ReferenceSymKey(sk);
+ }
+ PORT_Free(name);
+ }
+
+ sk = PK11_GetNextSymKey( sk );
+ }
+
+ /* We're done with the list now, let's free all the keys in it
+ It's okay to free our key, because we made a copy of it */
+
+ sk = firstSymKey;
+ while( sk != NULL )
+ {
+ nextSymKey = PK11_GetNextSymKey(sk);
+ PK11_FreeSymKey(sk);
+ sk = nextSymKey;
+ }
+
+ cleanup:
+ return foundSymKey;
+}
+
+PK11SymKey *RA::CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey)
+{
+ PK11SymKey *newKey = NULL;
+ PK11SymKey *firstEight = NULL;
+ PK11SymKey *concatKey = NULL;
+ PK11SymKey *internalOrigKey = NULL;
+ CK_ULONG bitPosition = 0;
+ SECItem paramsItem = { siBuffer, NULL, 0 };
+ CK_OBJECT_HANDLE keyhandle = 0;
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "entering.");
+
+ PK11SlotInfo *internal = PK11_GetInternalSlot();
+ if ( slot == NULL || origKey == NULL || internal == NULL)
+ goto loser;
+
+ if( internal != slot ) { //Make sure we do this on the NSS Generic Crypto services because concatanation
+ // only works there.
+ internalOrigKey = PK11_MoveSymKey( internal, CKA_ENCRYPT, 0, PR_FALSE, origKey );
+ }
+ // Extract first eight bytes from generated key into another key.
+ bitPosition = 0;
+ paramsItem.data = (CK_BYTE *) &bitPosition;
+ paramsItem.len = sizeof bitPosition;
+
+ if ( internalOrigKey)
+ firstEight = PK11_Derive(internalOrigKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+ else
+ firstEight = PK11_Derive(origKey, CKM_EXTRACT_KEY_FROM_KEY, &paramsItem, CKA_ENCRYPT , CKA_DERIVE, 8);
+
+ if (firstEight == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error deriving 8 byte portion of key.");
+ goto loser;
+ }
+
+ //Concatenate 8 byte key to the end of the original key, giving new 24 byte key
+ keyhandle = PK11_GetSymKeyHandle(firstEight);
+
+ paramsItem.data=(unsigned char *) &keyhandle;
+ paramsItem.len=sizeof(keyhandle);
+
+ if ( internalOrigKey ) {
+ concatKey = PK11_Derive ( internalOrigKey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ } else {
+ concatKey = PK11_Derive ( origKey , CKM_CONCATENATE_BASE_AND_KEY , &paramsItem ,CKM_DES3_ECB , CKA_DERIVE , 0);
+ }
+
+ if ( concatKey == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error concatenating 8 bytes on end of key.");
+ goto loser;
+ }
+
+ //Make sure we move this to the proper token, in case it got moved by NSS
+ //during the derive phase.
+
+ newKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, concatKey);
+
+ if ( newKey == NULL ) {
+ RA::Debug("RA_Enroll_Processor::CreateDesKey24Byte",
+ "error moving key to original slot.");
+ }
+
+loser:
+
+ if ( concatKey != NULL ) {
+ PK11_FreeSymKey( concatKey );
+ concatKey = NULL;
+ }
+
+ if ( firstEight != NULL ) {
+ PK11_FreeSymKey ( firstEight );
+ firstEight = NULL;
+ }
+
+ if ( internalOrigKey != NULL ) {
+ PK11_FreeSymKey ( internalOrigKey );
+ internalOrigKey = NULL;
+ }
+
+ if ( internal != NULL ) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ return newKey;
+}
diff --git a/base/tps/src/httpClient/Cache.cpp b/base/tps/src/httpClient/Cache.cpp
new file mode 100644
index 000000000..2ea628f8c
--- /dev/null
+++ b/base/tps/src/httpClient/Cache.cpp
@@ -0,0 +1,496 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+/**
+ * Simple cache implementation
+ */
+#include <string.h>
+#include <time.h>
+
+// NSS includes
+#include "pk11func.h"
+#include "hasht.h"
+
+// NSPR includes
+#include "nspr.h"
+#include "plhash.h"
+#include "plstr.h"
+#include "plbase64.h"
+
+// Always before PSCommonLib.h
+#define COMMON_LIB_DLL
+#include "httpClient/httpc/PSCommonLib.h"
+#include "httpClient/httpc/Defines.h"
+//-- #include "httpClient/httpc/PSError.h"
+#include "httpClient/httpc/Iterator.h"
+#include "httpClient/httpc/Cache.h"
+//-- #include "httpClient/httpc/DebugLogger.h"
+//-- #include "httpClient/httpc/ErrorLogger.h"
+
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+//-- static const char *DEBUG_MODULE = NULL;
+//-- static const char *DEBUG_CLASS_NAME = "StringKeyCache";
+
+// From the NSPR implementation of hashtables
+/* Compute the number of buckets in ht */
+#define NBUCKETS(ht) (1 << (PL_HASH_BITS - (ht)->shift))
+
+
+/**
+ * Called from the destructor
+ */
+extern "C" {
+static PRIntn onCacheRelease( PLHashEntry* he, PRIntn index, void* arg );
+/**
+ * Called to allocate and return copies of keys
+ */
+static PRIntn getKeys( PLHashEntry* he, PRIntn index, void* arg );
+}
+
+/**
+ * Constructor
+ *
+ * @param key Pointer to the key being cached
+ * @param data Pointer to the data being cached
+ */
+CacheEntry::CacheEntry( const char* key, void *data ) {
+ if( key != NULL ) {
+ m_key = strdup( key );
+ } else {
+ m_key = NULL;
+ }
+ m_data = data;
+ // NSPR counts in microseconds
+ m_startTime = (time_t)(PR_Now() / 1000000);
+}
+
+/**
+ * Destructor
+ */
+CacheEntry::~CacheEntry() {
+ if( m_key != NULL ) {
+ free( m_key );
+ m_key = NULL;
+ }
+}
+
+/**
+ * Returns a pointer to the cached key
+ *
+ * @return A pointer to the cached key
+ */
+const char *CacheEntry::GetKey() {
+ return m_key;
+}
+
+/**
+ * Returns a pointer to the cached data
+ *
+ * @return A pointer to the cached data
+ */
+void *CacheEntry::GetData() {
+ return m_data;
+}
+
+
+/**
+ * Returns the time when the entry was created
+ *
+ * @return The time when the entry was created
+ */
+long CacheEntry::GetStartTime() {
+ return (long)m_startTime;
+}
+
+
+/**
+ * Default constructor
+ */
+Cache::Cache() {
+ m_cache = NULL;
+ m_cacheLock = NULL;
+}
+
+/**
+ * Constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cache is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+Cache::Cache( const char *name, int ttl, bool implicitLock ) {
+
+ Initialize( name, ttl, implicitLock );
+}
+
+/**
+ * Destructor
+ */
+Cache::~Cache() {
+
+ if( m_cacheLock ) {
+ PR_DestroyRWLock( m_cacheLock );
+ m_cacheLock = NULL;
+ }
+ if( m_cache ) {
+ PL_HashTableEnumerateEntries( m_cache, onCacheRelease, NULL );
+ PL_HashTableDestroy( m_cache );
+ m_cache = NULL;
+ }
+
+}
+
+/**
+ * Initializes the object - to be called from the constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cache is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+void Cache::Initialize( const char *name, int ttl, bool implicitLock ) {
+
+ if ( !m_cache ) {
+ m_implicitLock = implicitLock;
+ m_ttl = ttl;
+ m_cache = PL_NewHashTable( 0,
+ PL_HashString,
+ PL_CompareStrings,
+ PL_CompareValues,
+ NULL,
+ NULL
+ );
+ m_cacheLock = PR_NewRWLock( PR_RWLOCK_RANK_NONE, name );
+ m_name = name;
+ }
+
+}
+
+/**
+ * Acquires a read lock on the cache. Multiple threads may simultaneously
+ * have a read lock, but attempts to acquire a read lock will block
+ * if another thread already has a write lock. It is illegal to request
+ * a read lock if the thread already has one.
+ */
+void Cache::ReadLock() {
+ PR_RWLock_Rlock( m_cacheLock );
+}
+
+/**
+ * Acquires a write lock on the cache. Only one thread may have a write
+ * lock at any given time; attempts to acquire a write lock will block
+ * if another thread already has one. It is illegal to request
+ * a write lock if the thread already has one.
+ */
+void Cache::WriteLock() {
+ PR_RWLock_Wlock( m_cacheLock );
+}
+
+/**
+ * Releases a read or write lock that the thread has on the cache
+ */
+void Cache::Unlock() {
+ PR_RWLock_Unlock( m_cacheLock );
+}
+
+/**
+ * Returns the number of entries in the cache
+ *
+ * @return The number of entries in the cache
+ */
+int Cache::GetCount() {
+ int nKeys = 0;
+ if ( m_implicitLock ) {
+ ReadLock();
+ }
+ nKeys = m_cache->nentries;
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+ return nKeys;
+}
+
+class KeyIterator : public Iterator {
+public:
+ /**
+ * Constructor
+ *
+ * @param ht A hashtable to iterate on
+ * @param cacheLock Lock for accessing the hashtable
+ * @param implictLock true if hashtable locking is to be done
+ * internally
+ */
+ KeyIterator( PLHashTable *ht, PRRWLock *cacheLock, bool implicitLock ) {
+ m_table = ht;
+ m_bucketIndex = 0;
+ m_entry = m_table->buckets[m_bucketIndex];
+ m_cacheLock = cacheLock;
+ m_implicitLock = implicitLock;
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~KeyIterator() {
+ }
+
+ /**
+ * Returns true if there is at least one more key
+ *
+ * @return true if there is at least one more key
+ */
+ bool HasMore() {
+ if ( NULL == m_entry ) {
+ Next();
+ }
+ return ( NULL != m_entry );
+ }
+
+ /**
+ * Returns the next key, if any; the key is deallocated by the Iterator
+ * in its destructor
+ *
+ * @return The next key, if any, or NULL
+ */
+ void *Next() {
+ PLHashEntry *he = m_entry;
+ m_entry = (m_entry != NULL) ? m_entry->next : NULL;
+ int nBuckets = NBUCKETS(m_table);
+ if ( m_implicitLock ) {
+ PR_RWLock_Rlock( m_cacheLock );
+ }
+ while ( (NULL == m_entry) && (m_bucketIndex < (nBuckets-1)) ) {
+ m_bucketIndex++;
+ m_entry = m_table->buckets[m_bucketIndex];
+ }
+ if ( m_implicitLock ) {
+ PR_RWLock_Unlock( m_cacheLock );
+ }
+ return ( he != NULL ) ? (void *)he->key : NULL;
+ }
+
+private:
+ PLHashTable *m_table;
+ PLHashEntry *m_entry;
+ int m_bucketIndex;
+ PRRWLock* m_cacheLock;
+ bool m_implicitLock;
+};
+
+/**
+ * Constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cache is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+StringKeyCache::StringKeyCache( const char *name, int ttl,
+ bool implicitLock ) {
+
+ Initialize( name, ttl, implicitLock );
+
+}
+
+/**
+ * Destructor
+ */
+StringKeyCache::~StringKeyCache() {
+}
+
+/**
+ * Returns a cache entry
+ *
+ * @param key The name of the cache entry
+ * @return The corresponding cache entry, or NULL if not found
+ */
+CacheEntry *StringKeyCache::Get( const char *key ) {
+ // Avoid recursion when the debug log is starting up
+
+ if ( m_implicitLock ) {
+ ReadLock();
+ }
+ CacheEntry *entry =
+ (CacheEntry *)PL_HashTableLookupConst( m_cache, key );
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+ if ( entry && m_ttl ) {
+ // Check if the cache entry has expired
+ // NSPR counts in microseconds
+ time_t now = (time_t)(PR_Now() / 1000000);
+ if ( ((long)now - entry->GetStartTime()) > m_ttl ) {
+ if( key != NULL ) {
+ Remove( key );
+ key = NULL;
+ }
+ if( entry != NULL ) {
+ delete entry;
+ entry = NULL;
+ }
+ // Avoid recursion when the debug log is starting up
+ if ( PL_strcasecmp( m_name, "DebugLogModuleCache" ) ) {
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+//-- logger->Log( LOGLEVEL_FINER, DEBUG_CLASS_NAME,
+//-- "Get",
+ RA::Debug( LL_PER_PDU,
+ "StringKeyCache::Get: ",
+ "Entry %s expired from cache %s",
+ key,
+ m_name );
+ }
+ }
+ }
+
+ return entry;
+}
+
+/**
+ * Adds a cache entry
+ *
+ * @param key The name of the cache entry; an internal copy is made
+ * @param value The value of the cache entry
+ * @return The corresponding cache entry, or NULL if it couldn't be added
+ */
+CacheEntry *StringKeyCache::Put( const char *key, void *value ) {
+ CacheEntry *entry = new CacheEntry( key, value );
+ if ( m_implicitLock ) {
+ WriteLock();
+ }
+ PL_HashTableAdd( m_cache, entry->GetKey(), entry );
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+
+ return entry;
+}
+
+/**
+ * Removes a cache entry; does not free the entry object
+ *
+ * @param key The name of the cache entry
+ * @return The corresponding cache entry, or NULL if not found
+ */
+CacheEntry *StringKeyCache::Remove( const char *key ) {
+
+ if ( m_implicitLock ) {
+ WriteLock();
+ }
+ CacheEntry *entry =
+ (CacheEntry *)PL_HashTableLookupConst( m_cache, key );
+ if( entry ) {
+ PL_HashTableRemove( m_cache, key );
+ }
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+
+ return entry;
+}
+
+class KeyArray {
+public:
+ KeyArray( int nKeys ) {
+ m_nKeys = nKeys;
+ m_keys = new char *[m_nKeys];
+ m_currentKey = 0;
+ }
+ virtual ~KeyArray() {
+ }
+ int m_currentKey;
+ int m_nKeys;
+ char **m_keys;
+};
+
+/**
+ * Returns an iterator over keys in the cache
+ *
+ * @return An iterator over keys in the cache
+ */
+Iterator *StringKeyCache::GetKeyIterator() {
+ return new KeyIterator( m_cache, m_cacheLock, m_implicitLock );
+}
+
+/**
+ * Allocates and returns a list of keys in the cache
+ *
+ * @param keys Returns an array of names; each name and also the
+ * array itself are to be freed by the caller with delete
+ * @return The number of keys found
+ */
+int StringKeyCache::GetKeys( char ***keys ) {
+
+ int nKeys = GetCount();
+ if ( m_implicitLock ) {
+ ReadLock();
+ }
+ KeyArray keyArray( nKeys );
+ PL_HashTableEnumerateEntries( m_cache, getKeys, &keyArray );
+ if ( m_implicitLock ) {
+ Unlock();
+ }
+ if( ( keyArray.m_nKeys < 1 ) && keyArray.m_keys ) {
+ delete [] keyArray.m_keys;
+ keyArray.m_keys = NULL;
+ }
+ *keys = keyArray.m_keys;
+
+ return keyArray.m_nKeys;
+}
+
+/**
+ * Adds cache entry keys to an accumulator
+ */
+extern "C" {
+static PRIntn getKeys( PLHashEntry* he, PRIntn index, void* arg ) {
+ PRIntn result = HT_ENUMERATE_NEXT;
+ if ( he != NULL ) {
+ if ( he->key ) {
+ KeyArray *keys = (KeyArray *)arg;
+ int len = strlen( (char *)he->key );
+ int i = keys->m_currentKey;
+ keys->m_keys[i] = new char[len+1];
+ strcpy( keys->m_keys[i], (char *)he->key );
+ keys->m_currentKey++;
+ }
+ }
+ return result;
+}
+
+/**
+ * Frees keys of entries in cache; does not free values
+ */
+static PRIntn onCacheRelease( PLHashEntry* he, PRIntn index, void* arg ) {
+ PRIntn result = HT_ENUMERATE_NEXT;
+ if( he != NULL ) {
+ if( he->key != NULL ) {
+ free( (char *) he->key );
+ he->key = NULL;
+ result = HT_ENUMERATE_REMOVE;
+ }
+ }
+ return result;
+}
+} // extern "C"
diff --git a/base/tps/src/httpClient/engine.cpp b/base/tps/src/httpClient/engine.cpp
new file mode 100644
index 000000000..621a37244
--- /dev/null
+++ b/base/tps/src/httpClient/engine.cpp
@@ -0,0 +1,775 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include "nspr.h"
+#include "sslproto.h"
+#include "prerror.h"
+
+#include "ssl.h"
+#include "nss.h"
+#include "pk11func.h"
+#include "cert.h"
+#include "certt.h"
+#include "sslerr.h"
+#include "secerr.h"
+
+#include "httpClient/httpc/engine.h"
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/PSPRUtil.h"
+#include "httpClient/httpc/Defines.h"
+//-- #include "httpClient/httpc/DebugLogger.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+char* certName = NULL;
+char* password = NULL;
+int ciphers[32];
+int cipherCount = 0;
+int _doVerifyServerCert = 1;
+
+//-- static const char *DEBUG_MODULE = "httpclient";
+//-- static const char *DEBUG_CLASS_NAME = "HttpEngine";
+
+PRIntervalTime Engine::globaltimeout = PR_TicksPerSecond()*30;
+
+static char * ownPasswd( PK11SlotInfo *slot, PRBool retry, void *arg) {
+ if (!retry) {
+ if( password != NULL ) {
+ return PL_strdup(password);
+ } else {
+ return PL_strdup( "httptest" );
+ }
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * Function: SECStatus myBadCertHandler()
+ * <BR>
+ * Purpose: This callback is called when the incoming certificate is not
+ * valid. We define a certain set of parameters that still cause the
+ * certificate to be "valid" for this session, and return SECSuccess to cause
+ * the server to continue processing the request when any of these conditions
+ * are met. Otherwise, SECFailure is return and the server rejects the
+ * request.
+ */
+SECStatus myBadCertHandler( void *arg, PRFileDesc *socket ) {
+
+ SECStatus secStatus = SECFailure;
+ PRErrorCode err;
+
+ /* log invalid cert here */
+
+ if ( !arg ) {
+ return secStatus;
+ }
+
+ *(PRErrorCode *)arg = err = PORT_GetError();
+
+ /* If any of the cases in the switch are met, then we will proceed */
+ /* with the processing of the request anyway. Otherwise, the default */
+ /* case will be reached and we will reject the request. */
+
+ switch (err) {
+ case SEC_ERROR_INVALID_AVA:
+ case SEC_ERROR_INVALID_TIME:
+ case SEC_ERROR_BAD_SIGNATURE:
+ case SEC_ERROR_EXPIRED_CERTIFICATE:
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ case SEC_ERROR_UNTRUSTED_CERT:
+ case SEC_ERROR_CERT_VALID:
+ case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+ case SEC_ERROR_CRL_EXPIRED:
+ case SEC_ERROR_CRL_BAD_SIGNATURE:
+ case SEC_ERROR_EXTENSION_VALUE_INVALID:
+ case SEC_ERROR_CA_CERT_INVALID:
+ case SEC_ERROR_CERT_USAGES_INVALID:
+ case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION:
+ case SEC_ERROR_EXTENSION_NOT_FOUND: // Added by Rob 5/21/2002
+ secStatus = SECSuccess;
+ break;
+ default:
+ secStatus = SECFailure;
+ break;
+ }
+
+ return secStatus;
+}
+
+
+PRBool __EXPORT InitSecurity(char* certDir, char* certname, char* certpassword, char *prefix,int verify ) {
+ if (certpassword) {
+ password = PL_strdup(certpassword);
+ } else {
+ password = PL_strdup( "httptest" );
+ }
+ if (certname) {
+ certName = PL_strdup(certname);
+ }
+
+ SECStatus stat;
+ PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0 );
+ if (!NSS_IsInitialized()) {
+ stat = NSS_Initialize( certDir, prefix, prefix,"secmod.db",
+ NSS_INIT_READONLY);
+ } else {
+ stat = SECSuccess;
+ RA::Debug( LL_PER_PDU,
+ "initSecurity: ",
+ "NSS Already initialized" );
+
+ }
+
+ if (SECSuccess != stat) {
+ // int err = PR_GetError();
+ return PR_FAILURE;
+ }
+ PK11_SetPasswordFunc(ownPasswd);
+
+ stat = NSS_SetDomesticPolicy();
+ SSL_CipherPrefSetDefault( SSL_RSA_WITH_NULL_MD5, PR_TRUE );
+
+ _doVerifyServerCert = verify;
+
+
+ return PR_TRUE;
+}
+
+
+int ssl2Suites[] = {
+ SSL_EN_RC4_128_WITH_MD5, /* A */
+ SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
+ SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
+ SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
+ SSL_EN_DES_64_CBC_WITH_MD5, /* E */
+ SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
+ 0
+};
+
+int ssl3Suites[] = {
+ SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */
+ SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, /* b */
+ SSL_RSA_WITH_RC4_128_MD5, /* c */
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA, /* d */
+ SSL_RSA_WITH_DES_CBC_SHA, /* e */
+ SSL_RSA_EXPORT_WITH_RC4_40_MD5, /* f */
+ SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* g */
+ SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* h */
+ SSL_RSA_WITH_NULL_MD5, /* i */
+ SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, /* j */
+ SSL_RSA_FIPS_WITH_DES_CBC_SHA, /* k */
+ TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, /* l */
+ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, /* m */
+ 0
+};
+
+int tlsSuites[] = {
+// TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+// TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+// TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+// TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+// TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+// TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+};
+
+void disableAllCiphersOnSocket(PRFileDesc* sock) {
+ int i;
+ int numsuites = SSL_NumImplementedCiphers;
+
+ /* disable all the cipher suites for that socket */
+ for (i = 0; i<numsuites; i++) {
+ SSL_CipherPrefSet(sock, SSL_ImplementedCiphers[i], SSL_NOT_ALLOWED);
+ }
+}
+
+void __EXPORT EnableAllSSL3Ciphers(PRFileDesc* sock) {
+ int i =0;
+ while (ssl3Suites[i]) {
+ SSL_CipherPrefSet(sock, ssl3Suites[i], SSL_ALLOWED);
+ }
+}
+
+void __EXPORT EnableAllTLSCiphers(PRFileDesc* sock) {
+ int i =0;
+ while (tlsSuites[i]) {
+ SSL_CipherPrefSet(sock, tlsSuites[i++], SSL_ALLOWED);
+ }
+}
+
+PRBool __EXPORT EnableCipher(const char* cipherString) {
+ int ndx;
+
+ if (!cipherString) {
+ return PR_FALSE;
+ }
+
+ while (0 != (ndx = *cipherString++)) {
+ int* cptr;
+ int cipher;
+
+ if (! isalpha(ndx)) {
+ continue;
+ }
+ cptr = islower(ndx) ? ssl3Suites : ssl2Suites;
+ for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) {
+ /* do nothing */;
+ }
+ ciphers[cipherCount++] = cipher;
+ }
+
+ return PR_TRUE;
+}
+
+SECStatus certcallback (
+ void *arg,
+ PRFileDesc *fd,
+ PRBool checksig,
+ PRBool isServer) {
+ return SECSuccess; // always succeed
+}
+
+/**
+ * Function: SECStatus myAuthCertificate()
+ * <BR>
+ * Purpose: This function is our custom certificate authentication handler.
+ * <BR>
+ * Note: This implementation is essentially the same as the default
+ * SSL_AuthCertificate().
+ */
+extern "C" {
+
+static SECStatus myAuthCertificate( void *arg,
+ PRFileDesc *socket,
+ PRBool checksig,
+ PRBool isServer ) {
+
+ SECCertUsage certUsage;
+ CERTCertificate * cert;
+ void * pinArg;
+ char * hostName = NULL;
+ SECStatus secStatus = SECSuccess;
+//-- static const char *DEBUG_METHOD_NAME = "myAuthCertificate";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( "httpclient");
+
+ if ( !arg || !socket ) {
+ return SECFailure;
+ }
+
+ /* Define how the cert is being used based upon the isServer flag. */
+
+ certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
+
+ cert = SSL_PeerCertificate( socket );
+
+ pinArg = SSL_RevealPinArg( socket );
+
+ // Skip the server cert verification fconditionally, because our test
+ // servers do not have a valid root CA cert.
+ if ( _doVerifyServerCert ) {
+
+ PRLock *verify_lock = RA::GetVerifyLock();
+ if (verify_lock == NULL) {
+ return SECFailure;
+ }
+ PR_Lock(verify_lock);
+ /* This function is not thread-safe. So we need to use a global lock */
+ secStatus = CERT_VerifyCertNow( (CERTCertDBHandle *)arg,
+ cert,
+ checksig,
+ certUsage,
+ pinArg);
+ PR_Unlock(verify_lock);
+
+ if( SECSuccess != secStatus ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ if (cert == NULL) {
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "Server Certificate Not Found" );
+ } else {
+ if (cert->subjectName == NULL) {
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "Untrusted server certificate" );
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "Untrusted server certificate error=%d subject='%s'", PORT_GetError(), cert->subjectName );
+ }
+ }
+ }
+ }
+
+ /* If this is a server, we're finished. */
+ if (isServer || secStatus != SECSuccess) {
+ return secStatus;
+ }
+
+ /* Certificate is OK. Since this is the client side of an SSL
+ * connection, we need to verify that the name field in the cert
+ * matches the desired hostname. This is our defense against
+ * man-in-the-middle attacks.
+ */
+
+ /* SSL_RevealURL returns a hostName, not an URL. */
+ hostName = SSL_RevealURL( socket );
+
+ if (hostName && hostName[0]) {
+ secStatus = CERT_VerifyCertName( cert, hostName );
+ if( SECSuccess != secStatus ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "Server name does not match that in certificate" );
+ }
+ } else {
+ secStatus = SECFailure;
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "myAuthCertificate: ",
+ "server name has been specified" );
+ }
+
+ if( hostName != NULL ) {
+ PR_Free( hostName );
+ hostName = NULL;
+ }
+
+ return secStatus;
+}
+
+
+/* Function: SECStatus ownGetClientAuthData()
+ *
+ * Purpose: This callback is used by SSL to pull client certificate
+ * information upon server request.
+ */
+static SECStatus ownGetClientAuthData(void *arg, PRFileDesc *socket,
+ CERTDistNames *caNames,
+ CERTCertificate **pRetCert,/*return */
+ SECKEYPrivateKey **pRetKey) {
+ CERTCertificate * cert = NULL;
+ SECKEYPrivateKey * privKey = NULL;
+ void * proto_win = NULL;
+ SECStatus rv = SECFailure;
+ char * localNickName = (char *)arg;
+
+ proto_win = SSL_RevealPinArg(socket);
+
+ if (localNickName) {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData looking for nickname=%s",
+ localNickName );
+ cert = PK11_FindCertFromNickname(localNickName, proto_win);
+ if (cert) {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData found cert" );
+ privKey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if (privKey) {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData found priv key for cert" );
+ rv = SECSuccess;
+ } else {
+ if( cert != NULL ) {
+ CERT_DestroyCertificate( cert );
+ cert = NULL;
+ }
+ }
+ }
+ else {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData did NOT find cert" );
+ }
+
+ if (rv == SECSuccess) {
+ *pRetCert = cert;
+ *pRetKey = privKey;
+ }
+
+ // if( localNickName != NULL ) {
+ // free( localNickName );
+ // localNickName = NULL;
+ // }
+ return rv;
+ }
+ else {
+ RA::Debug( LL_PER_PDU,
+ "ownGetClientAuthData: ",
+ "ownGetClientAuthData does not have nickname" );
+ }
+
+ char* chosenNickName = certName ? (char *)PL_strdup(certName) : NULL;
+ if (chosenNickName) {
+ cert = PK11_FindCertFromNickname(chosenNickName, proto_win);
+ if (cert) {
+ privKey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if (privKey) {
+ rv = SECSuccess;
+ } else {
+ if( cert != NULL ) {
+ CERT_DestroyCertificate( cert );
+ cert = NULL;
+ }
+ }
+ }
+ } else {
+ /* no nickname given, automatically find the right cert */
+ CERTCertNicknames * names;
+ int i;
+
+ names = CERT_GetCertNicknames( CERT_GetDefaultCertDB(),
+ SEC_CERT_NICKNAMES_USER,
+ proto_win);
+
+ if (names != NULL) {
+ for( i=0; i < names->numnicknames; i++ ) {
+ cert = PK11_FindCertFromNickname(names->nicknames[i],
+ proto_win);
+ if (!cert) {
+ continue;
+ }
+
+ /* Only check unexpired certs */
+ if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE) !=
+ secCertTimeValid) {
+ if( cert != NULL ) {
+ CERT_DestroyCertificate( cert );
+ cert = NULL;
+ }
+ continue;
+ }
+
+ rv = NSS_CmpCertChainWCANames(cert, caNames);
+
+ if (rv == SECSuccess) {
+ privKey = PK11_FindKeyByAnyCert(cert, proto_win);
+ if (privKey) {
+ // got the key
+ break;
+ }
+
+ // cert database password was probably wrong
+ rv = SECFailure;
+ break;
+ };
+ } /* for loop */
+ CERT_FreeNicknames(names);
+ } // names
+ } // no nickname chosen
+
+ if (rv == SECSuccess) {
+ *pRetCert = cert;
+ *pRetKey = privKey;
+ }
+
+ if( chosenNickName != NULL ) {
+ free( chosenNickName );
+ chosenNickName = NULL;
+ }
+
+ return rv;
+}
+} // extern "C"
+
+void nodelay(PRFileDesc* fd) {
+ PRSocketOptionData opt;
+ PRStatus rv;
+
+ opt.option = PR_SockOpt_NoDelay;
+ opt.value.no_delay = PR_FALSE;
+
+ rv = PR_GetSocketOption(fd, &opt);
+ if (rv == PR_FAILURE) {
+ return;
+ }
+
+ opt.option = PR_SockOpt_NoDelay;
+ opt.value.no_delay = PR_TRUE;
+ rv = PR_SetSocketOption(fd, &opt);
+ if (rv == PR_FAILURE) {
+ return;
+ }
+
+ return;
+}
+
+
+void __EXPORT setDefaultAllTLSCiphers() {
+ int i =0;
+ char alg[256];
+ while (tlsSuites[i]) {
+ PR_snprintf((char *)alg, 256, "%x", tlsSuites[i]);
+ RA::Debug( LL_PER_PDU,
+ "setDefaultAllTLSCiphers",
+ alg);
+ SSL_CipherPrefSetDefault(tlsSuites[i++], PR_TRUE);
+ }
+}
+
+/**
+ * Returns a file descriptor for I/O if the HTTP connection is successful
+ * @param addr PRnetAddr structure which points to the server to connect to
+ * @param SSLOn boo;elan to state if this is an SSL client
+ */
+PRFileDesc * Engine::_doConnect(PRNetAddr *addr, PRBool SSLOn,
+ const PRInt32* cipherSuite,
+ PRInt32 count, const char *nickName,
+ PRBool handshake,
+ /*const SecurityProtocols& secprots,*/
+ const char *serverName, PRIntervalTime timeout) {
+//-- static const char *DEBUG_METHOD_NAME = "doConnect";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( "httpclient");
+ PRFileDesc *tcpsock = NULL;
+ PRFileDesc *sock = NULL;
+
+ SSL_CipherPrefSetDefault(0xC005 /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */, PR_TRUE);
+ setDefaultAllTLSCiphers();
+
+ tcpsock = PR_OpenTCPSocket(addr->raw.family);
+
+ if (nickName != NULL)
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "_doConnect has nickname=%s",
+ nickName );
+ else
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "_doConnect has nickname=NULL" );
+
+ if (!tcpsock) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+//XXXX log NSPR error code
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "PR_OpenTCPSocket returned NULL" );
+ return NULL;
+ }
+
+ nodelay(tcpsock);
+
+ if (PR_TRUE == SSLOn) {
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL is ON" );
+ sock=SSL_ImportFD(NULL, tcpsock);
+ if (!sock) {
+ //xxx log
+ if( tcpsock != NULL ) {
+ PR_Close( tcpsock );
+ tcpsock = NULL;
+ }
+ return NULL;
+ }
+
+ int error = 0;
+ PRBool rv = SSL_OptionSet(sock, SSL_SECURITY, 1);
+ if ( SECSuccess == rv ) {
+ rv = SSL_OptionSet(sock, SSL_HANDSHAKE_AS_CLIENT, 1);
+ }
+ if ( SECSuccess == rv ) {
+ rv = SSL_OptionSet(sock, SSL_ENABLE_SSL3, PR_TRUE);
+ }
+ if ( SECSuccess == rv ) {
+ rv = SSL_OptionSet(sock, SSL_ENABLE_TLS, PR_TRUE);
+ }
+ if ( SECSuccess != rv ) {
+ error = PORT_GetError();
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL_OptionSet error: %d",
+ error );
+ return NULL;
+ }
+
+ rv = SSL_GetClientAuthDataHook( sock,
+ ownGetClientAuthData,
+ (void*)nickName);
+ if ( SECSuccess != rv ) {
+ error = PORT_GetError();
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL_GetClientAuthDataHook error: %d",
+ error );
+ return NULL;
+ }
+
+ rv = SSL_AuthCertificateHook(sock,
+ (SSLAuthCertificate)myAuthCertificate,
+ (void *)CERT_GetDefaultCertDB());
+
+ if (rv != SECSuccess ) {
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+ return NULL;
+ }
+
+ PRErrorCode errCode = 0;
+
+ rv = SSL_BadCertHook( sock,
+ (SSLBadCertHandler)myBadCertHandler,
+ &errCode );
+ rv = SSL_SetURL( sock, serverName );
+
+ if (rv != SECSuccess ) {
+ error = PORT_GetError();
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL_SetURL error: %d",
+ error );
+ return NULL;
+ }
+
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "end SSL is ON" );
+ //EnableAllTLSCiphers( sock);
+ //EnableAllSSL3Ciphers( sock);
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "SSL is OFF" );
+ sock = tcpsock;
+ }
+
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "about to call PR_Connect, timeout =%d",
+ timeout );
+
+ if ( PR_Connect(sock, addr, timeout) == PR_FAILURE ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "Engine::_doConnect: ",
+ "PR_Connect error: %d Msg=%s",
+ PR_GetError(),
+ "XXX" );
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+ return NULL;
+ }
+
+ return (sock);
+}
+
+/**
+ * Called from higher level to connect, sends a request
+ * and gets a response as an HttpResponse object
+ *
+ * @param request Contains the entire request url + headers etc
+ * @param server Has the host, port, protocol info
+ * @param timeout Time in seconds to wait for a response
+ * @return The response body and headers
+ */
+PSHttpResponse * HttpEngine::makeRequest( PSHttpRequest &request,
+ const PSHttpServer& server,
+ int timeout, PRBool expectChunked ) {
+ PRNetAddr addr;
+ PRFileDesc *sock = NULL;
+ PSHttpResponse *resp = NULL;
+
+ PRBool response_code = 0;
+
+ server.getAddr(&addr);
+
+ char *nickName = request.getCertNickName();
+
+ char *serverName = (char *)server.getAddr();
+ sock = _doConnect( &addr, request.isSSL(), 0, 0,nickName, 0, serverName );
+
+ if ( sock != NULL) {
+ PRBool status = request.send( sock );
+ if ( status ) {
+ resp = new PSHttpResponse( sock, &request, timeout, expectChunked );
+ response_code = resp->processResponse();
+
+ RA::Debug( LL_PER_PDU,
+ "HttpEngine::makeRequest: ",
+ "makeRequest response %d",
+ response_code );
+
+ if(!response_code)
+ {
+ RA::Debug( LL_PER_PDU,
+ "HttpEngine::makeRequest: ",
+ "Deleting response because of FALSE return, returning NULL." );
+ if( resp != NULL ) {
+ delete resp;
+ resp = NULL;
+ }
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+
+ return NULL;
+
+ }
+ }
+ if( sock != NULL ) {
+ PR_Close( sock );
+ sock = NULL;
+ }
+ }
+
+ return resp;
+}
diff --git a/base/tps/src/httpClient/http.cpp b/base/tps/src/httpClient/http.cpp
new file mode 100644
index 000000000..60ca48bf5
--- /dev/null
+++ b/base/tps/src/httpClient/http.cpp
@@ -0,0 +1,307 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include <string.h>
+
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/engine.h"
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/response.h"
+//-- #include "httpClient/httpc/DebugLogger.h"
+//-- #include "httpClient/httpc/ErrorLogger.h"
+#include "httpClient/httpc/PSPRUtil.h"
+#include "httpClient/httpc/Defines.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+
+//-- static const char *DEBUG_MODULE = "httpclient";
+//-- static const char *DEBUG_CLASS_NAME = "PSHttpServer";
+
+/**
+ * Constructor
+ * @param addr The hostname:port of the server to connect to. The default
+ * port is 80
+ * @param af The protocol family like PR_AF_INET
+ */
+PSHttpServer::PSHttpServer(const char *addr, PRUint16 af) {
+ SSLOn = PR_FALSE;
+ PRUint16 port = 80;
+//-- static const char *DEBUG_METHOD_NAME = "Constructor";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ char *pPort;
+
+
+ _addr = NULL;
+// if( _addr != NULL ) {
+// PL_strfree( _addr );
+// _addr = NULL;
+// }
+
+ if (addr) {
+ _addr = PL_strdup(addr);
+ }
+
+ pPort = PL_strchr(_addr, ':');
+ if (pPort) {
+ *pPort = '\0';
+ port = (PRUint16) atoi(++pPort);
+ }
+
+ /* kludge for doing IPv6 tests on localhost */
+ if (!PL_strcmp(_addr, "ip6-localhost") && (af == PR_AF_INET6)) {
+ PL_strcpy(_addr, "::1");
+ }
+
+// PR_InitializeNetAddr(PR_IpAddrNull, port, &_netAddr);
+
+ if (PR_StringToNetAddr(_addr, &_netAddr) == PR_FAILURE) {
+ char buf[2000];
+ PRHostEnt ent;
+
+ RA::Debug( LL_PER_PDU,
+ "PSHttpServer::PSHttpServer ",
+ " host %s port %d ",_addr,port );
+ PR_InitializeNetAddr(PR_IpAddrNull, port, &_netAddr);
+ if (PR_GetIPNodeByName(_addr, af, PR_AI_DEFAULT,
+ buf, sizeof(buf), &ent) == PR_SUCCESS) {
+ PR_EnumerateHostEnt(0, &ent, port, &_netAddr);
+ } else {
+//-- ErrorLogger::GetErrorLogger()->Log(
+//-- LOGLEVEL_SEVERE, PR_GetError(),
+ RA::Debug( LL_PER_PDU,
+ "PSHttpServer::PSHttpServer: ",
+ "PR_GetIPNodeByName returned error %d [%s] for "
+ "address %s",
+ PR_GetError (),
+ "XXX",
+ addr );
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpServer::PSHttpServer: ",
+ "PR_GetIPNodeByName returned error %d [%s] for "
+ "address %s",
+ PR_GetError(),
+ "XXX",
+ addr );
+ }
+ }
+}
+
+/**
+ * Destructor of the Httpserver class
+ */
+PSHttpServer::~PSHttpServer() {
+ if( _addr != NULL ) {
+ PL_strfree( _addr );
+ _addr = NULL;
+ }
+}
+
+/**
+ * Turns SSL on or off for the connection
+ * @param SSLstate PR_TRUE to make an SSL connection
+ */
+void PSHttpServer::setSSL(PRBool SSLstate) {
+ SSLOn = SSLstate;
+}
+
+/**
+ * Returns the current SSL state for this PSHttpServer object
+ * @return PR_TRUE if SSL is enabled else PR_FALSE
+ */
+PRBool PSHttpServer::isSSL() const {
+ return SSLOn;
+}
+
+/**
+ * Returns the IP address of the HTTP server
+ * @return IP address of the server as a long
+ */
+
+long PSHttpServer::getIp() const {
+ return _netAddr.inet.ip;
+}
+
+/**
+ * Returns the port for the HTTP server
+ * @return port of the server
+ */
+
+long PSHttpServer::getPort() const {
+ return (long) PR_ntohs(_netAddr.inet.port);
+}
+
+/**
+ * Returns the server IP address as a string
+ * @return server address as string
+*/
+const char * PSHttpServer::getAddr() const {
+ return _addr;
+}
+
+/**
+ * Gets the server addr as a PR_NetAddr structure
+ * @param addr PR_netaddr struct in which server address is returned
+ */
+void PSHttpServer::getAddr(PRNetAddr *addr) const {
+ memcpy(addr, &_netAddr, sizeof(_netAddr));
+}
+
+/**
+ * Fets the protocol as string: "HTTP/1.0" "HTTP/1.1" etc
+ * @return Protocol string
+ */
+const char *HttpProtocolToString(HttpProtocol proto) {
+ switch(proto) {
+ case HTTP09:
+ return "";
+ case HTTP10:
+ return "HTTP/1.0";
+ case HTTP11:
+ return "HTTP/1.1";
+ case HTTPBOGUS:
+ return "BOGO-PROTO";
+ case HTTPNA:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+/**
+* Constructor for HttpMessage. This is a base class for PSHttpRequest
+*/
+HttpMessage :: HttpMessage(long len, const char* buf) {
+ firstline = NULL;
+ cl = 0;
+ proto = HTTPNA;
+
+ // search for the first line
+ int counter=0;
+ PRBool found = PR_FALSE;
+ while ( ( (counter++<len) && (PR_FALSE == found) ) ) {
+ if (buf[counter] != '\n') {
+ continue;
+ }
+ found = PR_TRUE;
+ }
+
+ // extract the first line
+ if (PR_TRUE == found) {
+ firstline=new char[counter+1];
+ memcpy(firstline, buf, counter);
+ firstline[counter] = '\0';
+ }
+}
+
+HttpMessage :: ~HttpMessage() {
+ if( firstline != NULL ) {
+ delete firstline;
+ firstline = NULL;
+ }
+}
+
+/*SecurityProtocols :: SecurityProtocols(PRBool s2, PRBool s3, PRBool t)
+{
+ ssl2 = s2;
+ ssl3 = s3;
+ tls = t;
+};
+
+const SecurityProtocols& SecurityProtocols :: operator = (const RWTPtrSlist<char>& protlist)
+{
+ ssl2 = PR_FALSE;
+ ssl3 = PR_FALSE;
+ tls = PR_FALSE;
+ PRInt32 i;
+ for (i = 0;i<protlist.entries();i++)
+ {
+ if (0 == strcmp(protlist.at(i), "SSL2"))
+ {
+ ssl2 = PR_TRUE;
+ };
+ if (0 == strcmp(protlist.at(i), "SSL3"))
+ {
+ ssl3 = PR_TRUE;
+ };
+ if (0 == strcmp(protlist.at(i), "TLS"))
+ {
+ tls = PR_TRUE;
+ };
+ };
+ return *this;
+};
+
+const SecurityProtocols& SecurityProtocols :: operator = (const SecurityProtocols& rhs)
+{
+ ssl2 = rhs.ssl2;
+ ssl3 = rhs.ssl3;
+ tls = rhs.tls;
+ return *this;
+};
+*/
+
+
+PRBool PSHttpServer::putFile(const char* localFile,
+ const char* remoteUri) const {
+ PSHttpRequest request(this, remoteUri, HTTP10, Engine::globaltimeout);
+ request.setMethod("PUT");
+ request.useLocalFileAsBody(localFile);
+
+ PRBool rv = _putFile(request);
+ return rv;
+}
+
+PRBool PSHttpServer::putFile(const char *uri, int size) const {
+ PSHttpRequest request(this, uri, HTTP10, Engine::globaltimeout);
+ request.setMethod("PUT");
+ request.addRandomBody(size);
+
+ PRBool rv = _putFile(request);;
+ return rv;
+}
+
+PRBool PSHttpServer::_putFile(PSHttpRequest& request) const {
+ HttpEngine engine;
+ PRBool rv = PR_TRUE;
+
+ PSHttpResponse* response = engine.makeRequest(request, *this);
+
+ if (response) {
+ int status = response->getStatus();
+ if (status == 200 || status == 201 || status == 204) {
+ rv = PR_TRUE;
+ } else {
+ rv = PR_FALSE;
+ }
+ if( response != NULL ) {
+ delete response;
+ response = NULL;
+ }
+ } else {
+ rv = PR_FALSE;
+ }
+ return rv;
+}
+
diff --git a/base/tps/src/httpClient/httpClient.cpp b/base/tps/src/httpClient/httpClient.cpp
new file mode 100644
index 000000000..7f4e9fff3
--- /dev/null
+++ b/base/tps/src/httpClient/httpClient.cpp
@@ -0,0 +1,130 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "nspr.h"
+#include <sys/types.h>
+
+#include <stdio.h>
+#ifndef XP_WIN32
+#include <unistd.h> /* sleep */
+#else /* XP_WIN32 */
+#include <windows.h>
+#endif /* XP_WIN32 */
+
+#include "main/Base.h"
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/engine.h"
+
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+/*
+ * httpSend: sends to an HTTP server
+ * host_port should be in the for "host:port"
+ * e.g. ca.fedora.redhat.com:1027
+ * uri should contain uri including parameter values
+ * e.g. https://ca.fedora.redhat.com:1027/ca/profileSubmitSSLClient?profileId=userKey&screenname=user1&publickey=YWJjMTIzCg
+ * method has to be "GET" or "POST"
+ * body is the HTTP body. Can have nothing.
+ */
+PSHttpResponse *httpSend(char *host_port, char *uri, char *method, char *body)
+{
+ const char* nickname;
+ nickname = RA::GetConfigStore()->GetConfigAsString("ra.clientNickname", "");
+
+ char *pPort = NULL;
+ char *pPortActual = NULL;
+
+
+ char hostName[512];
+
+ /*
+ * Isolate the host name, account for IPV6 numeric addresses.
+ *
+ */
+
+ if(host_port)
+ strncpy(hostName,host_port,512);
+
+ pPort = hostName;
+ while(1) {
+ pPort = strchr(pPort, ':');
+ if (pPort) {
+ pPortActual = pPort;
+ pPort++;
+ } else
+ break;
+ }
+
+ if(pPortActual)
+ *pPortActual = '\0';
+
+
+ /*
+ * Rifle through the values for the host
+ */
+
+ PRAddrInfo *ai;
+ void *iter;
+ PRNetAddr addr;
+ int family = PR_AF_INET;
+
+ ai = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC, PR_AI_ADDRCONFIG);
+ if (ai) {
+ printf("%s\n", PR_GetCanonNameFromAddrInfo(ai));
+ iter = NULL;
+ while ((iter = PR_EnumerateAddrInfo(iter, ai, 0, &addr)) != NULL) {
+ char buf[512];
+ PR_NetAddrToString(&addr, buf, sizeof buf);
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::httpSend: ",
+ "Sending addr -- Msg='%s'\n",
+ buf );
+ family = PR_NetAddrFamily(&addr);
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::httpSend: ",
+ "Sending family -- Msg='%d'\n",
+ family );
+ break;
+ }
+ PR_FreeAddrInfo(ai);
+
+ }
+
+ PSHttpServer server(host_port, family);
+ server.setSSL(PR_TRUE);
+ // use "HTTP10" if no chunking
+ PSHttpRequest request( &server, uri, HTTP11, 0 );
+ request.setSSL(PR_TRUE);
+ request.setCertNickName(nickname);
+ request.setMethod(method);
+ if (body != NULL)
+ request.setBody( strlen(body), body);
+
+ // use with "POST" only
+ request.addHeader( "Content-Type", "text/xml" );
+ request.addHeader( "Connection", "keep-alive" );
+ HttpEngine engine;
+ PSHttpResponse *resp = engine.makeRequest( request, server, 120 /*_timeout*/ , PR_TRUE /* expect chunked*/);
+
+ return resp;
+}
diff --git a/base/tps/src/httpClient/nscperror.cpp b/base/tps/src/httpClient/nscperror.cpp
new file mode 100644
index 000000000..38c722de2
--- /dev/null
+++ b/base/tps/src/httpClient/nscperror.cpp
@@ -0,0 +1,358 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/* nscperrors.c
+ * Very crude error handling for nspr and libsec.
+ */
+
+#include "prerror.h"
+
+#define NSCP_NSPR_ERROR_BASE (PR_NSPR_ERROR_BASE)
+#define NSCP_NSPR_MAX_ERROR ((PR_MAX_ERROR) - 1)
+#define NSCP_LIBSEC_ERROR_BASE (-8192)
+#define NSCP_LIBSEC_MAX_ERROR (NSCP_LIBSEC_ERROR_BASE + 118)
+#define NSCP_LIBSSL_ERROR_BASE (-12288)
+#define NSCP_LIBSSL_MAX_ERROR (NSCP_LIBSSL_ERROR_BASE + 89)
+
+typedef struct nscp_error_t {
+ int errorNumber;
+ const char *errorString;
+} nscp_error_t;
+
+nscp_error_t nscp_nspr_errors[] = {
+ { 0, "Out of memory" },
+ { 1, "Bad file descriptor" },
+ { 2, "Data temporarily not available" },
+ { 3, "Access fault" },
+ { 4, "Invalid method" },
+ { 5, "Illegal access" },
+ { 6, "Unknown error" },
+ { 7, "Pending interrupt" },
+ { 8, "Not implemented" },
+ { 9, "IO error" },
+ { 10, "IO timeout error" },
+ { 11, "IO already pending error" },
+ { 12, "Directory open error" },
+ { 13, "Invalid Argument" },
+ { 14, "Address not available" },
+ { 15, "Address not supported" },
+ { 16, "Already connected" },
+ { 17, "Bad address" },
+ { 18, "Address already in use" },
+ { 19, "Connection refused" },
+ { 20, "Network unreachable" },
+ { 21, "Connection timed out" },
+ { 22, "Not connected" },
+ { 23, "Load library error" },
+ { 24, "Unload library error" },
+ { 25, "Find symbol error" },
+ { 26, "Insufficient resources" },
+ { 27, "Directory lookup error" },
+ { 28, "Invalid thread private data key" },
+ { 29, "PR_PROC_DESC_TABLE_FULL_ERROR" },
+ { 30, "PR_SYS_DESC_TABLE_FULL_ERROR" },
+ { 31, "Descriptor is not a socket" },
+ { 32, "Descriptor is not a TCP socket" },
+ { 33, "Socket address is already bound" },
+ { 34, "No access rights" },
+ { 35, "Operation not supported" },
+ { 36, "Protocol not supported" },
+ { 37, "Remote file error" },
+ { 38, "Buffer overflow error" },
+ { 39, "Connection reset by peer" },
+ { 40, "Range error" },
+ { 41, "Deadlock error" },
+ { 42, "File is locked" },
+ { 43, "File is too big" },
+ { 44, "No space on device" },
+ { 45, "Pipe error" },
+ { 46, "No seek on device" },
+ { 47, "File is a directory" },
+ { 48, "Loop error" },
+ { 49, "Name too long" },
+ { 50, "File not found" },
+ { 51, "File is not a directory" },
+ { 52, "Read-only filesystem" },
+ { 53, "Directory not empty" },
+ { 54, "Filesystem mounted" },
+ { 55, "Not same device" },
+ { 56, "Directory corrupted" },
+ { 57, "File exists" },
+ { 58, "Maximum directory entries" },
+ { 59, "Invalid device state" },
+ { 60, "Device is locked" },
+ { 61, "No more files" },
+ { 62, "End of file" },
+ { 63, "File seek error" },
+ { 64, "File is busy" },
+ { 65, "NSPR error 65" },
+ { 66, "In progress error" },
+ { 67, "Already initiated" },
+ { 68, "Group empty" },
+ { 69, "Invalid state" },
+ { 70, "Network down" },
+ { 71, "Socket shutdown" },
+ { 72, "Connect aborted" },
+ { 73, "Host unreachable" }
+};
+
+#if (PR_MAX_ERROR - PR_NSPR_ERROR_BASE) > 74
+// cfu temporarily get rid of the "#error NSPR error table is too small" error
+//#error NSPR error table is too small
+#endif
+
+nscp_error_t nscp_libsec_errors[] = {
+ { 0, "SEC_ERROR_IO - I/O Error" },
+ { 1, "SEC_ERROR_LIBRARY_FAILURE - Library Failure" },
+ { 2, "SEC_ERROR_BAD_DATA - Bad data was received" },
+ { 3, "SEC_ERROR_OUTPUT_LEN" },
+ { 4, "SEC_ERROR_INPUT_LEN" },
+ { 5, "SEC_ERROR_INVALID_ARGS" },
+ { 6, "SEC_ERROR_INVALID_ALGORITHM - Certificate contains invalid encryption or signature algorithm" },
+ { 7, "SEC_ERROR_INVALID_AVA" },
+ { 8, "SEC_ERROR_INVALID_TIME - Certificate contains an invalid time value" },
+ { 9, "SEC_ERROR_BAD_DER - Certificate is improperly DER encoded" },
+ { 10, "SEC_ERROR_BAD_SIGNATURE - Certificate has invalid signature" },
+ { 11, "SEC_ERROR_EXPIRED_CERTIFICATE - Certificate has expired" },
+ { 12, "SEC_ERROR_REVOKED_CERTIFICATE - Certificate has been revoked" },
+ { 13, "SEC_ERROR_UNKNOWN_ISSUER - Certificate is signed by an unknown issuer" },
+ { 14, "SEC_ERROR_BAD_KEY - Invalid public key in certificate." },
+ { 15, "SEC_ERROR_BAD_PASSWORD" },
+ { 16, "SEC_ERROR_UNUSED" },
+ { 17, "SEC_ERROR_NO_NODELOCK" },
+ { 18, "SEC_ERROR_BAD_DATABASE - Problem using certificate or key database" },
+ { 19, "SEC_ERROR_NO_MEMORY - Out of Memory" },
+ { 20, "SEC_ERROR_UNTRUSTED_ISSUER - Certificate is signed by an untrusted issuer" },
+ { 21, "SEC_ERROR_UNTRUSTED_CERT" },
+ { 22, "SEC_ERROR_DUPLICATE_CERT" },
+ { 23, "SEC_ERROR_DUPLICATE_CERT_TIME" },
+ { 24, "SEC_ERROR_ADDING_CERT" },
+ { 25, "SEC_ERROR_FILING_KEY" },
+ { 26, "SEC_ERROR_NO_KEY" },
+ { 27, "SEC_ERROR_CERT_VALID" },
+ { 28, "SEC_ERROR_CERT_NOT_VALID" },
+ { 29, "SEC_ERROR_CERT_NO_RESPONSE" },
+ { 30, "SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE" },
+ { 31, "SEC_ERROR_CRL_EXPIRED" },
+ { 32, "SEC_ERROR_CRL_BAD_SIGNATURE" },
+ { 33, "SEC_ERROR_CRL_INVALID" },
+ { 34, "SEC_ERROR_EXTENSION_VALUE_INVALID" },
+ { 35, "SEC_ERROR_EXTENSION_NOT_FOUND" },
+ { 36, "SEC_ERROR_CA_CERT_INVALID" },
+ { 37, "SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID" },
+ { 38, "SEC_ERROR_CERT_USAGES_INVALID" },
+ { 39, "SEC_INTERNAL_ONLY" },
+ { 40, "SEC_ERROR_INVALID_KEY" },
+ { 41, "SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION" },
+ { 42, "SEC_ERROR_OLD_CRL" },
+ { 43, "SEC_ERROR_NO_EMAIL_CERT" },
+ { 44, "SEC_ERROR_NO_RECIPIENT_CERTS_QUERY" },
+ { 45, "SEC_ERROR_NOT_A_RECIPIENT" },
+ { 46, "SEC_ERROR_PKCS7_KEYALG_MISMATCH" },
+ { 47, "SEC_ERROR_PKCS7_BAD_SIGNATURE" },
+ { 48, "SEC_ERROR_UNSUPPORTED_KEYALG" },
+ { 49, "SEC_ERROR_DECRYPTION_DISALLOWED" },
+ { 50, "XP_SEC_FORTEZZA_BAD_CARD" },
+ { 51, "XP_SEC_FORTEZZA_NO_CARD" },
+ { 52, "XP_SEC_FORTEZZA_NONE_SELECTED" },
+ { 53, "XP_SEC_FORTEZZA_MORE_INFO" },
+ { 54, "XP_SEC_FORTEZZA_PERSON_NOT_FOUND" },
+ { 55, "XP_SEC_FORTEZZA_NO_MORE_INFO" },
+ { 56, "XP_SEC_FORTEZZA_BAD_PIN" },
+ { 57, "XP_SEC_FORTEZZA_PERSON_ERROR" },
+ { 58, "SEC_ERROR_NO_KRL" },
+ { 59, "SEC_ERROR_KRL_EXPIRED" },
+ { 60, "SEC_ERROR_KRL_BAD_SIGNATURE" },
+ { 61, "SEC_ERROR_REVOKED_KEY" },
+ { 62, "SEC_ERROR_KRL_INVALID" },
+ { 63, "SEC_ERROR_NEED_RANDOM" },
+ { 64, "SEC_ERROR_NO_MODULE" },
+ { 65, "SEC_ERROR_NO_TOKEN" },
+ { 66, "SEC_ERROR_READ_ONLY" },
+ { 67, "SEC_ERROR_NO_SLOT_SELECTED" },
+ { 68, "SEC_ERROR_CERT_NICKNAME_COLLISION" },
+ { 69, "SEC_ERROR_KEY_NICKNAME_COLLISION" },
+ { 70, "SEC_ERROR_SAFE_NOT_CREATED" },
+ { 71, "SEC_ERROR_BAGGAGE_NOT_CREATED" },
+ { 72, "XP_JAVA_REMOVE_PRINCIPAL_ERROR" },
+ { 73, "XP_JAVA_DELETE_PRIVILEGE_ERROR" },
+ { 74, "XP_JAVA_CERT_NOT_EXISTS_ERROR" },
+ { 75, "SEC_ERROR_BAD_EXPORT_ALGORITHM" },
+ { 76, "SEC_ERROR_EXPORTING_CERTIFICATES" },
+ { 77, "SEC_ERROR_IMPORTING_CERTIFICATES" },
+ { 78, "SEC_ERROR_PKCS12_DECODING_PFX" },
+ { 79, "SEC_ERROR_PKCS12_INVALID_MAC" },
+ { 80, "SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM" },
+ { 81, "SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE" },
+ { 82, "SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE" },
+ { 83, "SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM" },
+ { 84, "SEC_ERROR_PKCS12_UNSUPPORTED_VERSION" },
+ { 85, "SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT" },
+ { 86, "SEC_ERROR_PKCS12_CERT_COLLISION" },
+ { 87, "SEC_ERROR_USER_CANCELLED" },
+ { 88, "SEC_ERROR_PKCS12_DUPLICATE_DATA" },
+ { 89, "SEC_ERROR_MESSAGE_SEND_ABORTED" },
+ { 90, "SEC_ERROR_INADEQUATE_KEY_USAGE" },
+ { 91, "SEC_ERROR_INADEQUATE_CERT_TYPE" },
+ { 92, "SEC_ERROR_CERT_ADDR_MISMATCH" },
+ { 93, "SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY" },
+ { 94, "SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN" },
+ { 95, "SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME" },
+ { 96, "SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY" },
+ { 97, "SEC_ERROR_PKCS12_UNABLE_TO_WRITE" },
+ { 98, "SEC_ERROR_PKCS12_UNABLE_TO_READ" },
+ { 99, "SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED" },
+ { 100, "SEC_ERROR_KEYGEN_FAIL" },
+ { 101, "SEC_ERROR_INVALID_PASSWORD" },
+ { 102, "SEC_ERROR_RETRY_OLD_PASSWORD" },
+ { 103, "SEC_ERROR_BAD_NICKNAME" },
+ { 104, "SEC_ERROR_NOT_FORTEZZA_ISSUER" },
+ { 105, "unused error" },
+ { 106, "SEC_ERROR_JS_INVALID_MODULE_NAME" },
+ { 107, "SEC_ERROR_JS_INVALID_DLL" },
+ { 108, "SEC_ERROR_JS_ADD_MOD_FAILURE" },
+ { 109, "SEC_ERROR_JS_DEL_MOD_FAILURE" },
+ { 110, "SEC_ERROR_OLD_KRL" },
+ { 111, "SEC_ERROR_CKL_CONFLICT" },
+ { 112, "SEC_ERROR_CERT_NOT_IN_NAME_SPACE" },
+ { 113, "SEC_ERROR_KRL_NOT_YET_VALID" },
+ { 114, "SEC_ERROR_CRL_NOT_YET_VALID" },
+ { 115, "SEC_ERROR_CERT_STATUS_SERVER_ERROR" },
+ { 116, "SEC_ERROR_CERT_STATUS_UNKNOWN" },
+ { 117, "SEC_ERROR_CERT_REVOKED_SINCE" },
+ { 118, "SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE" }
+};
+
+nscp_error_t nscp_libssl_errors[] = {
+ { 0, "SSL_ERROR_EXPORT_ONLY_SERVER - client does not support high-grade encryption." },
+ { 1, "SSL_ERROR_US_ONLY_SERVER - client requires high-grade encryption which is not supported." },
+ { 2, "SSL_ERROR_NO_CYPHER_OVERLAP - no common encryption algorithm(s) with client." },
+ { 3, "SSL_ERROR_NO_CERTIFICATE - unable to find the certificate or key necessary for authentication." },
+ { 4, "SSL_ERROR_BAD_CERTIFICATE - unable to communicate securely wih peer: peer's certificate was rejected." },
+ { 5, "unused SSL error #5" },
+ { 6, "SSL_ERROR_BAD_CLIENT - protocol error." },
+ { 7, "SSL_ERROR_BAD_SERVER - protocol error." },
+ { 8, "SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE - unsupported certificate type." },
+ { 9, "SSL_ERROR_UNSUPPORTED_VERSION - client is using unsupported SSL version." },
+ { 10, "unused SSL error #10" },
+ { 11, "SSL_ERROR_WRONG_CERTIFICATE - the public key in the server's own certificate does not match its private key" },
+ { 12, "SSL_ERROR_BAD_CERT_DOMAIN - requested domain name does not match the server's certificate." },
+ { 13, "SSL_ERROR_POST_WARNING" },
+ { 14, "SSL_ERROR_SSL2_DISABLED - peer only supports SSL version 2, which is locally disabled" },
+ { 15, "SSL_ERROR_BAD_MAC_READ - SSL has received a record with an incorrect Message Authentication Code." },
+ { 16, "SSL_ERROR_BAD_MAC_ALERT - SSL has received an error indicating an incorrect Message Authentication Code." },
+ { 17, "SSL_ERROR_BAD_CERT_ALERT - SSL client cannot verify your certificate." },
+ { 18, "SSL_ERROR_REVOKED_CERT_ALERT - the server has rejected your certificate as revoked." },
+ { 19, "SSL_ERROR_EXPIRED_CERT_ALERT - the server has rejected your certificate as expired." },
+ { 20, "SSL_ERROR_SSL_DISABLED - cannot connect: SSL is disabled." },
+ { 21, "SSL_ERROR_FORTEZZA_PQG - cannot connect: SSL peer is in another Fortezza domain" },
+ { 22, "SSL_ERROR_UNKNOWN_CIPHER_SUITE - an unknown SSL cipher suite has been requested" },
+ { 23, "SSL_ERROR_NO_CIPHERS_SUPPORTED - no cipher suites are present and enabled in this program" },
+ { 24, "SSL_ERROR_BAD_BLOCK_PADDING" },
+ { 25, "SSL_ERROR_RX_RECORD_TOO_LONG" },
+ { 26, "SSL_ERROR_TX_RECORD_TOO_LONG" },
+ { 27, "SSL_ERROR_RX_MALFORMED_HELLO_REQUEST" },
+ { 28, "SSL_ERROR_RX_MALFORMED_CLIENT_HELLO" },
+ { 29, "SSL_ERROR_RX_MALFORMED_SERVER_HELLO" },
+ { 30, "SSL_ERROR_RX_MALFORMED_CERTIFICATE" },
+ { 31, "SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH" },
+ { 32, "SSL_ERROR_RX_MALFORMED_CERT_REQUEST" },
+ { 33, "SSL_ERROR_RX_MALFORMED_HELLO_DONE" },
+ { 34, "SSL_ERROR_RX_MALFORMED_CERT_VERIFY" },
+ { 35, "SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH" },
+ { 36, "SSL_ERROR_RX_MALFORMED_FINISHED" },
+ { 37, "SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER" },
+ { 38, "SSL_ERROR_RX_MALFORMED_ALERT" },
+ { 39, "SSL_ERROR_RX_MALFORMED_HANDSHAKE" },
+ { 40, "SSL_ERROR_RX_MALFORMED_APPLICATION_DATA" },
+ { 41, "SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST" },
+ { 42, "SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO" },
+ { 43, "SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO" },
+ { 44, "SSL_ERROR_RX_UNEXPECTED_CERTIFICATE" },
+ { 45, "SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH" },
+ { 46, "SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST" },
+ { 47, "SSL_ERROR_RX_UNEXPECTED_HELLO_DONE" },
+ { 48, "SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY" },
+ { 49, "SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH" },
+ { 50, "SSL_ERROR_RX_UNEXPECTED_FINISHED" },
+ { 51, "SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER" },
+ { 52, "SSL_ERROR_RX_UNEXPECTED_ALERT" },
+ { 53, "SSL_ERROR_RX_UNEXPECTED_HANDSHAKE" },
+ { 54, "SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA" },
+ { 55, "SSL_ERROR_RX_UNKNOWN_RECORD_TYPE" },
+ { 56, "SSL_ERROR_RX_UNKNOWN_HANDSHAKE" },
+ { 57, "SSL_ERROR_RX_UNKNOWN_ALERT" },
+ { 58, "SSL_ERROR_CLOSE_NOTIFY_ALERT - SSL peer has closed the connection" },
+ { 59, "SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT" },
+ { 60, "SSL_ERROR_DECOMPRESSION_FAILURE_ALERT" },
+ { 61, "SSL_ERROR_HANDSHAKE_FAILURE_ALERT" },
+ { 62, "SSL_ERROR_ILLEGAL_PARAMETER_ALERT" },
+ { 63, "SSL_ERROR_UNSUPPORTED_CERT_ALERT" },
+ { 64, "SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT" },
+ { 65, "SSL_ERROR_GENERATE_RANDOM_FAILURE" },
+ { 66, "SSL_ERROR_SIGN_HASHES_FAILURE" },
+ { 67, "SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE" },
+ { 68, "SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE" },
+ { 69, "SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE" },
+ { 70, "SSL_ERROR_ENCRYPTION_FAILURE" },
+ { 71, "SSL_ERROR_DECRYPTION_FAILURE" },
+ { 72, "SSL_ERROR_SOCKET_WRITE_FAILURE" },
+ { 73, "SSL_ERROR_MD5_DIGEST_FAILURE" },
+ { 74, "SSL_ERROR_SHA_DIGEST_FAILURE" },
+ { 75, "SSL_ERROR_MAC_COMPUTATION_FAILURE" },
+ { 76, "SSL_ERROR_SYM_KEY_CONTEXT_FAILURE" },
+ { 77, "SSL_ERROR_SYM_KEY_UNWRAP_FAILURE" },
+ { 78, "SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED" },
+ { 79, "SSL_ERROR_IV_PARAM_FAILURE" },
+ { 80, "SSL_ERROR_INIT_CIPHER_SUITE_FAILURE" },
+ { 81, "SSL_ERROR_SESSION_KEY_GEN_FAILURE" },
+ { 82, "SSL_ERROR_NO_SERVER_KEY_FOR_ALG" },
+ { 83, "SSL_ERROR_TOKEN_INSERTION_REMOVAL" },
+ { 84, "SSL_ERROR_TOKEN_SLOT_NOT_FOUND" },
+ { 85, "SSL_ERROR_NO_COMPRESSION_OVERLAP" },
+ { 86, "SSL_ERROR_HANDSHAKE_NOT_COMPLETED" },
+ { 87, "SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE" },
+ { 88, "SSL_ERROR_CERT_KEA_MISMATCH" },
+ { 89, "SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA - the CA that signed the client certificate is not trusted locally" }
+};
+
+#ifdef WIN32
+#define __EXPORT __declspec(dllexport)
+#else
+#define __EXPORT
+#endif
+
+__EXPORT const char* nscperror_lookup(int error)
+{
+ const char *errmsg;
+
+ if ((error >= NSCP_NSPR_ERROR_BASE) && (error <= NSCP_NSPR_MAX_ERROR)) {
+ errmsg = nscp_nspr_errors[error-NSCP_NSPR_ERROR_BASE].errorString;
+ return errmsg;
+ } else if ((error >= NSCP_LIBSEC_ERROR_BASE) &&
+ (error <= NSCP_LIBSEC_MAX_ERROR)) {
+ return nscp_libsec_errors[error-NSCP_LIBSEC_ERROR_BASE].errorString;
+ } else if ((error >= NSCP_LIBSSL_ERROR_BASE) &&
+ (error <= NSCP_LIBSSL_MAX_ERROR)) {
+ return nscp_libssl_errors[error-NSCP_LIBSSL_ERROR_BASE].errorString;
+ } else {
+ return (const char *)NULL;
+ }
+}
diff --git a/base/tps/src/httpClient/request.cpp b/base/tps/src/httpClient/request.cpp
new file mode 100644
index 000000000..629f74821
--- /dev/null
+++ b/base/tps/src/httpClient/request.cpp
@@ -0,0 +1,431 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#include <string.h>
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/engine.h"
+#include "httpClient/httpc/PSPRUtil.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+//-- static const char *DEBUG_MODULE = "httpclient";
+//-- static const char *DEBUG_CLASS_NAME = "PSHttpRequest";
+
+/**
+ * Constructor
+ * @param server The server to send request to
+ * @param uri The uri representing the request e.g /presence/start
+ * @param prot HTTP10 or HTTP11 .
+ * @param to Timeout ... ignore for now
+ */
+
+PSHttpRequest::PSHttpRequest(const PSHttpServer* server,
+ const char *uri,
+ HttpProtocol prot,
+ PRIntervalTime to) : NetRequest(server) {
+ //timeout = to;
+ timeout = PR_INTERVAL_NO_TIMEOUT;
+ _method = PL_strdup("GET");
+ _uri = PL_strdup(uri);
+ _proto = prot;
+ _body = NULL;
+ _bodyLength = -1;
+ _expectedResponseLength = -1;
+ _expectStandardBody = PR_FALSE;
+ _expectDynamicBody = PR_FALSE;
+ _hangupOk = PR_FALSE;
+ _fileFd = NULL;
+ nickName = NULL;
+ _headers = new StringKeyCache("request",10*60);
+}
+
+/**
+ * Destructor
+ *
+ */
+
+PSHttpRequest::~PSHttpRequest() {
+ if( _method != NULL ) {
+ PL_strfree( _method );
+ _method = NULL;
+ }
+ if( _uri != NULL ) {
+ PL_strfree( _uri );
+ _uri = NULL;
+ }
+ if( nickName != NULL ) {
+ PL_strfree( nickName );
+ nickName = NULL;
+ }
+ if( _fileFd != NULL ) {
+ PR_Close( _fileFd );
+ _fileFd = NULL;
+ }
+ if( _headers != NULL ) {
+ delete _headers;
+ _headers = NULL;
+ }
+}
+
+/**
+ * sets the request method for Http protocol
+ * @param method GET /POST etc
+ *
+ */
+
+PRBool PSHttpRequest::setMethod(const char *method) {
+ if( _method != NULL ) {
+ free( _method );
+ _method = NULL;
+ }
+ _method = PL_strdup(method);
+ return PR_TRUE;
+}
+
+void PSHttpRequest::setExpectedResponseLength(int size) {
+ _expectedResponseLength = size;
+}
+
+void PSHttpRequest::setExpectStandardBody() {
+ _expectStandardBody = PR_TRUE;
+}
+
+void PSHttpRequest::setExpectDynamicBody() {
+ _expectDynamicBody = PR_TRUE;
+}
+
+PRBool PSHttpRequest::getExpectStandardBody() {
+ return _expectStandardBody;
+}
+
+PRBool PSHttpRequest::getExpectDynamicBody() {
+ return _expectDynamicBody;
+}
+
+int PSHttpRequest::getExpectedResponseLength() {
+ return _expectedResponseLength;
+}
+
+/**
+ * Returns the method to use
+ *
+ * @return GET /POST etc
+ */
+
+char * PSHttpRequest::getMethod() {
+ return _method;
+}
+
+/**
+ * Returns HTTP0 or HTTP11
+ */
+HttpProtocol HttpMessage::getProtocol() const {
+ return proto;
+}
+
+/**
+ * Adds an HTTP header to the request
+ *
+ * @param name header name
+ * @param value header value
+ */
+PRBool PSHttpRequest::addHeader(const char *name, const char *value) {
+ char *dvalue = PL_strdup(value);
+ CacheEntry *entry = _headers->Put(name,dvalue);
+ if (entry == NULL ) {
+ if( dvalue != NULL ) {
+ PL_strfree( dvalue );
+ dvalue = NULL;
+ }
+ return PR_FALSE;
+ } else {
+ return PR_TRUE;
+ }
+}
+
+/**
+ * Gets the value for a header for this HTTP request object
+ *
+ * @param name Name of the header
+ * @return The value of the header in the request object
+ */
+
+const char * PSHttpRequest::getHeader(const char *name) {
+ CacheEntry *entry = _headers->Get(name);
+ return entry ? (char *)entry->GetData() : NULL;
+}
+
+/**
+ * Sets the body of a POST message
+ *
+ * @param size Content length
+ * @param body Content of the message; it is not copied
+ * @return PR_TRUE if the Content-length header can be set
+ */
+PRBool PSHttpRequest::setBody(int size, const char* body) {
+ char byteStr[12];
+
+ sprintf(byteStr, "%d", size);
+ if (!addHeader("Content-length", byteStr)) {
+ return PR_FALSE;
+ }
+
+ _bodyLength = size;
+ _body = (char *)body;
+
+ return PR_TRUE;
+}
+
+PRBool PSHttpRequest::addRandomBody(int size) {
+ char byteStr[12];
+
+ sprintf(byteStr, "%d", size);
+ if (!addHeader("Content-length", byteStr)) {
+ return PR_FALSE;
+ }
+
+ _bodyLength = size;
+
+ return PR_TRUE;
+}
+
+PRBool PSHttpRequest::useLocalFileAsBody(const char* fileName) {
+ PRBool res = PR_FALSE;
+ PRFileInfo finfo;
+ if (PR_GetFileInfo(fileName, &finfo) == PR_SUCCESS) {
+ res = PR_TRUE;
+ char byteStr[25];
+ sprintf(byteStr, "%d", finfo.size);
+ if (!addHeader("Content-length", byteStr)) {
+ return PR_FALSE;
+ }
+ _bodyLength = finfo.size;
+ _fileFd = PR_Open(fileName, PR_RDONLY, 0);
+ if (!_fileFd) {
+ return PR_FALSE;
+ }
+ }
+
+ return PR_TRUE;
+}
+
+/**
+ * This function sends the HTTP request to the server.
+ * @param sock - the connection onto which the request is to be sent
+ */
+
+PRBool PSHttpRequest::send( PRFileDesc *sock ) {
+ const char *hostname;
+//-- static const char *DEBUG_METHOD_NAME = "send";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ PRBool rv = PR_FALSE;
+ if (!sock) {
+ return rv;
+ }
+
+ char *data = NULL;
+
+ if (_proto == HTTP11) {
+ hostname = getHeader("Host");
+
+ if (hostname == NULL) {
+ // long port = _server->getPort();
+
+ char address[100];
+ PR_snprintf(address, 100, "%s:%d", _server->getAddr(),
+ _server->getPort());
+ addHeader("Host", address);
+ }
+ }
+
+ // create the HTTP string "GET /presence/stop HTTP/1.0"
+ char *path = strstr( _uri, "//" );
+ if ( path ) {
+ path = strchr( path + 2, '/' );
+ }
+ if ( !path ) {
+ path = _uri;
+ }
+ data = PR_smprintf( "%s %s %s\r\n", _method, path,
+ HttpProtocolToString(_proto) );
+
+ // Send HTTP headers
+ char **keys;
+ char *headerValue = NULL;
+ int nKeys = _headers->GetKeys( &keys );
+ for ( int i = 0 ; i < nKeys; i++ ) {
+ CacheEntry *entry = _headers->Get( keys[i] );
+ if (entry) {
+ headerValue = (char *)entry->GetData();
+ //adds the headers name: value
+ data = PR_sprintf_append(data,"%s: %s\r\n",keys[i],headerValue);
+ if( headerValue != NULL ) {
+ PL_strfree( headerValue );
+ headerValue = NULL;
+ }
+ }
+ entry = _headers->Remove(keys[i]);
+ if( entry != NULL ) {
+ delete entry;
+ entry = NULL;
+ }
+ if( keys[i] != NULL ) {
+ delete [] ( keys[i] );
+ keys[i] = NULL;
+ }
+ }
+ if( keys != NULL ) {
+ delete [] keys;
+ keys = NULL;
+ }
+
+ // Send terminator
+ data = PR_sprintf_append(data,"\r\n");
+
+ int len = PL_strlen(data);
+ //send the data ..
+ int bytes = PR_Send(sock, data, len, 0, timeout);
+ if( data != NULL ) {
+ PR_smprintf_free( data );
+ data = NULL;
+ }
+ if ( bytes != len ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpRequest::send: ",
+ "Error sending request -- PR_Send returned(%d) Msg=%s\n",
+ PR_GetError(),
+ "XXX" );
+ return PR_FALSE;
+ }
+
+ if ( _fileFd ) {
+ // Send body from file
+ PRInt32 bytesSent = PR_TransmitFile(sock, _fileFd, 0, 0,
+ PR_TRANSMITFILE_KEEP_OPEN,
+ timeout);
+ if ( bytesSent < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpRequest::send: ",
+ "Error sending request\n" );
+ return PR_FALSE;
+ }
+ } else if (_bodyLength > 0) {
+ // Send internally stored body
+ char *allocated = NULL;
+ if ( !_body ) {
+ // Send a generated pattern
+ _body = allocated = new char[_bodyLength];
+ for ( int index = 0; index < _bodyLength; index++ ) {
+ _body[index] = (unsigned char)(index %256);
+ }
+ }
+ int sentBytes = 0;
+ char *toSend = _body;
+ for ( int i = _bodyLength; i > 0; i -= sentBytes ) {
+ sentBytes = PR_Send( sock, toSend, i, 0, timeout );
+ if ( sentBytes < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpRequest::send: ",
+ "Error sending request in PR_Send\n" );
+ return PR_FALSE;
+ }
+ toSend += sentBytes;
+ }
+ if ( allocated ) {
+ if( _body != NULL ) {
+ delete [] _body;
+ _body = NULL;
+ }
+ }
+ }
+
+ return PR_TRUE;
+}
+
+/**
+ * Sets the nickname for the client cert to be send to the server
+ * @param certName Nickname of the cert in the cert db
+ */
+void PSHttpRequest::setCertNickName(const char *certName) {
+ nickName = PL_strdup(certName);
+}
+
+/**
+ * Gets the nickname for the client cert
+ * @return certName Nickname of the cert in the cert db
+ */
+char * PSHttpRequest::getCertNickName() {
+ return nickName;
+}
+
+void PSHttpRequest::setHangupOk() {
+ _hangupOk = PR_TRUE;
+}
+
+PRBool PSHttpRequest::isHangupOk() {
+ return(_hangupOk);
+}
+
+
+/**
+ * returns PR_TRUE if ssl is enabled for this request
+ */
+PRBool NetRequest::isSSL() const {
+ return SSLOn;
+}
+
+/**
+ * enable/disable SSL for the request
+ */
+void NetRequest::setSSL(PRBool SSLstate) {
+ SSLOn=SSLstate;
+}
+
+/**
+* Constructor for NetRequest class. This is a superclass of httprequest class
+* @param server The server to which the request is to be send
+*/
+NetRequest :: NetRequest(const PSHttpServer* server) {
+ _server = server;
+ timeout = Engine::globaltimeout;
+ SSLOn=PR_FALSE;
+ if (server)
+ SSLOn=server->isSSL();
+ handshake = PR_FALSE;
+ cipherCount = 0;
+ cipherSet = NULL;
+
+}
+
+/**
+* Returns the current configured timeout
+*/
+PRIntervalTime NetRequest :: getTimeout() const {
+ return timeout;
+}
diff --git a/base/tps/src/httpClient/response.cpp b/base/tps/src/httpClient/response.cpp
new file mode 100644
index 000000000..89b900492
--- /dev/null
+++ b/base/tps/src/httpClient/response.cpp
@@ -0,0 +1,1115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+/**
+ * HTTP response handler
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+
+#include "nspr.h"
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/engine.h"
+//-- #include "httpClient/httpc/DebugLogger.h"
+#include "httpClient/httpc/PSPRUtil.h"
+#include "main/Memory.h"
+
+//-- static const char *DEBUG_MODULE = "httpclient";
+//-- static const char *DEBUG_CLASS_NAME = "PSHttpResponse";
+void printBuf(int , char* );
+
+/**
+ * Constructor. This class is used by the HttpResponse class for reading and
+ * processing data from the socket
+ * @param socket The NSPR socket from which the response is expected
+ * @param size The size of the internal buffer to hold data
+ * @param timeout Timeout in seconds on receiving a response
+ */
+
+RecvBuf::RecvBuf( const PRFileDesc *socket, int size, int timeout ) {
+ _socket = socket;
+ _allocSize = size;
+ _buf = (char *)PR_Malloc(size);
+ _curPos = 0;
+ _curSize = 0;
+ _chunkedMode = PR_FALSE;
+ _currentChunkSize = _currentChunkBytesRead = 0;
+ _timeout = PR_TicksPerSecond() * timeout;
+ _content = NULL;
+}
+
+/**
+ * Destructor
+ */
+RecvBuf::~RecvBuf() {
+ if( _buf != NULL ) {
+ PR_Free( _buf );
+ _buf = NULL;
+ }
+}
+
+/**
+ * Reads the specified number of bytes from the socket and place it into the buffer
+ *
+ * @param socket The NSPR socket from which the response is expected
+ * @param size The size of the buffer
+ * @return PR_TRUE on success, otherwise PR_FALSE
+ */
+PRBool RecvBuf::_getBytes(int size) {
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+ PRErrorCode pec;
+ _curPos = 0;
+
+ int num =1;
+ int i =0;
+ PRBool endChunk= PR_FALSE;
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "Start RecvBuf::_getBytes" );
+ // actual reading from the socket happens here
+ do {
+ num = PR_Recv( (PRFileDesc*)_socket,
+ &_buf[_curSize],
+ _allocSize-_curSize,
+ 0,
+ _timeout );
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "num of bytes read from the socket=%d",
+ num );
+ /*
+ * in chunked mode, ending chunk contains a 0 to begin
+ * loop through to see if it contains just 0 (skip carriage returns
+ * endChunk indicates possible end chunk.
+ */
+ if ((_chunkedMode == PR_TRUE) && (num < 10)) {
+ endChunk = PR_FALSE;
+
+ for (i=0; i< num; i++) {
+ if (endChunk == PR_TRUE) {
+ if ((_buf[_curSize+i] == 13) || (_buf[_curSize+i] == 10))
+ continue;
+ else {
+ endChunk = PR_FALSE;
+ break; // not an endChunk
+ }
+ } else { // endChunk==PR_FALSE
+ if (_buf[_curSize+i] == '0') {
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "may be chunked mode end chunk" );
+ endChunk = PR_TRUE;
+ } else if ((_buf[_curSize+i] == 13) || (_buf[_curSize+i] == 10))
+ continue;
+ else {
+ endChunk = PR_FALSE;
+ break; // not an endChunk
+ }
+ }
+ } // for
+ }
+
+ if (num >0)
+ _curSize = _curSize+num;
+
+ if (_chunkedMode == PR_FALSE) {
+ if (getAllContent()) {
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "Already got all the content, no need to call PR_Recv again." );
+ break;
+ }
+ }
+
+ if (endChunk == PR_TRUE)
+ break;
+ } while (num > 0);
+
+ if (num <0) {
+ pec = PR_GetError();
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::_getBytes: ",
+ "error in pr_recv, err=%d",
+ pec );
+ }
+
+ if ( _curSize <= 0 ) {
+ return PR_FALSE;
+ }
+
+ _buf[_curSize] = '\0';
+//-- logger->Log( LOGLEVEL_FINEST, DEBUG_CLASS_NAME,
+//-- "getBytes",
+
+ _content = (char *) PR_Malloc(_curSize+1);
+ if (_content == NULL) {
+ return PR_FALSE;
+ }
+ memcpy((char*) _content, (const char *)_buf, _curSize+1);
+ _contentSize = _curSize +1;
+
+ RA::Debug(LL_PER_PDU, "RecvBuf::_getBytes",
+ "buffer received with size %d follows:", _contentSize);
+ printBuf(_contentSize, _content);
+
+ return PR_TRUE;
+}
+
+int RecvBuf::getAllContent() {
+ //int result[10];
+ //int j=0;
+ //int k=0;
+ int number = 0;
+ for (int i=0; i<_curSize; i++) {
+ if (_buf[i] == '\r') {
+ if (i < (_curSize-3)) {
+ if (_buf[i+1] == '\n' && _buf[i+2] == '\r'
+ && _buf[i+3] == '\n') {
+ // find content length
+// strcasestr may not be supported by Solaris
+// char *clen = strcasestr(_buf, "Content-length:");
+ char *clen = strstr(_buf, "Content-Length:");
+ if (clen != NULL) {
+ clen = &clen[16];
+ number = atoi(clen);
+/*
+ while (1) {
+ if ((number=Util::ascii2numeric(clen[j++])) >= 0) {
+ result[k++] = number;
+ } else {
+ break;
+ }
+ }
+
+ number = 0;
+ for (int l=0; l<k; l++)
+ number = (int)(number + result[l]*(float)pow((float)10, (float)k-l-1));
+*/
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::getAllContent: ",
+ "content length number=%d",
+ number );
+ }
+ int remainingBytes = _curSize - (i+4);
+ RA::Debug( LL_PER_PDU,
+ "RecvBuf::getAllContent: ",
+ "remainingbytes=%d",
+ remainingBytes );
+ if (remainingBytes == number)
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+void printBuf(int len, char* buf) {
+ RA::Debug(LL_PER_PDU, "response:printBuf",
+ "Buffer print begins");
+ RA::Debug(LL_PER_PDU, "response::printBuf",
+ "%s", buf);
+ RA::Debug(LL_PER_PDU, "response:printBuf",
+ "Buffer print end");
+ /*
+ int times = len/256;
+ if (len%256)
+ times++;
+ RA::Debug("response:printBuf",
+ "%d times", times);
+ RA::Debug("response:printBuf",
+ "attempting to print the whole buffer:");
+
+ int i;
+
+ for (i = 0; i< times; i++) {
+ char *temp;
+ temp = PL_strdup((char *)buf+i*256);
+ RA::Debug("response:printBuf",
+ "%s", temp);
+ }
+ */
+}
+
+/**
+ * gets the next char from the buffer. If all the data in the buffer is read,
+ * read a chunk to the buffer
+ * @returns - the next char from the data
+ */
+char RecvBuf::_getChar() {
+ if (_curPos >= _curSize) {
+ if (!_getBytes(_allocSize)) {
+ /* bugscape #55624: Solaris RA exited
+ with a signal ABRT if we raised exception
+ without handling it */
+ return -1;
+ /* throw RecvBuf::EndOfFile(); */
+ }
+ }
+
+ return _buf[_curPos++];
+}
+
+
+/**
+ * gets the next char from the buffer. If all the data in the buffer is read ,
+ * read a chunk to the buffer
+ * @returns - the next char from the data
+ */
+char RecvBuf::getChar() {
+ if (!_chunkedMode)
+ return _getChar();
+
+ else
+ {
+ if (_currentChunkSize == 0)
+ {
+ // read the chunk header
+ char ch, chunkStr[20];
+ int index = 0;
+
+ while (!isspace(ch = _getChar()) )
+ chunkStr[index++] = ch;
+ chunkStr[index] = '\0';
+
+ sscanf((char *)chunkStr, "%x", (unsigned int *)(&_currentChunkSize));
+
+ if (ch != '\n')
+ {
+ char ch2 = _getChar();
+ if (ch != '\r' || ch2 != '\n')
+ {
+ printf( "did not find CRLF after chunk");
+ }
+ }
+
+ if (_currentChunkSize == 0)
+ return -1;
+
+ _currentChunkBytesRead = 1;
+ return _buf[_curPos++];
+ }
+ else
+ if (_currentChunkBytesRead < _currentChunkSize)
+ {
+ // read a byte from the chunk
+ _currentChunkBytesRead++;
+ return _getChar();
+ }
+ else
+ {
+ // read the chunk trailer
+ char ch1 = _getChar();
+ char ch2 = _getChar();
+ if (ch1 != '\r' || ch2 != '\n')
+ {
+ printf( "did not find CRLF after chunk");
+ };
+ _currentChunkSize = _currentChunkBytesRead = 0;
+ return getChar();
+ };
+ };
+
+}
+
+char *RecvBuf::get_content() {
+ return _content;
+}
+
+int RecvBuf::get_contentSize() {
+ return _contentSize;
+}
+
+/**
+ * Decrements the pointer to the internal buffer so that the next read would
+ * retrieve the last data again
+ */
+void RecvBuf::putBack() {
+ if (_curPos > 0) {
+ _curPos--;
+ if (_chunkedMode) {
+ _currentChunkBytesRead--;
+ }
+ }
+}
+
+/**
+ * Sets the chunked mode for reading data
+ * Not used now..
+ */
+void RecvBuf::setChunkedMode() {
+ _chunkedMode = PR_TRUE;
+ _currentChunkSize = _currentChunkBytesRead = 0;
+}
+
+/**
+ * Gets the timeout in seconds for reading
+ *
+ * @return The timeout in seconds for reading
+ */
+int RecvBuf::getTimeout() {
+ return _timeout / PR_TicksPerSecond();
+}
+
+
+Response::Response(const PRFileDesc *sock, NetRequest *request) {
+ _socket = sock;
+ _request = request;
+}
+
+/**
+ * Constructor
+ */
+
+PSHttpResponse::PSHttpResponse( const PRFileDesc *sock,
+ PSHttpRequest *request,
+ int timeout , PRBool expectChunked):
+ Response(sock, request) {
+ _request = request;
+ _proto = HTTPNA;
+ _protocol = NULL;
+ retcode =0 ;
+ _statusNum = NULL;
+ _statusString = NULL;
+ _keepAlive = -1;
+ _connectionClosed = 0;
+ _bodyLength = -1;
+ _content = NULL;
+
+ _headers = new StringKeyCache("response",10*60);
+ _expectChunked = expectChunked;
+ _chunkedResponse = PR_FALSE;
+ _timeout = timeout;
+}
+
+PSHttpResponse::~PSHttpResponse() {
+ if( _protocol != NULL ) {
+ PL_strfree( _protocol );
+ _protocol = NULL;
+ }
+ if( _statusString != NULL ) {
+ PL_strfree( _statusString );
+ _statusString = NULL;
+ }
+ if( _statusNum != NULL ) {
+ PL_strfree( _statusNum );
+ _statusNum = NULL;
+ }
+ if (_headers) {
+ Iterator* iterator = _headers->GetKeyIterator();
+ while ( iterator->HasMore() ) {
+ const char* name = (const char*)iterator->Next();
+ CacheEntry* entry = _headers->Remove( name );
+ if ( entry ) {
+ char* value = (char*)entry->GetData();
+ if( value != NULL ) {
+ PL_strfree( value );
+ value = NULL;
+ }
+ if( entry != NULL ) {
+ delete entry;
+ entry = NULL;
+ }
+ }
+ }
+ if( iterator != NULL ) {
+ delete iterator;
+ iterator = NULL;
+ }
+ if( _headers != NULL ) {
+ delete _headers;
+ _headers = NULL;
+ }
+ }
+ _socket = 0;
+}
+
+long PSHttpResponse::getStatus() {
+ return _statusNum ? atoi(_statusNum) : 0;
+}
+
+int PSHttpResponse::getReturnCode() {
+ return retcode;
+}
+
+char * PSHttpResponse::getStatusString() {
+ return _statusString?_statusString:(char*)"";
+}
+
+HttpProtocol PSHttpResponse::getProtocol() {
+ // first check the response protocol
+ if (_proto == HTTPNA) {
+ if (_protocol) {
+ int major, minor;
+
+ sscanf(_protocol, "HTTP/%d.%d", &major, &minor);
+
+ switch(major) {
+ case 1:
+ switch(minor) {
+ case 0:
+ _proto = HTTP10;
+ break;
+ case 1:
+ _proto = HTTP11;
+ break;
+ }
+ break;
+ }
+ } else {
+ _proto = HTTP09;
+ }
+ }
+
+ if (_proto == HTTP11) {
+ // A 1.1 compliant server response shows the protocol as HTTP/1.1 even
+ // for a HTTP/1.0 request, but it promises to only use HTTP/1.0 syntax.
+ if (_request->getProtocol() == HTTP10) {
+ _proto = HTTP10;
+ }
+ }
+
+ return _proto;
+};
+
+char * PSHttpResponse::getHeader(const char *name) {
+ CacheEntry *entry = _headers->Get(name);
+ return entry ? (char *)entry->GetData() : NULL;
+}
+
+int PSHttpResponse::getHeaders(char ***keys) {
+
+ return _headers->GetKeys( keys );
+
+}
+
+long PSHttpResponse::getBodyLength() {
+ return _bodyLength;
+}
+
+char * PSHttpResponse::getContent() {
+ return _content;
+}
+
+void PSHttpResponse::freeContent() {
+ if( _content != NULL ) {
+ PR_Free( _content );
+ _content = NULL;
+ }
+}
+
+int PSHttpResponse::getContentSize() {
+
+ return _contentSize;
+}
+
+char *PSHttpResponse::toString() {
+ char *resp = (char *)"";
+ char **keys;
+ char *headerBuf = NULL;
+ int nHeaders = getHeaders( &keys );
+ if ( nHeaders > 0 ) {
+ char **values = new char*[nHeaders];
+ int len = 0;
+ int *keyLengths = new int[nHeaders];
+ int *valueLengths = new int[nHeaders];
+ int i;
+ for( i = 0; i < nHeaders; i++ ) {
+ keyLengths[i] = strlen( keys[i] );
+ len += keyLengths[i] + 1;
+ values[i] = getHeader(keys[i]);
+ valueLengths[i] = strlen( values[i] );
+ len += valueLengths[i] + 1;
+ }
+ headerBuf = new char[len + nHeaders * 2];
+ char *p = headerBuf;
+ for( i = 0; i < nHeaders; i++ ) {
+ strcpy( p, keys[i] );
+ p += keyLengths[i];
+ *p++ = ':';
+ strcpy( p, values[i] );
+ p += valueLengths[i];
+ *p++ = ',';
+ }
+ *p = 0;
+ for( i = 0; i < nHeaders; i++ ) {
+ if( keys[i] != NULL ) {
+ delete [] keys[i];
+ keys[i] = NULL;
+ }
+ }
+ if( keys != NULL ) {
+ delete [] keys;
+ keys = NULL;
+ }
+ if( values != NULL ) {
+ delete [] values;
+ values = NULL;
+ }
+ if( keyLengths != NULL ) {
+ delete [] keyLengths;
+ keyLengths = NULL;
+ }
+ if( valueLengths != NULL ) {
+ delete [] valueLengths;
+ valueLengths = NULL;
+ }
+ }
+
+ char *s = NULL;
+ if ( headerBuf ) {
+ s = PR_smprintf( "PSHttpResponse [%s\nbody bytes:%d]",
+ headerBuf, _bodyLength );
+ } else {
+ s = PR_smprintf( "PSHttpResponse [body bytes:%d]", _bodyLength );
+ }
+ resp = new char[strlen(s) + 1];
+ strcpy( resp, s );
+ if( s != NULL ) {
+ PR_smprintf_free( s );
+ s = NULL;
+ }
+ return resp;
+}
+
+PRBool PSHttpResponse::checkKeepAlive() {
+ HttpProtocol proto;
+ const char *connectionHeader;
+//-- static const char *DEBUG_METHOD_NAME = "checkKeepAlive";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ if (_keepAlive < 0) {
+ proto = getProtocol();
+ if (proto == HTTP11) {
+ // default is connection: keep-alive
+ _keepAlive = 1;
+ } else {
+ // default is connection: close
+ // _keepAlive = 0;
+ //CMS needs keepalive with HTTP10 (so no chunked encoding)
+ _keepAlive=1;
+ }
+
+ connectionHeader = _request->getHeader("connection");
+ if (connectionHeader) {
+ if (!PL_strcasecmp(connectionHeader, "keep-alive")) {
+ _keepAlive = 1;
+ } else if (!PL_strcasecmp(connectionHeader, "close")) {
+ _keepAlive = 0;
+ } else {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::checkKeepAlive: ",
+ "Unknown connection header" );
+ }
+ }
+ }
+
+ return (_keepAlive == 0?PR_FALSE:PR_TRUE);
+}
+
+PRBool PSHttpResponse::checkConnection() {
+ // return true if the connection is OPEN
+ return (_connectionClosed == 0?PR_TRUE:PR_FALSE);
+}
+
+
+int PSHttpResponse::_verifyStandardBody(RecvBuf &buf,
+ int expectedBytes,
+ PRBool check) {
+ int bytesRead = 0;
+ int curPos = 0;
+ char ch;
+//-- static const char *DEBUG_METHOD_NAME = "_verifyStandardBody";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ while(expectedBytes > 0 ) {
+ ch = buf.getChar();
+ if (ch < 0 ) {
+ break;
+ }
+ // if check is true, we think we know what the content looks like
+ if ( check ) {
+ if (ch != (char) curPos%256) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_verifyStandardBody: ",
+ "Response data corrupt at byte %d (%d, %d)",
+ curPos,
+ ch,
+ ( curPos % 256 ) );
+ check = PR_FALSE;
+ break;
+ }
+ curPos++;
+ }
+
+ bytesRead++;
+
+ if (expectedBytes > 0) {
+ expectedBytes--;
+ }
+ }
+
+ return bytesRead;
+}
+
+
+PRBool PSHttpResponse::_handleBody( RecvBuf &buf ) {
+ char *clHeader; // content length header
+ char *teHeader; // transfer-encoding header
+ int expected_cl=-1; // expected content length
+//-- static const char *DEBUG_METHOD_NAME = "_handleBody";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+
+ teHeader = getHeader("transfer-encoding");
+ if (teHeader && !PL_strcasecmp(teHeader, "chunked")) {
+ _chunkedResponse = PR_TRUE;
+ buf.setChunkedMode();
+ } else {
+ _chunkedResponse = PR_FALSE;
+ clHeader = getHeader("Content-length");
+ if (clHeader) {
+ expected_cl = atoi(clHeader);
+ }
+ }
+
+ if (_request->getExpectStandardBody()) {
+ _bodyLength = _verifyStandardBody(buf, expected_cl, PR_TRUE);
+
+ } else {
+ _bodyLength = _verifyStandardBody(buf, expected_cl, PR_FALSE);
+ }
+
+ if (expected_cl >= 0) {
+ if (_bodyLength != expected_cl) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_handleBody: ",
+ "Content length was incorrect (%d/%d bytes)",
+ _bodyLength,
+ expected_cl );
+ }
+ }
+
+ return PR_TRUE;
+}
+
+/**
+ * Reads until the first space character
+ *
+ * @param buf Receive buffer to read from
+ * @param headerBuf Array to read header into
+ * @param len Size of headerBuf
+ * @return Number of characters read, or -1 if too many
+ */
+static int readHeader( RecvBuf& buf, char* headerBuf, int len ) {
+ int index = 0;
+
+ do {
+ char ch = buf.getChar();
+
+ if ( ch != -1 && !isspace(ch) ) {
+ headerBuf[index++] = ch;
+ if ( index >= (len-1) ) {
+ return -1;
+ }
+ } else {
+ headerBuf[index] = '\0';
+ break;
+ }
+ } while( true );
+ // RA::Debug( LL_PER_PDU,
+ // "readHeader: ",
+ // "headerBuf = %s",
+ // headerBuf );
+
+ return index;
+}
+
+
+PRBool PSHttpResponse::processResponse() {
+ RecvBuf buf( _socket, 8192, _timeout );
+
+ if (_expectChunked) {
+ buf.setChunkedMode();
+ }
+
+//-- static const char *DEBUG_METHOD_NAME = "processResponse";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Entered processResponse()" );
+
+ try {
+ char tmp[2048];
+ int tmpLen = sizeof(tmp);
+
+ // Get protocol string
+ int nRead = readHeader( buf, tmp, tmpLen );
+
+ if ( nRead < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Returned more than expected bytes %d "
+ "in protocol header",
+ sizeof( tmp ) );
+ return PR_FALSE;
+ }
+
+ _protocol = PL_strdup(tmp);
+//-- logger->Log( LOGLEVEL_FINER, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Protocol header: %s",
+ _protocol );
+
+ // Get status num
+ nRead = readHeader( buf, tmp, tmpLen );
+ if ( nRead < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Returned more than expected bytes %d "
+ "in status header",
+ tmpLen );
+ return PR_FALSE;
+ }
+
+ _statusNum = PL_strdup( tmp );
+
+//-- logger->Log( LOGLEVEL_FINER, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Status header: %s",
+ _statusNum );
+ retcode = atoi( tmp );
+
+ // Get status string
+ int index = 0;
+ do {
+ char ch = buf.getChar();
+ if ( ch != -1 && ch != '\r' ) {
+ tmp[index++] = ch;
+ if ( index >= (tmpLen-2) ) {
+ tmp[index] = 0;
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Returned more than expected bytes %d "
+ "in protocol header:\n%s",
+ tmpLen,
+ tmp );
+ return PR_FALSE;
+ }
+ } else {
+ break;
+ }
+ } while (true);
+ tmp[index] = '\0';
+ _statusString = PL_strdup( tmp );
+
+ // Skip CRLF
+ (void)buf.getChar();
+
+ // loop over response headers
+ index = 0;
+#ifdef CHECK
+ PRBool doneParsing = PR_FALSE;
+ PRBool atEOL = PR_FALSE;
+ PRBool inName = PR_TRUE;
+ char name[2048];
+ int nameLen = sizeof(name);
+
+ while ( !doneParsing ) {
+ char value[2048];
+ int valueLen = sizeof(value);
+ char ch = buf.getChar();
+
+ switch( ch ) {
+ case ':':
+ if ( inName ) {
+ name[index] = '\0';
+ index = 0;
+ inName = PR_FALSE;
+
+ nRead = readHeader( buf, value, valueLen );
+ if ( nRead < 0 ) {
+//-- logger->Log( LOGLEVEL_SEVERE,
+//-- DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ } else {
+ value[index++] = ch;
+ if ( index >= (int)(sizeof(value) - 1 ) ) {
+//-- logger->Log( LOGLEVEL_SEVERE,
+//-- DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ }
+ }
+ break;
+ case '\r':
+ if ( inName && !atEOL ) {
+ name[index] = '\0';
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ }
+ break;
+ case '\n':
+ if ( atEOL ) {
+ doneParsing = PR_TRUE;
+ break;
+ }
+ if ( inName ) {
+ name[index] = '\0';
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ }
+ value[index] = '\0';
+ index = 0;
+ inName = PR_TRUE;
+ _headers->Put(name, PL_strdup(value));
+ atEOL = PR_TRUE;
+ break;
+ default:
+ atEOL = PR_FALSE;
+ if (inName) {
+ name[index++] = ch;
+ } else {
+ value[index++] = ch;
+ }
+ if ( inName && (index >= (nameLen-2)) ) {
+ name[index] = '\0';
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header exceeds the expected "
+ "%d max characters",
+ name,
+ nameLen );
+ // return PR_FALSE;
+ } else if ( !inName && (index >= (valueLen-1)) ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Name %s in header does not "
+ "have a value",
+ name );
+ // return PR_FALSE;
+ }
+ break;
+ }
+ }
+
+ } //while
+#endif //CHECK
+ } catch ( RecvBuf::EndOfFile & ) {
+ if ( !_request->isHangupOk() ) {
+
+ int errCode = PR_GetError();
+ if ( PR_IO_TIMEOUT_ERROR == errCode ) {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Timed out reading response (%d seconds)",
+ buf.getTimeout() );
+ } else {
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Received unexpected end of file from server\n%s",
+ "XXX" );
+ }
+ }
+ return PR_FALSE;
+ }
+
+ // Read the body (HEAD requests don't have bodies)
+ // jpierre 1xx, 204 and 304 don't have bodies either
+ if ( PL_strcmp(_request->getMethod(), "HEAD") &&
+ (!((retcode>=100) && (retcode<200))) &&
+ (retcode!=204) &&
+ (retcode!=304) ) {
+ if ( _handleBody(buf) == PR_FALSE ) {
+ return PR_FALSE;
+ }
+ }
+
+ if ( checkConnection() && !checkKeepAlive() ) {
+ // if connection is still open, and we didn't expect a keepalive,
+ // read another byte to see if the connection has closed.
+ try {
+ char ch;
+ ch = buf.getChar();
+ buf.putBack();
+ // conflict!
+//-- logger->Log( LOGLEVEL_SEVERE, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "Connection kept alive when it shouldn't" );
+ } catch (RecvBuf::EndOfFile &) {
+ _connectionClosed = 1;
+ }
+ }
+
+ _checkResponseSanity();
+ _content = (char *)buf.get_content();
+ _contentSize = buf.get_contentSize();
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "processed Buffer contentSize=%d",
+ getContentSize() );
+ if (_content != NULL) {
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::processResponse: ",
+ "processed Buffer content=%s",
+ _content );
+ }
+ // char * yo = getContent();
+
+ return PR_TRUE;
+}
+
+void PSHttpResponse::_checkResponseSanity() {
+ char *clHeader = getHeader("Content-length");
+ char *teHeader = getHeader("Transfer-encoding");
+//-- static const char *DEBUG_METHOD_NAME = "checkResponseSanity";
+//-- DebugLogger *logger = DebugLogger::GetDebugLogger( DEBUG_MODULE );
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "in _checkResponseSanity" );
+
+ ///////////////////////////////////////////////////
+ // Check items relevant to HTTP/1.0 and HTTP/1.1 //
+ ///////////////////////////////////////////////////
+
+ // check for both content-length and chunked
+ if ( clHeader && teHeader ) {
+//-- logger->Log( LOGLEVEL_FINER, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Response contains both content-length and "
+ "transfer-encoding" );
+ }
+
+ // check for basic headers
+ if ( !getHeader("Date") ) {
+//-- logger->Log( LOGLEVEL_WARNING, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Response does not contain a date header" );
+ }
+ if ( !getHeader("Server") ) {
+//-- logger->Log( LOGLEVEL_WARNING, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Response does not contain a server header" );
+ }
+
+ int expectedLength;
+ if ((expectedLength = _request->getExpectedResponseLength()) > 0) {
+ if (expectedLength != _bodyLength) {
+//-- logger->Log( LOGLEVEL_INFO, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Response body length does not match expected "
+ "response length (%d/%d)",
+ _bodyLength,
+ expectedLength );
+ }
+ }
+
+ ///////////////////////////////////////
+ // Check items relevant to HTTP/1.0 //
+ ///////////////////////////////////////
+ if ( getProtocol() == HTTP10 ) {
+ if ( _chunkedResponse ) {
+//-- logger->Log( LOGLEVEL_INFO, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Server sent a chunked HTTP/1.0 response" );
+ }
+ }
+
+ ///////////////////////////////////////
+ // Check items relevant to HTTP/1.1 //
+ ///////////////////////////////////////
+ if ( getProtocol() == HTTP11 ) {
+ if ( (!clHeader && !_chunkedResponse) &&
+ (!((retcode>=100) && (retcode<200))) &&
+ (retcode!=204) &&
+ (retcode!=304) ) {
+//-- logger->Log( LOGLEVEL_INFO, DEBUG_CLASS_NAME,
+//-- DEBUG_METHOD_NAME,
+ RA::Debug( LL_PER_PDU,
+ "PSHttpResponse::_checkResponseSanity: ",
+ "Server responded with a HTTP/1.1 response without "
+ "content-length or chunked encoding" );
+ }
+ }
+}
diff --git a/base/tps/src/include/apdu/APDU.h b/base/tps/src/include/apdu/APDU.h
new file mode 100644
index 000000000..e0f778a19
--- /dev/null
+++ b/base/tps/src/include/apdu/APDU.h
@@ -0,0 +1,116 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef APDU_H
+#define APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Base.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+enum APDU_Type {
+ APDU_UNDEFINED = 0,
+ APDU_CREATE_OBJECT = 1,
+ APDU_EXTERNAL_AUTHENTICATE = 2,
+ APDU_INITIALIZE_UPDATE = 3,
+ APDU_LIFECYCLE = 4,
+ APDU_READ_BUFFER = 5,
+ APDU_SET_PIN = 6,
+ APDU_UNBLOCK_PIN = 7,
+ APDU_WRITE_OBJECT = 8,
+ APDU_GENERATE_KEY = 9,
+ APDU_PUT_KEY = 10,
+ APDU_SELECT = 11,
+ APDU_GET_VERSION = 12,
+ APDU_DELETE_FILE = 13,
+ APDU_INSTALL_APPLET = 14,
+ APDU_FORMAT_MUSCLE_APPLET = 15,
+ APDU_LOAD_FILE = 16,
+ APDU_INSTALL_LOAD = 17,
+ APDU_GET_STATUS = 18 ,
+ APDU_LIST_PINS = 19,
+ APDU_CREATE_PIN = 20,
+ APDU_GET_DATA = 21,
+ APDU_READ_OBJECT = 22,
+ APDU_LIST_OBJECTS = 23,
+ APDU_IMPORT_KEY = 24,
+ APDU_IMPORT_KEY_ENC = 25,
+ APDU_SET_ISSUERINFO = 26,
+ APDU_GET_ISSUERINFO = 27
+};
+
+class APDU
+{
+ public:
+ TPS_PUBLIC APDU();
+ TPS_PUBLIC APDU(const APDU &cpy);
+ TPS_PUBLIC virtual ~APDU();
+ public:
+ TPS_PUBLIC APDU& operator=(const APDU& cpy);
+ public:
+ TPS_PUBLIC virtual void SetCLA(BYTE cla);
+ TPS_PUBLIC virtual void SetINS(BYTE ins);
+ TPS_PUBLIC virtual void SetP1(BYTE p1);
+ TPS_PUBLIC virtual void SetP2(BYTE p2);
+ TPS_PUBLIC virtual void SetData(Buffer &data);
+ TPS_PUBLIC virtual void SetMAC(Buffer &mac);
+ TPS_PUBLIC virtual void GetEncoding(Buffer &data);
+ TPS_PUBLIC virtual void GetDataToMAC(Buffer &data);
+ TPS_PUBLIC virtual PRStatus SecureMessage(PK11SymKey *encSessionKey);
+ TPS_PUBLIC virtual APDU_Type GetType();
+ TPS_PUBLIC Buffer &GetData();
+ TPS_PUBLIC Buffer &GetMAC();
+ TPS_PUBLIC BYTE GetCLA();
+ TPS_PUBLIC BYTE GetINS();
+ TPS_PUBLIC BYTE GetP1();
+ TPS_PUBLIC BYTE GetP2();
+ protected:
+ BYTE m_cla;
+ BYTE m_ins;
+ BYTE m_p1;
+ BYTE m_p2;
+ Buffer m_data;
+ Buffer m_plainText;
+ Buffer m_mac;
+};
+
+#endif /* APDU_H */
diff --git a/base/tps/src/include/apdu/APDU_Response.h b/base/tps/src/include/apdu/APDU_Response.h
new file mode 100644
index 000000000..0d5c62b9d
--- /dev/null
+++ b/base/tps/src/include/apdu/APDU_Response.h
@@ -0,0 +1,66 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef APDU_RESPONSE_H
+#define APDU_RESPONSE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class APDU_Response
+{
+ public:
+ APDU_Response();
+ TPS_PUBLIC APDU_Response(Buffer &data);
+ ~APDU_Response();
+ APDU_Response(const APDU_Response &cpy);
+ public:
+ APDU_Response& operator=(const APDU_Response& cpy);
+ public:
+ BYTE GetSW1();
+ BYTE GetSW2();
+ TPS_PUBLIC Buffer &GetData();
+ private:
+ Buffer m_data;
+};
+
+#endif /* APDU_Response_H */
diff --git a/base/tps/src/include/apdu/Create_Object_APDU.h b/base/tps/src/include/apdu/Create_Object_APDU.h
new file mode 100644
index 000000000..7433e7ceb
--- /dev/null
+++ b/base/tps/src/include/apdu/Create_Object_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef CREATE_OBJECT_APDU_H
+#define CREATE_OBJECT_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Create_Object_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Create_Object_APDU(BYTE *object_id, BYTE *permissions, int len);
+ TPS_PUBLIC ~Create_Object_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* CREATE_OBJECT_APDU_H */
diff --git a/base/tps/src/include/apdu/Create_Pin_APDU.h b/base/tps/src/include/apdu/Create_Pin_APDU.h
new file mode 100644
index 000000000..7f666467d
--- /dev/null
+++ b/base/tps/src/include/apdu/Create_Pin_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef CREATE_PIN_APDU_H
+#define CREATE_PIN_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Create_Pin_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Create_Pin_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Create_Pin_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* CREATE_PIN_APDU_H */
diff --git a/base/tps/src/include/apdu/Delete_File_APDU.h b/base/tps/src/include/apdu/Delete_File_APDU.h
new file mode 100644
index 000000000..9e2eeeeb2
--- /dev/null
+++ b/base/tps/src/include/apdu/Delete_File_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef DELETE_FILE_APDU_H
+#define DELETE_FILE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Delete_File_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Delete_File_APDU(Buffer &AID);
+ TPS_PUBLIC ~Delete_File_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* DELETE_FILE_APDU_H */
diff --git a/base/tps/src/include/apdu/External_Authenticate_APDU.h b/base/tps/src/include/apdu/External_Authenticate_APDU.h
new file mode 100644
index 000000000..ff9a6bee7
--- /dev/null
+++ b/base/tps/src/include/apdu/External_Authenticate_APDU.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef EXTERNAL_AUTHENTICATE_APDU_H
+#define EXTERNAL_AUTHENTICATE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "channel/Secure_Channel.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class External_Authenticate_APDU : public APDU
+{
+ public:
+ // TPS_PUBLIC External_Authenticate_APDU(Buffer &data);
+ TPS_PUBLIC External_Authenticate_APDU(Buffer &data, SecurityLevel sl);
+ TPS_PUBLIC ~External_Authenticate_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC Buffer &GetHostCryptogram();
+};
+
+#endif /* EXTERNAL_AUTHENTICATE_APDU_H */
diff --git a/base/tps/src/include/apdu/Format_Muscle_Applet_APDU.h b/base/tps/src/include/apdu/Format_Muscle_Applet_APDU.h
new file mode 100644
index 000000000..b7fbbbea1
--- /dev/null
+++ b/base/tps/src/include/apdu/Format_Muscle_Applet_APDU.h
@@ -0,0 +1,65 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef FORMAT_MUSCLE_APPLET_APDU_H
+#define FORMAT_MUSCLE_APPLET_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Format_Muscle_Applet_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Format_Muscle_Applet_APDU(unsigned short memSize,
+ Buffer &PIN0, BYTE pin0Tries,
+ Buffer &unblockPIN0, BYTE unblock0Tries,
+ Buffer &PIN1, BYTE pin1Tries,
+ Buffer &unblockPIN1, BYTE unblock1Tries,
+ unsigned short objCreationPermissions,
+ unsigned short keyCreationPermissions,
+ unsigned short pinCreationPermissions);
+ TPS_PUBLIC ~Format_Muscle_Applet_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* FORMAT_MUSCLE_APPLET_APDU_H */
diff --git a/base/tps/src/include/apdu/Generate_Key_APDU.h b/base/tps/src/include/apdu/Generate_Key_APDU.h
new file mode 100644
index 000000000..d245b8336
--- /dev/null
+++ b/base/tps/src/include/apdu/Generate_Key_APDU.h
@@ -0,0 +1,60 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef GENERATE_KEY_APDU_H
+#define GENERATE_KEY_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Generate_Key_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Generate_Key_APDU (BYTE p1, BYTE p2, BYTE alg,
+ int keysize, BYTE option,
+ BYTE type, Buffer &wrapped_challenge, Buffer &key_check);
+ TPS_PUBLIC ~Generate_Key_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* GENERATE_KEY_APDU_H */
diff --git a/base/tps/src/include/apdu/Get_Data_APDU.h b/base/tps/src/include/apdu/Get_Data_APDU.h
new file mode 100644
index 000000000..a4f78634d
--- /dev/null
+++ b/base/tps/src/include/apdu/Get_Data_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef GET_DATA_APDU_H
+#define GET_DATA_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Get_Data_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Get_Data_APDU();
+ TPS_PUBLIC ~Get_Data_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* GET_DATA_APDU_H */
diff --git a/base/tps/src/include/apdu/Get_IssuerInfo_APDU.h b/base/tps/src/include/apdu/Get_IssuerInfo_APDU.h
new file mode 100644
index 000000000..075acc6d9
--- /dev/null
+++ b/base/tps/src/include/apdu/Get_IssuerInfo_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef GET_ISSUERINFO_APDU_H
+#define GET_ISSUERINFO_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Get_IssuerInfo_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Get_IssuerInfo_APDU();
+ TPS_PUBLIC ~Get_IssuerInfo_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* GET_ISSUERINFO_APDU_H */
diff --git a/base/tps/src/include/apdu/Get_Status_APDU.h b/base/tps/src/include/apdu/Get_Status_APDU.h
new file mode 100644
index 000000000..5d047bf16
--- /dev/null
+++ b/base/tps/src/include/apdu/Get_Status_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef GET_STATUS_APDU_H
+#define GET_STATUS_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Get_Status_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Get_Status_APDU();
+ TPS_PUBLIC ~Get_Status_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* GET_STATUS_APDU_H */
diff --git a/base/tps/src/include/apdu/Get_Version_APDU.h b/base/tps/src/include/apdu/Get_Version_APDU.h
new file mode 100644
index 000000000..8b6ff3c33
--- /dev/null
+++ b/base/tps/src/include/apdu/Get_Version_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef GET_VERSION_APDU_H
+#define GET_VERSION_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Get_Version_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Get_Version_APDU();
+ TPS_PUBLIC ~Get_Version_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* GET_VERSION_APDU_H */
diff --git a/base/tps/src/include/apdu/Import_Key_APDU.h b/base/tps/src/include/apdu/Import_Key_APDU.h
new file mode 100644
index 000000000..e00d97081
--- /dev/null
+++ b/base/tps/src/include/apdu/Import_Key_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef IMPORT_KEY_APDU_H
+#define IMPORT_KEY_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Import_Key_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Import_Key_APDU(BYTE p1);
+ TPS_PUBLIC ~Import_Key_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* IMPORT_KEY_APDU_H */
diff --git a/base/tps/src/include/apdu/Import_Key_Enc_APDU.h b/base/tps/src/include/apdu/Import_Key_Enc_APDU.h
new file mode 100644
index 000000000..bcc974987
--- /dev/null
+++ b/base/tps/src/include/apdu/Import_Key_Enc_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef IMPORT_KEY_ENC_APDU_H
+#define IMPORT_KEY_ENC_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Import_Key_Enc_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Import_Key_Enc_APDU(BYTE p1, BYTE p2, Buffer& data);
+ TPS_PUBLIC ~Import_Key_Enc_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* IMPORT_KEY_ENC_APDU_H */
diff --git a/base/tps/src/include/apdu/Initialize_Update_APDU.h b/base/tps/src/include/apdu/Initialize_Update_APDU.h
new file mode 100644
index 000000000..8e20d77ab
--- /dev/null
+++ b/base/tps/src/include/apdu/Initialize_Update_APDU.h
@@ -0,0 +1,60 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef INITIALIZE_UPDATE_APDU_H
+#define INITIALIZE_UPDATE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Initialize_Update_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Initialize_Update_APDU(BYTE key_version, BYTE key_index, Buffer &data);
+ TPS_PUBLIC ~Initialize_Update_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+ public:
+ TPS_PUBLIC Buffer &GetHostChallenge();
+};
+
+#endif /* INITIALIZE_UPDATE_APDU_H */
diff --git a/base/tps/src/include/apdu/Install_Applet_APDU.h b/base/tps/src/include/apdu/Install_Applet_APDU.h
new file mode 100644
index 000000000..08b799a64
--- /dev/null
+++ b/base/tps/src/include/apdu/Install_Applet_APDU.h
@@ -0,0 +1,59 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef INSTALL_APPLET_APDU_H
+#define INSTALL_APPLET_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Install_Applet_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Install_Applet_APDU(Buffer &packageAID, Buffer &appletAID,
+ BYTE appPrivileges, unsigned int instanceSize, unsigned int appletMemorySize);
+ TPS_PUBLIC Install_Applet_APDU(Buffer &data);
+ TPS_PUBLIC ~Install_Applet_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* INSTALL_APPLET_APDU_H */
diff --git a/base/tps/src/include/apdu/Install_Load_APDU.h b/base/tps/src/include/apdu/Install_Load_APDU.h
new file mode 100644
index 000000000..7d0ff9761
--- /dev/null
+++ b/base/tps/src/include/apdu/Install_Load_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef INSTALL_LOAD_APDU_H
+#define INSTALL_LOAD_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Install_Load_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Install_Load_APDU(Buffer& packageAID, Buffer& sdAID, unsigned int fileLen);
+ TPS_PUBLIC Install_Load_APDU(Buffer& data);
+ TPS_PUBLIC ~Install_Load_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* INSTALL_LOAD_APDU_H */
diff --git a/base/tps/src/include/apdu/Lifecycle_APDU.h b/base/tps/src/include/apdu/Lifecycle_APDU.h
new file mode 100644
index 000000000..a3adaf9c4
--- /dev/null
+++ b/base/tps/src/include/apdu/Lifecycle_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef LIFECYCLE_APDU_H
+#define LIFECYCLE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Lifecycle_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Lifecycle_APDU(BYTE lifecycle);
+ TPS_PUBLIC ~Lifecycle_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* LIFECYCLE_APDU_H */
diff --git a/base/tps/src/include/apdu/List_Objects_APDU.h b/base/tps/src/include/apdu/List_Objects_APDU.h
new file mode 100644
index 000000000..7d5b45bff
--- /dev/null
+++ b/base/tps/src/include/apdu/List_Objects_APDU.h
@@ -0,0 +1,59 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef LIST_OBJECTS_APDU_H
+#define LIST_OBJECTS_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class List_Objects_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC List_Objects_APDU(BYTE ret_size);
+ TPS_PUBLIC ~List_Objects_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* LIST_OBJECTS_APDU_H */
diff --git a/base/tps/src/include/apdu/List_Pins_APDU.h b/base/tps/src/include/apdu/List_Pins_APDU.h
new file mode 100644
index 000000000..04d1102c9
--- /dev/null
+++ b/base/tps/src/include/apdu/List_Pins_APDU.h
@@ -0,0 +1,60 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef LIST_PINS_APDU_H
+#define LIST_PINS_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class List_Pins_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC List_Pins_APDU(BYTE ret_size);
+ TPS_PUBLIC ~List_Pins_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ BYTE m_ret_size;
+ TPS_PUBLIC void GetEncoding(Buffer &data);
+};
+
+#endif /* LIST_PINS_APDU_H */
diff --git a/base/tps/src/include/apdu/Load_File_APDU.h b/base/tps/src/include/apdu/Load_File_APDU.h
new file mode 100644
index 000000000..ae5f57445
--- /dev/null
+++ b/base/tps/src/include/apdu/Load_File_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef LOAD_FILE_APDU_H
+#define LOAD_FILE_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Load_File_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Load_File_APDU(BYTE refControl, BYTE blockNum, Buffer& data);
+ TPS_PUBLIC ~Load_File_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* LOAD_FILE_APDU_H */
diff --git a/base/tps/src/include/apdu/Put_Key_APDU.h b/base/tps/src/include/apdu/Put_Key_APDU.h
new file mode 100644
index 000000000..63aa54599
--- /dev/null
+++ b/base/tps/src/include/apdu/Put_Key_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef PUT_KEY_APDU_H
+#define PUT_KEY_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Put_Key_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Put_Key_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Put_Key_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* PUT_KEY_APDU_H */
diff --git a/base/tps/src/include/apdu/Read_Buffer_APDU.h b/base/tps/src/include/apdu/Read_Buffer_APDU.h
new file mode 100644
index 000000000..3c94b564d
--- /dev/null
+++ b/base/tps/src/include/apdu/Read_Buffer_APDU.h
@@ -0,0 +1,61 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef READ_BUFFER_APDU_H
+#define READ_BUFFER_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Read_Buffer_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Read_Buffer_APDU(int len, int offset);
+ TPS_PUBLIC ~Read_Buffer_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC int GetLen();
+ TPS_PUBLIC int GetOffset();
+
+};
+
+#endif /* READ_BUFFER_APDU_H */
diff --git a/base/tps/src/include/apdu/Read_Object_APDU.h b/base/tps/src/include/apdu/Read_Object_APDU.h
new file mode 100644
index 000000000..e2357acdd
--- /dev/null
+++ b/base/tps/src/include/apdu/Read_Object_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef OBJECT_OBJECT_APDU_H
+#define OBJECT_OBJECT_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Read_Object_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Read_Object_APDU(BYTE *object_id, int offset, int len);
+ TPS_PUBLIC ~Read_Object_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* OBJECT_OBJECT_APDU_H */
diff --git a/base/tps/src/include/apdu/Select_APDU.h b/base/tps/src/include/apdu/Select_APDU.h
new file mode 100644
index 000000000..92c1c8ee8
--- /dev/null
+++ b/base/tps/src/include/apdu/Select_APDU.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef SELECT_APDU_H
+#define SELECT_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Select_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Select_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Select_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* SELECT_APDU_H */
diff --git a/base/tps/src/include/apdu/Set_IssuerInfo_APDU.h b/base/tps/src/include/apdu/Set_IssuerInfo_APDU.h
new file mode 100644
index 000000000..2507fdc97
--- /dev/null
+++ b/base/tps/src/include/apdu/Set_IssuerInfo_APDU.h
@@ -0,0 +1,59 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef SET_ISSUERINFO_APDU_H
+#define SET_ISSUERINFO_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Set_IssuerInfo_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Set_IssuerInfo_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Set_IssuerInfo_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC Buffer &GetIssuerInfo();
+};
+
+#endif /* SET_ISSUERINFO_APDU_H */
diff --git a/base/tps/src/include/apdu/Set_Pin_APDU.h b/base/tps/src/include/apdu/Set_Pin_APDU.h
new file mode 100644
index 000000000..f649147a1
--- /dev/null
+++ b/base/tps/src/include/apdu/Set_Pin_APDU.h
@@ -0,0 +1,59 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef SET_PIN_APDU_H
+#define SET_PIN_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Set_Pin_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Set_Pin_APDU(BYTE p1, BYTE p2, Buffer &data);
+ TPS_PUBLIC ~Set_Pin_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+ public:
+ TPS_PUBLIC Buffer &GetNewPIN();
+};
+
+#endif /* SET_PIN_APDU_H */
diff --git a/base/tps/src/include/apdu/Unblock_Pin_APDU.h b/base/tps/src/include/apdu/Unblock_Pin_APDU.h
new file mode 100644
index 000000000..583e7ae7d
--- /dev/null
+++ b/base/tps/src/include/apdu/Unblock_Pin_APDU.h
@@ -0,0 +1,54 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef UNBLOCK_PIN_APDU_H
+#define UNBLOCK_PIN_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Unblock_Pin_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Unblock_Pin_APDU();
+ TPS_PUBLIC ~Unblock_Pin_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* UNBLOCK_PIN_APDU_H */
diff --git a/base/tps/src/include/apdu/Write_Object_APDU.h b/base/tps/src/include/apdu/Write_Object_APDU.h
new file mode 100644
index 000000000..670cd6bbd
--- /dev/null
+++ b/base/tps/src/include/apdu/Write_Object_APDU.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef WRITE_OBJECT_APDU_H
+#define WRITE_OBJECT_APDU_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "apdu/APDU.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Write_Object_APDU : public APDU
+{
+ public:
+ TPS_PUBLIC Write_Object_APDU(BYTE *object_id, int offset, Buffer &data);
+ TPS_PUBLIC ~Write_Object_APDU();
+ TPS_PUBLIC APDU_Type GetType();
+};
+
+#endif /* WRITE_OBJECT_APDU_H */
diff --git a/base/tps/src/include/authentication/AuthParams.h b/base/tps/src/include/authentication/AuthParams.h
new file mode 100644
index 000000000..e0d39a249
--- /dev/null
+++ b/base/tps/src/include/authentication/AuthParams.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef AUTHPARAMS_H
+#define AUTHPARAMS_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/NameValueSet.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class AuthParams : public NameValueSet
+{
+ public:
+ TPS_PUBLIC AuthParams();
+ virtual ~AuthParams();
+ public:
+ TPS_PUBLIC void SetUID(char *uid);
+ TPS_PUBLIC char *GetUID();
+ TPS_PUBLIC void SetPassword(char *pwd);
+ TPS_PUBLIC char *GetPassword();
+ void SetSecuridValue(char *securidValue);
+ TPS_PUBLIC char *GetSecuridValue();
+ void SetSecuridPin(char *securidPin);
+ TPS_PUBLIC char *GetSecuridPin();
+};
+
+#endif /* AUTHPARAMS_H */
diff --git a/base/tps/src/include/authentication/Authentication.h b/base/tps/src/include/authentication/Authentication.h
new file mode 100644
index 000000000..ae2b0c6fb
--- /dev/null
+++ b/base/tps/src/include/authentication/Authentication.h
@@ -0,0 +1,80 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef AUTHENTICATION_H
+#define AUTHENTICATION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/RA_Session.h"
+#include "authentication/AuthParams.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#define TPS_AUTH_OK 0
+#define TPS_AUTH_ERROR_LDAP -1
+#define TPS_AUTH_ERROR_USERNOTFOUND -2
+#define TPS_AUTH_ERROR_PASSWORDINCORRECT -3
+
+
+class Authentication
+{
+ public:
+ TPS_PUBLIC Authentication();
+ TPS_PUBLIC virtual ~Authentication();
+ public:
+ virtual int Authenticate(AuthParams *params);
+ virtual void Initialize(int index);
+ public:
+ virtual const char *GetTitle(char *locale);
+ virtual const char *GetDescription(char *locale);
+ virtual int GetNumOfParamNames();
+ virtual char *GetParamID(int index);
+ virtual const char *GetParamName(int index, char *locale);
+ virtual char *GetParamType(int index);
+ virtual const char *GetParamDescription(int index, char *locale);
+ virtual char *GetParamOption(int index);
+ int GetNumOfRetries(); // retries if the user entered the wrong password/securid
+
+ protected:
+ int m_retries;
+};
+
+#endif /* AUTHENTICATION_H */
diff --git a/base/tps/src/include/authentication/LDAP_Authentication.h b/base/tps/src/include/authentication/LDAP_Authentication.h
new file mode 100644
index 000000000..2a8c0a7d5
--- /dev/null
+++ b/base/tps/src/include/authentication/LDAP_Authentication.h
@@ -0,0 +1,85 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef LDAP_AUTHENTICATION_H
+#define LDAP_AUTHENTICATION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/RA_Session.h"
+#include "authentication/Authentication.h"
+
+class LDAP_Authentication : public Authentication
+{
+ public:
+ LDAP_Authentication();
+ ~LDAP_Authentication();
+ public:
+ int Authenticate(AuthParams *params);
+ void Initialize(int index);
+ public:
+ bool IsSSL();
+ char *GetHostPort();
+
+ public:
+ void GetHostPort(char **p, char **q);
+ virtual const char *GetTitle(char *locale);
+ virtual const char *GetDescription(char *locale);
+ virtual int GetNumOfParamNames();
+ virtual char *GetParamID(int index);
+ virtual const char *GetParamName(int index, char *locale);
+ virtual char *GetParamType(int index);
+ virtual const char *GetParamDescription(int index, char *locale);
+ virtual char *GetParamOption(int index);
+
+ private:
+ int m_index;
+ bool m_isSSL;
+ char *m_hostport;
+ char *m_attributes;
+ char *m_ssl;
+ char *m_baseDN;
+ char *m_bindDN;
+ char *m_bindPwd;
+ int m_connectRetries; // for failover
+ ConnectionInfo *m_connInfo;
+};
+ extern "C"
+ {
+ Authentication *GetAuthentication();
+ };
+
+#endif /* LDAP_AUTHENTICATION_H */
diff --git a/base/tps/src/include/channel/Channel.h b/base/tps/src/include/channel/Channel.h
new file mode 100644
index 000000000..a49af8bf1
--- /dev/null
+++ b/base/tps/src/include/channel/Channel.h
@@ -0,0 +1,55 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/RA_Session.h"
+#include "apdu/APDU.h"
+#include "apdu/APDU_Response.h"
+
+class Channel
+{
+ public:
+ Channel();
+ ~Channel();
+ public:
+ int Close();
+};
+
+#endif /* CHANNEL_H */
diff --git a/base/tps/src/include/channel/Secure_Channel.h b/base/tps/src/include/channel/Secure_Channel.h
new file mode 100644
index 000000000..bac072407
--- /dev/null
+++ b/base/tps/src/include/channel/Secure_Channel.h
@@ -0,0 +1,158 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef SECURE_CHANNEL_H
+#define SECURE_CHANNEL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/RA_Session.h"
+#include "apdu/APDU.h"
+#include "apdu/APDU_Response.h"
+#include "channel/Channel.h"
+
+enum SecurityLevel {
+ SECURE_MSG_ANY = 0,
+ SECURE_MSG_MAC = 1,
+ SECURE_MSG_NONE = 2, // not yet supported
+ SECURE_MSG_MAC_ENC = 3
+} ;
+
+enum TokenKeyType {
+ KEY_TYPE_ENCRYPTION = 0,
+ KEY_TYPE_SIGNING = 1,
+ KEY_TYPE_SIGNING_AND_ENCRYPTION = 2
+};
+
+class Secure_Channel : public Channel
+{
+ public:
+
+ Secure_Channel(
+ RA_Session *session,
+ PK11SymKey *session_key,
+ PK11SymKey *enc_session_key,
+ char *drm_des_key_s,
+ char *kek_des_key_s,
+ char *keycheck_s,
+ Buffer &key_diversification_data,
+ Buffer &key_info_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge,
+ Buffer &host_cryptogram);
+
+ ~Secure_Channel();
+ public:
+ Buffer &GetKeyDiversificationData();
+ Buffer &GetKeyInfoData();
+ Buffer &GetCardChallenge();
+ Buffer &GetCardCryptogram();
+ Buffer &GetHostChallenge();
+ Buffer &GetHostCryptogram();
+ SecurityLevel GetSecurityLevel();
+ void SetSecurityLevel(SecurityLevel level);
+ char *getDrmWrappedDESKey();
+ char *getKekWrappedDESKey();
+ char *getKeycheck();
+
+ public:
+ int ImportKeyEnc(BYTE priv_key_number, BYTE pub_key_number, Buffer* data);
+ int ImportKey(BYTE key_number);
+ int CreatePin(BYTE pin_number, BYTE max_retries, const char *pin);
+ int ExternalAuthenticate();
+ int SetIssuerInfo(Buffer *info);
+ Buffer GetIssuerInfo();
+ int ResetPin(BYTE pin_number, char *pin);
+ int IsPinPresent(BYTE pin_number);
+ int SetLifecycleState(BYTE flag);
+ int StartEnrollment(BYTE p1, BYTE p2, Buffer *wrapped_challenge,
+ Buffer *key_check,
+ BYTE alg, int keysize, BYTE option);
+ int ReadBuffer(BYTE *buf, int buf_len);
+ int CreateObject(BYTE *object_id, BYTE* permissions, int len);
+ int WriteObject(BYTE *objid, BYTE *buf, int buf_len);
+ Buffer *ReadObject(BYTE *objid, int offset, int len);
+ int PutKeys(RA_Session *session, BYTE key_version,
+ BYTE key_index, Buffer *key_data);
+ int LoadFile(RA_Session *session, BYTE refControl, BYTE blockNum,
+ Buffer *data);
+ int InstallApplet(RA_Session *session,
+ Buffer &packageAID, Buffer &appletAID,
+ BYTE appPrivileges, unsigned int instanceSize, unsigned int appletMemorySize);
+ int InstallLoad(RA_Session *session,
+ Buffer& packageAID, Buffer& sdAID, unsigned int fileLen);
+ int DeleteFileX(RA_Session *session, Buffer *aid);
+ int Close();
+ public:
+ int CreateObject(BYTE *objid, BYTE *perms, Buffer *obj);
+ int CreateCertificate(const char *id, Buffer *cert);
+
+ Buffer CreatePKCS11CertAttrsBuffer(TokenKeyType type, const char *id, const char *label, Buffer *keyid);
+ int CreatePKCS11CertAttrs(TokenKeyType type, const char *id, const char *label, Buffer *keyid);
+ Buffer CreatePKCS11PriKeyAttrsBuffer(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix);
+ int CreatePKCS11PriKeyAttrs(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix);
+ Buffer CreatePKCS11PubKeyAttrsBuffer(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix);
+ int CreatePKCS11PubKeyAttrs(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix);
+ APDU_Response *SendTokenAPU(APDU *apdu);
+
+ public:
+ Buffer *ComputeAPDUMac(APDU *apdu);
+ int ComputeAPDU(APDU *apdu);
+
+ private:
+ PK11SymKey *m_session_key;
+ PK11SymKey *m_enc_session_key;
+ char *m_drm_wrapped_des_key_s;
+ char *m_kek_wrapped_des_key_s;
+ char *m_keycheck_s;
+ RA_Session *m_session;
+ Buffer m_icv;
+ Buffer m_cryptogram;
+ Buffer m_key_diversification_data;
+ Buffer m_key_info_data;
+ Buffer m_card_challenge;
+ Buffer m_card_cryptogram;
+ Buffer m_host_challenge;
+ Buffer m_host_cryptogram;
+ SecurityLevel m_security_level;
+};
+
+#endif /* SECURE_CHANNEL_H */
diff --git a/base/tps/src/include/cms/CertEnroll.h b/base/tps/src/include/cms/CertEnroll.h
new file mode 100644
index 000000000..442e28e8c
--- /dev/null
+++ b/base/tps/src/include/cms/CertEnroll.h
@@ -0,0 +1,75 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef CERTENROLL_H
+#define CERTENROLL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Buffer.h"
+
+#include "httpClient/httpc/response.h"
+#include "keythi.h"
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+class CertEnroll
+{
+ public:
+
+ TOKENDB_PUBLIC CertEnroll();
+ TOKENDB_PUBLIC ~CertEnroll();
+
+ SECKEYPublicKey *ParsePublicKeyBlob(unsigned char * /*blob*/,
+ Buffer * /*challenge*/);
+ Buffer *EnrollCertificate(SECKEYPublicKey * /*pk_parsed*/,
+ const char *profileId,
+ const char * /*uid*/,
+ const char * /*token cuid*/, const char *connid,
+ char *error_msg,
+ SECItem** encodedPublicKeyInfo = NULL);
+ ReturnStatus verifyProof(SECKEYPublicKey* /*pk*/, SECItem* /*siProof*/,
+ unsigned short /*pkeyb_len*/, unsigned char* /*pkeyb*/,
+ Buffer* /*challenge*/);
+ TOKENDB_PUBLIC Buffer *RenewCertificate(PRUint64 serialno, const char *connid, const char *profileId, char *error_msg);
+ TOKENDB_PUBLIC int RevokeCertificate(const char *reason, const char *serialno, const char *connid, char *&status);
+ TOKENDB_PUBLIC int UnrevokeCertificate(const char *serialno, const char *connid, char *&status);
+ PSHttpResponse * sendReqToCA(const char *servlet, const char *parameters, const char *connid);
+ Buffer * parseResponse(PSHttpResponse * /*resp*/);
+};
+#endif /* CERTENROLL_H */
diff --git a/base/tps/src/include/cms/ConnectionInfo.h b/base/tps/src/include/cms/ConnectionInfo.h
new file mode 100644
index 000000000..07e9c3a73
--- /dev/null
+++ b/base/tps/src/include/cms/ConnectionInfo.h
@@ -0,0 +1,66 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef CONNECTIONINFO_H
+#define CONNECTIONINFO_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Buffer.h"
+#include "main/NameValueSet.h"
+#include "pk11func.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#define HOST_PORT_MEMBERS 20
+
+class ConnectionInfo
+{
+ public:
+ TPS_PUBLIC ConnectionInfo();
+ TPS_PUBLIC ~ConnectionInfo();
+ TPS_PUBLIC void BuildFailoverList(const char *str);
+ TPS_PUBLIC int GetHostPortListLen();
+ TPS_PUBLIC char **GetHostPortList();
+
+ private:
+ int m_len;
+ char *m_hostPortList[HOST_PORT_MEMBERS];
+};
+
+#endif /* CONNECTIONINFO_H */
diff --git a/base/tps/src/include/cms/HttpConnection.h b/base/tps/src/include/cms/HttpConnection.h
new file mode 100644
index 000000000..da9d3a7fd
--- /dev/null
+++ b/base/tps/src/include/cms/HttpConnection.h
@@ -0,0 +1,88 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef HTTPCONNECTION_H
+#define HTTPCONNECTION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/engine.h"
+#include "httpClient/httpc/http.h"
+#include "ConnectionInfo.h"
+#include "main/NameValueSet.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class HttpConnection
+{
+ public:
+// HttpConnection();
+ TPS_PUBLIC HttpConnection(const char *id, ConnectionInfo *cinfo, int retries, int timeout,
+ bool isSSL, const char *clientnickname, bool keepAlive, NameValueSet *headers);
+ TPS_PUBLIC virtual ~HttpConnection();
+
+ public:
+ TPS_PUBLIC int GetNumOfRetries(); // failover retries
+ TPS_PUBLIC int GetTimeout();
+ TPS_PUBLIC ConnectionInfo *GetFailoverList();
+ TPS_PUBLIC char *GetId();
+ TPS_PUBLIC bool IsSSL();
+ TPS_PUBLIC char *GetClientNickname();
+ TPS_PUBLIC bool IsKeepAlive();
+ TPS_PUBLIC PSHttpResponse *getResponse(int index, const char *servletID, const char *body);
+ TPS_PUBLIC PRLock *GetLock();
+ TPS_PUBLIC int GetCurrentIndex();
+ TPS_PUBLIC void SetCurrentIndex(int index);
+
+ protected:
+ int m_max_conn;
+ ConnectionInfo *m_failoverList;
+ int m_retries;
+ int m_timeout;
+ char *m_Id;
+ bool m_isSSL;
+ char *m_clientnickname;
+ bool m_keepAlive;
+ NameValueSet *m_headers;
+ PRLock *m_lock;
+ int m_curr;
+};
+
+#endif /* HTTPCONNECTION_H */
diff --git a/base/tps/src/include/engine/RA.h b/base/tps/src/include/engine/RA.h
new file mode 100644
index 000000000..9e7db9857
--- /dev/null
+++ b/base/tps/src/include/engine/RA.h
@@ -0,0 +1,374 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_H
+#define RA_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "engine/audit.h"
+#include "ldap.h"
+#include "lber.h"
+#include "main/Base.h"
+#include "main/ConfigStore.h"
+#include "main/Buffer.h"
+#include "main/PublishEntry.h"
+#include "main/AuthenticationEntry.h"
+#include "main/LogFile.h"
+#include "authentication/Authentication.h"
+#include "apdu/APDU.h"
+#include "main/RA_Context.h"
+#include "channel/Secure_Channel.h"
+#include "cms/HttpConnection.h"
+#include "cms/ConnectionInfo.h"
+#include "publisher/IPublisher.h"
+
+/*
+ *
+ * LL_PER_SERVER = 4 these messages will occur only once during the
+ * entire invocation of the server, e.g. at startup
+ * or shutdown time., reading the conf parameters.
+ * Perhaps other infrequent events relating to
+ * failing over of CA, TKS, too
+ *
+ * LL_PER_CONNECTION = 6 these messages happen once per connection - most
+ * of the log events will be at this level
+ *
+ * LL_PER_PDU = 8 these messages relate to PDU processing. If you
+ * have something that is done for every PDU, such
+ * as applying the MAC, it should be logged at this
+ * level
+ *
+ * LL_ALL_DATA_IN_PDU = 9 dump all the data in the PDU - a more chatty
+ * version of the above
+ */
+enum RA_Log_Level {
+ LL_PER_SERVER = 4,
+ LL_PER_CONNECTION = 6,
+ LL_PER_PDU = 8,
+ LL_ALL_DATA_IN_PDU = 9
+};
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/* For now, this value must correspond exactly to the successful exit */
+/* status of RA::Initialize( char *cfg_path, RA_Context *ctx ). */
+#define RA_INITIALIZATION_SUCCESS 1
+
+#define TRANSPORT_KEY_NAME "sharedSecret"
+
+typedef char NSSUTF8;
+
+class RA
+{
+ public:
+ RA();
+ ~RA();
+ public:
+ static bool IsAuditEventSelected(const char *auditEvent);
+ static bool IsValidEvent(const char *auditEvent);
+ static void getLastSignature();
+ static int IsTokendbInitialized();
+ static int IsTpsConfigured();
+ TPS_PUBLIC static int Initialize(char *cfg_path, RA_Context *ctx);
+// TPS_PUBLIC static int InitializeInChild(RA_Context *ctx);
+ TPS_PUBLIC static int InitializeInChild(RA_Context *ctx, int nSignedAuditInitCount);
+ TPS_PUBLIC static int Shutdown();
+ TPS_PUBLIC static int Child_Shutdown();
+ public:
+
+ static PK11SymKey *ComputeSessionKey(RA_Session *session,
+ Buffer &CUID,
+ Buffer &keyinfo,
+ Buffer &card_challenge,
+ Buffer &host_challenge,
+ Buffer **host_cryptogram,
+ Buffer &card_cryptogram,
+ PK11SymKey **encSymKey,
+ char** drm_kekSessionKey_s,
+ char** kek_kekSessionKey_s,
+ char **keycheck_s,
+ const char *connId);
+ static void ServerSideKeyGen(RA_Session *session, const char* cuid,
+ const char *userid, char* kekSessionKey_s,
+ char **publickey_s,
+ char **wrappedPrivateKey_s,
+ char **ivParam_s, const char *connId,
+ bool archive, int keysize);
+ static void RecoverKey(RA_Session *session, const char* cuid,
+ const char *userid, char* kekSessionKey_s,
+ char *cert_s, char **publickey_s,
+ char **wrappedPrivateKey_s, const char *connId, char **ivParam_s);
+
+ static Buffer *ComputeHostCryptogram(Buffer &card_challenge, Buffer &host_challenge);
+
+ static PK11SymKey *FindSymKeyByName( PK11SlotInfo *slot, char *keyname);
+ static PK11SymKey *CreateDesKey24Byte(PK11SlotInfo *slot, PK11SymKey *origKey);
+ public:
+ TPS_PUBLIC static ConfigStore *GetConfigStore();
+ TPS_PUBLIC static bool match_comma_list(const char* item, char *list);
+ TPS_PUBLIC static char* remove_from_comma_list(const char*item, char *list);
+ public:
+ TPS_PUBLIC static void Audit(const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void Error(const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void SelfTestLog(const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void Debug(const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void DebugBuffer(const char *func_name, const char *prefix, Buffer *buf);
+ TPS_PUBLIC static void Audit(RA_Log_Level level, const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void Error(RA_Log_Level level, const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void SelfTestLog(RA_Log_Level level, const char *func_name, const char *fmt, ...);
+ TPS_PUBLIC static void Debug(RA_Log_Level level, const char *func_name, const char *fmt, ...);
+ static void DebugBuffer(RA_Log_Level level, const char *func_name, const char *prefix, Buffer *buf);
+ TPS_PUBLIC static void FlushAuditLogBuffer();
+ TPS_PUBLIC static void SignAuditLog(NSSUTF8 *msg);
+ TPS_PUBLIC static char *GetAuditSigningMessage(const NSSUTF8 *msg);
+ TPS_PUBLIC static void SetFlushInterval(int interval);
+ TPS_PUBLIC static void SetBufferSize(int size);
+ static void RunFlushThread(void *arg);
+ TPS_PUBLIC static int setup_audit_log(bool enable_signing, bool signing_changed);
+ TPS_PUBLIC static void enable_audit_logging(bool enable);
+ private:
+ static void AuditThis(RA_Log_Level level, const char *func_name, const char *fmt, va_list ap);
+ static void ErrorThis(RA_Log_Level level, const char *func_name, const char *fmt, va_list ap);
+ static void SelfTestLogThis(RA_Log_Level level, const char *func_name, const char *fmt, va_list ap);
+ static void DebugThis(RA_Log_Level level, const char *func_name, const char *fmt, va_list ap);
+ static void do_free(char *s);
+ public:
+ static int InitializeTokendb(char *cfg_path);
+ static int InitializeSignedAudit();
+ static PRLock *GetVerifyLock();
+ static PRLock *GetConfigLock();
+ TPS_PUBLIC static CERTCertificate **ra_get_certificates(LDAPMessage *e);
+ TPS_PUBLIC static LDAPMessage *ra_get_first_entry(LDAPMessage *e);
+ TPS_PUBLIC static LDAPMessage *ra_get_next_entry(LDAPMessage *e);
+ TPS_PUBLIC static struct berval **ra_get_attribute_values(LDAPMessage *e, const char *p);
+ TPS_PUBLIC static void ra_free_values(struct berval **values);
+ TPS_PUBLIC static char *ra_get_cert_attr_byname(LDAPMessage *e, const char *name);
+ TPS_PUBLIC static char *ra_get_token_id(LDAPMessage *e);
+ TPS_PUBLIC static char *ra_get_cert_tokenType(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_token_status(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_cn(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_status(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_type(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_serial(LDAPMessage *entry);
+ TPS_PUBLIC static char *ra_get_cert_issuer(LDAPMessage *entry);
+ TPS_PUBLIC static int ra_delete_certificate_entry(LDAPMessage *entry);
+ TPS_PUBLIC static int ra_tus_has_active_tokens(char *userid);
+ TPS_PUBLIC static char *ra_get_token_reason(LDAPMessage *msg);
+ TPS_PUBLIC static int ra_get_number_of_entries(LDAPMessage *ldapResult);
+ TPS_PUBLIC static int ra_find_tus_token_entries(char *filter,
+ int maxReturns, LDAPMessage **ldapResult, int num);
+ TPS_PUBLIC static int ra_find_tus_token_entries_no_vlv(char *filter,
+ LDAPMessage **ldapResult, int num);
+ TPS_PUBLIC static int ra_is_tus_db_entry_disabled(char *cuid);
+ TPS_PUBLIC static int ra_is_token_pin_resetable(char *cuid);
+ TPS_PUBLIC static int ra_is_token_present(char *cuid);
+ TPS_PUBLIC static int ra_allow_token_reenroll(char *cuid);
+ TPS_PUBLIC static int ra_allow_token_renew(char *cuid);
+ TPS_PUBLIC static int ra_force_token_format(char *cuid);
+ TPS_PUBLIC static int ra_is_update_pin_resetable_policy(char *cuid);
+ TPS_PUBLIC static char *ra_get_token_policy(char *cuid);
+ TPS_PUBLIC static char *ra_get_token_userid(char *cuid);
+ TPS_PUBLIC static int ra_update_token_policy(char *cuid, char *policy);
+ TPS_PUBLIC static int ra_update_cert_status(char *cn, const char *status);
+ TPS_PUBLIC static int ra_find_tus_certificate_entries_by_order(
+ char *filter, int num, LDAPMessage **msg, int order);
+ TPS_PUBLIC static int ra_find_tus_certificate_entries_by_order_no_vlv(
+ char *filter, LDAPMessage **msg, int order);
+ TPS_PUBLIC static void ra_tus_print_integer(char *out, SECItem *data);
+ TPS_PUBLIC static int ra_update_token_status_reason_userid(char *userid,
+ char *cuid, const char *status, const char *reason, int modifyDateOfCreate);
+ static int tdb_add_token_entry(char *userid, char* cuid, const char *status, const char *token_type);
+ static int tdb_update(const char *userid, char *cuid, char *applet_version, char *key_info, const char *state, const char *reason, const char * token_type);
+ static int tdb_update_certificates(char *cuid, char **tokentypes, char *userid, CERTCertificate **certificates, char **ktypes, char **origins, int numOfCerts);
+ static int tdb_activity(const char *ip, const char *cuid, const char *op, const char *result, const char *msg, const char *userid, const char *token_type);
+ static int testTokendb();
+ static int InitializeAuthentication();
+ static AuthenticationEntry *GetAuth(const char *id);
+ public:
+ static HttpConnection *GetCAConn(const char *id);
+ static void ReturnCAConn(HttpConnection *conn);
+ static HttpConnection *GetTKSConn(const char *id);
+ static void ReturnTKSConn(HttpConnection *conn);
+
+ static HttpConnection *GetDRMConn(const char *id);
+ static void ReturnDRMConn(HttpConnection *conn);
+ static int GetCurrentIndex(HttpConnection *conn);
+ static LogFile* GetLogFile(const char *log_type);
+
+ public:
+
+ static void SetPodIndex(int index);
+ static int GetPodIndex();
+ TPS_PUBLIC static int GetAuthCurrentIndex();
+ static void SetAuthCurrentIndex(int index);
+ TPS_PUBLIC static PRLock *GetAuthLock();
+ TPS_PUBLIC static void IncrementAuthCurrentIndex(int len);
+ TPS_PUBLIC static void update_signed_audit_selected_events(char *new_selected);
+ TPS_PUBLIC static void update_signed_audit_enable(const char *enable);
+ TPS_PUBLIC static void update_signed_audit_log_signing(const char *enable);
+
+ static void SetGlobalSecurityLevel(SecurityLevel sl);
+ static SecurityLevel GetGlobalSecurityLevel();
+ public: /* default values */
+ static const char *CFG_DEF_CARDMGR_INSTANCE_AID;
+ static const char *CFG_DEF_NETKEY_INSTANCE_AID;
+ static const char *CFG_DEF_NETKEY_FILE_AID;
+ static const char *CFG_DEF_NETKEY_OLD_INSTANCE_AID;
+ static const char *CFG_DEF_NETKEY_OLD_FILE_AID;
+ static const char *CFG_DEF_APPLET_SO_PIN;
+ public:
+ static const char *CFG_APPLET_DELETE_NETKEY_OLD;
+ static const char *CFG_APPLET_CARDMGR_INSTANCE_AID;
+ static const char *CFG_APPLET_NETKEY_INSTANCE_AID;
+ static const char *CFG_APPLET_NETKEY_FILE_AID;
+ static const char *CFG_APPLET_NETKEY_OLD_INSTANCE_AID;
+ static const char *CFG_APPLET_NETKEY_OLD_FILE_AID;
+ static const char *CFG_APPLET_SO_PIN;
+ static const char *CFG_DEBUG_ENABLE;
+ static const char *CFG_DEBUG_FILENAME;
+ static const char *CFG_DEBUG_LEVEL;
+ static const char *CFG_AUDIT_ENABLE;
+ static const char *CFG_AUDIT_FILENAME;
+ static const char *CFG_SIGNED_AUDIT_FILENAME;
+ static const char *CFG_AUDIT_LEVEL;
+ static const char *CFG_AUDIT_SIGNED;
+ static const char *CFG_AUDIT_SIGNING_CERT_NICK;
+ static const char *CFG_AUDIT_SELECTED_EVENTS;
+ static const char *CFG_AUDIT_SELECTABLE_EVENTS;
+ static const char *CFG_AUDIT_NONSELECTABLE_EVENTS;
+ static const char *CFG_ERROR_LEVEL;
+ static const char *CFG_ERROR_ENABLE;
+ static const char *CFG_ERROR_FILENAME;
+ static const char *CFG_SELFTEST_LEVEL;
+ static const char *CFG_SELFTEST_ENABLE;
+ static const char *CFG_SELFTEST_FILENAME;
+ static const char *CFG_CHANNEL_SEC_LEVEL;
+ static const char *CFG_CHANNEL_ENCRYPTION;
+ static const char *CFG_AUDIT_BUFFER_SIZE;
+ static const char *CFG_AUDIT_FLUSH_INTERVAL;
+ static const char *CFG_AUDIT_FILE_TYPE;
+ static const char *CFG_DEBUG_FILE_TYPE;
+ static const char *CFG_ERROR_FILE_TYPE;
+ static const char *CFG_SELFTEST_FILE_TYPE;
+ static const char *CFG_AUDIT_PREFIX;
+ static const char *CFG_DEBUG_PREFIX;
+ static const char *CFG_ERROR_PREFIX;
+ static const char *CFG_SELFTEST_PREFIX;
+
+
+ static const char *CFG_AUTHS_ENABLE;
+ static const char *CFG_AUTHS_CURRENTIMPL;
+ static const char *CFG_AUTHS_PLUGINS_NUM;
+ static const char *CFG_AUTHS_PLUGIN_NAME;
+
+ static const char *CFG_IPUBLISHER_LIB;
+ static const char *CFG_IPUBLISHER_FACTORY;
+
+ public:
+ static const char *TKS_RESPONSE_STATUS;
+ static const char *TKS_RESPONSE_SessionKey;
+ static const char *TKS_RESPONSE_EncSessionKey;
+ static const char *TKS_RESPONSE_KEK_DesKey;
+ static const char *TKS_RESPONSE_DRM_Trans_DesKey;
+ static const char *TKS_RESPONSE_HostCryptogram;
+
+ public:
+ static int m_used_tks_conn;
+ static int m_used_ca_conn;
+
+ static int m_used_drm_conn;
+ static HttpConnection* m_drmConnection[];
+ static int m_drmConns_len;
+ static int m_pod_curr;
+ static int m_auth_curr;
+ static bool m_pod_enable;
+ static PRLock *m_verify_lock;
+ static PRLock *m_pod_lock;
+ static PRLock *m_auth_lock;
+ static PRLock *m_error_log_lock;
+ static PRLock *m_selftest_log_lock;
+ static PRMonitor *m_audit_log_monitor;
+ static PRLock *m_debug_log_lock;
+ static PRLock *m_config_lock;
+ static int m_audit_log_level;
+ static int m_debug_log_level;
+ static int m_error_log_level;
+ static int m_selftest_log_level;
+ TPS_PUBLIC static bool m_audit_signed;
+ TPS_PUBLIC static bool m_audit_enabled;
+ static SECKEYPrivateKey *m_audit_signing_key;
+ static char *m_last_audit_signature;
+ static SECOidTag m_audit_signAlgTag;
+ TPS_PUBLIC static char *m_signedAuditSelectedEvents;
+ TPS_PUBLIC static char *m_signedAuditSelectableEvents;
+ TPS_PUBLIC static char *m_signedAuditNonSelectableEvents;
+ static char *m_audit_log_buffer;
+ static PRThread *m_flush_thread;
+ static size_t m_bytes_unflushed;
+ static size_t m_buffer_size;
+ static int m_flush_interval;
+
+ static HttpConnection* m_caConnection[];
+ static HttpConnection* m_tksConnection[];
+ static int m_caConns_len;
+ static int m_tksConns_len;
+ static int m_auth_len;
+ static AuthenticationEntry *m_auth_list[];
+ static SecurityLevel m_global_security_level;
+ static void SetCurrentIndex(HttpConnection *&conn, int index);
+
+ static PublisherEntry *publisher_list;
+ static int m_num_publishers;
+ static RA_Context *m_ctx;
+
+
+ static PublisherEntry *getPublisherById(const char *publisher_id);
+ static int InitializePublishers();
+ static int InitializeHttpConnections(const char *id, int *len, HttpConnection **conn, RA_Context *ctx);
+ static void CleanupPublishers();
+ static int Failover(HttpConnection *&conn, int len);
+
+ TPS_PUBLIC static SECCertificateUsage getCertificateUsage(const char *certusage);
+ TPS_PUBLIC static bool verifySystemCertByNickname(const char *nickname, const char *certUsage);
+ TPS_PUBLIC static bool verifySystemCerts();
+
+};
+
+#endif /* RA_H */
diff --git a/base/tps/src/include/engine/audit.h b/base/tps/src/include/engine/audit.h
new file mode 100644
index 000000000..f8b50de37
--- /dev/null
+++ b/base/tps/src/include/engine/audit.h
@@ -0,0 +1,90 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef AUDIT_H
+#define AUDIT_H
+
+#define AUDIT_SIG_MSG_FORMAT "[%s] %x [AuditEvent=%s][SubjectID=%s][Outcome=%s] signature of audit buffer just flushed: sig: %s"
+#define AUDIT_MSG_FORMAT "[SubjectID=%s][Outcome=%s] %s"
+
+// for EV_ROLE_ASSUME
+#define AUDIT_MSG_ROLE "[SubjectID=%s][Role=%s][Outcome=%s] %s"
+
+// for EV_CONFIG, EV_CONFIG_ROLE, EV_CONFIG_TOKEN, EV_CONFIG_PROFILE, EV_CONFIG_AUDIT
+/*
+ ParamNameValPairs must be a name;;value pair
+ (where name and value are separated by the delimiter ;;)
+ separated by + (if more than one name;;value pair) of config params changed
+ Object which identifies the object being modified has the same format name;;value eg. tokenid;;12345
+*/
+#define AUDIT_MSG_CONFIG "[SubjectID=%s][Role=%s][Outcome=%s][Object=%s][ParamNameValPairs=%s] %s"
+
+// for EV_APPLET_UPGRADE; note: "op" is operation such as "format," "enrollment"
+#define AUDIT_MSG_APPLET_UPGRADE "[SubjectID=%s][CUID=%s][MSN=%s][Outcome=%s][op=%s][KeyVersion=%s][OldAppletVersion=%s][NewAppletVersion=%s] %s"
+
+// for EV_KEY_CHANGEOVER; note: "op" is operation such as "format," "enrollment," "pinReset," "renewal"
+#define AUDIT_MSG_KEY_CHANGEOVER "[SubjectID=%s][CUID=%s][MSN=%s][Outcome=%s][op=%s][AppletVersion=%s][OldKeyVersion=%s][NewKeyVersion=%s] %s"
+
+// for EV_AUTH_SUCCESS and EV_AUTH_FAIL
+#define AUDIT_MSG_AUTH "[SubjectID=%s][AuthID=%s][Outcome=%s] %s"
+
+// for EV_AUTHZ_SUCCESS and EV_AUTHZ_FAIL
+#define AUDIT_MSG_AUTHZ "[SubjectID=%s][op=%s][Outcome=%s] %s"
+
+// for op's EV_FORMAT, EV_ENROLLMENT, EV_PIN_RESET, EV_RENEWAL
+#define AUDIT_MSG_PROC "[SubjectID=%s][CUID=%s][MSN=%s][Outcome=%s][op=%s][AppletVersion=%s][KeyVersion=%s] %s"
+
+// for op's EV_ENROLLMENT and EV_RENEWAL.
+#define AUDIT_MSG_PROC_CERT_REQ "[SubjectID=%s][CUID=%s][MSN=%s][Outcome=%s][op=%s][AppletVersion=%s][KeyVersion=%s][Serial=%s][CA_ID=%s] %s"
+
+// op is either "revoke" or "unrevoke"
+#define AUDIT_MSG_CERT_STATUS_CHANGE "[SubjectID=%s][Outcome=%s][op=%s][Serial=%s][CA_ID=%s] %s"
+
+/*
+ * Audit events definitions
+ */
+#define EV_AUDIT_LOG_STARTUP "AUDIT_LOG_STARTUP"
+#define EV_AUDIT_LOG_SHUTDOWN "AUDIT_LOG_SHUTDOWN"
+#define EV_CIMC_CERT_VERIFICATION "CIMC_CERT_VERIFICATION"
+#define EV_ROLE_ASSUME "ROLE_ASSUME"
+#define EV_ENROLLMENT "ENROLLMENT"
+#define EV_PIN_RESET "PIN_RESET"
+#define EV_FORMAT "FORMAT"
+#define EV_AUTHZ_FAIL "AUTHZ_FAIL"
+#define EV_AUTHZ_SUCCESS "AUTHZ_SUCCESS"
+
+// config operations from the TUS interface
+#define EV_CONFIG "CONFIG" // for config operations not specifically defined below
+#define EV_CONFIG_ROLE "CONFIG_ROLE"
+#define EV_CONFIG_TOKEN "CONFIG_TOKEN"
+#define EV_CONFIG_PROFILE "CONFIG_PROFILE"
+#define EV_CONFIG_AUDIT "CONFIG_AUDIT"
+
+#define EV_APPLET_UPGRADE "APPLET_UPGRADE"
+#define EV_KEY_CHANGEOVER "KEY_CHANGEOVER"
+
+#define EV_RENEWAL "RENEWAL"
+
+// authentication for both user login for token ops and role user login (this is different from EV_AUTHZ which is for role authorization)
+#define EV_AUTH_SUCCESS "AUTH_SUCCESS"
+#define EV_AUTH_FAIL "AUTH_FAIL"
+
+#endif //AUDIT_H
diff --git a/base/tps/src/include/httpClient/httpc/AccessLogger.h b/base/tps/src/include/httpClient/httpc/AccessLogger.h
new file mode 100644
index 000000000..2b600d7e6
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/AccessLogger.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __ACCESS_LOGGER_H__
+#define __ACCESS_LOGGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/Logger.h"
+
+/**
+ * A singleton class for writing to an access log
+ */
+class EXPORT_DECL AccessLogger : public Logger {
+private:
+ AccessLogger();
+ virtual ~AccessLogger();
+
+public:
+/**
+ * Gets a logger object with parameters obtained from the configuration manager
+ */
+static AccessLogger *GetAccessLogger();
+
+/**
+ * Writes an access log entry
+ *
+ * @param hostName The IP address or host name of the requestor
+ * @param userName The authenticated user name; NULL or "" if not authenticated
+ * @param requestName The name of the requested function
+ * @param status The status returned to the client
+ * @param responseLength The number of bytes returned to the client
+ * @return 0 on success
+ */
+int Log( const char *hostName,
+ const char *userName,
+ const char *requestName,
+ int status,
+ int responseLength );
+
+/**
+ * Initializes the object with parameters from the Config Manager
+ *
+ * @param configName The name of the configuration entry to use
+ * @return 0 on success
+ */
+ int Initialize( const char *configName );
+
+/**
+ * Flush any unwritten buffers
+ */
+void Flush();
+
+protected:
+/**
+ * Gets a formatted timestamp
+ *
+ * @param now The current time
+ * @param buffer Buffer to put time in
+ * @return A formatted timestamp
+ */
+char *GetTimeStamp( struct tm *now, char *buffer );
+
+private:
+ char *m_buffer;
+ int m_bufferIndex;
+ int m_bufferTime;
+ int m_bufferSize;
+ time_t m_lastWrite;
+ char m_gmtOffset[16];
+};
+
+#endif // __ACCESS_LOGGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/Auth.h b/base/tps/src/include/httpClient/httpc/Auth.h
new file mode 100644
index 000000000..72a5f77ee
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Auth.h
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_AUTH_H__
+#define __PS_AUTH_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "ldap.h"
+
+class PSConfig;
+class Pool;
+class PoolNode;
+
+/**
+ * Utility classes for authentication and authorization
+ *
+ * @author rweltman@netscape.com
+ * @version 1.0
+ */
+
+/**
+ * Maintains a pool of LDAP connections; not yet implemented as a pool
+ */
+class LDAPConnectionPool {
+public:
+ LDAPConnectionPool( const char *host, int port, int poolSize );
+ virtual ~LDAPConnectionPool() {}
+ int Initialize();
+ PoolNode *GetConnection();
+ PoolNode *GetAuthenticatedConnection( const char *binddn,
+ const char *bindpwd );
+ void ReleaseConnection( PoolNode *node );
+protected:
+private:
+ const char* m_host;
+ int m_port;
+ int m_size;
+ Pool *m_pool;
+ bool m_initialized;
+};
+
+/**
+ * Produces an authenticator for an auth domain and authenticates
+ */
+class EXPORT_DECL Authenticator {
+public:
+ virtual int Authenticate( const char *username,
+ const char *password,
+ char *&actualID ) = 0;
+ static Authenticator *GetAuthenticator( const char *domain );
+};
+
+class EXPORT_DECL LDAPAuthenticator:public Authenticator {
+public:
+ LDAPAuthenticator();
+ virtual ~LDAPAuthenticator();
+ virtual int Authenticate( const char *username,
+ const char *password,
+ char *&dn );
+
+protected:
+ static int GetHashSize();
+ char *CheckCache( const char *username,
+ const char *password );
+ void UpdateCache( const char *username,
+ const char *dn,
+ const char *password );
+ char *CreateHash( const char *password,
+ char *hash,
+ int maxChars );
+ /**
+ * Returns the DN corresponding to a username, if any
+ *
+ * @param username The user name to look up
+ * @param status The status of an LDAP search, if any
+ * @return The corresponding DN, or NULL if no DN found
+ */
+ char *GetUserDN( const char *username, int& status );
+
+private:
+ LDAPConnectionPool *m_pool;
+ const char* m_host;
+ int m_port;
+ const char* m_binddn;
+ const char* m_bindpassword;
+ const char* m_basedn;
+ const char* m_searchfilter;
+ const char* m_searchscope;
+ int m_nsearchscope;
+ char* m_attrs[2];
+ StringKeyCache *m_cache;
+};
+
+class EXPORT_DECL LDAPAuthorizer {
+public:
+ LDAPAuthorizer();
+ virtual ~LDAPAuthorizer();
+ static LDAPAuthorizer *GetAuthorizer();
+ virtual int Authorize( const char *dn,
+ const char *pwd,
+ const char *methodName );
+
+protected:
+ int GetLdapConnection( LDAP** ld );
+ int CheckCache( const char *username,
+ const char *methodName );
+ void UpdateCache( const char *username,
+ const char *methodName );
+
+private:
+ LDAPConnectionPool *m_pool;
+ const char* m_binddn;
+ const char* m_bindpassword;
+ const char* m_basedn;
+ const char* m_searchfilter;
+ const char* m_searchscope;
+ int m_nsearchscope;
+ char* m_attrs[2];
+ StringKeyCache *m_cache;
+};
+
+#endif // __PS_HELPER_H__
diff --git a/base/tps/src/include/httpClient/httpc/ByteBuffer.h b/base/tps/src/include/httpClient/httpc/ByteBuffer.h
new file mode 100644
index 000000000..cd5568c35
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ByteBuffer.h
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __BYTE_BUFFER_H
+#define __BYTE_BUFFER_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ByteBuffer.h 1.000 06/12/2002
+ *
+ * A byte buffer class
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+typedef unsigned char Byte;
+
+class EXPORT_DECL ByteBuffer {
+public:
+ /**
+ * Constructor
+ */
+ ByteBuffer();
+
+ /**
+ * Destructor
+ */
+ virtual ~ByteBuffer();
+
+public:
+ /**
+ * Reads a single byte from the buffer
+ *
+ * @param b byte returned
+ * @return 0 on success
+ */
+ int GetByte(Byte* b);
+
+ /**
+ * Reads a number of bytes as specified by size from the buffer
+ *
+ * @param size bytes to read
+ * @param buf bytes read
+ * @return 0 on success
+ */
+ int GetBytes(int size, Byte* buf);
+
+ /**
+ * Reads a short value from the buffer
+ *
+ * @param s a short value
+ * @return 0 on success
+ */
+ int GetShort(unsigned short* s);
+
+ /**
+ * Reads a integer value from the buffer
+ *
+ * @param i a integer value
+ * @return 0 on success
+ */
+ int GetInt(unsigned int* i);
+
+ /**
+ * Reads a string of given length from the buffer
+ *
+ * @param len length of the string
+ * @param str string value
+ * @return 0 on success
+ */
+ int GetString(int len, char* str);
+
+ /**
+ * Writes a single byte to the buffer
+ *
+ * @param b byte to set
+ * @return 0 on success
+ */
+ int SetByte(Byte b);
+
+ /**
+ * Writes a number of bytes as specified by size to the buffer
+ *
+ * @param size number of bytes
+ * @param buf bytes to write
+ * @return 0 on success
+ */
+ int SetBytes(int size, Byte* buf);
+
+ /**
+ * Writes a short value to the buffer
+ *
+ * @param s a short value
+ * @return 0 on success
+ */
+ int SetShort(unsigned short s);
+
+ /**
+ * Writes an integer value to the buffer
+ *
+ * @param i an integer value
+ * @return 0 on success
+ */
+ int SetInt(unsigned int i);
+
+ /**
+ * Writes a string to the buffer
+ *
+ * @param str a string to write
+ * @return 0 on success
+ */
+ int SetString(char* str);
+
+ /**
+ * Gets the current position in the buffer
+ *
+ * @param pos position in the buffer
+ * @return 0 on success
+ */
+ int GetPosition(unsigned long* pos);
+
+ /**
+ * Sets the pointer to the position specified by pos in the buffer
+ *
+ * @param pos position to be set in the buffer
+ * @return 0 on success
+ */
+ int SetPosition(unsigned long pos);
+
+ /**
+ * Gets total number of bytes in the buffer
+ *
+ * @param total total number of bytes
+ * @return 0 on success
+ */
+ int GetTotalBytes(unsigned long* total);
+
+ /**
+ * Dumps the buffer to the debug log
+ *
+ * @param logLevel Lowest debug level for which the log should be dumped
+ */
+ void Dump(int logLevel);
+
+private:
+ int SetTotalBytes(unsigned long size, unsigned long allocUnit);
+ int ValidateBuffer(unsigned long increment);
+
+private:
+ Byte* m_buffer;
+ Byte* m_bufferEnd;
+ Byte* m_bufPtr;
+ Byte* m_maxPtr;
+};
+
+#endif // __BYTE_BUFFER_H
+
diff --git a/base/tps/src/include/httpClient/httpc/CERTUtil.h b/base/tps/src/include/httpClient/httpc/CERTUtil.h
new file mode 100644
index 000000000..1f26efbb8
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/CERTUtil.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _CERT_UTIL_H
+#define _CERT_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * NSS CERT utility functions
+ */
+class EXPORT_DECL CERTUtil {
+private:
+ /**
+ * Constructor - can't be instantiated
+ */
+ CERTUtil() {}
+
+ /**
+ * Destructor
+ */
+ ~CERTUtil() {}
+
+public:
+ static CERTCertificate* FindCertificate(const char* nickname);
+ static SECItem* FindExtension(CERTCertificate* cert, const SECItem* oid);
+ static int GetAsInteger(SECItem* item);
+ static char* GetAsString(SECItem* item);
+ static bool IsCertExpired(CERTCertificate* cert);
+};
+
+#endif // _CERT_UTIL_H
+
diff --git a/base/tps/src/include/httpClient/httpc/Cache.h b/base/tps/src/include/httpClient/httpc/Cache.h
new file mode 100644
index 000000000..bc68f04df
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Cache.h
@@ -0,0 +1,226 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _CACHE_H_
+#define _CACHE_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/Iterator.h"
+
+/**
+ * Simple cache implementation
+ */
+
+/**
+ * Contains a cache entry and housekeeping info
+ */
+class CacheEntry {
+public:
+ /**
+ * Constructor
+ *
+ * @param key Pointer to the key being cached
+ * @param data Pointer to the data being cached
+ */
+ CacheEntry( const char *key, void *data );
+ /**
+ * Destructor
+ */
+ virtual ~CacheEntry();
+
+ /**
+ * Returns a pointer to the cached key
+ *
+ * @return A pointer to the cached key
+ */
+ const char *GetKey();
+
+ /**
+ * Returns a pointer to the cached data
+ *
+ * @return A pointer to the cached data
+ */
+ void *GetData();
+ /**
+ * Returns the time when the entry was created
+ *
+ * @return The time when the entry was created
+ */
+ long GetStartTime();
+
+private:
+ char *m_key;
+ void *m_data;
+ time_t m_startTime;
+};
+
+/**
+ * Contains a generic cache; this is currently an abstract base class
+ */
+class Cache {
+protected:
+ /**
+ * Default constructor
+ */
+ Cache();
+
+public:
+ /**
+ * Constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cached is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+ Cache( const char *name, int ttl, bool implictLock = false );
+
+ /**
+ * Destructor
+ */
+ virtual ~Cache();
+
+ /**
+ * Returns the number of entries in the cache
+ *
+ * @return The number of entries in the cache
+ */
+ virtual int GetCount();
+
+ /**
+ * Acquires a read lock on the cache. Multiple threads may simultaneously
+ * have a read lock, but attempts to acquire a read lock will block
+ * if another thread already has a write lock. It is illegal to request
+ * a read lock if the thread already has one.
+ */
+ void ReadLock();
+
+ /**
+ * Acquires a write lock on the cache. Only one thread may have a write
+ * lock at any given time; attempts to acquire a write lock will block
+ * if another thread already has one. It is illegal to request
+ * a write lock if the thread already has one.
+ */
+ void WriteLock();
+
+ /**
+ * Releases a read or write lock that the thread has on the cache
+ */
+ void Unlock();
+
+protected:
+ /**
+ * Initializes the object - to be called from the constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cached is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+ void Initialize( const char *name, int ttl, bool implictLock );
+
+protected:
+ const char *m_name;
+ int m_ttl;
+ PLHashTable* m_cache;
+ PRRWLock* m_cacheLock;
+ bool m_implicitLock;
+};
+
+/**
+ * Contains a cache where the keys are strings
+ */
+class StringKeyCache : public Cache {
+public:
+ /**
+ * Constructor
+ *
+ * @param name of the cache
+ * @param ttl Time to live of each cache entry
+ * @param implicitLock true if the Cached is to do locking internally
+ * when required; false if the caller will take responsibility
+ */
+ StringKeyCache( const char *name, int ttl, bool implictLock = false );
+
+ /**
+ * Destructor
+ */
+ virtual ~StringKeyCache();
+
+ /**
+ * Returns a cache entry
+ *
+ * @param key The name of the cache entry
+ * @return The corresponding cache entry, or NULL if not found
+ */
+ CacheEntry *Get( const char *key );
+
+ /**
+ * Adds a cache entry
+ *
+ * @param key The name of the cache entry; an internal copy is made
+ * @param value The value of the cache entry
+ * @return The corresponding cache entry, or NULL if it couldn't be added
+ */
+ CacheEntry *Put( const char *key, void *value );
+
+ /**
+ * Removes a cache entry; does not free the entry object
+ *
+ * @param key The name of the cache entry
+ * @return The corresponding cache entry, or NULL if not found
+ */
+ CacheEntry *Remove( const char *key );
+
+ /**
+ * Allocates and returns a list of keys in the cache
+ *
+ * @param keys Returns an array of names; each name and also the
+ * array itself are to be freed by the caller with delete
+ * @return The number of keys found
+ */
+ int GetKeys( char ***keys );
+
+ /**
+ * Returns an iterator over keys in the cache
+ *
+ * @return An iterator over keys in the cache
+ */
+ Iterator *GetKeyIterator();
+
+};
+
+#endif // _CACHE_H_
diff --git a/base/tps/src/include/httpClient/httpc/Connection.h b/base/tps/src/include/httpClient/httpc/Connection.h
new file mode 100644
index 000000000..5619d0dff
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Connection.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __CONNECTION_H
+#define __CONNECTION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Connection.h 1.000 06/12/2002
+ *
+ * Base class for all connection types. A user should extend this class
+ * and provide its protocol specific implementation
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL Connection {
+ friend class ServerConnection;
+public:
+ /**
+ * Constructor
+ */
+ Connection();
+
+ /**
+ * Destructor
+ */
+ virtual ~Connection();
+
+public:
+ /**
+ * Initiates a connection to a specified host.
+ *
+ * @param host server host name
+ * @param port server port
+ * @return 0 on success, negative error code otherwise
+ */
+ int Connect(const char* host, int port);
+
+ /**
+ * Reads specified number of bytes from the connection. The connection
+ * is locked for the period it is being read.
+ *
+ * @param buf buffer to read into
+ * @param size number of bytes to read
+ * @param timeout timeout before the read terminates
+ * @return number of bytes actually read
+ */
+ int Read(void* buf, int size, long timeout);
+
+ /**
+ * Writes specified number of bytes to the connection. The connection
+ * is locked for the period it is being written.
+ *
+ * @param buf buffer to write from
+ * @param size number of bytes to write
+ * @param timeout timeout before the write terminates
+ * @return number of bytes actually written
+ */
+ int Write(void* buf, int size, long timeout);
+
+ /**
+ * Gets the status of the connection
+ *
+ * @return true if closed, false otherwise
+ */
+ bool IsClosed();
+
+ /**
+ * Closes the connection
+ */
+ void Close();
+
+protected:
+ Socket* m_socket;
+
+private:
+ PRLock* m_lock;
+ bool m_closed;
+};
+
+#endif // __CONNECTION_H
+
diff --git a/base/tps/src/include/httpClient/httpc/ConnectionListener.h b/base/tps/src/include/httpClient/httpc/ConnectionListener.h
new file mode 100644
index 000000000..0b55900b3
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ConnectionListener.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __CONNECTION_LISTENER_H
+#define __CONNECTION_LISTENER_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ConnectionListener.h 1.000 06/12/2002
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL ConnectionListener {
+public:
+ virtual int OnConnectionReceived(Connection*) = 0;
+ virtual int OnDataAvailable(Connection*) = 0;
+ virtual int OnConnectionClosed(Connection*) = 0;
+ virtual int OnConnectionError(Connection*, int, const char*) = 0;
+};
+
+#endif // __CONNECTION_LISTENER_H
+
+
diff --git a/base/tps/src/include/httpClient/httpc/DebugLogger.h b/base/tps/src/include/httpClient/httpc/DebugLogger.h
new file mode 100644
index 000000000..37c7971c0
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/DebugLogger.h
@@ -0,0 +1,185 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __DEBUG_LOGGER_H__
+#define __DEBUG_LOGGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+struct PLHashTable;
+
+/**
+ * The DebugLogger class writes debug log entries conditionally. A single
+ * instance can be shared among modules or different modules can have
+ * their own instances. In either case, the log level can be changed
+ * globally across all instances with a single function call. All instances
+ * write through a singleton to ensure coordination in writing to a single
+ * file.
+ */
+class EXPORT_DECL DebugLogger {
+public:
+private:
+ DebugLogger( const char *moduleName );
+ virtual ~DebugLogger();
+
+public:
+/**
+ * Gets a logger object for a particular module. Provide a module name
+ * if there will be more than one logger object in use, with each module
+ * having its own instance. Pass NULL if a single logger object will be
+ * shared throughout the application.
+ *
+ * @param moduleName Name of a module
+ * @return A logger instance
+ */
+static DebugLogger *GetDebugLogger( const char *moduleName = NULL );
+
+/**
+ * Sets global default values for loggers; the values are assigned to
+ * DebugLogger objects created after this call returns
+ *
+ * @param configParams A table of key-value pairs to assign configuration
+ * parameters
+ */
+static void SetDefaults( PLHashTable *configParams );
+
+/**
+ * Sets the log level for this object
+ *
+ * @param logLevel Log level setting for the module
+ */
+void SetLogLevel( int logLevel );
+
+/**
+ * Gets the log level for this object
+ *
+ * @return logLevel Log level setting for the object
+ */
+int GetLogLevel();
+
+/**
+ * Sets the log level for a particular module or all modules
+ * in all debug logger objects
+ *
+ * @param logLevel Log level setting for the module
+ * @param moduleName Name of the module (does not need to be known before
+ * this call); if NULL, the level is applied to all modules
+ */
+static void SetGlobalLogLevel( int logLevel,
+ const char *moduleName = NULL );
+
+/**
+ * Gets the log level for a particular module
+ *
+ * @param moduleName Name of the module
+ * @return logLevel Log level setting for the module
+ */
+static int GetLogLevel( const char *moduleName );
+
+/**
+ * Writes a debug log entry if logLevel is equal to or higher than the
+ * logLevel setting of the object
+ *
+ * @param logLevel One of the log levels defined above
+ * @param className The name of the class recording the log entry
+ * @param methodName The name of the method that is calling this log method
+ * @param fmt A sprintf format string for the remaining arguments
+ * @param ... A varargs list of things to log
+ * @return 0 on success
+ */
+int Log( int logLevel,
+ const char *className,
+ const char *methodName,
+ const char *fmt, ... );
+
+/**
+ * Writes a trace entry if the logLevel setting of the object is FINER or FINEST
+ *
+ * @param className The name of the class recording the log entry
+ * @param methodName The name of the method that is calling this log method
+ * @param args An optional descriptive string
+ * @return 0 on success
+ */
+int Entering( const char *className,
+ const char *methodName,
+ const char *args = NULL );
+
+/**
+ * Writes a trace entry if the logLevel setting of the object is FINER or FINEST
+ *
+ * @param className The name of the class recording the log entry
+ * @param methodName The name of the method that is calling this log method
+ * @param args An optional descriptive string
+ * @return 0 on success
+ */
+int Exiting( const char *className,
+ const char *methodName,
+ const char *args = NULL );
+/**
+ * Shut down, flushing any buffers and releasing resources
+ */
+void Close();
+
+/**
+ * Shut down, flushing any buffers and releasing resources
+ */
+static void CloseAll();
+
+protected:
+/**
+ * Sets the log level for a particular module
+ *
+ * @param logLevel Log level setting for the module
+ * @param moduleName Name of the module (does not need to be known before
+ * this call)
+ */
+static void SetOneLogLevel( int logLevel,
+ const char *moduleName );
+
+private:
+/**
+ * Initializes the object with parameters from the Config Manager
+ *
+ * @param configName The name of the configuration entry to use
+ * @return 0 on success
+ */
+static int Initialize( const char *configName );
+
+private:
+ int m_level;
+ char *m_module;
+};
+
+#endif // __DEBUG_LOGGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/Defines.h b/base/tps/src/include/httpClient/httpc/Defines.h
new file mode 100644
index 000000000..90af8e3d0
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Defines.h
@@ -0,0 +1,219 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __DEFINES_H__
+#define __DEFINES_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Defines.h 1.000 04/30/2002
+ *
+ * This file contains global constants for the Presence Server
+ *
+ * @author Rob Weltman
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+
+// ??? SSR till we have server logging functionality
+#ifdef _DEBUG
+#define PS_LOG_LEVEL PS_LOG_LEVEL_DEBUG
+#else
+#define PS_LOG_LEVEL PS_LOG_LEVEL_WARN
+#endif
+
+#define PS_SERVER_CONFIG_FILE "psserver.conf"
+
+// Configuration file for WASP SOAP server
+#define SOAP_CONFIG_FILE "config.xml"
+
+#define CLIENT_DESCRIPTION "Netscape Presence Server"
+#define SERVER_VERSION "1.0"
+
+// Key to SoapAction field in WASP call context
+#define HEADER_FIELD_SOAPACTION "SOAP_ACTION"
+// Key to status field in WASP call context
+#define HEADER_STATUS "HEADER_STATUS"
+
+// Keys to client parameters passed through the call context
+
+#define SERVER_URL "SERVER_URL"
+#define CERTIFICATE_DIRECTORY "CERTIFICATE_DIRECTORY"
+#define CERTIFICATE_NICKNAME "CERTIFICATE_NICKNAME"
+#define DO_SERVER_CERT_VALIDATION "DO_SERVER_CERT_VALIDATION"
+#define CERTIFICATE_PASSWORD "CERTIFICATE_PASSWORD"
+
+#define STRING_ON_LINE "ONLINE"
+#define STRING_OFF_LINE "OFFLINE"
+
+#define BATCH_RESULT_SIZE 1000
+#define MAX_ATTR_SIZE 5
+
+#define NAME_BUFFER_LENGTH 256
+#define ATTR_BUFFER_LENGTH 256
+
+// Static strings for the attributes we support
+#define BUDDY_ATTRIBUTE_ON_LINE_STATUS "onlinestatus"
+#define BUDDY_ATTRIBUTE_IDLE_TIME "idletime"
+#define BUDDY_ATTRIBUTE_ON_LINE_SINCE "onlinesince"
+#define BUDDY_ATTRIBUTE_AWAY_MESSAGE "awaymessage"
+#define BUDDY_ATTRIBUTE_PROFILE "profile"
+#define BUDDY_ATTRIBUTE_CONNECTION_TYPE "connectiontype"
+#define BUDDY_ATTRIBUTE_CAPABILITIES "capabilities"
+
+#define PS_LOG_LEVEL_DEBUG 0
+#define PS_LOG_LEVEL_WARN 1
+#define PS_LOG_LEVEL_ERROR 2
+
+
+// Presence Server config parameters in the bootstrap configuration file
+// psserver.conf
+#define INSTANCE_ID "instanceid"
+#define HOST_ID "hostid"
+#define DOMAIN_NAME "domainname"
+#define SERVER_HOST "serverhost"
+#define SERVER_PORT "serverport"
+#define BINDDN "binddn"
+#define BINDPASSWORD "bindpassword"
+
+// dn, cn constants
+#define PS_ATTRIBUTE_DN "dn"
+#define PS_ATTRIBUTE_CN "cn"
+
+// nsPlugin class required attributes
+#define PLUGIN_DN "dn"
+#define PLUGIN_CN "cn"
+#define PLUGIN_ID "nspluginid"
+#define PLUGIN_PATH "nspluginpath"
+#define PLUGIN_INIT_FUNC "nsplugininitfunc"
+#define PLUGIN_ENABLED "nspluginenabled"
+#define PLUGIN_VERSION "nspluginversion"
+#define PLUGIN_DESC "nsplugindescription"
+
+// Operations when updating server
+#define PS_OPERATION_ADD 1
+#define PS_OPERATION_DELETE 2
+#define PS_OPERATION_REPLACE 4
+
+// Names of LDAP attributes for the LDAP data source
+#define LDAP_SOURCE_DN "dn"
+#define LDAP_SOURCE_CN "cn"
+#define LDAP_SOURCE_GROUP_NAME "nspsgroupname"
+#define LDAP_SOURCE_SERVER_ADDRESS "nsserveraddress"
+#define LDAP_SOURCE_SERVER_PORT "nsserverport"
+#define LDAP_SOURCE_BIND_DN "nsbinddn"
+#define LDAP_SOURCE_BIND_PASSWORD "nsbindpassword"
+#define LDAP_SOURCE_BASE_DN "nsbasedn"
+#define LDAP_SOURCE_SEARCH_FILTER "nssearchfilter"
+#define LDAP_SOURCE_SEARCH_SCOPE "nssearchscope"
+#define LDAP_SOURCE_IM_ID "nsimattributetype"
+#define LDAP_SOURCE_SEARCHABLE_ATTRIBUTES "nssearchableattributes"
+#define LDAP_SOURCE_ENABLE_SSL "nsenablessl"
+
+
+// Configuration attribute name for max results to return
+#define SEARCH_MAX_RESULTS "nsmaxresults"
+
+// Max results to return if SEARCH_MAX_RESULTS is not defined
+#define DEFAULT_MAX_RESULTS 1000
+
+// Names of configuration clusters
+#define CONFIG_BASE "ConfigBase"
+#define CONFIG_AUTHORIZE "ConfigAuthorize"
+#define CONFIG_ACCESS_LOG "ConfigAccessLog"
+#define CONFIG_ERROR_LOG "ConfigErrorLog"
+#define CONFIG_DEBUG_LOG "ConfigDebugLog"
+#define CONFIG_SERVER_LOCAL "ConfigServerLocal"
+
+// Configuration attributes for loggers
+#define LOG_ACCESS_DIR "nslogdir"
+#define LOG_ERROR_DIR "nslogdir"
+#define LOG_DEBUG_DIR "nslogdir"
+#define LOG_ACCESS_BUFFER_SIZE "nslogbuffersize"
+#define LOG_ACCESS_BUFFER_TIME "nslogbuffertime"
+#define LOG_ACCESS_ROTATION_TIME "nslogrotationtime"
+#define LOG_ACCESS_ROTATION_SIZE "nslogrotationsize"
+#define LOG_ACCESS_MAX_LOGS "nslogmaxlogs"
+#define LOG_ERROR_ROTATION_TIME "nslogrotationtime"
+#define LOG_ERROR_ROTATION_SIZE "nslogrotationsize"
+#define LOG_ERROR_MAX_LOGS "nslogmaxlogs"
+#define LOG_DEBUG_LEVEL "nsloglevel"
+#define LOG_DEBUG_FORMAT "nslogformat"
+
+// Static constants for logging
+#define LOG_ACCESS_FILENAME "access"
+#define LOG_ERROR_FILENAME "error"
+#define LOG_DEBUG_FILENAME "debug"
+
+// Log level definitions
+
+typedef enum {
+ LOGLEVEL_OFF = 0,
+ LOGLEVEL_SEVERE = 1,
+ LOGLEVEL_WARNING = 2,
+ LOGLEVEL_INFO = 3,
+ LOGLEVEL_CONFIG = 4,
+ LOGLEVEL_FINE = 5,
+ LOGLEVEL_FINER = 6,
+ LOGLEVEL_FINEST = 7,
+ LOGLEVEL_ALL = 100
+} LogLevel;
+
+// Config params
+#define CONFIG_DEFAULT_BUFFER_LEN 2048
+#define BASE_CONFIG_DN "cn=Netscape Presence Server,cn=Server Group,cn=%s,ou=%s,o=NetscapeRoot"
+
+// COOL Service params
+#define COOL_SERVICE_SERVER_HOST "CoolServerHost"
+#define COOL_SERVICE_SERVER_PORT "CoolServerPort"
+#define COOL_SERVICE_LOGIN_NAME "CoolLoginName"
+#define COOL_SERVICE_LOGIN_PSWD "CoolLoginPswd"
+
+#define COOL_DEFAULT_SERVER_HOST "coolkey.fedora.redhat.com"
+#define COOL_DEFAULT_SERVER_PORT "5190"
+
+// Key to service ID in global config
+#define SERVICE_TYPE "service_type"
+
+#define MODULE_IM_SERVICE "ModuleIMService"
+#define MODULE_DATA_SOURCE "ModuleDataSource"
+
+#define PROVIDER_BATCH_SIZE_ATTR "nsbatchsize"
+#define PROVIDER_UPDATE_INTERVAL_ATTR "nsupdateinterval"
+
+#define THREAD_POOL_TASK_NAME "ThreadPoolTask"
+
+#endif // __DEFINES_H__
diff --git a/base/tps/src/include/httpClient/httpc/ErrorLogger.h b/base/tps/src/include/httpClient/httpc/ErrorLogger.h
new file mode 100644
index 000000000..df2617b06
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ErrorLogger.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __ERROR_LOGGER_H__
+#define __ERROR_LOGGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/Logger.h"
+
+/**
+ * A singleton class for writing to an error log
+ */
+class EXPORT_DECL ErrorLogger : public Logger {
+private:
+ ErrorLogger();
+ virtual ~ErrorLogger();
+
+public:
+ /**
+ * Gets a logger object with parameters obtained from the
+ * configuration manager
+ */
+ static ErrorLogger *GetErrorLogger();
+
+ /**
+ * Writes an error log entry
+ *
+ * @param level SEVERE, WARNING, or INFO
+ * @param errorCode An error code
+ * @param fmt A message to be written to the log
+ * @return 0 on success
+ */
+ int Log( int level,
+ int errorCode,
+ const char *fmt,
+ ... );
+
+ /**
+ * Initializes the object with parameters from the Config Manager
+ *
+ * @param configName The name of the configuration entry to use
+ * @return 0 on success
+ */
+ int Initialize( const char *configName );
+
+protected:
+ /**
+ * Writes the fixed argument part of an error log entry
+ *
+ * @param fp File pointer to write to
+ * @param level SEVERE, WARNING, or INFO
+ * @param errorCode An error code
+ * @return 0 on success
+ */
+ int LogProlog( FILE *fp,
+ int level,
+ int errorCode );
+};
+
+#endif // __ERROR_LOGGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/Iterator.h b/base/tps/src/include/httpClient/httpc/Iterator.h
new file mode 100644
index 000000000..9b15a93e2
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Iterator.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _ITERATOR_H_
+#define _ITERATOR_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Base class for iterators
+ */
+
+class EXPORT_DECL Iterator {
+public:
+ /**
+ * Returns true if there is at least one more element
+ *
+ * @return true if there is at least one more element
+ */
+ virtual bool HasMore() = 0;
+
+ /**
+ * Returns the next element, if any
+ *
+ * @return The next element, if any, or NULL
+ */
+ virtual void *Next() = 0;
+};
+
+#endif // _ITERATOR_H_
diff --git a/base/tps/src/include/httpClient/httpc/LogRotationTask.h b/base/tps/src/include/httpClient/httpc/LogRotationTask.h
new file mode 100644
index 000000000..eed098b6b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/LogRotationTask.h
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __LOG_ROTATION_TASK_H__
+#define __LOG_ROTATION_TASK_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/ScheduledTask.h"
+
+/**
+ * Log rotation task in Presence Server
+ */
+
+class EXPORT_DECL LogRotationTask: public ScheduledTask {
+public:
+ /**
+ * Constructor - creates an initialized task for log rotation
+ *
+ * @param name Name of task
+ * @param fileName Name of file to rotate
+ * @param startTime Time when the file is to be rotated
+ * @param maxLogs Max logs to keep
+ * @param interval Time between rotations
+ * @param fp File pointer for log file
+ * @param lock Lock for writing to log file
+ */
+ LogRotationTask( const char *name,
+ const char *fileName,
+ time_t startTime,
+ int maxLogs,
+ int interval,
+ FILE **fp,
+ PRLock *lock );
+ /**
+ * Destructor
+ */
+ virtual ~LogRotationTask();
+ /**
+ * Returns a copy of the task
+ *
+ * @return A copy of the task
+ */
+ virtual ScheduledTask *Clone();
+ /**
+ * Executes the task
+ *
+ * @return 0 on successfully starting the task
+ */
+ virtual int Start();
+
+protected:
+ /**
+ * Composes a file name from a base name and a time value
+ *
+ * @param filename The base file name (may be a path)
+ * @param ltime The time value
+ * @param outbuf Returns the composed file name
+ * @return 0 on success
+ */
+ int CreateFilename( const char *filename,
+ time_t ltime,
+ char *outbuf );
+ /**
+ * Extracts the folder and base name components of a file path
+ *
+ * @param fileName The full file path to examine
+ * @param dirName A buffer in which to place the folder found
+ * @param baseName A buffer in which to place the base name found
+ */
+ static void GetPathComponents( const char *fileName,
+ char *dirName,
+ char *baseName );
+
+ /**
+ * Counts the number of files with the same initial path as fileName
+ * (the same folder and the same base pattern)
+ *
+ * @param fileName The file name to compare (including a folder)
+ * @return The number of matching files
+ */
+ static int CountFiles( const char *fileName );
+
+ /**
+ * Purges (deletes) files with the same initial path as fileName
+ * (the same folder and the same base pattern)
+ *
+ * @param fileName The file name to compare (including a folder)
+ * @param maxLogs The number of files to purge to
+ * @return The number of files purged
+ */
+ static int PurgeLogs( const char *fileName, int maxLogs );
+
+ char *m_fileName;
+ int m_maxLogs;
+ FILE **m_fp;
+ PRLock *m_lock;
+};
+
+#endif // __LOG_ROTATION_TASK_H__
diff --git a/base/tps/src/include/httpClient/httpc/Logger.h b/base/tps/src/include/httpClient/httpc/Logger.h
new file mode 100644
index 000000000..b41d5dfbf
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Logger.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __LOGGER_H__
+#define __LOGGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <time.h>
+
+struct PRLock;
+class LogRotationTask;
+
+/**
+ * A base class for writing to a log
+ */
+class EXPORT_DECL Logger {
+
+protected:
+ /**
+ * Constructor
+ */
+ Logger();
+
+ /**
+ * Destructor
+ */
+ virtual ~Logger();
+
+ /**
+ * Parses a time string in HH:MM format into a time_t for the next
+ * occurrence of the time
+ *
+ * @param timeString A time string in HH:MM format
+ * @return A time_t for the next occurrence of the time, or -1 if the
+ * string is not in a valid format
+ */
+ time_t ParseTime( const char *timeString );
+
+ /**
+ * Creates a time-of-day rotation task
+ *
+ * @param taskName Name of task
+ * @param filename Name of log file
+ * @param rotationTime Time of day to rotate at
+ * @return Rotation task on success
+ */
+ LogRotationTask *CreateRotationTask( const char *taskName,
+ const char *filename,
+ const char *rotationTime );
+
+public:
+
+ /**
+ * Shut down, flushing any buffers and releasing resources
+ */
+ void Close();
+ /**
+ * Gets the local time of day
+ *
+ * @param now The current local time of day
+ */
+ static void GetLocalTime( struct tm *now );
+
+protected:
+ int m_rotationSize;
+ time_t m_rotationTime;
+ int m_maxLogs;
+ char *m_dir;
+ FILE *m_fp;
+ /**
+ * Lock for writing to the file
+ */
+ PRLock *m_fileLock;
+ /**
+ * Task that rotates a log file
+ */
+ LogRotationTask *m_rotator;
+ /**
+ * True if object has been successfully initialized
+ */
+ bool m_initialized;
+};
+
+#endif // __LOGGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/NSPRerrs.h b/base/tps/src/include/httpClient/httpc/NSPRerrs.h
new file mode 100644
index 000000000..2e131fd7a
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/NSPRerrs.h
@@ -0,0 +1,160 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * 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 is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/NSPRerrs.h
+ */
+
+/* General NSPR 2.0 errors */
+/* Caller must #include "prerror.h" */
+
+ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." )
+ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." )
+ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." )
+ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." )
+ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." )
+ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." )
+ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." )
+ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." )
+ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." )
+ER2( PR_IO_ERROR, "I/O function error." )
+ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." )
+ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." )
+ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." )
+ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." )
+ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." )
+ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." )
+ER2( PR_IS_CONNECTED_ERROR, "Already connected." )
+ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." )
+ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." )
+ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." )
+ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." )
+ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." )
+ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." )
+ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." )
+ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." )
+ER2( PR_FIND_SYMBOL_ERROR,
+"Symbol not found in any of the loaded dynamic libraries." )
+ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." )
+ER2( PR_DIRECTORY_LOOKUP_ERROR,
+"A directory lookup on a network address has failed." )
+ER2( PR_TPD_RANGE_ERROR,
+"Attempt to access a TPD key that is out of range." )
+ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." )
+ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." )
+ER2( PR_NOT_SOCKET_ERROR,
+"Network operation attempted on non-network file descriptor." )
+ER2( PR_NOT_TCP_SOCKET_ERROR,
+"TCP-specific function attempted on a non-TCP file descriptor." )
+ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." )
+ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." )
+ER2( PR_OPERATION_NOT_SUPPORTED_ERROR,
+"The requested operation is not supported by the platform." )
+ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR,
+"The host operating system does not support the protocol requested." )
+ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." )
+ER2( PR_BUFFER_OVERFLOW_ERROR,
+"The value requested is too large to be stored in the data buffer provided." )
+ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." )
+ER2( PR_RANGE_ERROR, "Unused." )
+ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." )
+ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." )
+ER2( PR_FILE_TOO_BIG_ERROR,
+"Write would result in file larger than the system allows." )
+ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." )
+ER2( PR_PIPE_ERROR, "Unused." )
+ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." )
+ER2( PR_IS_DIRECTORY_ERROR,
+"Cannot perform a normal file operation on a directory." )
+ER2( PR_LOOP_ERROR, "Symbolic link loop." )
+ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." )
+ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." )
+ER2( PR_NOT_DIRECTORY_ERROR,
+"Cannot perform directory operation on a normal file." )
+ER2( PR_READ_ONLY_FILESYSTEM_ERROR,
+"Cannot write to a read-only file system." )
+ER2( PR_DIRECTORY_NOT_EMPTY_ERROR,
+"Cannot delete a directory that is not empty." )
+ER2( PR_FILESYSTEM_MOUNTED_ERROR,
+"Cannot delete or rename a file object while the file system is busy." )
+ER2( PR_NOT_SAME_DEVICE_ERROR,
+"Cannot rename a file to a file system on another device." )
+ER2( PR_DIRECTORY_CORRUPTED_ERROR,
+"The directory object in the file system is corrupted." )
+ER2( PR_FILE_EXISTS_ERROR,
+"Cannot create or rename a filename that already exists." )
+ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR,
+"Directory is full. No additional filenames may be added." )
+ER2( PR_INVALID_DEVICE_STATE_ERROR,
+"The required device was in an invalid state." )
+ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." )
+ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." )
+ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." )
+ER2( PR_FILE_SEEK_ERROR, "Seek error." )
+ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." )
+ER2( PR_IN_PROGRESS_ERROR,
+"Operation is still in progress (probably a non-blocking connect)." )
+ER2( PR_ALREADY_INITIATED_ERROR,
+"Operation has already been initiated (probably a non-blocking connect)." )
+
+#ifdef PR_GROUP_EMPTY_ERROR
+ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." )
+#endif
+
+#ifdef PR_INVALID_STATE_ERROR
+ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." )
+#endif
+
+#ifdef PR_NETWORK_DOWN_ERROR
+ER2( PR_NETWORK_DOWN_ERROR, "Network is down." )
+#endif
+
+#ifdef PR_SOCKET_SHUTDOWN_ERROR
+ER2( PR_SOCKET_SHUTDOWN_ERROR, "The socket was previously shut down." )
+#endif
+
+#ifdef PR_CONNECT_ABORTED_ERROR
+ER2( PR_CONNECT_ABORTED_ERROR, "TCP Connection aborted." )
+#endif
+
+#ifdef PR_HOST_UNREACHABLE_ERROR
+ER2( PR_HOST_UNREACHABLE_ERROR, "Host is unreachable." )
+#endif
+
+/* always last */
+ER2( PR_MAX_ERROR, "Placeholder for the end of the list" )
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddy.h b/base/tps/src/include/httpClient/httpc/PSBuddy.h
new file mode 100644
index 000000000..4d84b8727
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddy.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_BUDDY_H__
+#define __PS_BUDDY_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddy.h 1.000 05/15/2002
+ *
+ * Interface to store buddy online status attributes
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/15/2002
+ */
+class EXPORT_DECL PSBuddy {
+public:
+ PSBuddy() { };
+ virtual ~PSBuddy() { };
+ /**
+ * Gets the buddy name
+ *
+ * @return name of the buddy
+ */
+ virtual const char* GetName() = 0;
+
+ /**
+ * Gets online status of the buddy
+ *
+ * @return true if online, false otherwise
+ */
+ virtual bool IsOnline() = 0;
+
+ /**
+ * Gets the value of the specified online status attribute
+ *
+ * @param attribute type
+ * @param attribute value upon success
+ * @return 0 on Success, error code otherwise
+ */
+ virtual int GetStatus(const char*, char**) = 0;
+
+ /**
+ * Returns a copy of the buddy
+ *
+ * @return A copy of the buddy
+ */
+ virtual PSBuddy* Clone() = 0;
+};
+
+#endif // __PS_BUDDY_H__
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddyCache.h b/base/tps/src/include/httpClient/httpc/PSBuddyCache.h
new file mode 100644
index 000000000..3c880074b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddyCache.h
@@ -0,0 +1,123 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_BUDDY_CACHE_H__
+#define __PS_BUDDY_CACHE_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddyCache.h 1.000 04/30/2002
+ *
+ * Cache of PSBuddy objects containing online status
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class PSBuddyCache
+{
+public:
+
+ /**
+ * Constructor - initializes the internal cache
+ */
+ PSBuddyCache();
+
+ /**
+ * Destructor
+ */
+ virtual ~PSBuddyCache();
+
+ /**
+ * Adds a buddy to the cache. The old entry, if exists, is deleted
+ * from the cache
+ *
+ * @param name name of the new buddy
+ * @param buddy object containing onlinestatus attributes
+ * @return 0 on success
+ */
+ int AddBuddy(const char* name, PSBuddy* buddy);
+
+ /**
+ * Removes a buddy from the cache
+ *
+ * @param name name of the buddy to be removed
+ * @return 0 on success
+ */
+ int RemoveBuddy(const char* name);
+
+ /**
+ * Gets the buddy object
+ *
+ * @param name name of the new buddy
+ * @return object containing onlinestatus attributes, NULL if not found
+ */
+ PSBuddy* GetBuddy(const char* name);
+
+ /**
+ * Gets count of buddies in the cache
+ *
+ * @return count of buddies
+ */
+ int GetBuddyCount();
+
+ /**
+ * Gets all the screen names
+ *
+ * @param names On return, contains array of screen names
+ * @return number of screen names
+ */
+ int GetAllBuddies(char*** names);
+
+ /**
+ * Acquires a read lock on the cache. Multiple threads may simultaneously
+ * have a read lock, but attempts to acquire a read lock will block
+ * if another thread already has a write lock. It is illegal to request
+ * a read lock if the thread already has one.
+ */
+ void ReadLock();
+
+ /**
+ * Releases a read lock that the thread has on the cache
+ */
+ void Unlock();
+
+private:
+ StringKeyCache* m_buddies;
+};
+
+#endif // __PS_BUDDY_CACHE_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddyList.h b/base/tps/src/include/httpClient/httpc/PSBuddyList.h
new file mode 100644
index 000000000..49155a8a5
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddyList.h
@@ -0,0 +1,373 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_BUDDY_LIST_H__
+#define __PS_BUDDY_LIST_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddyList.h 1.000 05/21/2002
+ *
+ * This class maintains users information which are set for
+ * online status tracking. The online status of users are updated
+ * through a PSBuddyListener interface implemented by this class.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/21/2002
+ */
+class PSBuddyList :
+ public PSBuddyListener
+{
+private:
+
+ /**
+ * Constructor
+ */
+ PSBuddyList();
+
+ /**
+ * Destructor
+ */
+ virtual ~PSBuddyList();
+
+public:
+
+ /**
+ * Gets an instance of the class
+ */
+ static PSBuddyList* GetBuddyList();
+
+ public:
+
+ /**
+ * Save the users maintain by an instance of presence server
+ * to a local file in the BLT format
+ *
+ * @return 0 on succcess, negative error code otherwise
+ */
+ int SaveBuddyList();
+
+ /**
+ * Loads the users into an instance of presence server
+ * from a local file
+ *
+ * @return 0 on succcess, negative error code otherwise
+ */
+ int LoadBuddyList();
+
+ /**
+ * Sets a service provider. We currently support only one service
+ * provider in a presence server instance.
+ *
+ * @return 0 on succcess, negative error code otherwise
+ */
+ int RegisterService(PSBuddyService* service);
+
+ /**
+ * Gets the online status of a user along with the
+ * requested additional attributes
+ *
+ * @param group group name to which the user belongs
+ * @param name the screen name of the user to query status for
+ * @param nAttributes number of attributes
+ * @param attributes the names of the attributes of the user to return
+ * @param user upon return, filled with user attributes
+ * @return 0 on success, a negative error code on failure
+ */
+ int GetUserStatus( const char* group,
+ const char* name,
+ int nAttributes,
+ char** attributes,
+ PSUser** user );
+
+ /**
+ * Gets the online status of multiple users along with the requested
+ * additional attributes
+ *
+ * @param group group name to which the user belongs
+ * @param nUsers the number of screen names to status query for
+ * @param names the screen names of the users to query status for
+ * @param nAttributes number of attributes
+ * @param attributes the names of the attributes of the user to return
+ * @param user upon return, filled with user attributes
+ * @return 0 on success, a negative error code on failure
+ */
+ int GetMultipleUserStatus( const char* group,
+ int nUsers,
+ char** names,
+ int nAttributes,
+ char** attributes,
+ PSUser*** users );
+
+ /**
+ * Gets the screen names and attributes of users that match
+ * certain search criteria
+ *
+ * @param group group name to query from
+ * @param filter an LDAP-like search expression on
+ * presence status attributes
+ * @param nAttrbiutes number of attributes
+ * @param attributes the names of the attributes of the user to return
+ * @param user upon return, an array of users with
+ * requested attributes
+ * @return number of users returned, or a negative error code
+ */
+ int GetUsersByFilter( const char* group,
+ const char* filter,
+ int nAttributes,
+ char** attributes,
+ PSUser*** users );
+
+ /**
+ * Gets the screen names and attributes of users that match certain search
+ * criteria and sorts the results (currently only by entryId)
+ *
+ * @param group group name to query from
+ * @param filter an LDAP-like search expression on presence status
+ * attributes
+ * @param sortKey name of attribute to sort on
+ * @param sortKeyType 1 for numeric, 2 for string
+ * @param nAttributes number of attributes
+ * @param attributes the names of the attributes of the user to return
+ * @param user upon return, an array of users with requested
+ * attributes
+ * @return number of users returned, or a negative error code
+ */
+ int GetSortedUsersByFilter( const char* group,
+ const char* filter,
+ const char *sortKey,
+ int sortKeyType,
+ int nAttributes,
+ char** attributes,
+ PSUser*** users );
+
+ /**
+ * Gets the number of users who are online or offline in a group
+ *
+ * @param group Name of group to query; NULL or empty for all groups
+ * @param bOnline true to return the count of online users, false for offline
+ * @return Number of users, or a negative error code on failure
+ *
+ * Error Code(s):
+ * PS_UNKOWN_GROUP
+ */
+ int GetBuddyCount( const char* group, int bOnline );
+
+ /**
+ * Add a new group
+ *
+ * @param group name of the new group
+ * @param nAttributes number of attributes
+ * @param attributes attributes the group will support
+ * @return 0 on success, a negative error code on failure
+ */
+ int AddGroup( const char* group, int nAttributes, char** attributes );
+
+ /**
+ * Adds a user to be tracked.
+ *
+ * @param group name of the group to add the user in
+ * @param name screen name of the user to track
+ * @param nAttributes number of attributes
+ * @param attributes the attributes of the users to be stored
+ * @return on success, 0 or an error code
+ */
+ int AddUser( const char* group,
+ const char* name,
+ int nAttributes,
+ PSAttribute** attributes );
+
+ /**
+ * Adds a number of users to track.
+ *
+ * @param group name of the group to which the users belong
+ * @param nUsers number of users
+ * @param users names and attributes of users to track
+ * @return number of users added on success,
+ or a negative error code on failure
+ */
+ int AddUsers( const char* group,
+ int nUsers,
+ PSUser** users );
+
+ /**
+ * Removes a user to be tracked.
+ *
+ * @param group name of the group to which the user belongs
+ * @param name screen name of the user to be removed
+ * @return 0 on success, or a negative error code on failure
+ */
+ int RemoveUser( const char* group, const char* name );
+
+ /**
+ * Removes a number of users to be tracked.
+ *
+ * @param group name of the group to which the users belong
+ * @param nUsers number of users
+ * @param names screen name of the users to be removed
+ * @return number of users removed on success,
+ * or a negative error code on failure
+ */
+ int RemoveUsers( const char* group, int nUsers, char** names );
+
+ /**
+ * Removes a group.
+ *
+ * @param group name of the group to be removed
+ * @return number of users removed on success,
+ * or a negative error code on failure
+ *
+ * Error Code(s):
+ * PS_UNKNOWN_GROUP
+ */
+ int RemoveGroup(const char* group);
+
+ /**
+ * Gets the list of groups.
+ *
+ * @param groups upon return, array containing group names
+ * @return number of groups or 0 if no group present
+ *
+ * Error Code(s):
+ * PS_NO_GROUPS
+ */
+ int GetAllGroups(char*** groups);
+
+ /**
+ * Gets the users in a group(s).
+ *
+ * @param group name of the group to query
+ * @param users upon return, array of User objects
+ * @return number of users returned,
+ * or a negative error code on failure
+ */
+ int GetAllUsers( const char* group, PSUser*** users );
+
+ /**
+ * Gets the attributes supported by a group(s)
+ *
+ * @param group name of the group
+ * @param attributes upon return, array of attributes
+ * @return number of users removed on success,
+ * or a negative error code on failure
+ */
+ int GetSearchableAttributes( const char* group, char*** attributes );
+
+ // PSBuddyListener interface
+ /**
+ * Callback to notify buddy changes
+ *
+ * @param service the reporting buddy service
+ * @param buddy buddy object containing online status attributes
+ * @return 0 on success
+ */
+ int OnBuddyChanged(PSBuddyService* service, PSBuddy* buddy);
+
+ /**
+ * Callback to refresh the list of screen names to the buddy queue
+ *
+ * @param the reporting buddy service
+ * @return 0 on success
+ */
+ int OnRefreshList(PSBuddyService* service);
+
+ /**
+ * Removes a user from a group based on its entry Id
+ *
+ * @param group name of the group
+ * @param entryId user's entry id
+ * @return 0
+ */
+ int RemoveUserByEntryId(const char* group, char* entryId);
+
+protected:
+
+ /**
+ * Gets the max number of search results to return
+ *
+ * @return The max number of search results to return
+ */
+ int GetMaxSearchResults();
+
+private:
+
+ /**
+ * Parses the LDAP like filter and create a map object containing
+ * filter in the form of name-value pair
+ *
+ * @param filter LDAP like filter
+ * @param map array containing break up of filter into name-value pair
+ * @return 0 on success
+ */
+ int ParseFilter(const char* filter, PSAttribute*** map);
+
+ /**
+ * Checks whether a given string is NULL or ""
+ *
+ * @param value a string to be tested for NULL or ""
+ * @return true if NULL, false otherwise
+ */
+ bool IsNull(const char* value);
+
+ /**
+ * Prints buddy information
+ *
+ * @param buddy a buddy object containing online status attributes
+ * @return 0 on success
+ */
+ int DumpBuddy(PSBuddy* buddy);
+
+ /**
+ * Sorts a list of users based on a "entryId"
+ *
+ * @param users array of users to be sorted
+ * @param nUsers number of users in the array
+ * @return 0 on success
+ */
+ int SortUsersByEntryId(PSUser** users, int nUsers);
+
+private:
+ PSBuddyCache* m_buddies;
+ PSGroupCache* m_groups;
+ PSBuddyService* m_service;
+
+ /* flag indicating if buddy list is loaded from the disk */
+ bool m_loadedList;
+};
+
+#endif // __PS_BUDDY_LIST_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddyListener.h b/base/tps/src/include/httpClient/httpc/PSBuddyListener.h
new file mode 100644
index 000000000..87e701373
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddyListener.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_BUDDY_LISTENER_H__
+#define __PS_BUDDY_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddyListener.h 1.000 05/15/2002
+ *
+ * A listener interface for getting notifications from a buddy service.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/15/2002
+ */
+class PSBuddyListener :
+ public PSListener
+{
+public:
+
+/**
+ * Notifies the listener of the buddy status changes
+ *
+ * @param the reporting buddy service
+ * @param buddy object containing online status attributes
+ * @return 0 on success
+ */
+virtual int OnBuddyChanged(PSBuddyService*, PSBuddy*) = 0;
+
+/**
+ * Notifies the listener of the service to refresh the list
+ * of screen names to the buddy queue
+ *
+ * @param the reporting buddy service
+ * @return 0 on success
+ */
+virtual int OnRefreshList(PSBuddyService*) = 0;
+
+};
+
+#endif // __PS_BUDDY_LISTENER_H__
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSBuddyService.h b/base/tps/src/include/httpClient/httpc/PSBuddyService.h
new file mode 100644
index 000000000..2556420e9
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSBuddyService.h
@@ -0,0 +1,121 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_BUDDY_SERVICE_H__
+#define __PS_BUDDY_SERVICE_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSBuddyService.h 1.000 05/16/2002
+ *
+ * A pure virtual class defining Buddy Service interface
+ * to be implemented by the various IM presence service providers.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/16/2002
+ */
+class EXPORT_DECL PSBuddyService {
+public:
+
+/**
+ * Registers a listener with this class. The listener
+ * is notified of any changes to the buddies being tracked.
+ *
+ * @param a buddy service listener
+ * @return 0 on success
+ */
+virtual int RegisterListener(PSListener*) = 0;
+
+/**
+ * An entry point to start the service. This function is responsible
+ * for authentication with the backend service.
+ *
+ * @param config parameters for the service to start
+ * @return 0 on success
+ */
+virtual int SignOn(PSConfig*) = 0;
+
+/**
+ * Shutdown of the service.
+ *
+ * @return 0 on success
+ */
+virtual int SignOff() = 0;
+
+/**
+ * Sets a user name for online status tracking.
+ *
+ * @param user name to be tracked
+ * @return 0 on success
+ */
+virtual int WatchBuddy(const char*) = 0;
+
+/**
+ * Sets a number of users for online status tracking
+ *
+ * @param number of users to be tracked
+ * @param array of user names
+ * @return 0 on success
+ */
+virtual int WatchBuddies(int, char**) = 0;
+
+/**
+ * Unsets a user name from online status tracking.
+ *
+ * @param user name to be tracked
+ * @return 0 on success
+ */
+virtual int UnwatchBuddy(const char*) = 0;
+
+/**
+ * Unsets a number of users from online status tracking
+ *
+ * @param number of users to be tracked
+ * @param array of user names
+ * @return 0 on success
+ */
+virtual int UnwatchBuddies(int, char**) = 0;
+
+/**
+ * Gets the service config entry
+ *
+ * @return config object
+ */
+virtual PSConfig* GetServiceConfig() = 0;
+
+};
+
+#endif // __PS_BUDDY_SERVICE_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSCertExtension.h b/base/tps/src/include/httpClient/httpc/PSCertExtension.h
new file mode 100644
index 000000000..f528a54b4
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSCertExtension.h
@@ -0,0 +1,153 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _PS_CERT_EXTENSION_H
+#define _PS_CERT_EXTENSION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Presence Server cert extension. This extension contains customer
+ * specific information as per the contract apart from host and port
+ * used by BIG service provider to send user updates.
+ */
+
+class EXPORT_DECL PSCertExtension {
+public:
+ /**
+ * Constructor -
+ */
+ PSCertExtension();
+
+ /**
+ * Destructor
+ */
+ ~PSCertExtension();
+
+public:
+ /**
+ * Loads the extension data from the specified cert. This function
+ * will also verify the validity these fields :
+ * HOST_NAME - should not be NULL or ""
+ * PORT_NUMBER - > 0 and <= 65535
+ * MAX_USERS - >= 0
+ *
+ * @param nickname cert nickname which contains the extension
+ * return 0 on success,
+ * -1 if nickname is missing from the argument
+ * -2 if unable to find the cert
+ * -3 if the presence extension is mising
+ * -4 if the required values (hostname, port, maxusers) are invalid
+ * -5 if the cert is expired
+ */
+ int Load(const char* nickname);
+
+ /**
+ * Gets the service version number from the cert ext
+ *
+ * return version number as specified in the cert
+ */
+ int GetVersion();
+
+ /**
+ * Gets the street address from the cert
+ *
+ * return street address as specified in the cert ext
+ */
+ const char* GetStreetAddress();
+
+ /**
+ * Gets the telephone number from the cert
+ *
+ * return telephone number as specified in the cert ext
+ */
+ const char* GetTelephoneNumber();
+
+ /**
+ * Gets the RFC822 name from the cert
+ *
+ * return RFC822 name as specified in the cert ext
+ */
+ const char* GetRFC822Name();
+
+ /**
+ * Gets the IM id from the cert
+ *
+ * return IM id as specified in the cert ext
+ */
+ const char* GetID();
+
+ /**
+ * Gets the hostname from the cert ext
+ *
+ * return hostname as specified in the cert ext
+ */
+ const char* GetHostName();
+
+ /**
+ * Gets the port number from the cert ext
+ *
+ * return port number as specified in the cert ext
+ */
+ int GetPortNumber();
+
+ /**
+ * Gets the max users allowed from the cert ext
+ *
+ * return max users as specified in the cert ext
+ */
+ int GetMaxUsers();
+
+ /**
+ * Gets the service level from the cert ext
+ *
+ * return service level as specified in the cert ext
+ */
+ int GetServiceLevel();
+
+private:
+ int m_version;
+ char* m_streetAddress;
+ char* m_telephoneNumber;
+ char* m_rfc822Name;
+ char* m_id;
+ char* m_hostName;
+ int m_portNumber;
+ int m_maxUsers;
+ int m_serviceLevel;
+};
+
+#endif // _PS_CERT_EXTENSION_H
+
diff --git a/base/tps/src/include/httpClient/httpc/PSCommonLib.h b/base/tps/src/include/httpClient/httpc/PSCommonLib.h
new file mode 100644
index 000000000..09903b38f
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSCommonLib.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _PS_COMMON_LIB_H_
+#define _PS_COMMON_LIB_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#undef EXPORT_DECL
+#ifdef _MSC_VER
+#ifdef COMMON_LIB_DLL
+#define EXPORT_DECL __declspec( dllexport )
+#else
+#define EXPORT_DECL __declspec (dllimport )
+#endif // COMMON_LIB_DLL
+#else
+#define EXPORT_DECL
+#endif // _MSC_VER
+
+#endif // _PS_COMMON_LIB_H_
diff --git a/base/tps/src/include/httpClient/httpc/PSConfig.h b/base/tps/src/include/httpClient/httpc/PSConfig.h
new file mode 100644
index 000000000..897def3c9
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSConfig.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_CONFIG_H__
+#define __PS_CONFIG_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSConfig.h 1.000 04/30/2002
+ *
+ * This class provides structure to store and fetch string type data.
+ * Typical usage of this class would be storing server config data.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSConfig {
+public:
+ PSConfig();
+ PSConfig( const char *name );
+ virtual ~PSConfig();
+
+public:
+ void SetAttribute( const char* key, char* value );
+ char* GetAttribute( const char* key );
+ void SetName( const char *name );
+ const char *GetName();
+
+private:
+ PLHashTable* m_entryData;
+ const char *m_name;
+};
+
+#endif // __PS_CONFIG_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSConfigManager.h b/base/tps/src/include/httpClient/httpc/PSConfigManager.h
new file mode 100644
index 000000000..d2f5d3335
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSConfigManager.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_CONFIG_MANAGER_H__
+#define __PS_CONFIG_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSConfigManager.h 1.000 04/30/2002
+ *
+ * This class is a singleton that provides access to configuration parameters
+ * for the Presence Server.
+ *
+ * @author rweltman@netscape.com
+ * @version 1.0
+ */
+class EXPORT_DECL PSConfigManager {
+private:
+ PSConfigManager();
+ virtual ~PSConfigManager();
+
+public:
+ static PSConfigManager *GetConfigManager();
+
+public:
+ void SetConfigEntry( PSConfig *entry );
+ PSConfig *GetConfigEntry( const char *name );
+
+private:
+ PLHashTable* m_configEntries;
+};
+
+#endif // __PS_CONFIG_MANAGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSConfigReader.h b/base/tps/src/include/httpClient/httpc/PSConfigReader.h
new file mode 100644
index 000000000..a507a26dc
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSConfigReader.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_CONFIG_READER_H__
+#define __PS_CONFIG_READER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSConfigReader.h 1.000 04/30/2002
+ *
+ * This class provides access to the server configuration entries. The
+ * implementation of the config store is hidden from the user.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSConfigReader
+{
+private:
+ PSConfigReader();
+ virtual ~PSConfigReader();
+
+public:
+ static PSConfigReader* GetConfigReader();
+
+public:
+ int GetSubEntries(const char* root, char*** entries);
+ int GetEntryConfig(const char* entry, PSConfig** params);
+
+private:
+ int Init();
+
+private:
+ LDAP* m_LD;
+ char* m_bindPassword;
+};
+
+#endif // __PS_CONFIG_READER_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSCrypt.h b/base/tps/src/include/httpClient/httpc/PSCrypt.h
new file mode 100644
index 000000000..bfd05788d
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSCrypt.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PSCRYPT_H__
+#define __PSCRYPT_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Encrypt/Decrypt
+ */
+
+class EXPORT_DECL PSCrypt {
+private:
+ /**
+ * Constructor
+ */
+ PSCrypt( );
+ /**
+ * Destructor
+ */
+ virtual ~PSCrypt();
+
+public:
+ /**
+ * Retuns the decrypted string
+ * Assumption: The input string is base64 encoded
+ * Assumption: Caller has to free the returned string using free
+ * @param base64 encoded string to be decrypted
+ * @param decrypted upon return, string in ascii
+ * @return 0 on success, -1 on failure
+ */
+ static int Decrypt (const char* encrypted, char** decrypted);
+
+ /**
+ * Retuns the encrypted string in base64
+ *
+ * Assumption: Caller has to free the returned string using free
+ * @param text to encrypt
+ * @param encrypted upon return, text in base64
+ * @return 0 on success, -1 on failure
+ */
+ static int Encrypt(const char* text, char** encrypted);
+};
+
+#endif /* __PSCRYPT_H__ */
+
diff --git a/base/tps/src/include/httpClient/httpc/PSDataSourceListener.h b/base/tps/src/include/httpClient/httpc/PSDataSourceListener.h
new file mode 100644
index 000000000..36842904d
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSDataSourceListener.h
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_DATA_SOURCE_LISTENER_H__
+#define __PS_DATA_SOURCE_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/PSUser.h"
+
+/**
+ * PSDataSourceListener.h 1.000 04/30/2002
+ *
+ * A listener class for data source type plugins. The plugins
+ * notify the data source service manager through the functions
+ * provided by this interface.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSDataSourceListener :
+ public PSListener
+{
+public:
+
+/**
+ * Notifies the listener of any errors encountered by
+ * the data sources
+ *
+ * @param sourceId reporting source ID
+ * @param errCode error code
+ * @param errString error message
+ * @return 0 on success
+ */
+virtual int OnSourceError( const char* sourceId,
+ int errCode,
+ const char* errString) = 0;
+
+/**
+ * Notifies the listener of any new group
+ *
+ * @param group name of the group
+ * @param nAttrs number of attributes
+ * @param attrs array of attributes supported by the group
+ * @return 0 on success
+ */
+virtual int OnNewGroup( const char* group, int nAttrs, char** attrs ) = 0;
+
+/**
+ * Notifies the listener of any new users
+ *
+ * @param group name of the group
+ * @param nUsers number of users
+ * @param users array containing user objects
+ * @return 0 on success
+ */
+virtual int OnNewUsers( const char* group, int nUsers, PSUser** users ) = 0;
+
+/**
+ * Notifies the listener of any changes to the user being
+ * watched
+ *
+ * @param op operation to be performed ( add/replace/remove)
+ * @param group name of the group
+ * @param user the user object containing modified attributes
+ * @return 0 on success
+ */
+virtual int OnUserChanged(int op, const char* group, PSUser* user) = 0;
+
+};
+
+#endif // __PS_DATA_SOURCE_LISTENER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSDataSourceManager.h b/base/tps/src/include/httpClient/httpc/PSDataSourceManager.h
new file mode 100644
index 000000000..1b0662b69
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSDataSourceManager.h
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_DATA_SOURCE_MANAGER_H__
+#define __PS_DATA_SOURCE_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSDataSourceManager.h 1.000 05/21/2002
+ *
+ * This class manages presence server data sources plugins.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/21/2002
+ */
+class PSDataSourceManager :
+ public PSDataSourceListener
+{
+private:
+
+ /**
+ * Constructor - creates a data source manager object
+ */
+ PSDataSourceManager();
+
+ /**
+ * Destructor
+ */
+ virtual ~PSDataSourceManager();
+
+public:
+
+ /**
+ * Gets an instance of this class.
+ */
+ static PSDataSourceManager* GetDataSourceManager();
+
+public:
+
+ /**
+ * Registers a listener with this class. Only one listener is
+ * allowed to be registered. If an attempt is made to register
+ * more than one listener, then an error condition is raised.
+ *
+ * @param listener a server listener
+ * @return 0 on success, negative error upon failure
+ */
+ int RegisterListener(PSServerListener* listener);
+
+ /**
+ * Loads all data source type plugins.
+ *
+ * @return 0 for success, negative error code otherwise
+ */
+ int LoadDataSources();
+
+ /**
+ * Unloads all data source type plugins.
+ *
+ * @return 0 for success, negative error code otherwise
+ */
+ int UnloadDataSources();
+
+// PSDataSourceListener interface
+public:
+
+ /**
+ * Callback function to notify the manager upon data source error.
+ *
+ * @param sourceid id of the source calling
+ * @param errorcode error code
+ * @param errorstring error string
+ * @return 0 on success
+ *
+ */
+ int OnSourceError(const char* sourceid, int errorcode, const char* errorstring);
+
+ /**
+ * Callback function to notify the manager upon new group.
+ *
+ * @param group name of the new group
+ * @param nAttrs number of attributes
+ * @param attrs attributes the group will support
+ * @return 0 on success
+ *
+ */
+ int OnNewGroup(const char* group, int nAttrs, char** attrs);
+
+ /**
+ * Callback function to notify the manager of new users
+ *
+ * @param group name of the group
+ * @param nUsers number of users
+ * @param users array containing user objects
+ * @return 0 on success, a negative error code on failure
+ */
+ int OnNewUsers(const char* group, int nUsers, PSUser** users);
+
+ /**
+ * Callback function to notify the manager of changes to a user.
+ * The valid operations are :
+ * PS_OPERATION_ADD
+ * PS_OPERATION_REPLACE
+ * PS_OPERATION_DELETE
+ *
+ * @param op operation to be performed
+ * @param group name of the group
+ * @param user the user object containing modified attributes
+ * @return 0 on success, a negative error code on failure
+ */
+ int OnUserChanged(int op, const char* group, PSUser* user);
+
+private:
+ char* m_dataSourceDN;
+ PSServerListener* m_serverListener;
+ bool m_dataSourcesLoaded;
+};
+
+#endif // __PS_DATA_SOURCE_MANAGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSGroup.h b/base/tps/src/include/httpClient/httpc/PSGroup.h
new file mode 100644
index 000000000..8427c39c3
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSGroup.h
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_GROUP_H__
+#define __PS_GROUP_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+class PSUser;
+
+/**
+ * PSGroup.h 1.000 04/30/2002
+ *
+ * This class stores information about the users belonging to a group.
+ * All the users must belong to at least one group in the server.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class PSGroup
+{
+public:
+ PSGroup(const char* name, int nAttributes, char** attributes);
+ virtual ~PSGroup();
+
+public:
+ char* GetName();
+ int GetAttributeCount();
+ char** GetAttributes();
+ int GetAttributes(int offset, char** & attributes);
+
+ int AddUser(PSUser* user);
+ int RemoveUser(const char* name);
+ PSUser* GetUser(const char* name);
+ bool UserExists(const char* name);
+
+ int GetUserCount();
+ int GetAllUsers(int offset, PSUser** & users, int maxcount);
+ int GetAllUsers(int offset, char** & names, int maxcount);
+
+ int UpdateStatus(const char* name, bool changeToOnline);
+ int GetOnlineUsers(char*** names);
+ int GetOfflineUsers(char*** names);
+ int GetOnlineCount();
+ int GetOfflineCount();
+
+ void ReadLock();
+ void Unlock();
+
+private:
+ char* m_name;
+ int m_count;
+ char** m_attributes;
+
+ PRRWLock* m_psOnlineLock;
+ PRRWLock* m_psOfflineLock;
+ StringList* m_psOnlineUsers;
+ StringList* m_psOfflineUsers;
+
+ StringKeyCache* m_users;
+};
+
+#endif // __PS_GROUP_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSGroupCache.h b/base/tps/src/include/httpClient/httpc/PSGroupCache.h
new file mode 100644
index 000000000..6807e50e4
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSGroupCache.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_GROUP_CACHE_H__
+#define __PS_GROUP_CACHE_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSGroupCache.h 1.000 04/30/2002
+ *
+ * This class provides caching of various groups maintained in the
+ * server.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class PSGroupCache
+{
+public:
+ PSGroupCache();
+ virtual ~PSGroupCache();
+
+ int AddGroup(const char* name, PSGroup* group);
+ int RemoveGroup(const char* name);
+ PSGroup* GetGroup(const char* name);
+ bool GroupExists(const char* name);
+ int GetAllGroups(char*** names);
+
+ int GetAttributeCount(int nGroups, char** groups);
+ int GetUserCount(int nGroups, char** groups);
+ int GetOnlineCount(int nGroups, char** groups);
+ int GetOfflineCount(int nGroups, char** groups);
+
+ void ReadLock();
+ void Unlock();
+
+private:
+ StringKeyCache* m_groups;
+};
+
+#endif // __PS_GROUP_CACHE_H__
diff --git a/base/tps/src/include/httpClient/httpc/PSHelper.h b/base/tps/src/include/httpClient/httpc/PSHelper.h
new file mode 100644
index 000000000..7b9240b1b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSHelper.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_HELPER_H__
+#define __PS_HELPER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSHelper.h 1.000 04/30/2002
+ *
+ * A utility class used for logging, utility functions
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+// ??? SSR temporary logging solution
+class EXPORT_DECL PSLogger
+{
+public:
+ PSLogger(int level);
+ virtual ~PSLogger();
+
+public:
+ void Log(int level, char* fmt, ...);
+private:
+ int m_Level;
+};
+
+extern "C" {
+ EXPORT_DECL PSLogger* getServerLogger();
+ EXPORT_DECL void toLower(char* str);
+ EXPORT_DECL void normalize(char* str);
+}
+
+#endif // __PS_HELPER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSListener.h b/base/tps/src/include/httpClient/httpc/PSListener.h
new file mode 100644
index 000000000..1d85a9912
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSListener.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_LISTENER_H__
+#define __PS_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSListener.h 1.000 05/22/2002
+ *
+ * A Generic base class for all listeners.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/22/2002
+ */
+class EXPORT_DECL PSListener
+{
+};
+
+#endif // __PS_LISTENER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSPRUtil.h b/base/tps/src/include/httpClient/httpc/PSPRUtil.h
new file mode 100644
index 000000000..f3b104cc0
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSPRUtil.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _PS_PRUTIL_H
+#define _PS_PRUTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * NSPR related Utility functions
+ */
+
+// define a stuct to store the mesasge
+struct tuple_str {
+ PRErrorCode errNum;
+ const char * errString;
+};
+
+typedef struct tuple_str tuple_str;
+
+#define ER2(a,b) {a, b},
+#define ER3(a,b,c) {a, c},
+
+
+class EXPORT_DECL PSPRUtil {
+
+private:
+ /**
+ * Constructor - can't be instantiated
+ */
+ PSPRUtil() {}
+
+ /**
+ * Destructor
+ */
+ ~PSPRUtil() {}
+
+public:
+ /**
+ * Returns a string corresponding to an NSPR or NSS error code
+ *
+ * @param errNum Error number from PR_GetError()
+ * @retuns An immutable string, the empty string if the code is not known
+ */
+ static const char * GetErrorString (PRErrorCode errCode);
+
+
+ /**
+ * Returns an error string for the latest NSPR or NSS error
+ *
+ * @return An error string, or the empty string if there is no current
+ * NSPR or NSS error
+ */
+ static const char * GetErrorString();
+
+
+};
+
+#endif // _PS_PRUTIL_H
+
diff --git a/base/tps/src/include/httpClient/httpc/PSPlugin.h b/base/tps/src/include/httpClient/httpc/PSPlugin.h
new file mode 100644
index 000000000..f6655591e
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSPlugin.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_PLUGIN_H__
+#define __PS_PLUGIN_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSPlugin.h 1.000 04/30/2002
+ *
+ * Pure virtual class defining the functions to be implemented by
+ * different types of plugins in the server. The listener object passed
+ * the Init function is used to notify the server.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSPlugin {
+public:
+
+/**
+ * Initialize the plugin.
+ *
+ * @param a listener for this plugin
+ * @return 0 on success
+ */
+virtual int Init(PSListener*) = 0;
+
+/**
+ * Start the plugin.
+ *
+ * @param config params for the plugin
+ * @return 0 on success
+ */
+virtual int Start(PSConfig*) = 0;
+
+/**
+ * Stops the plugin.
+ *
+ * @return 0 on success
+ */
+virtual int Stop() = 0;
+
+};
+
+#endif // __PSPLUGIN_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSPluginManager.h b/base/tps/src/include/httpClient/httpc/PSPluginManager.h
new file mode 100644
index 000000000..7ea12829a
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSPluginManager.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_PLUGIN_MANAGER_H__
+#define __PS_PLUGIN_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSPluginManager.h 1.000 05/21/2002
+ *
+ * This class manages loading and unloading of all server plugin modules.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/21/2002
+ */
+class PSPluginManager
+{
+private:
+
+/**
+ * Constructor - creates an instance of Plugin manager object
+ */
+PSPluginManager();
+
+/**
+ * Destructor
+ */
+virtual ~PSPluginManager();
+
+public:
+
+/**
+ * Gets an instance of the class
+ */
+static PSPluginManager* GetPluginManager();
+
+public:
+
+/**
+ * Loads a group of plugins based on the type (dn) specified. If the loading
+ * is successful the specified listener is registered with the plugin and
+ * the plugin is started.
+ *
+ * @param dn root DN of the plugins
+ * @param listener listener associated with the specified type of plugins
+ * @return 0 on success, negative error code otherwise
+ */
+int LoadPlugin(const char* dn, PSListener* listener);
+
+/**
+ * Unloads a group of plugins based on the type ( dn ) specified.
+ * This function just issues a Stop on all the loaded plugins.
+ * It doesn't attempt to release any allocated data structures.
+ *
+ * @param dn root DN of the plugins
+ * @return 0 for success or error code for failure
+ */
+int UnloadPlugin(const char* dn);
+
+private:
+ StringKeyCache* m_serverPlugins;
+};
+
+#endif // __PS_PLUGIN_MANAGER_H__
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServer.h b/base/tps/src/include/httpClient/httpc/PSServer.h
new file mode 100644
index 000000000..86d2ca326
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServer.h
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_SERVER_H__
+#define __PS_SERVER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <time.h>
+#include <ctype.h>
+
+#include "nspr.h"
+#include "plhash.h"
+#include "plstr.h"
+
+#include "ldap.h"
+
+#define PRESENCESERVER_DLL
+#include "httpClient/httpc/PSServerLib.h"
+#include "httpClient/httpc/PresenceServer.h"
+
+#include "httpClient/httpc/Defines.h"
+#include "httpClient/httpc/PSError.h"
+#include "httpClient/httpc/PSHelper.h"
+#include "httpClient/httpc/PSConfig.h"
+#include "httpClient/httpc/PSConfigReader.h"
+#include "httpClient/httpc/PSConfigManager.h"
+#include "httpClient/httpc/Cache.h"
+#include "httpClient/httpc/StringList.h"
+#include "httpClient/httpc/StringUtil.h"
+#include "httpClient/httpc/ScheduledTask.h"
+#include "httpClient/httpc/PSCrypt.h"
+
+#include "httpClient/httpc/PSListener.h"
+#include "httpClient/httpc/PSBuddy.h"
+#include "httpClient/httpc/PSBuddyService.h"
+#include "httpClient/httpc/PSBuddyListener.h"
+#include "httpClient/httpc/PSServerListener.h"
+#include "httpClient/httpc/PSServiceListener.h"
+#include "httpClient/httpc/PSPluginManager.h"
+#include "httpClient/httpc/PSServiceManager.h"
+#include "httpClient/httpc/PSPlugin.h"
+#include "httpClient/httpc/PSUser.h"
+#include "httpClient/httpc/PSDataSourceListener.h"
+#include "httpClient/httpc/PSDataSourceManager.h"
+#include "httpClient/httpc/PSGroup.h"
+#include "httpClient/httpc/PSGroupCache.h"
+#include "httpClient/httpc/PSBuddyCache.h"
+#include "httpClient/httpc/PSBuddyList.h"
+#include "httpClient/httpc/PresenceManager.h"
+#include "httpClient/httpc/PSServerManager.h"
+
+#include "httpClient/httpc/ErrorLogger.h"
+#include "httpClient/httpc/DebugLogger.h"
+#include "httpClient/httpc/ScheduledTask.h"
+#include "httpClient/httpc/LogRotationTask.h"
+#include "httpClient/httpc/TaskList.h"
+#include "httpClient/httpc/Scheduler.h"
+
+#endif // __PS_SERVER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServerLib.h b/base/tps/src/include/httpClient/httpc/PSServerLib.h
new file mode 100644
index 000000000..079134230
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServerLib.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_SERVER_LIB_H__
+#define __PS_SERVER_LIB_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServerLib.h 1.000 05/27/2002
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/27/2002
+ */
+
+#ifdef _MSC_VER
+ #ifdef PRESENCESERVER_DLL
+ #define EXPORT_DECL __declspec( dllexport )
+ #else
+ #define EXPORT_DECL __declspec (dllimport )
+ #endif // PRESENCESERVER_DLL
+#else
+ #define EXPORT_DECL
+#endif // _MSC_VER
+
+#endif // __PS_SERVER_LIB_H__
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServerListener.h b/base/tps/src/include/httpClient/httpc/PSServerListener.h
new file mode 100644
index 000000000..152fbf58f
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServerListener.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_SERVER_LISTENER_H__
+#define __PS_SERVER_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServerListener.h 1.000 04/30/2002
+ *
+ * A listener class to report back into the server.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSServerListener :
+ public PSListener
+{
+public:
+
+/**
+ * Callback to report startup of a service.
+ *
+ * @param reporting module ID
+ * @return 0 on success
+ */
+virtual int OnStartup(const char*) = 0;
+
+/**
+ * Callback to report shutdown of a service.
+ *
+ * @param reporting module ID
+ * @return 0 on success
+ */
+virtual int OnShutdown(const char*) = 0;
+
+/**
+ * Callback to report any errors encountered during service execution.
+ *
+ * @param reporting module ID
+ * @param error code
+ * @param error message
+ * @return 0 on success
+ */
+virtual int OnCriticalError(const char*, int, const char*) = 0;
+
+};
+
+#endif // __PS_SERVER_LISTENER_H__
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServerManager.h b/base/tps/src/include/httpClient/httpc/PSServerManager.h
new file mode 100644
index 000000000..6597ad605
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServerManager.h
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_SERVER_MANAGER_H__
+#define __PS_SERVER_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServerManager.h 1.000 05/21/2002
+ *
+ * This class manages the server execution. It is responsible for loading
+ * of configurations, starting of services and proper shutdown of services.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/21/2002
+ */
+class PSServerManager :
+ public PSServerListener
+{
+private:
+
+/**
+ * Constructor - creates an instance of server manager object
+ */
+PSServerManager();
+
+/**
+ * Destructor
+ */
+virtual ~PSServerManager();
+
+public:
+
+/**
+ * Gets an instance of this class.
+ */
+static PSServerManager* GetServerManager();
+
+public:
+
+/**
+ * Loads general configuration into the ConfigManager
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+int InitServices();
+
+/**
+ * Starts services after server startup. The presence services are
+ * started before anything else and if it fails then no attempt is
+ * made to start other services.
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+int StartServices();
+
+/**
+ * Stops services before server shutdown.
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+int StopServices();
+
+private:
+
+/**
+ * Loads one configuration entry
+ *
+ * @param configdn The DN of the LDAP entry containing the config
+ * @param configName The name of the config entry
+ * @param descr A description of the config entry
+ * @return 0 on success
+ */
+int LoadOneConfig(const char* configdn, const char* configName, const char* descr);
+
+// PSServerListener interface
+public:
+
+/**
+ * Callback to notify server upon a service startup
+ *
+ * @param moduleid the notifying service id
+ * @return 0 on success
+ */
+int OnStartup(const char* moduleid);
+
+/**
+ * Callback to notify server upon a service shutdown
+ *
+ * @param moduleid the notifying service id
+ * @return 0 on success
+ */
+int OnShutdown(const char* moduleid);
+
+/**
+ * Callback to notify server upon a critical errors. The server immediately
+ * shuts down upon receipt of any such notification.
+ *
+ * @param moduleid the notifying service id
+ * @param errorcode negative error code
+ * @param errorstring negative error code
+ * @return 0 on success
+ */
+int OnCriticalError(const char* moduleid, int errorcode, const char* errorstring);
+
+private:
+ bool m_loadServiceDone;
+};
+
+#endif // __PS_SERVER_MANAGER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServiceListener.h b/base/tps/src/include/httpClient/httpc/PSServiceListener.h
new file mode 100644
index 000000000..358f0c295
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServiceListener.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_SERVICE_LISTENER_H__
+#define __PS_SERVICE_LISTENER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServiceListener.h 1.000 05/16/2002
+ *
+ * A listener interface for all the IM services to report back into
+ * service manager.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/16/2002
+ */
+class EXPORT_DECL PSServiceListener :
+ public PSListener
+{
+public:
+
+/**
+ * Callback to report start of a buddy service.
+ *
+ * @param reporting module
+ * @return 0 on success
+ */
+virtual int OnServiceStart(PSBuddyService*) = 0;
+
+/**
+ * Callback to report buddy service errors.
+ *
+ * @param reporting module
+ * @param error code
+ * @param error message
+ * @return 0 on success
+ */
+virtual int OnServiceError(PSBuddyService*, int, const char*) = 0;
+
+
+/**
+ * Callback to report shutdown of a buddy service.
+ *
+ * @param reporting module
+ * @return 0 on success
+ */
+virtual int OnServiceStop(PSBuddyService*) = 0;
+
+};
+
+#endif // __PS_SERVICE_LISTENER_H__
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSServiceManager.h b/base/tps/src/include/httpClient/httpc/PSServiceManager.h
new file mode 100644
index 000000000..1fd755c14
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSServiceManager.h
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PS_SERVICE_MANAGER_H__
+#define __PS_SERVICE_MANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * PSServiceManager.h 1.000 05/16/2002
+ *
+ * A Singleton class to manage presence services. Currently we support
+ * only one service to be loaded.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 05/16/2002
+ */
+class PSServiceManager :
+ public PSServiceListener
+{
+private:
+
+/**
+ * Constructor - creates a service manager object
+ */
+PSServiceManager();
+
+/**
+ * Destructor
+ */
+virtual ~PSServiceManager();
+
+public:
+
+/**
+ * Gets an instance of this class.
+ */
+static PSServiceManager* GetServiceManager();
+
+public:
+
+/**
+ * Registers a listener with this class. Only one listener is
+ * allowed to be registered. If an attempt is made to register
+ * more than one listener, then an error condition is raised.
+ *
+ * @param listener a server listener
+ * @return 0 on success, negative error upon failure
+ */
+int RegisterListener(PSServerListener* listener);
+
+/**
+ * Loads all providers type plugins.
+ *
+ * @return 0 for success, negative error code otherwise
+ */
+int LoadServices();
+
+/**
+ * Unloads all providers type plugins.
+ *
+ * @return 0 for success, negative error code otherwise
+ */
+int UnloadServices();
+
+/**
+ * Gets the service currently loaded. Only one service can
+ * be configured at a time.
+ *
+ * @return an im service
+ */
+PSBuddyService* GetService();
+
+// PSServiceListener interface
+public:
+
+/**
+ * Callback function to notify the manager of a service being started.
+ *
+ * @param service a buddy service
+ */
+int OnServiceStart(PSBuddyService* service);
+
+/**
+ * Callback function to notify the manager of a service error.
+ *
+ * @param service a buddy service
+ * @param errorcode a negative error code
+ * @param errorstring an error message
+ */
+int OnServiceError(PSBuddyService* service, int errorcode, const char* errorstring);
+
+/**
+ * Callback function to notify the manager of a service being stopped.
+ *
+ * @param service a buddy service
+ */
+int OnServiceStop(PSBuddyService* service);
+
+private:
+ char* m_serviceDN;
+ PSServerListener* m_serverListener;
+ PSBuddyService* m_service;
+
+ bool m_servicesLoaded;
+};
+
+#endif // __PS_SERVICE_MANAGER_H__
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSUser.h b/base/tps/src/include/httpClient/httpc/PSUser.h
new file mode 100644
index 000000000..a66c4e32f
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSUser.h
@@ -0,0 +1,164 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PSUSER_H__
+#define __PSUSER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "PresenceServer.h"
+
+/**
+ * PSUser.h 1.000 04/30/2002
+ *
+ * This class represents one attribute of a user.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSAttribute
+{
+public:
+
+/**
+ * Construts a new PSAttribute object.
+ *
+ * @param name name of the attribute
+ * @param value value of the attribute
+ */
+PSAttribute(const char* name, const char* value);
+
+/**
+ * Destructor
+ */
+virtual ~PSAttribute();
+
+/**
+ * Gets the name of the attribute.
+ *
+ * @return name of the attribute
+ */
+char* GetName();
+
+/**
+ * Gets the value of the specified attribute.
+ *
+ * @return value of the attribute
+ */
+char* GetValue();
+
+private:
+ char* m_name;
+ char* m_value;
+};
+
+/**
+ * PSUser.h 1.000 04/30/2002
+ *
+ * This class represents information about a single user.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PSUser
+{
+public:
+
+/**
+ * Construts a new PSUser object with just one attribute.
+ *
+ * @param name name of the user
+ * @param attribute a user attribute
+ */
+PSUser(const char* name, PSAttribute* attribute);
+
+/**
+ * Construts a new PSUser object with number of attributes.
+ *
+ * @param name name of the user
+ * @param nAttributes number of attributes
+ * @param attribute array containing user attributes
+ */
+PSUser(const char* name, int nAttributes, PSAttribute** attributes);
+
+/**
+ * Destructor
+ */
+virtual ~PSUser();
+
+/**
+ * Gets the name of the user.
+ *
+ * @return user name
+ */
+char* GetName();
+
+/**
+ * Get the count of user attributes.
+ *
+ * @return count of user attributes
+ */
+int GetCount();
+
+/**
+ * Gets a list of attribute objects for the user.
+ *
+ * @return array of attribute objects
+ */
+PSAttribute** GetAttributes();
+
+/**
+ * Gets the user attribute based on the specified attribute name.
+ *
+ * @return user attribute object on success, NULL otherwise
+ */
+PSAttribute* Lookup(char* key);
+
+/**
+ * Creates a new copy of the current user object.
+ *
+ * @return new user object
+ */
+void Clone(PSUser** user);
+
+private:
+ char* m_name;
+ int m_attrCount;
+ PSAttribute** m_attributes;
+};
+
+#endif
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PSWaspLib.h b/base/tps/src/include/httpClient/httpc/PSWaspLib.h
new file mode 100644
index 000000000..8fdea6bcc
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PSWaspLib.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _PS_WASP_LIB_H_
+#define _PS_WASP_LIB_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#ifdef _MSC_VER
+#undef EXPORT_DECL
+#ifdef WASP_LIB_DLL
+#define EXPORT_DECL __declspec( dllexport )
+#else
+#define EXPORT_DECL __declspec (dllimport )
+#endif // EXPORT_LIB_DLL
+#else
+#define EXPORT_DECL
+#endif // _MSC_VER
+
+// Key to hostname in WASP CallContext
+#define CONTEXT_HOSTNAME_TOKEN "Hostname"
+
+#endif // _PS_WASP_LIB_H_
diff --git a/base/tps/src/include/httpClient/httpc/Pool.h b/base/tps/src/include/httpClient/httpc/Pool.h
new file mode 100644
index 000000000..074b36b3b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Pool.h
@@ -0,0 +1,149 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __POOL_H__
+#define __POOL_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#define AUTOTOOLS_CONFIG_H
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Utility classes for object pools
+ *
+ * @author rweltman@netscape.com
+ * @version 1.0
+ */
+
+class PoolNode;
+class Pool;
+
+typedef int (*PoolEnumerator)(PoolNode *node);
+
+/**
+ * A node in a pool
+ */
+class EXPORT_DECL PoolNode {
+ friend class Pool;
+public:
+ /**
+ * Constructor
+ *
+ * @param data The real data of the node
+ */
+ PoolNode( void *data );
+ /**
+ * Destructor
+ */
+ virtual ~PoolNode();
+ /**
+ * Returns the real data of the node
+ *
+ * @return The real data of the node
+ */
+ void *GetData();
+ /**
+ * Returns the next entry in the list
+ *
+ * @return The next entry in the list
+ */
+ PoolNode *GetNext();
+ /**
+ * Returns the previous entry in the list
+ *
+ * @return The previous entry in the list
+ */
+ PoolNode *GetPrev();
+private:
+ void *m_data;
+ PoolNode *m_next;
+ PoolNode *m_prev;
+};
+
+/**
+ * A generic object pool
+ */
+class EXPORT_DECL Pool {
+public:
+ /**
+ * Constructor - creates a pool with an internal list of nodes
+ *
+ * @param name Name of pool
+ * @param poolSize Max number of nodes kept
+ * @param enumerator Optional enumerator to be called on destruction
+ */
+ Pool( const char *name, int poolSize, PoolEnumerator enumerator = NULL );
+ /**
+ * Destructor - Empties the pool
+ */
+ virtual ~Pool();
+ /**
+ * Appends an entry to the end of the internal list
+ *
+ * @param node An entry to add
+ * @return The added entry
+ */
+ PoolNode *Append( PoolNode *node );
+ /**
+ * Retrieves the head of the internal list and removes it
+ *
+ * @return The head of the internal list
+ */
+ PoolNode *RemoveHead();
+ /**
+ * Returns true if the pool is empty
+ *
+ * @return true if the pool is empty
+ */
+ bool IsEmpty();
+
+ /**
+ * Returns the number of entries in the pool
+ *
+ * @return The number of entries in the pool
+ */
+ int GetCount();
+
+protected:
+private:
+ PoolNode *m_list;
+ char *m_name;
+ int m_maxNodes;
+ int m_count;
+ PoolEnumerator m_enumerator;
+ PRRWLock *m_lock;
+ PRLock *m_conditionLock;
+ PRCondVar *m_condition;
+};
+
+#endif // __POOL_H__
diff --git a/base/tps/src/include/httpClient/httpc/PresenceManager.h b/base/tps/src/include/httpClient/httpc/PresenceManager.h
new file mode 100644
index 000000000..f7f4f753f
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PresenceManager.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PRESENCEMANAGER_H__
+#define __PRESENCEMANAGER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#define AUTOTOOLS_CONFIG_H
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/PSUser.h"
+
+/**
+ * PresenceManager.h 1.000 04/30/2002
+ *
+ * Wrapper class around the core buddylist management API.
+ *
+ * @author Rob Weltman
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+class EXPORT_DECL PresenceManager {
+public:
+ PresenceManager();
+ virtual ~PresenceManager();
+
+ int GetUserStatus(const char* group, const char* name, int nAttributes, char** attributes, PSUser** user);
+ int GetMultipleUserStatus(const char* group,
+ int nUsers,
+ char** names,
+ int nAttributes,
+ char** attributes,
+ PSUser*** users);
+ int GetUsersByFilter(const char* group, const char* filter, int nAttributes, char** attributes, PSUser*** users);
+ int GetSortedUsersByFilter(const char* group, const char* filter,
+ const char *sortKey, int sortKeyType,
+ int nAttributes, char** attributes, PSUser*** users);
+ /**
+ * Gets the number of users who are online or offline in a group
+ *
+ * @param group Name of group to query; NULL or empty for all groups
+ * @param bOnline true to return the count of online users, false for
+ * offline
+ * @return Number of users, or a negative error code on failure
+ *
+ * Error Code(s):
+ * PS_UNKOWN_GROUP
+ */
+ int GetUserCount( const char* group, int bOnline );
+ int AddGroup(const char* group, int nAttributes, char** attributes);
+ int AddUser(const char* group, const char* name, int nAttributes, PSAttribute** attributes);
+ int AddUsers(const char* group, int nUsers, PSUser** users);
+ int RemoveUser(const char* group, const char* name);
+ int RemoveUsers(const char* group, int nUsers, char** names);
+ int RemoveGroup(const char* group);
+ int GetAllGroups(char*** groups);
+ int GetAllUsers(const char* group, PSUser*** users);
+ int GetSearchableAttributes(const char* group, char*** attributes);
+
+private:
+};
+
+#endif // __PRESENCEMANAGER_H__
diff --git a/base/tps/src/include/httpClient/httpc/PresenceServer.h b/base/tps/src/include/httpClient/httpc/PresenceServer.h
new file mode 100644
index 000000000..1a9b259e9
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PresenceServer.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PRESENCE_SERVER_H__
+#define __PRESENCE_SERVER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/PSServerLib.h"
+
+/**
+ * PresenceServer.h 1.000 04/30/2002
+ *
+ * Starts and stops presence services
+ *
+ * @author Rob Weltman
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+
+extern "C" {
+EXPORT_DECL int presence_main( int argc, char* argv[] );
+EXPORT_DECL void presence_exit();
+}
+
+#endif // __PRESENCE_SERVER_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/PresenceServerImpl.h b/base/tps/src/include/httpClient/httpc/PresenceServerImpl.h
new file mode 100644
index 000000000..8c07b9140
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/PresenceServerImpl.h
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __PRESENCE_SERVER_IMPL_H__
+#define __PRESENCE_SERVER_IMPL_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+class PSUser;
+
+/**
+ * PresenceServerImpl.h 1.000 04/30/2002
+ *
+ * Interface for WASP implementation of presence service
+ *
+ * @author Rob Weltman
+ * @author Surendra Rajam
+ * @version 1.000, 04/30/2002
+ */
+
+class EXPORT_DECL PresenceServerImpl:public PresenceServiceImpl {
+public:
+ PresenceServerImpl() {}
+ virtual ~PresenceServerImpl() {}
+ virtual int getAllGroups (ArrayOfstring *& groups);
+ virtual int getAllUsers (WASP_String * group, ArrayOfstring *& users);
+ virtual int removeGroup (WASP_String * group);
+ virtual int getUsersByFilter (WASP_String * group, WASP_String * filter, int nAttributes, ArrayOfstring * attributes, ArrayOfPresenceUser *& users);
+ virtual int getMultipleUserStatus (WASP_String * group,
+ int nUsers,
+ ArrayOfstring * names,
+ int nAttributes,
+ ArrayOfstring * attributes,
+ ArrayOfPresenceUser *& users);
+ virtual int removeUser (WASP_String * group, WASP_String * name);
+ virtual int getUserStatus (WASP_String * group, WASP_String * name, int nAttributes, ArrayOfstring * attributes, PresenceUser *& user);
+ /**
+ * Gets the number of users who are online or offline in a group
+ *
+ * @param group Name of group to query; NULL or empty for all groups
+ * @param bOnline true to return the count of online users, false for offline
+ * @return Number of users, or a negative error code on failure
+ *
+ * Error Code(s):
+ * PS_UNKOWN_GROUP
+ */
+ virtual int getUserCount( WASP_String* group, int bOnline );
+ virtual int addUsers (WASP_String * group, int nUsers, ArrayOfPresenceUser * users);
+ virtual int addGroup (WASP_String * group, int nAttributes, ArrayOfstring * attributes);
+ virtual int getSearchableAttributes (WASP_String * group, ArrayOfstring *& attributes);
+ virtual int addUser (WASP_String * group, WASP_String * name, int nAttributes, ArrayOfUserAttribute * attributes);
+ virtual int getSortedUsersByFilter (WASP_String * group,
+ WASP_String * filter,
+ WASP_String * sortKey,
+ int sortKeyType,
+ int nAttributes,
+ ArrayOfstring * attributes,
+ ArrayOfPresenceUser *& users);
+ virtual int removeUsers (WASP_String * group, int nUsers, ArrayOfstring * names);
+protected:
+ void doLog(const char *func, int status);
+ static int parseUsers(int nUsers, PSUser** tusers,
+ ArrayOfPresenceUser*& users);
+ /**
+ * Decodes an array of Unicode strings from a WASP string array object;
+ * the result should be freed by deleting the individual strings as well as
+ * the array itself; nStrings is set to 0 if wStrings is NULL
+ *
+ * @param attributes WASP string array object to convert
+ * @param nAttributes Number of strings to process
+ * @return Array of strings
+ */
+ char **DecodeStringArrayObject( ArrayOfstring* wStrings,
+ int& nStrings );
+};
+
+#endif // __PRESENCE_SERVER_IMPL_H__
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SECerrs.h b/base/tps/src/include/httpClient/httpc/SECerrs.h
new file mode 100644
index 000000000..d7495ff28
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SECerrs.h
@@ -0,0 +1,522 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * 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 is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/SECerrs.h
+ */
+
+/* General security error codes */
+/* Caller must #include "secerr.h" */
+
+ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0,
+"An I/O error occurred during security authorization.")
+
+ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1,
+"security library failure.")
+
+ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2,
+"security library: received bad data.")
+
+ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3,
+"security library: output length error.")
+
+ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4,
+"security library has experienced an input length error.")
+
+ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5,
+"security library: invalid arguments.")
+
+ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6,
+"security library: invalid algorithm.")
+
+ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7,
+"security library: invalid AVA.")
+
+ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8,
+"Improperly formatted time string.")
+
+ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9,
+"security library: improperly formatted DER-encoded message.")
+
+ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10,
+"Peer's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11,
+"Peer's Certificate has expired.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12,
+"Peer's Certificate has been revoked.")
+
+ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13,
+"Peer's Certificate issuer is not recognized.")
+
+ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14,
+"Peer's public key is invalid.")
+
+ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15,
+"The security password entered is incorrect.")
+
+ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16,
+"New password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17,
+"security library: no nodelock.")
+
+ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18,
+"security library: bad database.")
+
+ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19,
+"security library: memory allocation failure.")
+
+ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20,
+"Peer's certificate issuer has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21,
+"Peer's certificate has been marked as not trusted by the user.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22),
+"Certificate already exists in your database.")
+
+ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23),
+"Downloaded certificate's name duplicates one already in your database.")
+
+ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24),
+"Error adding certificate to database.")
+
+ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25),
+"Error refiling the key for this certificate.")
+
+ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26),
+"The private key for this certificate cannot be found in key database")
+
+ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27),
+"This certificate is valid.")
+
+ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28),
+"This certificate is not valid.")
+
+ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29),
+"Cert Library: No Response")
+
+ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
+"The certificate issuer's certificate has expired. Check your system date and time.")
+
+ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
+"The CRL for the certificate's issuer has expired. Update it or check your system data and time.")
+
+ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
+"The CRL for the certificate's issuer has an invalid signature.")
+
+ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33),
+"New CRL has an invalid format.")
+
+ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34),
+"Certificate extension value is invalid.")
+
+ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35),
+"Certificate extension not found.")
+
+ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
+"Issuer certificate is invalid.")
+
+ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
+"Certificate path length constraint is invalid.")
+
+ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
+"Certificate usages field is invalid.")
+
+ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
+"**Internal ONLY module**")
+
+ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
+"The key does not support the requested operation.")
+
+ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
+"Certificate contains unknown critical extension.")
+
+ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
+"New CRL is not later than the current one.")
+
+ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
+"Not encrypted or signed: you do not yet have an email certificate.")
+
+ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44),
+"Not encrypted: you do not have certificates for each of the recipients.")
+
+ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
+"Cannot decrypt: you are not a recipient, or matching certificate and \
+private key not found.")
+
+ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46),
+"Cannot decrypt: key encryption algorithm does not match your certificate.")
+
+ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47),
+"Signature verification failed: no signer found, too many signers found, \
+or improper or corrupted data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48),
+"Unsupported or unknown key algorithm.")
+
+ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49),
+"Cannot decrypt: encrypted using a disallowed algorithm or key size.")
+
+
+/* Fortezza Alerts */
+ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50),
+"Fortezza card has not been properly initialized. \
+Please remove it and return it to your issuer.")
+
+ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51),
+"No Fortezza cards Found")
+
+ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52),
+"No Fortezza card selected")
+
+ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53),
+"Please select a personality to get more info on")
+
+ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54),
+"Personality not found")
+
+ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55),
+"No more information on that Personality")
+
+ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56),
+"Invalid Pin")
+
+ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
+"Couldn't initialize Fortezza personalities.")
+/* end fortezza alerts. */
+
+ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58),
+"No KRL for this site's certificate has been found.")
+
+ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59),
+"The KRL for this site's certificate has expired.")
+
+ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60),
+"The KRL for this site's certificate has an invalid signature.")
+
+ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61),
+"The key for this site's certificate has been revoked.")
+
+ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62),
+"New KRL has an invalid format.")
+
+ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63),
+"security library: need random data.")
+
+ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64),
+"security library: no security module can perform the requested operation.")
+
+ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65),
+"The security card or token does not exist, needs to be initialized, or has been removed.")
+
+ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66),
+"security library: read-only database.")
+
+ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67),
+"No slot or token was selected.")
+
+ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68),
+"A certificate with the same nickname already exists.")
+
+ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69),
+"A key with the same nickname already exists.")
+
+ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70),
+"error while creating safe object")
+
+ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71),
+"error while creating baggage object")
+
+ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72),
+"Couldn't remove the principal")
+
+ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73),
+"Couldn't delete the privilege")
+
+ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74),
+"This principal doesn't have a certificate")
+
+ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75),
+"Required algorithm is not allowed.")
+
+ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76),
+"Error attempting to export certificates.")
+
+ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77),
+"Error attempting to import certificates.")
+
+ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78),
+"Unable to import. Decoding error. File not valid.")
+
+ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79),
+"Unable to import. Invalid MAC. Incorrect password or corrupt file.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80),
+"Unable to import. MAC algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81),
+"Unable to import. Only password integrity and privacy modes supported.")
+
+ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82),
+"Unable to import. File structure is corrupt.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83),
+"Unable to import. Encryption algorithm not supported.")
+
+ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84),
+"Unable to import. File version not supported.")
+
+ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85),
+"Unable to import. Incorrect privacy password.")
+
+ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86),
+"Unable to import. Same nickname already exists in database.")
+
+ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87),
+"The user pressed cancel.")
+
+ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88),
+"Not imported, already in database.")
+
+ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89),
+"Message not sent.")
+
+ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90),
+"Certificate key usage inadequate for attempted operation.")
+
+ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91),
+"Certificate type not approved for application.")
+
+ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92),
+"Address in signing certificate does not match address in message headers.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93),
+"Unable to import. Error attempting to import private key.")
+
+ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94),
+"Unable to import. Error attempting to import certificate chain.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95),
+"Unable to export. Unable to locate certificate or key by nickname.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96),
+"Unable to export. Private Key could not be located and exported.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97),
+"Unable to export. Unable to write the export file.")
+
+ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98),
+"Unable to import. Unable to read the import file.")
+
+ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99),
+"Unable to export. Key database corrupt or deleted.")
+
+ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100),
+"Unable to generate public/private key pair.")
+
+ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101),
+"Password entered is invalid. Please pick a different one.")
+
+ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102),
+"Old password entered incorrectly. Please try again.")
+
+ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103),
+"Certificate nickname already in use.")
+
+ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104),
+"Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
+
+ER3(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, (SEC_ERROR_BASE + 105),
+"A sensitive key cannot be moved to the slot where it is needed.")
+
+ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106),
+"Invalid module name.")
+
+ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107),
+"Invalid module path/filename")
+
+ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108),
+"Unable to add module")
+
+ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109),
+"Unable to delete module")
+
+ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110),
+"New KRL is not later than the current one.")
+
+ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111),
+"New CKL has different issuer than current CKL. Delete current CKL.")
+
+ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
+"The Certifying Authority for this certificate is not permitted to issue a \
+certificate with this name.")
+
+ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113),
+"The key revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114),
+"The certificate revocation list for this certificate is not yet valid.")
+
+ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115),
+"The requested certificate could not be found.")
+
+ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116),
+"The signer's certificate could not be found.")
+
+ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117),
+"The location for the certificate status server has invalid format.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118),
+"The OCSP response cannot be fully decoded; it is of an unknown type.")
+
+ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119),
+"The OCSP server returned unexpected/invalid HTTP data.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120),
+"The OCSP server found the request to be corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121),
+"The OCSP server experienced an internal error.")
+
+ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122),
+"The OCSP server suggests trying again later.")
+
+ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123),
+"The OCSP server requires a signature on this request.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124),
+"The OCSP server has refused this request as unauthorized.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125),
+"The OCSP server returned an unrecognizable status.")
+
+ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126),
+"The OCSP server has no status for the certificate.")
+
+ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127),
+"You must enable OCSP before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128),
+"You must set the OCSP default responder before performing this operation.")
+
+ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129),
+"The response from the OCSP server was corrupted or improperly formed.")
+
+ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130),
+"The signer of the OCSP response is not authorized to give status for \
+this certificate.")
+
+ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131),
+"The OCSP response is not yet valid (contains a date in the future).")
+
+ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132),
+"The OCSP response contains out-of-date information.")
+
+ER3(SEC_ERROR_DIGEST_NOT_FOUND, (SEC_ERROR_BASE + 133),
+"The CMS or PKCS #7 Digest was not found in signed message.")
+
+ER3(SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, (SEC_ERROR_BASE + 134),
+"The CMS or PKCS #7 Message type is unsupported.")
+
+ER3(SEC_ERROR_MODULE_STUCK, (SEC_ERROR_BASE + 135),
+"PKCS #11 module could not be removed because it is still in use.")
+
+ER3(SEC_ERROR_BAD_TEMPLATE, (SEC_ERROR_BASE + 136),
+"Could not decode ASN.1 data. Specified template was invalid.")
+
+ER3(SEC_ERROR_CRL_NOT_FOUND, (SEC_ERROR_BASE + 137),
+"No matching CRL was found.")
+
+ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138),
+"You are attempting to import a cert with the same issuer/serial as \
+an existing cert, but that is not the same cert.")
+
+ER3(SEC_ERROR_BUSY, (SEC_ERROR_BASE + 139),
+"NSS could not shutdown. Objects are still in use.")
+
+ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140),
+"DER-encoded message contained extra unused data.")
+
+ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141),
+"Unsupported elliptic curve.")
+
+ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
+"Unsupported elliptic curve point form.")
+
+ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
+"Unrecognized Object IDentifier.")
+
+ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144),
+"Invalid OCSP signing certificate in OCSP response.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145),
+"Certificate is revoked in issuer's certificate revocation list.")
+
+ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146),
+"Issuer's OCSP responder reports certificate is revoked.")
+
+ER3(SEC_ERROR_CRL_INVALID_VERSION, (SEC_ERROR_BASE + 147),
+"Issuer's Certificate Revocation List has an unknown version number.")
+
+ER3(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 148),
+"Issuer's V1 Certificate Revocation List has a critical extension.")
+
+ER3(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 149),
+"Issuer's V2 Certificate Revocation List has an unknown critical extension.")
+
+ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150),
+"Unknown object type specified.")
+
+ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151),
+"PKCS #11 driver violates the spec in an incompatible way.")
+
+ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152),
+"No new slot event is available at this time.")
+
+ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153),
+"CRL already exists.")
+
+ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154),
+"NSS is not initialized.")
+
+ER3(SEC_ERROR_TOKEN_NOT_LOGGED_IN, (SEC_ERROR_BASE + 155),
+"The operation failed because the PKCS#11 token is not logged in.")
+
diff --git a/base/tps/src/include/httpClient/httpc/SSLServerSocket.h b/base/tps/src/include/httpClient/httpc/SSLServerSocket.h
new file mode 100644
index 000000000..a059d7279
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SSLServerSocket.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __SSL_SERVER_SOCKET_H
+#define __SSL_SERVER_SOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * SSLServerSocket.h 1.000 06/12/2002
+ *
+ * A Secure server socket implementation based on NSPR / NSS
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL SSLServerSocket : public ServerSocket {
+public:
+ /**
+ * Constructor
+ */
+ SSLServerSocket( const char* host,
+ int port,
+ const char* nickname,
+ int requestcert );
+
+ /**
+ * Destructor
+ */
+ virtual ~SSLServerSocket();
+
+public:
+ /**
+ * Initializes cert and private key before calling base class
+ * Accept function.
+ */
+ Socket* Accept();
+
+private:
+ /**
+ * Overrides base class function to create SSL sockets
+ *
+ * @return a newly accepted SSL socket
+ */
+ Socket* InternalAccept(PRFileDesc* fd);
+
+private:
+ char* m_nickName;
+ int m_requestCert;
+ CERTCertificate* m_serverCert;
+ SECKEYPrivateKey* m_serverPrivKey;
+ SSLKEAType m_certKEA;
+};
+
+#endif // __SSL_SERVER_SOCKET_H
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SSLSocket.h b/base/tps/src/include/httpClient/httpc/SSLSocket.h
new file mode 100644
index 000000000..14d647c60
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SSLSocket.h
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __SSL_SOCKET_H
+#define __SSL_SOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * SSLSocket.h 1.000 06/12/2002
+ *
+ * A Secure socket implementation based on NSPR / NSS
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL SSLSocket : public Socket {
+ friend class SSLServerSocket;
+public:
+ /**
+ * Constructor
+ */
+ SSLSocket();
+
+ /**
+ * Destructor
+ */
+ virtual ~SSLSocket();
+
+private:
+ /**
+ * Sets up this socket to behave as a SSL server
+ *
+ * @param cert server certificate object
+ * @param privKey private key structure
+ * @param password password to access DB
+ * @param requestCert whether to request cert from the client
+ * @return 0 on success, negative error code otherwise
+ *
+ */
+ int SetupSSLServer( CERTCertificate* serverCert,
+ SECKEYPrivateKey* privKey,
+ SSLKEAType certKEA,
+ int requestCert );
+private:
+ // server callbacks
+ /**
+ * Specifies a certificate authentication callback function called
+ * to authenticate an incoming certificate
+ *
+ * @param arg pointer supplied by the application
+ * (in the call to SSL_AuthCertificateHook)
+ * that can be used to pass state information
+ * @param socket pointer to the file descriptor for the SSL socket
+ * @param checksig PR_TRUE means signatures are to be checked and
+ * the certificate chain is to be validated
+ * @param isServer PR_TRUE means the callback function should
+ * evaluate the certificate as a server does,
+ * treating the remote end is a client
+ * @return SECSuccess on success, SECFailure otherwise
+ *
+ */
+ static SECStatus AuthCertificate( void* arg,
+ PRFileDesc* socket,
+ PRBool checksig,
+ PRBool isServer );
+
+ /**
+ * Sets up a callback function to deal with a situation where the
+ * SSL_AuthCertificate callback function has failed. This callback
+ * function allows the application to override the decision made by
+ * the certificate authorization callback and authorize the certificate
+ * for use in the SSL connection.
+ *
+ * @param arg The arg parameter passed to SSL_BadCertHook
+ * @param socket pointer to the file descriptor for the SSL socket
+ * @return SECSuccess on success, SECFailure otherwise
+ */
+ static SECStatus BadCertHandler( void* arg,
+ PRFileDesc* socket );
+
+ /**
+ * Sets up a callback function used by SSL to inform either a client
+ * application or a server application when the handshake is completed
+ *
+ * @param arg The arg parameter passed to SSL_HandshakeCallback
+ * @param socket pointer to the file descriptor for the SSL socket
+ * @return SECSuccess on success, SECFailure otherwise
+ */
+ static SECStatus HandshakeCallback( PRFileDesc* socket,
+ void* arg );
+
+private:
+ bool m_initializedAsServer;
+};
+
+#endif // __SSL_SOCKET_H
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SSLerrs.h b/base/tps/src/include/httpClient/httpc/SSLerrs.h
new file mode 100644
index 000000000..818da3e87
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SSLerrs.h
@@ -0,0 +1,392 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * 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 is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/* Originally obtained from:
+ *
+ * CVSROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
+ * cvs export -r NSS_3_11_3_RTM -N mozilla/security/nss/cmd/lib/SSLerrs.h
+ */
+
+/* SSL-specific security error codes */
+/* caller must include "sslerr.h" */
+
+ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
+"Unable to communicate securely. Peer does not support high-grade encryption.")
+
+ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
+"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
+
+ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
+"Cannot communicate securely with peer: no common encryption algorithm(s).")
+
+ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
+"Unable to find the certificate or key necessary for authentication.")
+
+ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
+"Unable to communicate securely with peer: peers's certificate was rejected.")
+
+/* unused (SSL_ERROR_BASE + 5),*/
+
+ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
+"The server has encountered bad data from the client.")
+
+ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
+"The client has encountered bad data from the server.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
+"Unsupported certificate type.")
+
+ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
+"Peer using unsupported version of security protocol.")
+
+/* unused (SSL_ERROR_BASE + 10),*/
+
+ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
+"Client authentication failed: private key in key database does not match public key in certificate database.")
+
+ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
+"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
+
+/* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13),
+ defined in sslerr.h
+*/
+
+ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
+"Peer only supports SSL version 2, which is locally disabled.")
+
+
+ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
+"SSL received a record with an incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
+"SSL peer reports incorrect Message Authentication Code.")
+
+ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
+"SSL peer cannot verify your certificate.")
+
+ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
+"SSL peer rejected your certificate as revoked.")
+
+ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
+"SSL peer rejected your certificate as expired.")
+
+ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
+"Cannot connect: SSL is disabled.")
+
+ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
+"Cannot connect: SSL peer is in another FORTEZZA domain.")
+
+
+ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
+"An unknown SSL cipher suite has been requested.")
+
+ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
+"No cipher suites are present and enabled in this program.")
+
+ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
+"SSL received a record with bad block padding.")
+
+ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
+"SSL received a record that exceeded the maximum permissible length.")
+
+ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
+"SSL attempted to send a record that exceeded the maximum permissible length.")
+
+/*
+ * Received a malformed (too long or short or invalid content) SSL handshake.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
+"SSL received a malformed Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
+"SSL received a malformed Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
+"SSL received a malformed Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
+"SSL received a malformed Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
+"SSL received a malformed Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
+"SSL received a malformed Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
+"SSL received a malformed Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
+"SSL received a malformed Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
+"SSL received a malformed Client Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
+"SSL received a malformed Finished handshake message.")
+
+/*
+ * Received a malformed (too long or short) SSL record.
+ */
+ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
+"SSL received a malformed Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
+"SSL received a malformed Alert record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
+"SSL received a malformed Handshake record.")
+
+ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
+"SSL received a malformed Application Data record.")
+
+/*
+ * Received an SSL handshake that was inappropriate for the state we're in.
+ * E.g. Server received message from server, or wrong state in state machine.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
+"SSL received an unexpected Hello Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
+"SSL received an unexpected Client Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
+"SSL received an unexpected Server Hello handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
+"SSL received an unexpected Certificate handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
+"SSL received an unexpected Server Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
+"SSL received an unexpected Certificate Request handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
+"SSL received an unexpected Server Hello Done handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
+"SSL received an unexpected Certificate Verify handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
+"SSL received an unexpected Cllient Key Exchange handshake message.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
+"SSL received an unexpected Finished handshake message.")
+
+/*
+ * Received an SSL record that was inappropriate for the state we're in.
+ */
+ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
+"SSL received an unexpected Change Cipher Spec record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
+"SSL received an unexpected Alert record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
+"SSL received an unexpected Handshake record.")
+
+ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
+"SSL received an unexpected Application Data record.")
+
+/*
+ * Received record/message with unknown discriminant.
+ */
+ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
+"SSL received a record with an unknown content type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
+"SSL received a handshake message with an unknown message type.")
+
+ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
+"SSL received an alert record with an unknown alert description.")
+
+/*
+ * Received an alert reporting what we did wrong. (more alerts above)
+ */
+ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
+"SSL peer has closed this connection.")
+
+ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
+"SSL peer was not expecting a handshake message it received.")
+
+ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
+"SSL peer was unable to succesfully decompress an SSL record it received.")
+
+ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
+"SSL peer was unable to negotiate an acceptable set of security parameters.")
+
+ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
+"SSL peer rejected a handshake message for unacceptable content.")
+
+ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
+"SSL peer does not support certificates of the type it received.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
+"SSL peer had some unspecified issue with the certificate it received.")
+
+
+ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
+"SSL experienced a failure of its random number generator.")
+
+ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
+"Unable to digitally sign data required to verify your certificate.")
+
+ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
+"SSL was unable to extract the public key from the peer's certificate.")
+
+ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
+"Unspecified failure while processing SSL Server Key Exchange handshake.")
+
+ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
+"Unspecified failure while processing SSL Client Key Exchange handshake.")
+
+ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
+"Bulk data encryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
+"Bulk data decryption algorithm failed in selected cipher suite.")
+
+ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
+"Attempt to write encrypted data to underlying socket failed.")
+
+ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
+"MD5 digest function failed.")
+
+ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
+"SHA-1 digest function failed.")
+
+ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
+"MAC computation failed.")
+
+ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
+"Failure to create Symmetric Key context.")
+
+ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
+"Failure to unwrap the Symmetric key in Client Key Exchange message.")
+
+ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
+"SSL Server attempted to use domestic-grade public key with export cipher suite.")
+
+ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
+"PKCS11 code failed to translate an IV into a param.")
+
+ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
+"Failed to initialize the selected cipher suite.")
+
+ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
+"Client failed to generate session keys for SSL session.")
+
+ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
+"Server has no key for the attempted key exchange algorithm.")
+
+ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
+"PKCS#11 token was inserted or removed while operation was in progress.")
+
+ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
+"No PKCS#11 token could be found to do a required operation.")
+
+ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
+"Cannot communicate securely with peer: no common compression algorithm(s).")
+
+ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
+"Cannot initiate another SSL handshake until current handshake is complete.")
+
+ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
+"Received incorrect handshakes hash values from peer.")
+
+ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
+"The certificate provided cannot be used with the selected key exchange algorithm.")
+
+ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89),
+"No certificate authority is trusted for SSL client authentication.")
+
+ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90),
+"Client's SSL session ID not found in server's session cache.")
+
+ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91),
+"Peer was unable to decrypt an SSL record it received.")
+
+ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92),
+"Peer received an SSL record that was longer than is permitted.")
+
+ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93),
+"Peer does not recognize and trust the CA that issued your certificate.")
+
+ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94),
+"Peer received a valid certificate, but access was denied.")
+
+ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95),
+"Peer could not decode an SSL handshake message.")
+
+ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96),
+"Peer reports failure of signature verification or key exchange.")
+
+ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97),
+"Peer reports negotiation not in compliance with export regulations.")
+
+ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98),
+"Peer reports incompatible or unsupported protocol version.")
+
+ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99),
+"Server requires ciphers more secure than those supported by client.")
+
+ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100),
+"Peer reports it experienced an internal error.")
+
+ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101),
+"Peer user canceled handshake.")
+
+ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
+"Peer does not permit renegotiation of SSL security parameters.")
+
+ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103),
+"SSL server cache not configured and not disabled for this socket.")
+
+ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104),
+"SSL peer does not support requested TLS hello extension.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105),
+"SSL peer could not obtain your certificate from the supplied URL.")
+
+ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106),
+"SSL peer has no certificate for the requested DNS name.")
+
+ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107),
+"SSL peer was unable to get an OCSP response for its certificate.")
+
+ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108),
+"SSL peer reported bad certificate hash value.")
diff --git a/base/tps/src/include/httpClient/httpc/ScheduledTask.h b/base/tps/src/include/httpClient/httpc/ScheduledTask.h
new file mode 100644
index 000000000..cbb99ab61
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ScheduledTask.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __SCHEDULED_TASK_H__
+#define __SCHEDULED_TASK_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <time.h>
+
+class TaskList;
+
+/**
+ * Base class for scheduled tasks in Presence Server
+ */
+
+class EXPORT_DECL ScheduledTask {
+ friend class TaskList;
+public:
+ /**
+ * Constructor - creates an empty task
+ */
+ ScheduledTask();
+ /**
+ * Constructor - creates an empty task
+ *
+ * @param name Name of task
+ */
+ ScheduledTask( const char *name );
+ /**
+ * Destructor
+ */
+ virtual ~ScheduledTask();
+ /**
+ * Returns a copy of the task
+ *
+ * @return A copy of the task
+ */
+ virtual ScheduledTask *Clone();
+ /**
+ * Executes the task
+ *
+ * @return 0 on successfully starting the task
+ */
+ virtual int Start();
+protected:
+ char *m_name;
+ ScheduledTask *m_next;
+ ScheduledTask *m_prev;
+ time_t m_time;
+ int m_interval;
+};
+
+#endif // __SCHEDULED_TASK_H__
diff --git a/base/tps/src/include/httpClient/httpc/Scheduler.h b/base/tps/src/include/httpClient/httpc/Scheduler.h
new file mode 100644
index 000000000..a0e77ffb4
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Scheduler.h
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __SCHEDULER_H__
+#define __SCHEDULER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+class ScheduledTask;
+class TaskList;
+
+/**
+ * Base class for scheduled tasks in Presence Server
+ */
+
+class EXPORT_DECL Scheduler {
+private:
+ /**
+ * Constructor - creates a scheduler object
+ */
+ Scheduler();
+ /**
+ * Destructor
+ */
+ ~Scheduler();
+public:
+ /**
+ * Returns the single scheduler object
+ *
+ * @return The single scheduler object
+ */
+ static Scheduler *GetScheduler();
+ /**
+ * Starts executing a sleep and check task list loop
+ *
+ * @return 0 on success
+ */
+ int Run();
+ /**
+ * Shuts down the scheduler
+ */
+ static void Shutdown();
+ /**
+ * Launches a thread that executes Run()
+ *
+ * @param interval Interval in seconds between checking for task execution
+ * time
+ * @return 0 on success
+ */
+ int Start( int interval );
+ /**
+ * Adds a task to the list
+ *
+ * @param task A task to be executed
+ */
+ void AddTask( ScheduledTask *task );
+ /**
+ * Removes a task from the list
+ *
+ * @param taskName Name of a task to be removed
+ */
+ void RemoveTask( const char *taskName );
+private:
+ TaskList *m_taskList;
+ int m_interval;
+ bool m_done;
+ bool m_running;
+};
+
+#endif /* __SCHEDULER_H__ */
+
diff --git a/base/tps/src/include/httpClient/httpc/SecurityHeaders.h b/base/tps/src/include/httpClient/httpc/SecurityHeaders.h
new file mode 100644
index 000000000..a54ecb1a2
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SecurityHeaders.h
@@ -0,0 +1,48 @@
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __SECURITY_HEADERS_H__
+#define __SECURITY_HEADERS_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+// SOAP header elements defined by WS-SECURITY and used to transfer
+// username and password
+#define HEADER_FIELD_USERNAME "Username"
+#define HEADER_FIELD_PASSWORD "Password"
+#define HEADER_FIELD_SECURITY "Security"
+#define HEADER_FIELD_NS "http://schemas.xmlsoap.org/ws/2002/04/secext"
+#define HEADER_FIELD_TOKEN "UsernameToken"
+
+#endif /* __SECURITY_HEADERS_H__ */
+
diff --git a/base/tps/src/include/httpClient/httpc/ServerConnection.h b/base/tps/src/include/httpClient/httpc/ServerConnection.h
new file mode 100644
index 000000000..bc33aa216
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ServerConnection.h
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __SERVER_CONNECTION_H
+#define __SERVER_CONNECTION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ServerConnection.h 1.000 06/12/2002
+ *
+ * This class handles server side connections. The accept happens on
+ * a separate thread and newly accepted connection are polled for
+ * read ready state. Once data is available on one or more connections
+ * the listeners are notified about it.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL ServerConnection {
+ friend class PollThread;
+ friend class AcceptThread;
+public:
+ /**
+ * Constructor
+ */
+ ServerConnection();
+
+ /**
+ * Destructor
+ */
+ virtual ~ServerConnection();
+
+public:
+ /**
+ * Registers a listener interface to notify on the connections
+ *
+ * @param listener listener object
+ * @return 0 on success, negative error code otherwise
+ */
+ int RegisterListener(ConnectionListener* listener);
+
+ /**
+ * Listens for connections on a specified socket
+ *
+ * @param host host name / ip
+ * @param port listen port
+ * @return 0 on success, negative error code otherwise
+ */
+
+ int Start(char* host, int port);
+
+ /**
+ * Listens for connections on a specified socket for SSL connections
+ *
+ * @param host host name / ip
+ * @param port listen port
+ * @param nickename name of the server cert
+ * @param password password for DB
+ * @param requestCert request client certficate for authentication
+ * @return 0 on success, negative error code otherwise
+ */
+ int Start( char* host,
+ int port,
+ const char* nickname,
+ int requestcert);
+
+ /**
+ * Closes the server connection
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+ int Shutdown();
+
+ /**
+ * Releases the connection to the read pool.
+ *
+ * @param conn a connection object
+ */
+ void PollRead(Connection* conn);
+
+ /**
+ * Releases the connection to the write pool.
+ *
+ * @param conn a connection object
+ */
+ void Release(Connection* conn);
+
+ /**
+ * Gets a connection from the write pool. This connection should be
+ * returned to the pool after writing.
+ *
+ * @return 0 on success, negative error code otherwise
+ */
+ Connection* GetConnection();
+
+ /**
+ * Returns the number of connections
+ *
+ * @return number of connections
+ */
+ int GetCount();
+
+ static void Poll(void* arg);
+ static void Accept(void* arg);
+
+protected:
+ /**
+ * Protocol specific implementations should implement this
+ * function and return their own connection object
+ *
+ * @return a newly created connection
+ */
+ virtual Connection* AcceptedConnection();
+
+ const char* GetPeerHost(Connection* conn);
+ int GetPeerPort(Connection* conn);
+
+private:
+ int InternalStart();
+ void SetServerFlag(Connection* conn);
+ PRFileDesc* GetFD( Connection* conn );
+ void SetSocket(Connection* conn, Socket* socket);
+ int UpdateWritePool(Connection* conn);
+
+private:
+ ServerSocket* m_server;
+ ConnectionListener* m_connectionListener;
+
+ Pool* m_readPool;
+ Pool* m_writePool;
+
+ PRLock* m_readLock;
+ PRLock* m_writeLock;
+
+ PRBool m_threadInitialized;
+ PRLock* m_threadLock;
+ PRCondVar* m_threadCondv;
+
+ int m_totalConnections;
+ bool m_serverRunning;
+};
+
+#endif // __SERVER_CONNECTION_H
+
+
diff --git a/base/tps/src/include/httpClient/httpc/ServerHeaderProcessor.h b/base/tps/src/include/httpClient/httpc/ServerHeaderProcessor.h
new file mode 100644
index 000000000..213d3b13b
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ServerHeaderProcessor.h
@@ -0,0 +1,72 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef __WASP_SERVER_HEADER_PROCESSOR_H
+#define __WASP_SERVER_HEADER_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <waspc/config/config.h>
+#include <waspc/util/exceptions.h>
+#include <waspc/xmlprotocol/header/HeaderProcessor.h>
+
+class ServerHeaderProcessorItemConfiguration;
+
+/**
+ * Creates WS-Security header with a session token
+ */
+class EXPORT_DECL ServerHeaderProcessor : public WASP_HeaderProcessor {
+protected:
+ virtual ~ServerHeaderProcessor();
+public:
+ ServerHeaderProcessor();
+
+ //inherited methods from WASP_Configurable
+ virtual void load (WASP_Configuration *, EXCENV_DECL);
+ virtual void init (EXCENV_DECL);
+ virtual void destroy ();
+
+ //inherited from WASP_HeaderProcessor
+ virtual void processInput(WASP_XMLProtocolMessage *message, EXCENV_DECL);
+ virtual void processOutput(WASP_XMLProtocolMessage *message, EXCENV_DECL);
+ virtual void processInputFault(WASP_XMLProtocolMessage *message, EXCENV_DECL);
+ virtual void processOutputFault(WASP_XMLProtocolMessage *message, EXCENV_DECL);
+ virtual WASP_String **getUnderstandHeaders(int &count, EXCENV_DECL);
+
+protected:
+ WASP_String **mppsUnderstandHeaderNamesAndNs;
+ int miUnderstandHeaderCount;
+};
+
+#endif //__WASP_SERVER_HEADER_PROCESSOR_H
diff --git a/base/tps/src/include/httpClient/httpc/ServerSocket.h b/base/tps/src/include/httpClient/httpc/ServerSocket.h
new file mode 100644
index 000000000..3cec2444a
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ServerSocket.h
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __SERVER_SOCKET_H
+#define __SERVER_SOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ServerSocket.h 1.000 06/12/2002
+ *
+ * A NSPR implementation of ServerSocket
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL ServerSocket {
+public:
+
+ /**
+ * Constructor - Creates a new TCP socket
+ *
+ * @param host host name / ip
+ * @param port a listen port
+ */
+ ServerSocket(const char* host, int port);
+
+ /**
+ * Constructor - Creates a new TCP socket
+ *
+ * @param port a listen port
+ */
+ ServerSocket(int port);
+
+ /**
+ * Desstructor
+ */
+ virtual ~ServerSocket();
+
+public:
+
+ /**
+ * Binds the socket to the specified port and starts listening for
+ * connections. The first connection is accepted from the queue of
+ * pending connections and creates a new socket for the newly accepted
+ * connection. The accept is blocked with no time out in its own thread.
+ *
+ * @return a new socket for the newly accepted connection
+ */
+ virtual Socket* Accept();
+
+ /**
+ * Closes the server socket
+ */
+ virtual void Shutdown();
+
+protected:
+ /**
+ * Internal method to call accept. Sub classes should override this
+ * to provide their own implementation for returned sockets.
+ *
+ * @return a newly accepted socket
+ */
+ virtual Socket* InternalAccept(PRFileDesc* fd);
+
+protected:
+ bool m_initialized;
+
+private:
+ PRFileDesc* m_fd;
+ PRNetAddr m_addr;
+ char* m_host;
+ int m_port;
+ int m_backlog;
+};
+
+#endif // __SERVER_SOCKET_H
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/Socket.h b/base/tps/src/include/httpClient/httpc/Socket.h
new file mode 100644
index 000000000..c2ef4afd4
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/Socket.h
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __SOCKET_H
+#define __SOCKET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Socket.h 1.000 06/12/2002
+ *
+ * A NSPR implementation of socket
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL Socket {
+ friend class ServerSocket;
+ friend class ServerConnection;
+public:
+
+ /**
+ * Constructor
+ */
+ Socket();
+
+ /**
+ * Constructor - creates a socket connecting to the host and port
+ *
+ * @param host hostname to connect to
+ * @param port port of the machine
+ */
+ Socket(const char* host, int port);
+
+ /**
+ * Destructor
+ */
+ virtual ~Socket();
+
+public:
+
+ /**
+ * Reads specified number of bytes from the socket. This is a blocking
+ * socket read with timeout.
+ *
+ * @param buf buffer to read into
+ * @param size number of bytes to read
+ * @param timeout timeout before the read terminates
+ * @return number of bytes actually read
+ */
+ int Read(void* buf, int size, long timeout);
+
+ /**
+ * Writes specified number of bytes to the socket. This is a blocking
+ * socket write with timeout.
+ *
+ * @param buf buffer to write from
+ * @param size number of bytes to write
+ * @param timeout timeout before the write terminates
+ * @return number of bytes actually written
+ */
+ int Write(void* buf, int size, long timeout);
+
+ /**
+ * Gets ip address for a specified socket
+ *
+ * @return ip address
+ */
+ const char* GetLocalIp();
+
+ /**
+ * Gets port for a specified socket
+ *
+ * @return port
+ */
+ int GetLocalPort();
+
+ /**
+ * Gets ip address of a connected peer
+ *
+ * @return ip address
+ */
+ const char* GetPeerIp();
+
+ /**
+ * Gets port of a connected peer
+ *
+ * @return ip address
+ */
+ int GetPeerPort();
+
+ /**
+ * Shuts down part of a full-duplex connection on a specified socket
+ *
+ * @param how the kind of disallowed operations on the socket
+ * the possible values are :
+ * PR_SHUTDOWN_RCV
+ * PR_SHUTDOWN_SEND
+ * PR_SHUTDOWN_BOTH
+ */
+ void Shutdown(PRShutdownHow how);
+
+protected:
+ int Init(PRFileDesc* fd);
+
+private:
+ void CancelIO(PRInt32 err);
+
+protected:
+ PRFileDesc* m_fd;
+
+private:
+ char* m_localIp;
+ char* m_peerIp;
+ int m_localPort;
+ int m_peerPort;
+ bool m_initialized;
+ PRLock* m_readLock;
+ PRLock* m_writeLock;
+};
+
+#endif // __SOCKET_H
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SocketINC.h b/base/tps/src/include/httpClient/httpc/SocketINC.h
new file mode 100644
index 000000000..43b36c9a0
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SocketINC.h
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _SOCKET_INC_H_
+#define _SOCKET_INC_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * SocketINC.h 1.000 06/12/2002
+ *
+ * Public header file for Socket / Connection module
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+/**************************************************
+ * Imported header files
+ **************************************************/
+#include <time.h>
+#include <string.h>
+
+#include "nspr.h"
+#include "plhash.h"
+#include "plstr.h"
+#include "private/pprio.h"
+
+#include "pk11func.h"
+#include "secitem.h"
+#include "ssl.h"
+#include "certt.h"
+#include "nss.h"
+#include "secrng.h"
+#include "secder.h"
+#include "key.h"
+#include "sslproto.h"
+
+#include "httpClient/httpc/Defines.h" // ??? SSR should be spilt into respective modules
+#include "httpClient/httpc/Pool.h"
+#include "httpClient/httpc/DebugLogger.h"
+#include "httpClient/httpc/ErrorLogger.h"
+#include "httpClient/httpc/CERTUtil.h"
+#include "httpClient/httpc/PSPRUtil.h"
+
+/**************************************************
+ * Socket / Connection module header files
+ **************************************************/
+#include "httpClient/httpc/Socket.h"
+#include "httpClient/httpc/ServerSocket.h"
+#include "httpClient/httpc/SSLSocket.h"
+#include "httpClient/httpc/SSLServerSocket.h"
+#include "httpClient/httpc/Connection.h"
+#include "httpClient/httpc/ConnectionListener.h"
+#include "httpClient/httpc/ServerConnection.h"
+
+
+/*************************************************
+ * Error codes used by this module
+ *************************************************/
+// Socket errors
+typedef enum {
+ SOCKET_ERROR_CREATE_SOCKET = -2001,
+ SOCKET_ERROR_SET_OPTION = -2002,
+ SOCKET_ERROR_BIND = -2003,
+ SOCKET_ERROR_LISTEN = -2004,
+ SOCKET_ERROR_CONNECTION_CLOSED = -2005,
+ SOCKET_ERROR_READ = -2006,
+ SOCKET_ERROR_WRITE = -2007,
+ SOCKET_ERROR_ACCEPT_THREAD = -2008,
+ SOCKET_ERROR_ALREADY_REGISTERED = -2009,
+ SOCKET_ERROR_ALREADY_LISTENING = -2010,
+ SOCKET_ERROR_POLL_THREAD = -2011,
+ SOCKET_ERROR_NO_LISTENER = -2012,
+ SOCKET_ERROR_POLL = -2013,
+ SOCKET_ERROR_POLL_TIMED_OUT = -2014,
+ SOCKET_ERROR_ALREADY_CONNECTED = -2015,
+ SOCKET_ERROR_INITIALIZATION_FAILED = -2016
+} SocketError;
+
+typedef enum {
+ SSL_ERROR_SERVER_CERT = -2016,
+ SSL_ERROR_SERVER_PRIVATE_KEY = -2017,
+ SSL_ERROR_IMPORT_FD = -2018,
+ SSL_ERROR_OPTION_SECURITY = -2019,
+ SSL_ERROR_OPTION_SERVER_HANDSHAKE = -2020,
+ SSL_ERROR_OPTION_REQUEST_CERTIFCATE = -2021,
+ SSL_ERROR_OPTION_REQUIRE_CERTIFCATE = -2022,
+ SSL_ERROR_CALLBACK_AUTH_CERTIFICATE = -2023,
+ SSL_ERROR_CALLBACK_BAD_CERT_HANDLER = -2024,
+ SSL_ERROR_CALLBACK_HAND_SHAKE = -2025,
+ SSL_ERROR_CALLBACK_PASSWORD_ARG = -2026,
+ SSL_ERROR_CONFIG_SECURE_SERVER = -2027,
+ SSL_ERROR_RESET_HAND_SHAKE = -2028,
+ SSL_ERROR_OPTION_ENABLE_FDX = -2029
+} SslError;
+
+/**************************************************
+ * Defines used by this module
+ **************************************************/
+#define SOCKET_DEFAULT_HOST_NAME "localhost"
+#define SOCKET_DEFAULT_READ_TIME_OUT 1000UL // 1 sec
+#define SOCKET_DEFAULT_WRITE_TIME_OUT 0xffffffffUL // infinte
+#define SOCKET_DEFAULT_READ_BUFFER_SIZE 4096 // 4k
+#define SOCKET_DEFAULT_WRITE_BUFFER_SIZE 4096 // 4k
+#define SOCKET_DEFAULT_POLL_TIMEOUT 1000UL // 1 sec
+#define SOCKET_DEFAULT_BACKLOG 50 // pending conns
+#define SOCKET_DEFAULT_POOL_SIZE 100 // conn pool size
+
+typedef enum {
+ SOCKET_ERROR_SEVERE = 1,
+ SOCKET_ERROR_WARNING = 2,
+ SOCKET_ERROR_INFO = 3
+} SocketErrorLevel;
+
+
+typedef enum {
+ REQUEST_CERT_NONE = 0,
+ REQUIRE_CERT_NONE = 1,
+ REQUEST_CERT_ONCE = 2,
+ REQUIRE_CERT_ONCE = 3,
+ REQUEST_CERT_ALL = 4,
+ REQUIRE_CERT_ALL = 5
+} RequireCert;
+
+#endif // _SOCKET_INC_H_
+
+
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/SocketLib.h b/base/tps/src/include/httpClient/httpc/SocketLib.h
new file mode 100644
index 000000000..5a00b2ecb
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/SocketLib.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _SOCKET_LIB_H_
+#define _SOCKET_LIB_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * SocketLib.h 1.000 06/12/2002
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+#undef EXPORT_DECL
+#ifdef _MSC_VER
+#ifdef PS_SOCKET_LIB_INTERNAL
+ #define EXPORT_DECL __declspec( dllexport )
+#else
+ #define EXPORT_DECL __declspec (dllimport )
+#endif // PS_SOCKET_LIB_INTERNAL
+#else
+ #define EXPORT_DECL
+#endif // _MSC_VER
+
+#endif // _CONNECTION_LIB_H_
+
+
+
diff --git a/base/tps/src/include/httpClient/httpc/StringList.h b/base/tps/src/include/httpClient/httpc/StringList.h
new file mode 100644
index 000000000..80cd61dd6
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/StringList.h
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _STRING_LIST_H
+#define _STRING_LIST_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Simple String list class using the STL List template
+ */
+
+#include <list>
+#ifdef HPUX
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+
+#include "httpClient/httpc/Iterator.h"
+
+#ifndef HPUX
+using namespace std;
+#endif
+
+typedef EXPORT_DECL list<const char *> LISTSTR;
+
+class EXPORT_DECL StringList {
+public:
+ /**
+ * Constructor
+ */
+ StringList();
+
+ /**
+ * Destructor
+ */
+ ~StringList();
+
+ /**
+ * Appends a string to the end of the list
+ *
+ * @param value The string value to append
+ */
+ void Add( const char *value );
+
+ /**
+ * Gets the string at a particular index in the list
+ *
+ * @param index Index of the string to retrieve
+ * @return The string at the specified index, or NULL if outside
+ * the range of the list
+ */
+ const char *GetAt( int index );
+
+ /**
+ * Returns the index of a string in the list
+ *
+ * @param matchString The string to match
+ * @param startIndex The index to start searching from
+ * @return The index of the string, or -1 if not found
+ */
+ int Find( const char *matchString,
+ int startIndex );
+
+ /**
+ * Returns the number of strings in the list
+ *
+ * @return The number of strings in the list
+ */
+ int GetCount();
+
+ /**
+ * Inserts a string before the specified position
+ *
+ * @param index Position to insert the string
+ * @param value The string to insert
+ * @return The index of the string, or -1 if the requested index
+ * is beyond the end of the list
+ */
+ int Insert( int index, const char *value );
+
+ /**
+ * Removes a string at the specified position
+ *
+ * @param index Position to remove the string
+ * @return 0 on sucess, or -1 if the requested index
+ * is beyond the end of the list
+ */
+ int Remove( int index );
+
+ /**
+ * Removes all strings
+ */
+ void RemoveAll();
+
+ /**
+ * Returns an iterator over strings in the list
+ *
+ * @return An iterator over strings in the list
+ */
+ Iterator *GetIterator();
+
+ EXPORT_DECL friend ostream& operator<< ( ostream& os, StringList& list );
+
+protected:
+ /**
+ * Gets the iterator for an indexed element
+ *
+ * @param index Position to get
+ * @return Iterator for the position (could be end())
+ */
+ LISTSTR::iterator GetIteratorAt( int index );
+
+private:
+ LISTSTR m_list;
+};
+
+#endif // _STRING_LIST_H
diff --git a/base/tps/src/include/httpClient/httpc/StringUtil.h b/base/tps/src/include/httpClient/httpc/StringUtil.h
new file mode 100644
index 000000000..5c8955d37
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/StringUtil.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _STRING_UTIL_H
+#define _STRING_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * String utility functions
+ */
+
+class EXPORT_DECL StringUtil {
+private:
+ /**
+ * Constructor - can't be instantiated
+ */
+ StringUtil() {}
+
+ /**
+ * Destructor
+ */
+ ~StringUtil() {}
+
+public:
+ /**
+ * Normalizes a screen name
+ *
+ * @param raw The raw screen name
+ * @param normalized The normalized screen name (lower case, no spaces)
+ */
+ static void NormalizeScreenName( const char *raw, char *normalized );
+
+ /**
+ * Converts the string to lower case
+ *
+ * @param raw string to be converted
+ */
+ static void ToLower(char* raw);
+};
+
+#endif // _STRING_UTIL_H
diff --git a/base/tps/src/include/httpClient/httpc/TaskList.h b/base/tps/src/include/httpClient/httpc/TaskList.h
new file mode 100644
index 000000000..779d27ead
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/TaskList.h
@@ -0,0 +1,114 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __TASK_LIST_H__
+#define __TASK_LIST_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * Base class for scheduled tasks in Presence Server
+ */
+
+class EXPORT_DECL TaskList {
+public:
+ /**
+ * Constructor - creates an empty task list
+ *
+ * @param name Name of task list
+ */
+ TaskList( const char *name );
+ /**
+ * Destructor - Empties the task list, deleting each entry
+ */
+ virtual ~TaskList();
+ /**
+ * Returns true if the task list is empty
+ *
+ * @return true if the task list is empty
+ */
+ bool IsEmpty();
+ /**
+ * Adds a task to the list; the list is sorted by execution time
+ *
+ * @param node An entry to add
+ * @return The added entry
+ */
+ ScheduledTask *Add( ScheduledTask *node );
+ /**
+ * Removes a node from the list but does not delete it
+ *
+ * @param taskName The name of the node to remove
+ * @return The node with the name taskName, or NULL if not found
+ */
+ ScheduledTask *Remove( const char *taskName );
+ /**
+ * Executes each task for which the time is right in a separate thread;
+ * if the task is repeating, a new entry is created for it, otherwise
+ * it is removed from the list
+ *
+ * @return The number of tasks executed
+ */
+ int ExecuteCurrent();
+ /**
+ * Dumps the task list to the debug log
+ *
+ * @param logLevel Lowest debug level for which the log should be dumped
+ */
+ void Dump( int logLevel );
+private:
+ /**
+ * Removes a node from the list but does not delete it; does not lock
+ *
+ * @param node The node to remove
+ * @return The node
+ */
+ ScheduledTask *InternalRemove( ScheduledTask *node );
+ /**
+ * Adds a task to the list; the list is sorted by execution time
+ *
+ * @param node An entry to add
+ * @return The added entry
+ */
+ ScheduledTask *InternalAdd( ScheduledTask *node );
+
+ char *m_name;
+ ScheduledTask *m_next;
+ int m_interval;
+ PRLock *m_lock;
+};
+
+#endif /* __TASK_LIST_H__ */
+
diff --git a/base/tps/src/include/httpClient/httpc/ThreadPool.h b/base/tps/src/include/httpClient/httpc/ThreadPool.h
new file mode 100644
index 000000000..389d42606
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/ThreadPool.h
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef __THREAD_POOL_H
+#define __THREAD_POOL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * ThreadPool.h 1.000 06/12/2002
+ *
+ * A worker thread pool.
+ *
+ * @author Surendra Rajam
+ * @version 1.000, 06/12/2002
+ */
+
+class EXPORT_DECL ThreadPool {
+ friend class WorkerThread;
+public:
+ /**
+ * Constructor - creates the pool with default values
+ *
+ * @param name name of the threadpool
+ */
+ ThreadPool(const char* name);
+
+ /**
+ * Constructor
+ *
+ * @param name name of the threadpool
+ * @param min minimum threads in the pool
+ * @param max maximum threads that can be created
+ * @param timeout timeout for each thread
+ */
+ ThreadPool(const char* name, int min, int max, int timeout);
+
+ /**
+ * Destructor
+ */
+ virtual ~ThreadPool();
+
+public:
+
+ /**
+ * Initializes the thread pool with minimum threads
+ */
+ void Init();
+
+ /**
+ * Shutdown the thread pool
+ */
+ void Shutdown();
+
+ /**
+ * Adds a task for future execution
+ *
+ * @param task a task to execute
+ */
+ void AddTask(ScheduledTask* task);
+
+ /**
+ * Executes the task immediately
+ *
+ * @param task a task to execute
+ */
+ void ExecuteTask(ScheduledTask* task);
+
+ /**
+ * Gets the number of active threads in the pool
+ *
+ * @return number of active threads
+ */
+ int GetThreads();
+
+ /**
+ * Gets the number of pending tasks in the list
+ *
+ * @return number of pending tasks
+ */
+ int GetPendingTasks();
+
+ /**
+ * Function to start a NSPR thread
+ */
+ static void StartWorkerThread(void* arg);
+
+private:
+ /**
+ * Initializes constructor params
+ */
+ void ConstructorInit(const char* name, int min, int max, int timeout);
+
+ /**
+ * Creates a new thread
+ */
+ void CreateNewThread();
+
+ /**
+ * Notify one of the threads waiting on a condition
+ */
+ void Notify();
+
+private:
+ char* m_name;
+ TaskList* m_taskList;
+
+ int m_minThreads;
+ int m_maxThreads;
+ int m_timeout;
+
+ int m_threads;
+ int m_activeThreads;
+
+ PRBool m_threadWait;
+ PRLock* m_threadLock;
+ PRCondVar* m_threadCondVar;
+
+ PRBool m_newThreadInitialized;
+ PRLock* m_newThreadLock;
+ PRCondVar* m_newThreadCondVar;
+
+ bool m_keepRunning;
+};
+
+#endif // __THREAD_POOL_H
+
diff --git a/base/tps/src/include/httpClient/httpc/URLUtil.h b/base/tps/src/include/httpClient/httpc/URLUtil.h
new file mode 100644
index 000000000..379986999
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/URLUtil.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _URL_UTIL_H
+#define _URL_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/**
+ * URL utility functions
+ */
+
+typedef enum {
+ URL_TYPE_HTTP = 1,
+ URL_TYPE_HTTPS = 2,
+ URL_TYPE_LDAP = 3,
+ URL_TYPE_LDAPS = 4,
+ URL_TYPE_UNKNOWN = 5
+} UrlType;
+
+class EXPORT_DECL URLUtil {
+private:
+ /**
+ * Constructor - can't be instantiated
+ */
+ URLUtil() {}
+
+ /**
+ * Destructor
+ */
+ ~URLUtil() {}
+
+public:
+ /**
+ * Parses the URL
+ *
+ * @param url url to parse
+ * @param type protocol header type
+ * @param host hostname from the url
+ * @param port port number from the url
+ * @param path uri from the url
+ * @return 0 on success, negative error code otherwise
+ */
+ static int ParseURL( const char* url,
+ int* type,
+ char** host,
+ int* port,
+ char** path );
+
+private:
+ static int ParseURLType(const char* url, int* type, int* hlen);
+ static int ParseAtPort(const char* url, int* port, char** path);
+ static int ParseAtPath(const char* url, char** path);
+ static int GetPort(const char* url, int* port);
+ static bool IsAsciiSpace(char c);
+ static bool IsAsciiDigit(char c);
+};
+
+#endif // _URL_UTIL_H
+
diff --git a/base/tps/src/include/httpClient/httpc/engine.h b/base/tps/src/include/httpClient/httpc/engine.h
new file mode 100644
index 000000000..9a57b024e
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/engine.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _HTTP_ENGINE_
+#define _HTTP_ENGINE_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/request.h"
+
+class __EXPORT Engine {
+ public:
+ Engine() {};
+ ~Engine() {};
+
+ PRFileDesc *_doConnect(PRNetAddr *addr, PRBool SSLOn = PR_FALSE,
+ const PRInt32* cipherSuite = NULL,
+ PRInt32 count = 0, const char* nickname = NULL,
+ PRBool handshake = PR_FALSE,
+ /*const SecurityProtocols& secprots = SecurityProtocols() ,*/
+ const char *serverName ="localhost",
+ PRIntervalTime iv = PR_SecondsToInterval(30));
+ static PRIntervalTime globaltimeout;
+};
+
+
+class __EXPORT HttpEngine: public Engine {
+ public:
+ HttpEngine() {};
+ ~HttpEngine() {};
+
+ PSHttpResponse *makeRequest( PSHttpRequest &request,
+ const PSHttpServer& server,
+ int timeout = 30, PRBool expectChunked = PR_FALSE);
+};
+
+PRBool __EXPORT InitSecurity(char* dbpath, char* certname, char* certpassword,
+ char * prefix ,int verify=1);
+PRBool __EXPORT EnableCipher(const char* ciphername);
+void __EXPORT EnableAllSSL3Ciphers();
+void __EXPORT EnableAllTLSCiphers();
+__EXPORT const char * nscperror_lookup(int error);
+
+#endif
diff --git a/base/tps/src/include/httpClient/httpc/http.h b/base/tps/src/include/httpClient/httpc/http.h
new file mode 100644
index 000000000..0dccfddbd
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/http.h
@@ -0,0 +1,120 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _HTTP_SERVER_
+#define _HTTP_SERVER_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include <prnetdb.h>
+#include <prio.h>
+#include <time.h>
+#include <plhash.h>
+#include <nspr.h>
+#include <plstr.h>
+
+#include "httpClient/httpc/PSCommonLib.h"
+#include "httpClient/httpc/Cache.h"
+#include "httpClient/httpc/Defines.h"
+//#include "httpClient/httpc/DebugLogger.h"
+//#include "httpClient/httpc/ErrorLogger.h"
+
+#ifdef WIN32
+#define __EXPORT __declspec(dllexport)
+#else
+#define __EXPORT
+#endif
+
+class PSHttpRequest;
+
+class __EXPORT PSHttpServer
+{
+public:
+ PSHttpServer(const char *addr, PRUint16 af);
+ ~PSHttpServer();
+
+ long getIp() const;
+ long getPort() const;
+ const char *getAddr() const;
+ void getAddr(PRNetAddr *addr) const;
+ void setSSL(PRBool SSLstate);
+ PRBool isSSL() const;
+
+ // put a file on the server of size bytes
+ PRBool putFile(const char *uri, int size) const;
+ PRBool putFile(const char* uri, const char* localFile) const;
+
+private:
+ char *_addr;
+ PRNetAddr _netAddr;
+ PRBool SSLOn;
+ PRBool _putFile(PSHttpRequest& rq) const;
+};
+
+typedef __EXPORT enum HttpProtocol_e { HTTPNA = 0x0,
+ HTTP09 = 0x1,
+ HTTP10 = 0x2,
+ HTTP11 = 0x4,
+ HTTPBOGUS = 0x8 } HttpProtocol;
+
+#define NUM_PROTOS 5 // needed for arrays of tests
+
+__EXPORT const char *HttpProtocolToString(HttpProtocol);
+
+class __EXPORT HttpMessage
+{
+ public:
+ HttpMessage(long len = 0, const char* buf = NULL);
+ ~HttpMessage();
+
+ PRBool operator == (const HttpMessage& rhs);
+
+ void addData(long len, const void* buf);
+
+ // set data on the message
+ void setProtocol(HttpProtocol prot);
+
+ // get data about the message
+ HttpProtocol getProtocol() const;
+
+
+ protected:
+ char* firstline; // first line - may be the request-line or server status
+ HttpProtocol proto;
+ long cl;
+};
+
+
+#endif
diff --git a/base/tps/src/include/httpClient/httpc/request.h b/base/tps/src/include/httpClient/httpc/request.h
new file mode 100644
index 000000000..0399732ef
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/request.h
@@ -0,0 +1,115 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef _REQUEST_H_
+#define _REQUEST_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/http.h"
+
+// abstract request class
+class __EXPORT NetRequest
+{
+ public:
+ NetRequest(const PSHttpServer* server);
+ PRBool isSSL() const;
+ void setSSL(PRBool SSLstate);
+ void getAddr(PRNetAddr *addr);
+ const char* getAddr();
+ const char* getHost();
+ const PSHttpServer * getServer();
+ void setServer(PSHttpServer* _server);
+ PRIntervalTime getTimeout() const;
+ const PRInt32* cipherSet;
+ PRInt32 cipherCount;
+ PRBool handshake;
+// SecurityProtocols secprots;
+
+ protected:
+ PRBool SSLOn;
+ const PSHttpServer * _server;
+ PRIntervalTime timeout;
+
+};
+
+// Netscape-style request
+class __EXPORT PSHttpRequest: public HttpMessage, public NetRequest
+{
+public:
+ PSHttpRequest(const PSHttpServer* server, const char *uri, HttpProtocol proto, PRIntervalTime to);
+ virtual ~PSHttpRequest();
+
+ // connection related stuff
+
+ // set data on the request
+ PRBool setMethod(const char *method);
+ PRBool addHeader(const char *name, const char *value);
+ PRBool addRandomBody(int size);
+ PRBool useLocalFileAsBody(const char* fileName);
+ PRBool setBody(int size, const char* body);
+ void setExpectedResponseLength(int size);
+ void setExpectStandardBody();
+ void setExpectDynamicBody();
+ void setHangupOk();
+ PRBool isHangupOk();
+
+ // get data about the request
+ char *getMethod();
+ //HttpProtocol getProtocol();
+ const char *getHeader(const char *name);
+ int getExpectedResponseLength();
+ PRBool getExpectStandardBody();
+ PRBool getExpectDynamicBody();
+
+ PRBool send(PRFileDesc *sock);
+ void setCertNickName(const char *);
+ char *getCertNickName();
+
+private:
+ char *_method;
+ char *_uri;
+ HttpProtocol _proto;
+ int _bodyLength;
+ char *_body;
+ char *nickName;
+ StringKeyCache *_headers;
+ int _expectedResponseLength;
+ PRBool _expectStandardBody;
+ PRBool _expectDynamicBody;
+ PRBool _hangupOk;
+ PRFileDesc* _fileFd;
+};
+
+#endif
diff --git a/base/tps/src/include/httpClient/httpc/response.h b/base/tps/src/include/httpClient/httpc/response.h
new file mode 100644
index 000000000..5c45d574c
--- /dev/null
+++ b/base/tps/src/include/httpClient/httpc/response.h
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ */
+/** BEGIN COPYRIGHT BLOCK
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifndef _RESPONSE_H_
+#define _RESPONSE_H_
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/request.h"
+
+class __EXPORT RecvBuf
+{
+public:
+ RecvBuf(const PRFileDesc *socket, int size, int timeout = 30);
+ virtual ~RecvBuf();
+
+ char getChar();
+ void putBack();
+
+ void setChunkedMode();
+ int getAllContent();
+ int getTimeout();
+
+ char *get_content();
+ int get_contentSize();
+
+ class EndOfFile {};
+ class EndOfChunking {};
+
+private:
+ char _getChar();
+ PRBool _getBytes(int size);
+
+ const PRFileDesc *_socket;
+ int _allocSize;
+ char *_buf;
+ int _curPos;
+ int _curSize;
+
+ PRBool _chunkedMode;
+ int _currentChunkSize;
+ int _currentChunkBytesRead;
+ PRIntervalTime _timeout;
+ char *_content;
+ int _contentSize;
+};
+
+
+class __EXPORT Response
+{
+ public:
+ Response(const PRFileDesc *sock, NetRequest *request);
+
+ protected:
+ const PRFileDesc *_socket;
+ NetRequest *_request;
+};
+
+
+class __EXPORT PSHttpResponse: public Response
+{
+ public:
+ PSHttpResponse( const PRFileDesc *sock,
+ PSHttpRequest *request );
+ PSHttpResponse( const PRFileDesc *sock,
+ PSHttpRequest *request,
+ int timeout, PRBool expectChunked );
+ virtual ~PSHttpResponse();
+ virtual PRBool processResponse();
+
+ int getReturnCode();
+ long getStatus();
+ char *getStatusString();
+ HttpProtocol getProtocol();
+ char *getHeader(const char *name);
+ int getHeaders(char ***keys);
+
+ PRBool checkKeepAlive(); // return true if we *expect* keepalive based on request
+ PRBool checkConnection(); // return true if connection is open
+
+ long getBodyLength();
+ char *getContent();
+ void freeContent();
+ int getContentSize();
+ char *toString();
+
+ protected:
+ PSHttpRequest *_request;
+ int _verifyStandardBody(RecvBuf &, int, PRBool);
+ PRBool _handleBody(RecvBuf &buf);
+ void _checkResponseSanity();
+
+ HttpProtocol _proto;
+ char *_protocol;
+ int retcode;
+ char *_statusNum;
+ char *_statusString;
+
+ int _keepAlive;
+ int _connectionClosed;
+
+ long _bodyLength;
+
+ PRBool _expectChunked;
+ PRBool _chunkedResponse;
+
+ StringKeyCache *_headers;
+
+ int _timeout;
+ char *_content;
+ int _contentSize;
+};
+
+
+#endif
diff --git a/base/tps/src/include/main/AttributeSpec.h b/base/tps/src/include/main/AttributeSpec.h
new file mode 100644
index 000000000..3aa0655b5
--- /dev/null
+++ b/base/tps/src/include/main/AttributeSpec.h
@@ -0,0 +1,68 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_ATTRIBUTESPEC_H
+#define RA_ATTRIBUTESPEC_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class AttributeSpec
+{
+ public:
+ AttributeSpec();
+ ~AttributeSpec();
+ public:
+ static AttributeSpec *Parse(Buffer *b, int offset);
+ void SetAttributeID(unsigned long v);
+ unsigned long GetAttributeID();
+ void SetType(BYTE v);
+ BYTE GetType();
+ void SetData(Buffer data);
+ Buffer GetData(); // this gets entire AttributeSpec
+ Buffer GetValue(); // this gets AttributeValue
+ public:
+ unsigned long m_id;
+ BYTE m_type;
+ Buffer m_data; // this contains AttributeValue
+};
+
+#endif /* RA_ATTRIBUTESPEC_H */
diff --git a/base/tps/src/include/main/AuthenticationEntry.h b/base/tps/src/include/main/AuthenticationEntry.h
new file mode 100644
index 000000000..e4ec0715c
--- /dev/null
+++ b/base/tps/src/include/main/AuthenticationEntry.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef AUTHENTICATIONENTRY_H
+#define AUTHENTICATIONENTRY_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "authentication/Authentication.h"
+
+class AuthenticationEntry
+{
+ public:
+ AuthenticationEntry();
+ virtual ~AuthenticationEntry();
+ public:
+ void SetLibrary(PRLibrary* lib);
+ PRLibrary *GetLibrary();
+ void SetId(const char *id);
+ char *GetId();
+ void SetAuthentication(Authentication *auth);
+ Authentication *GetAuthentication();
+ void SetType(const char *type);
+ char *GetType();
+
+ private:
+ PRLibrary *m_lib;
+ char *m_Id;
+ char *m_type;
+ Authentication *m_authentication;
+};
+
+#endif /* AUTHENTICATIONENTRY_H */
diff --git a/base/tps/src/include/main/Base.h b/base/tps/src/include/main/Base.h
new file mode 100644
index 000000000..3c5260178
--- /dev/null
+++ b/base/tps/src/include/main/Base.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef BASE_H
+#define BASE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "nspr.h"
+
+typedef unsigned char BYTE;
+
+enum nsNKeyMsgEnum {
+ VRFY_FAILURE,
+ VRFY_SUCCESS,
+ ENCODE_DER_PUBKEY_FAILURE,
+ B64ENCODE_FAILURE,
+ VFY_BEGIN_FAILURE,
+ VFY_UPDATE_FAILURE,
+ HTTP_REQ_EXE_FAILURE,
+ HTTP_ERROR_RCVD,
+ BASE64_DECODE_FAILURE,
+ REQ_TO_CA_SUCCESS,
+ MSG_INVALID
+};
+
+struct ReturnStatus {
+ PRStatus status;
+ nsNKeyMsgEnum statusNum;
+};
+
+#endif /* BASE_H */
diff --git a/base/tps/src/include/main/Buffer.h b/base/tps/src/include/main/Buffer.h
new file mode 100644
index 000000000..4fa7af6df
--- /dev/null
+++ b/base/tps/src/include/main/Buffer.h
@@ -0,0 +1,196 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef BUFFER_H
+#define BUFFER_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "main/Base.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * This class represents a byte array.
+ */
+class Buffer {
+
+ private:
+ BYTE *buf;
+ unsigned int len;
+ unsigned int res;
+
+ public:
+ /**
+ * Creates an empty Buffer.
+ */
+ TPS_PUBLIC Buffer() : buf(0), len(0), res(0) { }
+
+ /**
+ * Creates a Buffer of length 'len', with each byte initialized to 'b'.
+ */
+ TPS_PUBLIC Buffer(unsigned int len, BYTE b);
+
+ /**
+ * Creates a Buffer of length 'len', initialized to zeroes.
+ */
+ TPS_PUBLIC explicit Buffer(unsigned int len);
+
+ /**
+ * Creates a Buffer of length 'len', initialized from 'buf'. 'buf' must
+ * contain at least 'len' bytes.
+ */
+ TPS_PUBLIC Buffer(const BYTE* buf, unsigned int len);
+
+ /**
+ * Copy constructor.
+ */
+ TPS_PUBLIC Buffer(const Buffer& cpy);
+
+ /**
+ * Destructor.
+ */
+ TPS_PUBLIC ~Buffer();
+
+ /**
+ * Assignment operator.
+ */
+ TPS_PUBLIC Buffer& operator=(const Buffer& cpy);
+
+ /**
+ * Returns true if the two buffers are the same length and contain
+ * the same byte at each offset.
+ */
+ TPS_PUBLIC bool operator==(const Buffer& cmp) const;
+
+ /**
+ * Returns ! operator==(cmp).
+ */
+ TPS_PUBLIC bool operator!=(const Buffer& cmp) const { return ! (*this == cmp); }
+
+ /**
+ * Concatenation operator.
+ */
+ TPS_PUBLIC Buffer operator+(const Buffer&addend) const;
+
+ /**
+ * Append operators.
+ */
+ TPS_PUBLIC Buffer& operator+=(const Buffer&addend);
+ TPS_PUBLIC Buffer& operator+=(BYTE b);
+
+ /**
+ * Returns a pointer into the Buffer. This also enables the subscript
+ * operator, so you can say, for example, 'buf[4] = b' or 'b = buf[4]'.
+ */
+ TPS_PUBLIC operator BYTE*() { return buf; }
+ TPS_PUBLIC operator const BYTE*() const { return buf; }
+
+ /**
+ * The length of buffer. The actual amount of space allocated may be
+ * higher--see capacity().
+ */
+ TPS_PUBLIC unsigned int size() const { return len; }
+
+ /**
+ * The amount of memory allocated for the buffer. This is the maximum
+ * size the buffer can grow before it needs to allocate more memory.
+ */
+ TPS_PUBLIC unsigned int capacity() const { return res; }
+
+ /**
+ * Sets all bytes in the buffer to 0.
+ */
+ TPS_PUBLIC void zeroize();
+
+ /**
+ * Changes the length of the Buffer. If 'newLen' is shorter than the
+ * current length, the Buffer is truncated. If 'newLen' is longer, the
+ * new bytes are initialized to 0. If 'newLen' is the same as size(),
+ * this is a no-op.
+ */
+ TPS_PUBLIC void resize(unsigned int newLen);
+
+ /**
+ * Ensures that capacity() is at least 'reserve'. Allocates more memory
+ * if necessary. If 'reserve' is <= capacity(), this is a no-op.
+ * Does not affect size().
+ */
+ TPS_PUBLIC void reserve(unsigned int reserve);
+
+ /**
+ * Returns a new Buffer that is a substring of this Buffer, starting
+ * from offset 'start' and continuing for 'len' bytes. This Buffer
+ * must have size() >= (start + len).
+ */
+ TPS_PUBLIC Buffer substr(unsigned int start, unsigned int len) const;
+
+ /**
+ * Replaces bytes i through i+n in this Buffer using the values in 'cpy'.
+ * This Buffer is resized if necessary. The 'cpy' argument can be a
+ * Buffer.
+ */
+ TPS_PUBLIC void replace(unsigned int i, const BYTE* cpy, unsigned int n);
+
+ /**
+ * returns a hex version of the buffer
+ */
+ TPS_PUBLIC char *toHex();
+
+ /**
+ * Dumps this Buffer to the given file as formatted hex: 16 bytes per
+ * line, separated by spaces.
+ */
+ TPS_PUBLIC void dump(FILE* file) const;
+
+ /**
+ * returns a null-terminated string of the buf.
+ * should be called only by callers that are certain that buf
+ * is entirely representable by printable characters and wants
+ * a string instead.
+ */
+ TPS_PUBLIC char *string();
+
+ /**
+ * dump()s this Buffer to stdout.
+ */
+ TPS_PUBLIC void dump() const;
+
+};
+
+#endif
diff --git a/base/tps/src/include/main/ConfigStore.h b/base/tps/src/include/main/ConfigStore.h
new file mode 100644
index 000000000..d34e0ce7b
--- /dev/null
+++ b/base/tps/src/include/main/ConfigStore.h
@@ -0,0 +1,126 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef CONFIG_STORE_H
+#define CONFIG_STORE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "plhash.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+class ConfigStoreRoot;
+
+class ConfigStore
+{
+ public:
+ ConfigStore(ConfigStoreRoot* root, const char *subStoreName);
+ //ConfigStore::ConfigStore(const ConfigStore &X);
+
+ ~ConfigStore();
+ static ConfigStore *Parse(const char *s, const char *separator);
+ static ConfigStore *CreateFromConfigFile(const char *cfg_path);
+
+ int IsNameDefined(const char *name);
+ void SetFilePath(const char* cfg_file_path);
+ void Add(const char *name, const char *value);
+ void Remove(const char *name);
+ const char * GetConfig(const char *name);
+ int Size();
+ const char * GetNameAt(int pos);
+ ConfigStore GetSubStore(const char*name);
+ ConfigStore *GetPatternSubStore(const char* pattern);
+
+ // Retrieve config parameters
+ Buffer * GetConfigAsBuffer(const char *key);
+ Buffer * GetConfigAsBuffer(const char *key, const char *def);
+ int GetConfigAsInt(const char *key);
+ TPS_PUBLIC int GetConfigAsInt(const char *key, int def);
+ unsigned int GetConfigAsUnsignedInt(const char *key);
+ TPS_PUBLIC unsigned int GetConfigAsUnsignedInt(const char *key,
+ unsigned int def);
+ bool GetConfigAsBool(const char *key);
+ TPS_PUBLIC bool GetConfigAsBool(const char *key, bool def);
+ TOKENDB_PUBLIC const char *GetConfigAsString(const char *key, const char *def);
+ TPS_PUBLIC int Commit(const bool backup, char* error_msg, int len);
+ TPS_PUBLIC const char *GetConfigAsString(const char *key);
+ TPS_PUBLIC const char *GetOrderedList();
+ /**
+ * operator[] is used to look up config strings in the ConfigStore.
+ * For example:
+ * <PRE>
+ * const char *param = cfg["filename"]; // equivalent
+ * const char *param = cfg.GetConfig("filename"); // equivalent
+ * </PRE>
+ */
+ const char * operator[](const char*key);
+
+ private:
+ char *m_substore_name;
+ ConfigStoreRoot *m_root;
+ char *m_cfg_file_path;
+ PRLock *m_lock;
+};
+
+class ConfigStoreRoot
+{
+ friend class ConfigStore;
+ public:
+ ConfigStoreRoot();
+ ~ConfigStoreRoot();
+ void addref();
+ void release();
+
+ private:
+ PLHashTable* getSet();
+ PLHashTable *m_set;
+ int m_set_refcount;
+
+};
+
+
+
+#endif /* CONFIG_STORE_H */
diff --git a/base/tps/src/include/main/LogFile.h b/base/tps/src/include/main/LogFile.h
new file mode 100644
index 000000000..663929eb2
--- /dev/null
+++ b/base/tps/src/include/main/LogFile.h
@@ -0,0 +1,89 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef LOGFILE_H
+#define LOGFILE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include "main/RA_Context.h"
+#include "main/Util.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class LogFile {
+ protected:
+ PRFileDesc *m_fd;
+ char* m_fname;
+ volatile bool m_signed_log;
+ volatile size_t m_bytes_written;
+ volatile bool m_signed;
+ PRMonitor *m_monitor;
+ RA_Context *m_ctx;
+
+ public:
+ TPS_PUBLIC LogFile();
+ TPS_PUBLIC virtual ~LogFile() {}
+
+ /* startup and shutdown */
+ virtual int startup(RA_Context* ctx, const char* prefix, const char *fname, bool sign_audit);
+ virtual void shutdown();
+ virtual void child_init() {}
+
+ /* open/close the file */
+ int open();
+ int close();
+ bool isOpen();
+
+ /* read and write */
+ virtual int write(const char * msg);
+ int printf(const char* fmt, ...);
+ int write(char *msg, size_t n);
+ int vfprintf(const char* fmt, va_list ap);
+ int ReadLine(char *buf, int buf_len, int *removed_return);
+
+ /* accessor and setters */
+ void setSigned(bool val);
+ bool getSigned();
+ int get_bytes_written();
+ void set_bytes_written(int val);
+ RA_Context * get_context();
+ void set_context(RA_Context *ctx);
+};
+
+#endif
diff --git a/base/tps/src/include/main/Login.h b/base/tps/src/include/main/Login.h
new file mode 100644
index 000000000..81a22870e
--- /dev/null
+++ b/base/tps/src/include/main/Login.h
@@ -0,0 +1,55 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef LOGIN_H
+#define LOGIN_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+
+class Login
+{
+ public:
+ Login(char *uid, char *pwd);
+ ~Login();
+ public:
+ char *GetUID();
+ char *GetPassword();
+ private:
+ char *m_uid;
+ char *m_pwd;
+};
+
+#endif /* LOGIN_H */
diff --git a/base/tps/src/include/main/Memory.h b/base/tps/src/include/main/Memory.h
new file mode 100644
index 000000000..ca9608466
--- /dev/null
+++ b/base/tps/src/include/main/Memory.h
@@ -0,0 +1,130 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_MEMORY_H
+#define RA_MEMORY_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/MemoryMgr.h"
+
+#ifdef MEM_PROFILING
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+extern void MEM_init(char *audit_file, char *dump_file);
+extern void MEM_shutdown();
+extern void MEM_dump_unfree();
+extern char *MEM_strdup(const char *, const char *, const char *, const char *, int);
+extern void *MEM_malloc(int, const char *, const char *, const char *, int);
+extern void MEM_free(void *i, const char *, const char *, const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+#ifdef strdup
+#undef strdup
+#endif
+
+#ifdef PL_strdup
+#undef PL_strdup
+#endif
+
+#ifdef PL_strfree
+#undef PL_strfree
+#endif
+
+
+#define strdup(s) MEM_strdup(s,"strcpy",__FUNCTION__,__FILE__,__LINE__)
+#define malloc(size) MEM_malloc(size,"malloc",__FUNCTION__,__FILE__,__LINE__)
+#define free(p) MEM_free(p,"free",__FUNCTION__,__FILE__,__LINE__)
+#define PR_MALLOC(size) MEM_malloc(size,"PL_MALLOC",__FUNCTION__,__FILE__,__LINE__)
+#define PR_Malloc(size) MEM_malloc(size,"PR_Malloc",__FUNCTION__,__FILE__,__LINE__)
+#define PR_Free(p) MEM_free(p,"free",__FUNCTION__,__FILE__,__LINE__)
+
+#define PL_strdup(s) MEM_strdup(s,"PL_strdup",__FUNCTION__,__FILE__,__LINE__)
+#define PL_strfree(p) MEM_free(p,"PL_strfree",__FUNCTION__,__FILE__,__LINE__)
+
+#if 0
+extern void *operator new(size_t size, const char *func, const char *file, int line);
+extern void *operator new[](size_t size, const char *func, const char *file, int line);
+#endif
+extern void operator delete(void* p);
+extern void operator delete[](void* p);
+
+inline void *operator new(size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, "new", func, file, line);
+}
+
+inline void *operator new[](size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, "new[]", func, file, line);
+}
+
+#if 0
+inline void operator delete(void *p)
+{
+ MEM_free(p,"delete","", "", 0);
+}
+
+inline void operator delete[](void *p)
+{
+ MEM_free(p,"delete[]","", "", 0);
+}
+#endif
+
+
+#ifdef new
+#undef new
+#endif
+
+#define new new(__FUNCTION__,__FILE__,__LINE__)
+
+#endif
+
+#endif /* RA_MEMORY_H */
diff --git a/base/tps/src/include/main/MemoryMgr.h b/base/tps/src/include/main/MemoryMgr.h
new file mode 100644
index 000000000..7e2f71dc1
--- /dev/null
+++ b/base/tps/src/include/main/MemoryMgr.h
@@ -0,0 +1,46 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_MEMORY_MGR_H
+#define RA_MEMORY_MGR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+/* Uncomment the following to enable memory profiling */
+
+/* #define MEM_PROFILING */
+#define MEM_AUDIT_FILE "/tmp/mem-audit.log"
+#define MEM_DUMP_FILE "/tmp/mem-dump.log"
+
+#endif /* RA_MEMORY_MGR_H */
diff --git a/base/tps/src/include/main/NameValueSet.h b/base/tps/src/include/main/NameValueSet.h
new file mode 100644
index 000000000..6c9055a59
--- /dev/null
+++ b/base/tps/src/include/main/NameValueSet.h
@@ -0,0 +1,72 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef NAME_VALUE_SET_H
+#define NAME_VALUE_SET_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "plhash.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class NameValueSet
+{
+ public:
+ TPS_PUBLIC NameValueSet();
+ TPS_PUBLIC ~NameValueSet();
+ public:
+ TPS_PUBLIC static NameValueSet *Parse(const char *s, const char *separator);
+ TPS_PUBLIC int IsNameDefined(const char *name);
+ TPS_PUBLIC void Remove(const char *name);
+ TPS_PUBLIC void Add(const char *name, const char *value);
+ TPS_PUBLIC char *GetValue(const char *name);
+ TPS_PUBLIC int Size();
+ TPS_PUBLIC char *GetNameAt(int pos);
+ TPS_PUBLIC int GetValueAsInt(const char *key);
+ TPS_PUBLIC int GetValueAsInt(const char *key, int def);
+ TPS_PUBLIC int GetValueAsBool(const char *key);
+ TPS_PUBLIC int GetValueAsBool(const char *key, int def);
+ TPS_PUBLIC char *GetValueAsString(const char *key, char *def);
+ TPS_PUBLIC char *GetValueAsString(const char *key);
+
+ private:
+ PLHashTable *m_set;
+};
+
+#endif /* NAME_VALUE_SET_H */
diff --git a/base/tps/src/include/main/ObjectSpec.h b/base/tps/src/include/main/ObjectSpec.h
new file mode 100644
index 000000000..3b0bee72c
--- /dev/null
+++ b/base/tps/src/include/main/ObjectSpec.h
@@ -0,0 +1,79 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_OBJECTSPEC_H
+#define RA_OBJECTSPEC_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/AttributeSpec.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class ObjectSpec
+{
+ public:
+ ObjectSpec();
+ ~ObjectSpec();
+ public:
+ static ObjectSpec *ParseFromTokenData(unsigned long objid, Buffer *b);
+ static ObjectSpec *Parse(Buffer *b, int offset, int *nread);
+ static void ParseAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b);
+ static void ParseCertificateAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b);
+ static void ParseKeyAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b);
+ static void ParseCertificateBlob(char *objectID, ObjectSpec *ObjectSpec, Buffer *b);
+
+ void SetObjectID(unsigned long v);
+ unsigned long GetObjectID();
+ void SetFixedAttributes(unsigned long v);
+ unsigned long GetFixedAttributes();
+ int GetAttributeSpecCount();
+ AttributeSpec *GetAttributeSpec(int p);
+ void AddAttributeSpec(AttributeSpec *p);
+ void RemoveAttributeSpec(int p);
+ Buffer GetData();
+ public:
+ unsigned long m_objectID;
+ unsigned long m_fixedAttributes;
+#define MAX_ATTRIBUTE_SPEC 30
+ AttributeSpec *m_attributeSpec[MAX_ATTRIBUTE_SPEC];
+};
+
+#endif /* RA_OBJECTSPEC_H */
diff --git a/base/tps/src/include/main/PKCS11Obj.h b/base/tps/src/include/main/PKCS11Obj.h
new file mode 100644
index 000000000..ef3fca964
--- /dev/null
+++ b/base/tps/src/include/main/PKCS11Obj.h
@@ -0,0 +1,80 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_PKCS11OBJ_H
+#define RA_PKCS11OBJ_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/ObjectSpec.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class PKCS11Obj
+{
+ public:
+ PKCS11Obj();
+ ~PKCS11Obj();
+ public:
+ static PKCS11Obj *Parse(Buffer *b, int offset);
+ void SetFormatVersion(unsigned short v);
+ unsigned short GetFormatVersion();
+ void SetObjectVersion(unsigned short v);
+ unsigned short GetObjectVersion();
+ void SetCUID(Buffer CUID);
+ Buffer GetCUID();
+ void SetTokenName(Buffer tokenName);
+ Buffer GetTokenName();
+ Buffer GetData();
+ Buffer GetCompressedData();
+ int GetObjectSpecCount();
+ ObjectSpec *GetObjectSpec(int p);
+ void AddObjectSpec(ObjectSpec *p);
+ void RemoveObjectSpec(int p);
+ public:
+ unsigned short m_formatVersion;
+ unsigned short m_objectVersion;
+ Buffer m_CUID;
+ Buffer m_tokenName;
+#define MAX_OBJECT_SPEC 20
+ ObjectSpec *m_objSpec[MAX_OBJECT_SPEC];
+};
+
+#endif /* RA_PKCS11OBj_H */
diff --git a/base/tps/src/include/main/PublishEntry.h b/base/tps/src/include/main/PublishEntry.h
new file mode 100644
index 000000000..05d5939a4
--- /dev/null
+++ b/base/tps/src/include/main/PublishEntry.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_PUBLISH_ENTRY_H
+#define RA_PUBLISH_ENTRY_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "publisher/IPublisher.h"
+#define MAX_PUBLISHERS 10
+
+struct PublisherEntry
+{
+
+ char *id;
+ IPublisher *publisher;
+ PRLibrary *publisher_lib;
+ char *factory;
+
+ struct PublisherEntry *next;
+};
+
+typedef struct PublisherEntry PublisherEntry;
+
+#endif /* RA_PUBLISH_ENTRY_H */
+
diff --git a/base/tps/src/include/main/RA_Context.h b/base/tps/src/include/main/RA_Context.h
new file mode 100644
index 000000000..e313f45fd
--- /dev/null
+++ b/base/tps/src/include/main/RA_Context.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_CONTEXT_H
+#define RA_CONTEXT_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Context
+{
+ public:
+ TPS_PUBLIC RA_Context();
+ TPS_PUBLIC virtual ~RA_Context();
+ public:
+ virtual void LogError(const char *func, int line, const char *fmt,...);
+ virtual void LogInfo(const char *func, int line, const char *fmt,...);
+ virtual void InitializationError(const char *func, int line);
+};
+
+#endif /* RA_CONTEXT_H */
diff --git a/base/tps/src/include/main/RA_Msg.h b/base/tps/src/include/main/RA_Msg.h
new file mode 100644
index 000000000..d94063b00
--- /dev/null
+++ b/base/tps/src/include/main/RA_Msg.h
@@ -0,0 +1,79 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_MSG_H
+#define RA_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+enum RA_Op_Type {
+ OP_ENROLL = 1,
+ OP_UNBLOCK = 2,
+ OP_RESET_PIN = 3,
+ OP_RENEW = 4,
+ OP_FORMAT = 5
+};
+
+enum RA_Msg_Type {
+ MSG_UNDEFINED = -1,
+ MSG_BEGIN_OP = 2,
+ MSG_LOGIN_REQUEST = 3,
+ MSG_LOGIN_RESPONSE = 4,
+ MSG_SECUREID_REQUEST = 5,
+ MSG_SECUREID_RESPONSE = 6,
+ MSG_ASQ_REQUEST = 7,
+ MSG_ASQ_RESPONSE = 8,
+ MSG_NEW_PIN_REQUEST = 11,
+ MSG_NEW_PIN_RESPONSE = 12,
+ MSG_TOKEN_PDU_REQUEST = 9,
+ MSG_TOKEN_PDU_RESPONSE = 10,
+ MSG_END_OP = 13,
+ MSG_STATUS_UPDATE_REQUEST = 14,
+ MSG_STATUS_UPDATE_RESPONSE = 15,
+ MSG_EXTENDED_LOGIN_REQUEST = 16,
+ MSG_EXTENDED_LOGIN_RESPONSE = 17
+};
+
+class RA_Msg
+{
+ public:
+ RA_Msg();
+ virtual ~RA_Msg();
+ public:
+ virtual RA_Msg_Type GetType();
+};
+
+#endif /* RA_MSG_H */
diff --git a/base/tps/src/include/main/RA_Session.h b/base/tps/src/include/main/RA_Session.h
new file mode 100644
index 000000000..520a94b6a
--- /dev/null
+++ b/base/tps/src/include/main/RA_Session.h
@@ -0,0 +1,61 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_SESSION_H
+#define RA_SESSION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_pblock.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Session
+{
+ public:
+ TPS_PUBLIC RA_Session();
+ TPS_PUBLIC virtual ~RA_Session();
+ public:
+ virtual RA_pblock *create_pblock( char *data );
+ virtual RA_Msg *ReadMsg();
+ virtual char *GetRemoteIP();
+ virtual void WriteMsg(RA_Msg *msg);
+};
+
+#endif /* RA_SESSION_H */
diff --git a/base/tps/src/include/main/RA_pblock.h b/base/tps/src/include/main/RA_pblock.h
new file mode 100644
index 000000000..685dc321b
--- /dev/null
+++ b/base/tps/src/include/main/RA_pblock.h
@@ -0,0 +1,74 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_PBLOCK_H
+#define RA_PBLOCK_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Buffer.h"
+
+#define MAX_NVS 50
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+struct Buffer_nv {
+ char *name;
+ char *value_s;
+ Buffer *value;
+};
+
+class RA_pblock
+{
+ public:
+ TPS_PUBLIC RA_pblock( int tm_nargs, Buffer_nv** tm_nvs );
+ TPS_PUBLIC ~RA_pblock();
+ public:
+ Buffer_nv **GetNVs();
+ TPS_PUBLIC Buffer *find_val( const char * name );
+ TPS_PUBLIC char* find_val_s( const char * name );
+ void free_pblock();
+ TPS_PUBLIC char *get_name( int i );
+ TPS_PUBLIC int get_num_of_names();
+ public:
+ // an array of pointers to name/value pairs
+ Buffer_nv *m_nvs[MAX_NVS];
+ int m_nargs;
+};
+
+#endif /* RA_PBLOCK_H */
diff --git a/base/tps/src/include/main/RollingLogFile.h b/base/tps/src/include/main/RollingLogFile.h
new file mode 100644
index 000000000..63239b94b
--- /dev/null
+++ b/base/tps/src/include/main/RollingLogFile.h
@@ -0,0 +1,93 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef ROLLINGLOGFILE_H
+#define ROLLINGLOGFILE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/LogFile.h"
+
+class RollingLogFile: public LogFile {
+ private:
+ size_t m_max_file_size;
+ volatile int m_rollover_interval;
+ volatile int m_expiration_time;
+ int m_expiration_sleep_time;
+ volatile bool m_rotation_needed;
+ PRThread* m_rollover_thread;
+ PRThread* m_expiration_thread;
+
+ public:
+ static const char *CFG_MAX_FILE_SIZE;
+ static const char *CFG_ROLLOVER_INTERVAL;
+ static const char *CFG_EXPIRATION_INTERVAL;
+ static const int MAX_SLEEP;
+
+ public:
+ TPS_PUBLIC RollingLogFile();
+ TPS_PUBLIC ~RollingLogFile() {}
+
+ int startup(RA_Context *ctx, const char* prefix, const char *fname, bool sign_audit);
+ void shutdown();
+ void child_init();
+ int write(char *msg);
+ void rotate();
+
+ /* accessors and mutators */
+ void set_rollover_interval(int interval);
+ int get_rollover_interval();
+ void set_expiration_time(int interval);
+ int get_expiration_time();
+ void set_rotation_needed(bool val);
+ bool get_rotation_needed();
+
+ private:
+ static void start_rollover_thread(void *args);
+ void run_rollover_thread();
+
+ static void start_expiration_thread(void *args);
+ void run_expiration_thread();
+ void expire();
+
+};
+
+#endif
diff --git a/base/tps/src/include/main/SecureId.h b/base/tps/src/include/main/SecureId.h
new file mode 100644
index 000000000..fd7e6a158
--- /dev/null
+++ b/base/tps/src/include/main/SecureId.h
@@ -0,0 +1,55 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef SECUREID_H
+#define SECUREID_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+
+class SecureId
+{
+ public:
+ SecureId(char *value, char *pin);
+ ~SecureId();
+ public:
+ char *GetValue();
+ char *GetPIN(); /* optional pin */
+ private:
+ char *m_value;
+ char *m_pin;
+};
+
+#endif /* RA_MSG_H */
diff --git a/base/tps/src/include/main/Util.h b/base/tps/src/include/main/Util.h
new file mode 100644
index 000000000..c4d670483
--- /dev/null
+++ b/base/tps/src/include/main/Util.h
@@ -0,0 +1,99 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_UTIL_H
+#define RA_UTIL_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "pk11func.h"
+#include "main/Buffer.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class Util
+{
+ public:
+ TPS_PUBLIC Util();
+ TPS_PUBLIC ~Util();
+ public:
+ TPS_PUBLIC static int ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return);
+ TPS_PUBLIC static int ascii2numeric(char ch);
+ TPS_PUBLIC static char *Buffer2String (Buffer &data);
+ TPS_PUBLIC static Buffer *Str2Buf (const char *s);
+ TPS_PUBLIC static char *URLEncode (Buffer &data);
+ TPS_PUBLIC static char *URLEncodeInHex (Buffer &data);
+ TPS_PUBLIC static char *URLEncode (const char *data);
+ TPS_PUBLIC static char *URLEncode1 (const char *data);
+ TPS_PUBLIC static Buffer *URLDecode(const char *data);
+ TPS_PUBLIC static char *SpecialURLEncode (Buffer &data);
+ TPS_PUBLIC static Buffer *SpecialURLDecode(const char *data);
+ TPS_PUBLIC static PRStatus GetRandomChallenge(Buffer &random);
+ TPS_PUBLIC static PRStatus CreateKeySetData(
+ Buffer &key_set_version,
+ Buffer &old_kek_key,
+ Buffer &new_auth_key,
+ Buffer &new_mac_key,
+ Buffer &new_kek_key,
+ Buffer &output);
+ TPS_PUBLIC static PRStatus ComputeCryptogram(PK11SymKey *key,
+ const Buffer &card_challenge,
+ const Buffer &host_challenge,
+ Buffer &output);
+ TPS_PUBLIC static PRStatus ComputeMAC(PK11SymKey *key,
+ Buffer &input, const Buffer &icv,
+ Buffer &output);
+ TPS_PUBLIC static PRStatus ComputeKeyCheck(
+ const Buffer& newKey, Buffer& output);
+ TPS_PUBLIC static PK11SymKey *DeriveKey(const Buffer& permKey,
+ const Buffer& hostChallenge,
+ const Buffer& cardChallenge);
+ TPS_PUBLIC static PRStatus EncryptData(PK11SymKey *encSessionKey,
+ Buffer &input, Buffer &output);
+ TPS_PUBLIC static PRStatus EncryptData(Buffer &kek_key,
+ Buffer &input, Buffer &output);
+ TPS_PUBLIC static PK11SymKey *DiversifyKey(PK11SymKey *master,
+ Buffer &data, PK11SlotInfo *slot);
+ TPS_PUBLIC static PRStatus DecryptData(Buffer &kek_key,
+ Buffer &input, Buffer &output);
+ TPS_PUBLIC static PRStatus DecryptData(PK11SymKey* enc_key,
+ Buffer &input, Buffer &output);
+ TPS_PUBLIC static BYTE* bool2byte(bool p);
+};
+
+#endif /* RA_UTIL_H */
diff --git a/base/tps/src/include/modules/tps/AP_Context.h b/base/tps/src/include/modules/tps/AP_Context.h
new file mode 100644
index 000000000..4faca55ac
--- /dev/null
+++ b/base/tps/src/include/modules/tps/AP_Context.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef AP_CONTEXT_H
+#define AP_CONTEXT_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Context.h"
+
+class AP_Context : public RA_Context
+{
+ public:
+ AP_Context( server_rec *sv );
+ virtual ~AP_Context();
+ public:
+ virtual void LogError( const char *func, int line,
+ const char *fmt, ... );
+ virtual void LogInfo( const char *func, int line,
+ const char *fmt, ... );
+ virtual void InitializationError( const char *func, int line );
+ private:
+ server_rec *m_sv;
+};
+
+#endif /* AP_CONTEXT_H */
diff --git a/base/tps/src/include/modules/tps/AP_Session.h b/base/tps/src/include/modules/tps/AP_Session.h
new file mode 100644
index 000000000..832166a1b
--- /dev/null
+++ b/base/tps/src/include/modules/tps/AP_Session.h
@@ -0,0 +1,56 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef AP_SESSION_H
+#define AP_SESSION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Session.h"
+
+class AP_Session : public RA_Session
+{
+ public:
+ AP_Session( request_rec *rq );
+ virtual ~AP_Session();
+ public:
+ virtual char *GetRemoteIP();
+ virtual RA_pblock *create_pblock( char *data );
+ virtual RA_Msg *ReadMsg();
+ virtual void WriteMsg( RA_Msg *msg );
+ private:
+ request_rec *m_rq;
+};
+
+#endif /* AP_SESSION_H */
diff --git a/base/tps/src/include/msg/RA_ASQ_Request_Msg.h b/base/tps/src/include/msg/RA_ASQ_Request_Msg.h
new file mode 100644
index 000000000..15f8bd7a4
--- /dev/null
+++ b/base/tps/src/include/msg/RA_ASQ_Request_Msg.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_ASQ_REQUEST_MSG_H
+#define RA_ASQ_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_ASQ_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_ASQ_Request_Msg(char *question);
+ TPS_PUBLIC ~RA_ASQ_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetQuestion();
+ private:
+ char *m_question;
+};
+
+#endif /* RA_ASQ_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_ASQ_Response_Msg.h b/base/tps/src/include/msg/RA_ASQ_Response_Msg.h
new file mode 100644
index 000000000..3614e443f
--- /dev/null
+++ b/base/tps/src/include/msg/RA_ASQ_Response_Msg.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_ASQ_RESPONSE_MSG_H
+#define RA_ASQ_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_ASQ_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_ASQ_Response_Msg(char *answer);
+ TPS_PUBLIC ~RA_ASQ_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetAnswer();
+ private:
+ char *m_answer;
+};
+
+#endif /* RA_ASQ_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Begin_Op_Msg.h b/base/tps/src/include/msg/RA_Begin_Op_Msg.h
new file mode 100644
index 000000000..48a61a659
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Begin_Op_Msg.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_BEGIN_OP_MSG_H
+#define RA_BEGIN_OP_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+#include "main/NameValueSet.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Begin_Op_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Begin_Op_Msg(RA_Op_Type op, NameValueSet *exts);
+ TPS_PUBLIC ~RA_Begin_Op_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC RA_Op_Type GetOpType();
+ TPS_PUBLIC NameValueSet *GetExtensions();
+ private:
+ RA_Op_Type m_op;
+ NameValueSet *m_exts;
+};
+
+#endif /* RA_BEGIN_OP_MSG_H */
diff --git a/base/tps/src/include/msg/RA_End_Op_Msg.h b/base/tps/src/include/msg/RA_End_Op_Msg.h
new file mode 100644
index 000000000..fe396f05b
--- /dev/null
+++ b/base/tps/src/include/msg/RA_End_Op_Msg.h
@@ -0,0 +1,84 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_END_OP_MSG_H
+#define RA_END_OP_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+
+#define NKEY_ERROR_NO_ERROR 0
+#define NKEY_ERROR_SNAC 1
+#define NKEY_ERROR_SEC_INIT_UPDATE 2
+#define NKEY_ERROR_CREATE_CARDMGR 3
+#define NKEY_ERROR_MAC_RESET_PIN_PDU 4
+#define NKEY_ERROR_MAC_CERT_PDU 5
+#define NKEY_ERROR_MAC_LIFESTYLE_PDU 6
+#define NKEY_ERROR_MAC_ENROLL_PDU 7
+#define NKEY_ERROR_READ_OBJECT_PDU 8
+#define NKEY_ERROR_BAD_STATUS 9
+#define NKEY_ERROR_CA_RESPONSE 10
+#define NKEY_ERROR_READ_BUFFER_OVERFLOW 11
+#define NKEY_ERROR_TOKEN_RESET_PIN_FAILED 12
+#define NKEY_ERROR_CONNECTION 13
+
+#define RESULT_GOOD 0
+#define RESULT_ERROR 1
+
+class RA_End_Op_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_End_Op_Msg(RA_Op_Type op, int result, int msg);
+ TPS_PUBLIC ~RA_End_Op_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC RA_Op_Type GetOpType();
+ TPS_PUBLIC int GetResult();
+ TPS_PUBLIC int GetMsg();
+ private:
+ RA_Op_Type m_op;
+ int m_result;
+ int m_msg;
+};
+
+#endif /* RA_BEGIN_OP_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Extended_Login_Request_Msg.h b/base/tps/src/include/msg/RA_Extended_Login_Request_Msg.h
new file mode 100644
index 000000000..fdfceedcf
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Extended_Login_Request_Msg.h
@@ -0,0 +1,73 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_EXTENDED_LOGIN_REQUEST_MSG_H
+#define RA_EXTENDED_LOGIN_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Extended_Login_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Extended_Login_Request_Msg(int invalid_pw,
+ int blocked, char **parameters, int len,
+ char *title, char *description);
+ TPS_PUBLIC ~RA_Extended_Login_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC int IsInvalidPassword();
+ TPS_PUBLIC int IsBlocked();
+ TPS_PUBLIC int GetLen();
+ TPS_PUBLIC char *GetParam(int i);
+ TPS_PUBLIC char *GetTitle();
+ TPS_PUBLIC char *GetDescription();
+ private:
+ char *m_title;
+ char *m_description;
+ int m_invalid_pw;
+ int m_blocked;
+ char **m_parameters;
+ int m_len;
+};
+
+#endif /* RA_EXTENDED_LOGIN_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Extended_Login_Response_Msg.h b/base/tps/src/include/msg/RA_Extended_Login_Response_Msg.h
new file mode 100644
index 000000000..37da9feb3
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Extended_Login_Response_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_EXTENDED_LOGIN_RESPONSE_MSG_H
+#define RA_EXTENDED_LOGIN_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "authentication/AuthParams.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Extended_Login_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Extended_Login_Response_Msg(AuthParams *param);
+ TPS_PUBLIC ~RA_Extended_Login_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC AuthParams *GetAuthParams();
+ private:
+ AuthParams *m_params;
+};
+
+#endif /* RA_EXTENDED_LOGIN_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Login_Request_Msg.h b/base/tps/src/include/msg/RA_Login_Request_Msg.h
new file mode 100644
index 000000000..01a7a5acd
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Login_Request_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_LOGIN_REQUEST_MSG_H
+#define RA_LOGIN_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Login_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Login_Request_Msg(int invalid_pw, int blocked);
+ TPS_PUBLIC ~RA_Login_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC int IsInvalidPassword();
+ TPS_PUBLIC int IsBlocked();
+ private:
+ int m_invalid_pw;
+ int m_blocked;
+};
+
+#endif /* RA_LOGIN_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Login_Response_Msg.h b/base/tps/src/include/msg/RA_Login_Response_Msg.h
new file mode 100644
index 000000000..dcc9e3530
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Login_Response_Msg.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_LOGIN_RESPONSE_MSG_H
+#define RA_LOGIN_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Login_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Login_Response_Msg(char *uid, char *password);
+ TPS_PUBLIC ~RA_Login_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetUID();
+ TPS_PUBLIC char *GetPassword();
+ private:
+ char *m_uid;
+ char *m_password;
+};
+
+#endif /* RA_LOGIN_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_New_Pin_Request_Msg.h b/base/tps/src/include/msg/RA_New_Pin_Request_Msg.h
new file mode 100644
index 000000000..8ebf16259
--- /dev/null
+++ b/base/tps/src/include/msg/RA_New_Pin_Request_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_NEW_PIN_REQUEST_MSG_H
+#define RA_NEW_PIN_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_New_Pin_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_New_Pin_Request_Msg(int min_len, int max_len);
+ TPS_PUBLIC ~RA_New_Pin_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC int GetMinLen();
+ TPS_PUBLIC int GetMaxLen();
+ private:
+ int m_min_len;
+ int m_max_len;
+};
+
+#endif /* RA_NEW_PIN_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_New_Pin_Response_Msg.h b/base/tps/src/include/msg/RA_New_Pin_Response_Msg.h
new file mode 100644
index 000000000..f062adcf0
--- /dev/null
+++ b/base/tps/src/include/msg/RA_New_Pin_Response_Msg.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_NEW_PIN_RESPONSE_MSG_H
+#define RA_NEW_PIN_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_New_Pin_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_New_Pin_Response_Msg(char *new_pin);
+ TPS_PUBLIC ~RA_New_Pin_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetNewPIN();
+ private:
+ char *m_new_pin;
+};
+
+#endif /* RA_NEW_PIN_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_SecureId_Request_Msg.h b/base/tps/src/include/msg/RA_SecureId_Request_Msg.h
new file mode 100644
index 000000000..132e04c22
--- /dev/null
+++ b/base/tps/src/include/msg/RA_SecureId_Request_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_SECUREID_REQUEST_MSG_H
+#define RA_SECUREID_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_SecureId_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_SecureId_Request_Msg(int pin_required, int next_value);
+ TPS_PUBLIC ~RA_SecureId_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC int IsPinRequired();
+ TPS_PUBLIC int IsNextValue();
+ private:
+ int m_pin_required;
+ int m_next_value;
+};
+
+#endif /* RA_SECUREID_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_SecureId_Response_Msg.h b/base/tps/src/include/msg/RA_SecureId_Response_Msg.h
new file mode 100644
index 000000000..279e07475
--- /dev/null
+++ b/base/tps/src/include/msg/RA_SecureId_Response_Msg.h
@@ -0,0 +1,64 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_SECUREID_RESPONSE_MSG_H
+#define RA_SECUREID_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_SecureId_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_SecureId_Response_Msg(char *value, char *pin);
+ TPS_PUBLIC ~RA_SecureId_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ public:
+ TPS_PUBLIC char *GetValue();
+ TPS_PUBLIC char *GetPIN();
+ private:
+ char *m_value;
+ char *m_pin;
+};
+
+#endif /* RA_SECUREID_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Status_Update_Request_Msg.h b/base/tps/src/include/msg/RA_Status_Update_Request_Msg.h
new file mode 100644
index 000000000..bdc037c97
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Status_Update_Request_Msg.h
@@ -0,0 +1,65 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_STATUS_UPDATE_REQUEST_MSG_H
+#define RA_STATUS_UPDATE_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Status_Update_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Status_Update_Request_Msg(int status, const char *info);
+ TPS_PUBLIC ~RA_Status_Update_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ TPS_PUBLIC int GetStatus();
+ TPS_PUBLIC char *GetInfo();
+ private:
+ int m_status;
+ char *m_info;
+};
+
+#endif /* RA_STATUS_UPDATE_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Status_Update_Response_Msg.h b/base/tps/src/include/msg/RA_Status_Update_Response_Msg.h
new file mode 100644
index 000000000..c5a13eaa4
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Status_Update_Response_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_STATUS_UPDATE_RESPONSE_MSG_H
+#define RA_STATUS_UPDATE_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Status_Update_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Status_Update_Response_Msg(int status);
+ TPS_PUBLIC ~RA_Status_Update_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ TPS_PUBLIC int GetStatus();
+ private:
+ int m_status;
+};
+
+#endif /* RA_STATUS_UPDATE_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Token_PDU_Request_Msg.h b/base/tps/src/include/msg/RA_Token_PDU_Request_Msg.h
new file mode 100644
index 000000000..bcbdfc7fc
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Token_PDU_Request_Msg.h
@@ -0,0 +1,63 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_TOKEN_PDU_REQUEST_MSG_H
+#define RA_TOKEN_PDU_REQUEST_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Base.h"
+#include "main/Buffer.h"
+#include "apdu/APDU.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Token_PDU_Request_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Token_PDU_Request_Msg(APDU *apdu);
+ TPS_PUBLIC ~RA_Token_PDU_Request_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ TPS_PUBLIC APDU *GetAPDU();
+ private:
+ APDU *m_apdu;
+};
+
+#endif /* RA_TOKEN_PDU_REQUEST_MSG_H */
diff --git a/base/tps/src/include/msg/RA_Token_PDU_Response_Msg.h b/base/tps/src/include/msg/RA_Token_PDU_Response_Msg.h
new file mode 100644
index 000000000..e7c2d538f
--- /dev/null
+++ b/base/tps/src/include/msg/RA_Token_PDU_Response_Msg.h
@@ -0,0 +1,62 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_TOKEN_PDU_RESPONSE_MSG_H
+#define RA_TOKEN_PDU_RESPONSE_MSG_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "apdu/APDU.h"
+#include "apdu/APDU_Response.h"
+#include "main/RA_Msg.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Token_PDU_Response_Msg : public RA_Msg
+{
+ public:
+ TPS_PUBLIC RA_Token_PDU_Response_Msg(APDU_Response *response);
+ TPS_PUBLIC ~RA_Token_PDU_Response_Msg();
+ public:
+ TPS_PUBLIC RA_Msg_Type GetType();
+ TPS_PUBLIC APDU_Response *GetResponse();
+ private:
+ APDU_Response *m_response;
+};
+
+#endif /* RA_TOKEN_PDU_RESPONSE_MSG_H */
diff --git a/base/tps/src/include/processor/RA_Enroll_Processor.h b/base/tps/src/include/processor/RA_Enroll_Processor.h
new file mode 100644
index 000000000..b78d33f36
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Enroll_Processor.h
@@ -0,0 +1,300 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_ENROLL_PROCESSOR_H
+#define RA_ENROLL_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Session.h"
+#include "main/PKCS11Obj.h"
+#include "processor/RA_Processor.h"
+#include "cms/HttpConnection.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Enroll_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Enroll_Processor();
+ TPS_PUBLIC ~RA_Enroll_Processor();
+ public:
+ int ParsePublicKeyBlob(unsigned char *blob,
+ unsigned char *challenge,
+ SECKEYPublicKey *pk);
+ RA_Status DoEnrollment(AuthParams *login, RA_Session *session,
+ CERTCertificate **certificates,
+ char **origins,
+ char **ktypes,
+ int pkcs11obj,
+ PKCS11Obj * pkcs_objx,
+ NameValueSet *extensions,
+ int index, int keyTypeNum,
+ int start_progress,
+ int end_progress,
+ Secure_Channel *channel, Buffer *wrapped_challenge,
+ const char *tokenType,
+ const char *keyType,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ const char *cuid,
+ const char *msn,
+ const char *khex,
+ TokenKeyType key_type,
+ const char *profileId,
+ const char *userid,
+ const char *cert_id,
+ const char *publisher_id,
+ const char *cert_attr_id,
+ const char *pri_attr_id,
+ const char *pub_attr_id,
+ BYTE se_p1, BYTE se_p2, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version);
+
+ bool DoRenewal(const char *connid,
+ const char *profileId,
+ CERTCertificate *i_cert,
+ CERTCertificate **o_cert,
+ char *error_msg, int *error_code);
+
+ bool GenerateCertificate(AuthParams *login,
+ int keyTypeNum,
+ const char *keyTypeValue,
+ int i,
+ RA_Session *session,
+ char **origins,
+ char **ktypes,
+ char *tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ NameValueSet *extensions,
+ Secure_Channel *channel,
+ Buffer *wrapped_challenge,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ char *khex,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **certificates);
+
+ bool GenerateCertsAfterRecoveryPolicy(AuthParams *login,
+ RA_Session *session,
+ char **&origins,
+ char **&ktypes,
+ char *&tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ NameValueSet *extensions,
+ Secure_Channel *channel,
+ Buffer *wrapped_challenge,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ char *khex,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **&certificates,
+ int &o_certNums, char **&tokenTypes);
+
+ bool GenerateCertificates(AuthParams *login,
+ RA_Session *session,
+ char **&origins,
+ char **&ktypes,
+ char *tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ NameValueSet *extensions,
+ Secure_Channel *channel,
+ Buffer *wrapped_challenge,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ char *khex,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **&certificates,
+ int &o_certNums, char **&tokenTypes);
+
+ int DoPublish(
+ const char *cuid,
+ SECItem *encodedPublicKeyInfo,
+ Buffer *cert,
+ const char *publisher_id,
+ char *applet_version);
+
+ bool ProcessRecovery(AuthParams *login,
+ char *reason,
+ RA_Session *session,
+ char **&origins,
+ char **&ktypes,
+ char *tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ NameValueSet *extensions,
+ Secure_Channel *channel,
+ Buffer *wrapped_challenge,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ char *khex,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **&certificates,
+ char *lostTokenCUID,
+ int &o_certNums, char **&tokenTypes, char *origTokenType);
+
+ bool ProcessRenewal(AuthParams *login,
+ RA_Session *session,
+ char **&ktypes,
+ char **&origins,
+ char *tokenType,
+ PKCS11Obj *pkcs11objx,
+ int pkcs11obj_enable,
+ Secure_Channel *channel,
+ const char *cuid,
+ char *msn,
+ const char *final_applet_version,
+ const char *userid,
+ RA_Status &o_status,
+ CERTCertificate **&certificates,
+ int &o_certNums, char **&tokenTypes);
+
+ bool GetCardManagerAppletInfo(
+ RA_Session*,
+ Buffer *,
+ RA_Status&,
+ char*&,
+ char*&,
+ Buffer& );
+
+ bool GetAppletInfo(
+ RA_Session *a_session, /* in */
+ Buffer *a_aid , /* in */
+ BYTE &o_major_version,
+ BYTE &o_minor_version,
+ BYTE &o_app_major_version,
+ BYTE &o_app_minor_version);
+
+ bool FormatAppletVersionInfo(
+ RA_Session *a_session,
+ const char *a_tokenType,
+ char *a_cuid,
+ BYTE a_app_major_version,
+ BYTE a_app_minor_version,
+ RA_Status &status, // out
+ char * &o_appletVersion // out
+ );
+
+ bool RequestUserId(
+ RA_Session * a_session,
+ NameValueSet *extensions,
+ const char * a_configname,
+ const char * a_tokenType,
+ char *a_cuid,
+ AuthParams *& o_login, // out
+ const char *&o_userid, // out
+ RA_Status &o_status //out
+ );
+
+
+ bool AuthenticateUser(
+ RA_Session * a_session,
+ const char * a_configname,
+ char *a_cuid,
+ NameValueSet *a_extensions,
+ const char *a_tokenType,
+ AuthParams *& a_login,
+ const char *&o_userid,
+ RA_Status &o_status
+ );
+
+ bool AuthenticateUserLDAP(
+ RA_Session *a_session,
+ NameValueSet *extensions,
+ char *a_cuid,
+ AuthenticationEntry *a_auth,
+ AuthParams *& o_login,
+ RA_Status &o_status,
+ const char *token_type);
+
+ bool CheckAndUpgradeApplet(
+ RA_Session *a_session,
+ NameValueSet *a_extensions,
+ char *a_cuid,
+ const char *a_tokenType,
+ char *&o_current_applet_on_token,
+ BYTE &o_major_version,
+ BYTE &o_minor_version,
+ Buffer *a_aid,
+ const char *msn,
+ const char *userid,
+ RA_Status &o_status,
+ char **key_version );
+
+ bool CheckAndUpgradeSymKeys(
+ RA_Session *session,
+ NameValueSet* extensions,
+ char *cuid,
+ const char *tokenType,
+ char *msn,
+ const char* applet_version,
+ const char* userid,
+ const char* key_version,
+ Buffer *a_cardmanagerAID, /* in */
+ Buffer *a_appletAID, /* in */
+ Secure_Channel *&channel, /* out */
+ RA_Status &status /* out */
+ );
+
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+
+ private:
+ int GetNextFreeCertIdNumber(PKCS11Obj *pkcs11objx);
+ bool isCertRenewable(CERTCertificate *cert, int graceBefore, int graceAfter);
+ int UnrevokeRecoveredCert(const LDAPMessage *e, char *&statusString);
+};
+
+#endif /* RA_ENROLL_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Format_Processor.h b/base/tps/src/include/processor/RA_Format_Processor.h
new file mode 100644
index 000000000..836c89080
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Format_Processor.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_FORMAT_PROCESSOR_H
+#define RA_FORMAT_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "processor/RA_Processor.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Format_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Format_Processor();
+ TPS_PUBLIC ~RA_Format_Processor();
+ public:
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+};
+
+#endif /* RA_UPGRADE_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Pin_Reset_Processor.h b/base/tps/src/include/processor/RA_Pin_Reset_Processor.h
new file mode 100644
index 000000000..a3d511865
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Pin_Reset_Processor.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_PIN_RESET_PROCESSOR_H
+#define RA_PIN_RESET_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "processor/RA_Processor.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Pin_Reset_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Pin_Reset_Processor();
+ TPS_PUBLIC ~RA_Pin_Reset_Processor();
+ public:
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+};
+
+#endif /* RA_PIN_RESET_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Processor.h b/base/tps/src/include/processor/RA_Processor.h
new file mode 100644
index 000000000..74e869a52
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Processor.h
@@ -0,0 +1,214 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_PROCESSOR_H
+#define RA_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/RA_Session.h"
+#include "authentication/AuthParams.h"
+#include "apdu/APDU.h"
+#include "apdu/APDU_Response.h"
+#include "channel/Secure_Channel.h"
+
+enum RA_Status {
+ STATUS_NO_ERROR=0,
+ STATUS_ERROR_SNAC=1,
+ STATUS_ERROR_SEC_INIT_UPDATE=2,
+ STATUS_ERROR_CREATE_CARDMGR=3,
+ STATUS_ERROR_MAC_RESET_PIN_PDU=4,
+ STATUS_ERROR_MAC_CERT_PDU=5,
+ STATUS_ERROR_MAC_LIFESTYLE_PDU=6,
+ STATUS_ERROR_MAC_ENROLL_PDU=7,
+ STATUS_ERROR_READ_OBJECT_PDU=8,
+ STATUS_ERROR_BAD_STATUS=9,
+ STATUS_ERROR_CA_RESPONSE=10,
+ STATUS_ERROR_READ_BUFFER_OVERFLOW=11,
+ STATUS_ERROR_TOKEN_RESET_PIN_FAILED=12,
+ STATUS_ERROR_CONNECTION=13,
+ STATUS_ERROR_LOGIN=14,
+ STATUS_ERROR_DB=15,
+ STATUS_ERROR_TOKEN_DISABLED=16,
+ STATUS_ERROR_SECURE_CHANNEL=17,
+ STATUS_ERROR_MISCONFIGURATION=18,
+ STATUS_ERROR_UPGRADE_APPLET=19,
+ STATUS_ERROR_KEY_CHANGE_OVER=20,
+ STATUS_ERROR_EXTERNAL_AUTH=21,
+ STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND=22,
+ STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND=23,
+ STATUS_ERROR_PUBLISH=24,
+ STATUS_ERROR_LDAP_CONN=25,
+ STATUS_ERROR_DISABLED_TOKEN=26,
+ STATUS_ERROR_NOT_PIN_RESETABLE=27,
+ STATUS_ERROR_CONN_LOST=28,
+ STATUS_ERROR_CREATE_TUS_TOKEN_ENTRY=29,
+ STATUS_ERROR_NO_SUCH_TOKEN_STATE=30,
+ STATUS_ERROR_NO_SUCH_LOST_REASON=31,
+ STATUS_ERROR_UNUSABLE_TOKEN_KEYCOMPROMISE=32,
+ STATUS_ERROR_INACTIVE_TOKEN_NOT_FOUND=33,
+ STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN=34,
+ STATUS_ERROR_CONTACT_ADMIN=35,
+ STATUS_ERROR_RECOVERY_IS_PROCESSED=36,
+ STATUS_ERROR_RECOVERY_FAILED=37,
+ STATUS_ERROR_NO_OPERATION_ON_LOST_TOKEN=38,
+ STATUS_ERROR_KEY_ARCHIVE_OFF=39,
+ STATUS_ERROR_NO_TKS_CONNID=40,
+ STATUS_ERROR_UPDATE_TOKENDB_FAILED=41,
+ STATUS_ERROR_REVOKE_CERTIFICATES_FAILED=42,
+ STATUS_ERROR_NOT_TOKEN_OWNER=43,
+ STATUS_ERROR_RENEWAL_IS_PROCESSED=44,
+ STATUS_ERROR_RENEWAL_FAILED=45
+};
+
+class RA_Processor
+{
+ public:
+ RA_Processor();
+ virtual ~RA_Processor();
+ virtual RA_Status Process(RA_Session *session, NameValueSet *extensions);
+ char *MapPattern(NameValueSet *nv, char *pattern);
+
+ int InitializeUpdate(RA_Session *session,
+ BYTE key_version, BYTE key_index,
+ Buffer &key_diversification_data,
+ Buffer &key_info_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge, const char *connId);
+
+ int CreatePin(RA_Session *session, BYTE pin_number, BYTE max_retries, char *pin);
+
+ int IsPinPresent(RA_Session *session,BYTE pin_number);
+
+ AuthParams *RequestLogin(RA_Session *session, int invalid_pw, int blocked);
+ AuthParams *RequestExtendedLogin(RA_Session *session, int invalid_pw, int blocked, char **parameters, int len, char *title, char *description);
+
+ void StatusUpdate(RA_Session *session, NameValueSet *extensions, int status, const char *info);
+ void StatusUpdate(RA_Session *session, int status, const char *info);
+
+ Buffer *GetAppletVersion(RA_Session *session);
+
+ Secure_Channel *SetupSecureChannel(RA_Session *session, BYTE key_version, BYTE key_index, const char *connId);
+ Secure_Channel *SetupSecureChannel(RA_Session *session,
+ BYTE key_version, BYTE key_index, SecurityLevel security_level, const char *connId);
+
+ SecureId *RequestSecureId(RA_Session *session);
+
+ char *RequestNewPin(RA_Session *session, unsigned int min_len, unsigned int max_len);
+
+ char *RequestASQ(RA_Session *session, char *question);
+
+ int EncryptData(Buffer &cuid, Buffer &versionID, Buffer &in, Buffer &out, const char *connid);
+
+ int ComputeRandomData(Buffer &data_out, int dataSize, const char *connid);
+
+ int CreateKeySetData(
+ Buffer &cuid,
+ Buffer &versionID,
+ Buffer &NewMasterVer,
+ Buffer &out,
+ const char *connid);
+
+ bool GetTokenType(
+ const char *prefix,
+ int major_version, int minor_version,
+ const char *cuid, const char *msn,
+ NameValueSet *extensions,
+ RA_Status &o_status,
+ const char *&o_tokenType);
+
+ Buffer *ListObjects(RA_Session *session, BYTE seq);
+
+ Buffer *GetStatus(RA_Session *session, BYTE p1, BYTE p2);
+
+ Buffer *GetData(RA_Session *session);
+
+ int SelectApplet(RA_Session *session, BYTE p1, BYTE p2, Buffer *aid);
+
+ int UpgradeApplet(
+ RA_Session *session,
+ char *prefix,
+ char *tokenType,
+ BYTE major_version, BYTE minor_version,
+ const char *new_version,
+ const char *applet_dir,
+ SecurityLevel security_level,
+ const char *connid,
+ NameValueSet *extensions,
+ int start_progress, int end_progress,
+ char **key_version);
+
+ int UpgradeKey(RA_Session *session, BYTE major_version, BYTE minor_version, int new_version);
+
+ int SelectCardManager(RA_Session *session, char *prefix, char *tokenType);
+
+ int FormatMuscleApplet(
+ RA_Session *session,
+ unsigned short memSize,
+ Buffer &PIN0, BYTE pin0Tries,
+ Buffer &unblockPIN0, BYTE unblock0Tries,
+ Buffer &PIN1, BYTE pin1Tries,
+ Buffer &unblockPIN1, BYTE unblock1Tries,
+ unsigned short objCreationPermissions,
+ unsigned short keyCreationPermissions,
+ unsigned short pinCreationPermissions);
+
+ Secure_Channel *GenerateSecureChannel(
+ RA_Session *session, const char *connid,
+ Buffer &card_diversification_data,
+ Buffer &card_key_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge);
+ AuthenticationEntry *GetAuthenticationEntry(
+ const char * a_prefix,
+ const char * a_configname,
+ const char * a_tokenType);
+
+ protected:
+ RA_Status Format(RA_Session *session, NameValueSet *extensions, bool skipAuth);
+ bool RevokeCertificates(RA_Session *session, char *cuid, char *audit_msg,
+ char *final_applet_version,
+ char *keyVersion,
+ char *tokenType, char *userid, RA_Status &status );
+ int IsTokenDisabledByTus(Secure_Channel *channel);
+
+ int totalAvailableMemory;
+ int totalFreeMemory;
+};
+
+#endif /* RA_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Renew_Processor.h b/base/tps/src/include/processor/RA_Renew_Processor.h
new file mode 100644
index 000000000..bb8710a74
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Renew_Processor.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_RENEW_PROCESSOR_H
+#define RA_RENEW_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "processor/RA_Processor.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Renew_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Renew_Processor();
+ TPS_PUBLIC ~RA_Renew_Processor();
+ public:
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+};
+
+#endif /* RA_RENEW_PROCESSOR_H */
diff --git a/base/tps/src/include/processor/RA_Unblock_Processor.h b/base/tps/src/include/processor/RA_Unblock_Processor.h
new file mode 100644
index 000000000..ae28ea593
--- /dev/null
+++ b/base/tps/src/include/processor/RA_Unblock_Processor.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef RA_UNBLOCK_PROCESSOR_H
+#define RA_UNBLOCK_PROCESSOR_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "processor/RA_Processor.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+class RA_Unblock_Processor : public RA_Processor
+{
+ public:
+ TPS_PUBLIC RA_Unblock_Processor();
+ TPS_PUBLIC ~RA_Unblock_Processor();
+ public:
+ TPS_PUBLIC RA_Status Process(RA_Session *session, NameValueSet *extensions);
+};
+
+#endif /* RA_UNBLOCK_PROCESSOR_H */
diff --git a/base/tps/src/include/publisher/IConnector.h b/base/tps/src/include/publisher/IConnector.h
new file mode 100644
index 000000000..9a5caa70e
--- /dev/null
+++ b/base/tps/src/include/publisher/IConnector.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef __ICONNECTOR_H__
+#define __ICONNECTOR_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (I_CONNECTOR_H)
+#define I_CONNECTOR_H
+
+#include "IPublish_Data.h"
+class IConnector
+{
+public:
+
+ virtual ~IConnector() {};
+ virtual int init() = 0;
+ virtual void shutdown() = 0;
+ virtual int send_msg(IPublish_Data *data) =0;
+
+};
+
+#endif
+
+#endif /* __ICONNECTOR_H__ */
+
diff --git a/base/tps/src/include/publisher/IPublish_Data.h b/base/tps/src/include/publisher/IPublish_Data.h
new file mode 100644
index 000000000..50b7e3247
--- /dev/null
+++ b/base/tps/src/include/publisher/IPublish_Data.h
@@ -0,0 +1,56 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef __IPUBLISH_DATA_H__
+#define __IPUBLISH_DATA_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (IPUBLISH_DATA_H)
+#define IPUBLISH_DATA_H
+
+
+
+class IPublish_Data
+{
+public:
+
+ virtual void Reset() = 0;
+
+};
+
+#endif
+
+#endif /* __IPUBLISH_DATA_H__ */
+
diff --git a/base/tps/src/include/publisher/IPublisher.h b/base/tps/src/include/publisher/IPublisher.h
new file mode 100644
index 000000000..56a1b7357
--- /dev/null
+++ b/base/tps/src/include/publisher/IPublisher.h
@@ -0,0 +1,74 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef __IPUBLISHER_H__
+#define __IPUBLISHER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (IPUBLISHER_H)
+
+#define IPUBLISHER_H
+
+#include "IConnector.h"
+
+class IPublisher
+{
+
+public:
+
+ virtual ~IPublisher() {
+ if( m_connector != NULL ) {
+ delete m_connector;
+ m_connector = NULL;
+ }
+ };
+ virtual int init(void) = 0;
+
+ virtual int publish(unsigned char *cuid, int cuid_len,long key_type,unsigned char * public_key,int public_key_len,
+ unsigned long cert_activate_date,unsigned long cert_expire_date,unsigned long applet_version,unsigned long applet_version_date)= 0;
+
+ IConnector *getConnector() { return m_connector;}
+
+protected:
+
+ IConnector * m_connector;
+
+
+};
+
+#endif
+
+#endif /* __IPUBLISHER_H__ */
+
diff --git a/base/tps/src/include/publisher/NetkeyPublisher.h b/base/tps/src/include/publisher/NetkeyPublisher.h
new file mode 100644
index 000000000..05cf4d191
--- /dev/null
+++ b/base/tps/src/include/publisher/NetkeyPublisher.h
@@ -0,0 +1,74 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef __NETKEY_PUBLISHER_H__
+#define __NETKEY_PUBLISHER_H__
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#if !defined (NETKEY_PUBLISHER_H)
+#define NETKEY_PUBLISHER_H
+
+#include "IPublisher.h"
+class IPublisher;
+class NetkeyPublisher : public IPublisher
+{
+
+public:
+
+
+ NetkeyPublisher();
+ ~NetkeyPublisher();
+
+ int init(void) ;
+
+ int publish(unsigned char *cuid, int cuid_len,long key_type,unsigned char * public_key,int public_key_len,
+ unsigned long cert_activate_date,unsigned long cert_expire_date,unsigned long applet_version,unsigned long applet_version_date);
+
+
+ static pthread_mutex_t mutex;
+
+
+};
+
+extern "C"
+{
+ IPublisher *GetIPublisher();
+
+};
+
+#endif
+
+#endif /* __NETKEY_PUBLISHER_H__ */
+
diff --git a/base/tps/src/include/selftests/SelfTest.h b/base/tps/src/include/selftests/SelfTest.h
new file mode 100644
index 000000000..c52f62f23
--- /dev/null
+++ b/base/tps/src/include/selftests/SelfTest.h
@@ -0,0 +1,74 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef SELFTEST_H
+#define SELFTEST_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/ConfigStore.h"
+
+
+class SelfTest
+{
+ public:
+ SelfTest();
+ ~SelfTest();
+ static void Initialize (ConfigStore *cfg);
+ static int runStartUpSelfTests (const char *nickname); /* per cert */
+ static int runStartUpSelfTests (); /* general */
+ static int runOnDemandSelfTests ();
+ static int isOnDemandEnabled ();
+ static int isOnDemandCritical ();
+
+ static const int nTests;
+ static const char *TEST_NAMES[];
+
+ protected:
+ static const char *CFG_SELFTEST_STARTUP;
+ static const char *CFG_SELFTEST_ONDEMAND;
+
+ private:
+ static int isInitialized;
+ static int StartupSystemCertsVerificationRun;
+};
+
+#endif
diff --git a/base/tps/src/include/selftests/TPSPresence.h b/base/tps/src/include/selftests/TPSPresence.h
new file mode 100644
index 000000000..114f4ae57
--- /dev/null
+++ b/base/tps/src/include/selftests/TPSPresence.h
@@ -0,0 +1,78 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef TPSPRESENCE_H
+#define TPSPRESENCE_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/ConfigStore.h"
+#include "selftests/SelfTest.h"
+
+class TPSPresence : public SelfTest
+{
+
+ public:
+ TPSPresence();
+ ~TPSPresence();
+ static void Initialize (ConfigStore *cfg);
+ static int runSelfTest ();
+ static int runSelfTest (const char *nick_name);
+ static int runSelfTest (const char *nick_name, CERTCertificate **cert);
+ static bool isStartupEnabled ();
+ static bool isOnDemandEnabled ();
+ static bool isStartupCritical ();
+ static bool isOnDemandCritical ();
+ static const char *TEST_NAME;
+
+ private:
+ static bool startupEnabled;
+ static bool onDemandEnabled;
+ static bool startupCritical;
+ static bool onDemandCritical;
+ static int initialized;
+ static char *nickname;
+ static const char *UNINITIALIZED_NICKNAME;
+ static const char *NICKNAME_NAME;
+ static const char *CRITICAL_TEST_NAME;
+};
+
+#endif
diff --git a/base/tps/src/include/selftests/TPSSystemCertsVerification.h b/base/tps/src/include/selftests/TPSSystemCertsVerification.h
new file mode 100644
index 000000000..40a4d3fd4
--- /dev/null
+++ b/base/tps/src/include/selftests/TPSSystemCertsVerification.h
@@ -0,0 +1,76 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef TPSSYSTEMCERTSVERIFICATION_H
+#define TPSSYSTEMCERTSVERIFICATION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+// #include "main/Util.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/ConfigStore.h"
+#include "selftests/SelfTest.h"
+
+class TPSSystemCertsVerification : public SelfTest
+{
+
+ public:
+ TPSSystemCertsVerification();
+ ~TPSSystemCertsVerification();
+ static void Initialize (ConfigStore *cfg);
+ static int runSelfTest ();
+ static bool isStartupEnabled ();
+ static bool isOnDemandEnabled ();
+ static bool isStartupCritical ();
+ static bool isOnDemandCritical ();
+ static const char *TEST_NAME;
+
+ private:
+ static bool startupEnabled;
+ static bool onDemandEnabled;
+ static bool startupCritical;
+ static bool onDemandCritical;
+ static int initialized;
+ static const char *CRITICAL_TEST_NAME;
+ static const char *UNINITIALIZED_NICKNAME;
+ static const char *SUBSYSTEM_NICKNAME;
+};
+
+#endif
diff --git a/base/tps/src/include/selftests/TPSValidity.h b/base/tps/src/include/selftests/TPSValidity.h
new file mode 100644
index 000000000..548052a83
--- /dev/null
+++ b/base/tps/src/include/selftests/TPSValidity.h
@@ -0,0 +1,79 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifndef TPSVALIDITY_H
+#define TPSVALIDITY_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+// #include "main/Util.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "main/ConfigStore.h"
+#include "selftests/SelfTest.h"
+
+class TPSValidity : public SelfTest
+{
+
+ public:
+ TPSValidity();
+ ~TPSValidity();
+ static void Initialize (ConfigStore *cfg);
+ static int runSelfTest ();
+ static int runSelfTest (const char *nick_name);
+ static int runSelfTest (const char *nick_name, CERTCertificate *cert);
+ static bool isStartupEnabled ();
+ static bool isOnDemandEnabled ();
+ static bool isStartupCritical ();
+ static bool isOnDemandCritical ();
+ static const char *TEST_NAME;
+
+ private:
+ static bool startupEnabled;
+ static bool onDemandEnabled;
+ static bool startupCritical;
+ static bool onDemandCritical;
+ static int initialized;
+ static char *nickname;
+ static const char *UNINITIALIZED_NICKNAME;
+ static const char *NICKNAME_NAME;
+ static const char *CRITICAL_TEST_NAME;
+};
+
+#endif
diff --git a/base/tps/src/include/service/NK_Context.h b/base/tps/src/include/service/NK_Context.h
new file mode 100644
index 000000000..e5ed59992
--- /dev/null
+++ b/base/tps/src/include/service/NK_Context.h
@@ -0,0 +1,57 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef NK_CONTEXT_H
+#define NK_CONTEXT_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Context.h"
+
+class NK_Context : public RA_Context
+{
+ public:
+ NK_Context(pblock *pb, Session *sn, Request *rq);
+ virtual ~NK_Context();
+ public:
+ virtual void LogError(const char *func, int line, const char *fmt,...);
+ virtual void LogInfo(const char *func, int line, const char *fmt,...);
+ virtual void InitializationError(const char *func, int line);
+ private:
+ pblock *m_pb;
+ Session *m_sn;
+ Request *m_rq;
+};
+
+#endif /* NK_CONTEXT_H */
diff --git a/base/tps/src/include/service/NK_Session.h b/base/tps/src/include/service/NK_Session.h
new file mode 100644
index 000000000..55cd19439
--- /dev/null
+++ b/base/tps/src/include/service/NK_Session.h
@@ -0,0 +1,58 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef NK_SESSION_H
+#define NK_SESSION_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#include "main/RA_Session.h"
+
+class NK_Session : public RA_Session
+{
+ public:
+ NK_Session(pblock *pb, Session *sn, Request *rq);
+ virtual ~NK_Session();
+ public:
+ virtual char *GetRemoteIP();
+ virtual RA_pblock *create_pblock( char *data );
+ virtual RA_Msg *ReadMsg();
+ virtual void WriteMsg(RA_Msg *msg);
+ private:
+ pblock *m_pb;
+ Session *m_sn;
+ Request *m_rq;
+};
+
+#endif /* NK_SESSION_H */
diff --git a/base/tps/src/include/tus/tus_db.h b/base/tps/src/include/tus/tus_db.h
new file mode 100644
index 000000000..b1c7ebe86
--- /dev/null
+++ b/base/tps/src/include/tus/tus_db.h
@@ -0,0 +1,273 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifndef TUS_DB_H
+#define TUS_DB_H
+
+#ifdef HAVE_CONFIG_H
+#ifndef AUTOTOOLS_CONFIG_H
+#define AUTOTOOLS_CONFIG_H
+
+/* Eliminate warnings when using Autotools */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
+#include <config.h>
+#endif /* AUTOTOOLS_CONFIG_H */
+#endif /* HAVE_CONFIG_H */
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#include "ldap.h"
+#include "lber.h"
+#include "pk11func.h"
+#include "cryptohi.h"
+#include "keyhi.h"
+#include "base64.h"
+#include "nssb64.h"
+#include "prlock.h"
+
+#define I_TOKEN_ID 0
+#define TOKEN_ID "cn"
+#define I_TOKEN_USER 1
+#define TOKEN_USER "tokenUserID"
+#define I_TOKEN_STATUS 2
+#define TOKEN_STATUS "tokenStatus"
+#define I_TOKEN_APPLET 3
+#define TOKEN_APPLET "tokenAppletID"
+#define I_TOKEN_KEY_INFO 4
+#define TOKEN_KEY_INFO "keyInfo"
+#define I_TOKEN_MODS 5
+#define TOKEN_MODS "modified"
+#define I_TOKEN_C_DATE 6
+#define TOKEN_C_DATE "dateOfCreate"
+#define I_TOKEN_M_DATE 7
+#define TOKEN_M_DATE "dateOfModify"
+#define I_TOKEN_RESETS 8
+#define TOKEN_RESETS "numberOfResets"
+#define I_TOKEN_ENROLLMENTS 9
+#define TOKEN_ENROLLMENTS "numberOfEnrollments"
+#define I_TOKEN_RENEWALS 10
+#define TOKEN_RENEWALS "numberOfRenewals"
+#define I_TOKEN_RECOVERIES 11
+#define TOKEN_RECOVERIES "numberOfRecoveries"
+#define I_TOKEN_POLICY 12
+#define TOKEN_POLICY "tokenPolicy"
+
+#define I_TOKEN_CUID 13
+#define TOKEN_CUID "tokenID"
+#define I_TOKEN_OP 14
+#define TOKEN_OP "tokenOp"
+#define I_TOKEN_MSG 15
+#define TOKEN_MSG "tokenMsg"
+#define I_TOKEN_RESULT 16
+#define TOKEN_RESULT "tokenResult"
+#define I_TOKEN_IP 17
+#define TOKEN_IP "tokenIP"
+#define I_TOKEN_CERT 18
+#define TOKEN_CERT "userCertificate"
+#define I_TOKEN_SUBJECT 19
+#define TOKEN_SUBJECT "tokenSubject"
+#define I_TOKEN_ISSUER 20
+#define TOKEN_ISSUER "tokenIssuer"
+#define I_TOKEN_ORIGIN 21
+#define TOKEN_ORIGIN "tokenOrigin"
+#define I_TOKEN_SERIAL 22
+#define TOKEN_SERIAL "tokenSerial"
+#define I_TOKEN_TYPE 23
+#define TOKEN_TYPE "tokenType"
+#define I_TOKEN_KEY_TYPE 24
+#define TOKEN_KEY_TYPE "tokenKeyType"
+#define I_TOKEN_REASON 13
+#define TOKEN_REASON "tokenReason"
+#define I_TOKEN_NOT_BEFORE 26
+#define TOKEN_NOT_BEFORE "tokenNotBefore"
+#define I_TOKEN_NOT_AFTER 27
+#define TOKEN_NOT_AFTER "tokenNotAfter"
+
+#define I_STATE_UNINITIALIZED 0
+#define STATE_UNINITIALIZED "uninitialized"
+#define I_STATE_ACTIVE 1
+#define STATE_ACTIVE "active"
+#define I_STATE_DISABLED 2
+#define STATE_DISABLED "disabled"
+#define I_STATE_LOST 3
+#define STATE_LOST "lost"
+
+#define C_TIME "createTimeStamp"
+#define M_TIME "modifyTimeStamp"
+#define USER_ID "uid"
+#define USER_PASSWORD "userPassword"
+#define USER_SN "sn"
+#define USER_CN "cn"
+#define USER_GIVENNAME "givenName"
+#define USER_CERT "userCertificate"
+#define PROFILE_ID "profileID"
+#define GROUP_MEMBER "member"
+#define SUBGROUP_ID "cn"
+
+/* roles */
+#define OPERATOR "Operators"
+#define AGENT "Agents"
+#define ADMINISTRATOR "Administrators"
+#define MAX_RETRIES 2
+
+#define ALL_PROFILES "All Profiles"
+#define NO_PROFILES "NO_PROFILES"
+#define NO_TOKEN_TYPE "no_token_type"
+
+TPS_PUBLIC void set_tus_db_port(int number);
+TPS_PUBLIC void set_tus_db_host(char *name);
+TPS_PUBLIC void set_tus_db_baseDN(char *dn);
+TPS_PUBLIC void set_tus_db_bindDN(char *dn);
+TPS_PUBLIC void set_tus_db_bindPass(char *p);
+
+TPS_PUBLIC int is_tus_db_initialized();
+TPS_PUBLIC int get_tus_db_config(char *name);
+TPS_PUBLIC int tus_db_init(char **errorMsg);
+TPS_PUBLIC int allow_token_reenroll(char *cn);
+TPS_PUBLIC int allow_token_renew(char *cn);
+TPS_PUBLIC int force_token_format(char *cn);
+TPS_PUBLIC int is_token_pin_resetable(char *cn);
+TPS_PUBLIC int is_update_pin_resetable_policy(char *cn);
+TPS_PUBLIC int is_token_present(char *cn);
+TPS_PUBLIC int update_token_policy (char *cn, char *policy);
+TPS_PUBLIC char *get_token_policy (char *cn);
+TPS_PUBLIC char *get_token_userid(char *cn);
+TPS_PUBLIC void tus_db_end();
+TPS_PUBLIC void tus_db_cleanup();
+TPS_PUBLIC void tus_print_as_hex(char *out, SECItem *data);
+TPS_PUBLIC void tus_print_integer(char *out, SECItem *data);
+TPS_PUBLIC int is_tus_db_entry_disabled(char *cn);
+TPS_PUBLIC int add_default_tus_db_entry (const char *uid, const char *agentid, char *cn, const char *status, char *applet_version, char *key_info, const char *token_type );
+TPS_PUBLIC int delete_tus_db_entry (char *userid, char *cn);
+TPS_PUBLIC int delete_tus_general_db_entry (char *dn);
+TPS_PUBLIC int find_tus_db_entry (char *cn, int max, LDAPMessage **result);
+TPS_PUBLIC int find_tus_db_entries (const char *filter, int max, LDAPMessage **result);
+TPS_PUBLIC int find_tus_db_entries_pcontrol_1 (const char *filter, int max, int time_limit, int size_limit, LDAPMessage **result);
+TPS_PUBLIC int find_tus_token_entries (char *filter, int max, LDAPMessage **result, int order);
+TPS_PUBLIC int find_tus_token_entries_no_vlv (char *filter, LDAPMessage **result, int order);
+TPS_PUBLIC int tus_has_active_tokens(char *userid);
+TPS_PUBLIC char *get_token_reason(LDAPMessage *e);
+
+TPS_PUBLIC int update_tus_db_entry (const char *agentid,
+ char *cn, const char *uid, char *keyInfo,
+ const char *status,
+ char *applet_version, const char *reason, const char* token_type);
+TPS_PUBLIC int update_tus_db_entry_with_mods (const char *agentid, const char *cn, LDAPMod **mods);
+TPS_PUBLIC int check_and_modify_tus_db_entry (char *userid, char *cn, char *check, LDAPMod **mods);
+TPS_PUBLIC int modify_tus_db_entry (char *userid, char *cn, LDAPMod **mods);
+TPS_PUBLIC int add_activity (const char *ip, const char *id, const char *op, const char *result, const char *msg, const char *userid, const char *token_type);
+TPS_PUBLIC int find_tus_certificate_entries_by_order_no_vlv (char *filter,
+ LDAPMessage **result, int order);
+TPS_PUBLIC int find_tus_certificate_entries_by_order (char *filter, int max,
+ LDAPMessage **result, int order);
+TPS_PUBLIC int add_certificate (char *tokenid, char *origin, char *tokenType, char *userid, CERTCertificate *certificate, char *ktype, const char *status);
+TPS_PUBLIC int add_tus_db_entry (char *cn, LDAPMod **mods);
+TPS_PUBLIC int add_new_tus_db_entry (const char *userid, char *cn, const char *uid, int flag, const char *status, char *applet_version, char *key_info, const char *token_type);
+TPS_PUBLIC int find_tus_activity_entries (char *filter, int max, LDAPMessage **result);
+TPS_PUBLIC int find_tus_activity_entries_pcontrol_1 (char *filter, int max, int time_limit, int size_limit, LDAPMessage **result);
+TPS_PUBLIC int find_tus_activity_entries_no_vlv (char *filter, LDAPMessage **result, int order);
+TPS_PUBLIC int get_number_of_entries (LDAPMessage *result);
+TPS_PUBLIC int free_results (LDAPMessage *results);
+
+TPS_PUBLIC LDAPMessage *get_first_entry (LDAPMessage *result);
+TPS_PUBLIC LDAPMessage *get_next_entry (LDAPMessage *entry);
+TPS_PUBLIC CERTCertificate **get_certificates(LDAPMessage *entry);
+
+TPS_PUBLIC char **get_token_states();
+TPS_PUBLIC char **get_token_attributes();
+TPS_PUBLIC char **get_activity_attributes();
+TPS_PUBLIC char **get_user_attributes();
+TPS_PUBLIC char **get_view_user_attributes();
+TPS_PUBLIC struct berval **get_attribute_values(LDAPMessage *entry, const char *attribute);
+TPS_PUBLIC void free_values(struct berval **values, int ldapValues);
+TPS_PUBLIC struct berval **get_token_users(LDAPMessage *entry);
+TPS_PUBLIC char *get_token_id(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_tokenType(LDAPMessage *entry);
+TPS_PUBLIC char *get_token_status(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_cn(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_status(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_type(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_serial(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_issuer(LDAPMessage *entry);
+TPS_PUBLIC char *get_cert_attr_byname(LDAPMessage *entry, const char *name);
+TPS_PUBLIC char *get_applet_id(LDAPMessage *entry);
+TPS_PUBLIC char *get_key_info(LDAPMessage *entry);
+TPS_PUBLIC char *get_creation_date(LDAPMessage *entry);
+TPS_PUBLIC char *get_modification_date(LDAPMessage *entry);
+TPS_PUBLIC char *get_policy_name();
+TPS_PUBLIC char *get_reason_name();
+int find_tus_certificate_entries (char *filter, int max, LDAPMessage **result);
+TPS_PUBLIC char **get_certificate_attributes();
+
+TPS_PUBLIC int get_number_of_modifications(LDAPMessage *entry);
+TPS_PUBLIC int get_number_of_resets(LDAPMessage *entry);
+TPS_PUBLIC int get_number_of_enrollments(LDAPMessage *entry);
+TPS_PUBLIC int get_number_of_renewals(LDAPMessage *entry);
+TPS_PUBLIC int get_number_of_recoveries(LDAPMessage *entry);
+
+TPS_PUBLIC char *get_token_users_name();
+TPS_PUBLIC char *get_token_id_name();
+TPS_PUBLIC char *get_token_status_name();
+TPS_PUBLIC char *get_applet_id_name();
+TPS_PUBLIC char *get_key_info_name();
+TPS_PUBLIC char *get_creation_date_name();
+TPS_PUBLIC char *get_modification_date_name();
+TPS_PUBLIC char *get_number_of_modifications_name();
+TPS_PUBLIC char *get_number_of_resets_name();
+TPS_PUBLIC char *get_number_of_enrollments_name();
+TPS_PUBLIC char *get_number_of_renewals_name();
+TPS_PUBLIC char *get_number_of_recoveries_name();
+TPS_PUBLIC char *get_dn(LDAPMessage *entry);
+
+TPS_PUBLIC LDAPMod **allocate_modifications(int size);
+TPS_PUBLIC void free_modifications(LDAPMod **mods, int ldapValues);
+TPS_PUBLIC char **allocate_values(int size, int extra);
+TPS_PUBLIC char **create_modification_date_change();
+TPS_PUBLIC int base64_decode(char *src, unsigned char *dst);
+TPS_PUBLIC char *tus_authenticate(char *cert);
+TPS_PUBLIC int tus_authorize(const char *group, const char *userid);
+TPS_PUBLIC int update_cert_status(char *cn, const char *status);
+TPS_PUBLIC int update_token_status_reason(char *userid, char *cuid,
+ const char *tokenStatus, const char *reason);
+TPS_PUBLIC int update_token_status_reason_userid(const char *userid, char *cuid,
+ const char *tokenStatus, const char *reason, int modifyDateOfCreate);
+
+TPS_PUBLIC int add_user_db_entry(const char *agentid, char *userid, char *userPassword, char *sn, char *givenName, char *cn, char * userCert);
+TPS_PUBLIC int find_tus_user_entries_no_vlv(char *filter, LDAPMessage **result, int order);
+TPS_PUBLIC int update_user_db_entry(const char *agentid, char *uid, char *lastName, char *givenName, char *userCN, char *userCert);
+TPS_PUBLIC int add_profile_to_user(const char *agentid, char *userid, const char *profile);
+TPS_PUBLIC int delete_profile_from_user(const char *agentid, char *userid, const char *profile);
+TPS_PUBLIC int add_user_to_role_db_entry(const char *agentid, char *userid, const char *role);
+TPS_PUBLIC int delete_user_from_role_db_entry(const char *agentid, char *userid, const char *role);
+TPS_PUBLIC int find_tus_user_role_entries( const char*uid, LDAPMessage **result);
+TPS_PUBLIC char *get_authorized_profiles(const char *userid, int is_admin);
+TPS_PUBLIC int delete_user_db_entry(const char *agentid, char *uid);
+TPS_PUBLIC int delete_all_profiles_from_user(const char *agentid, char *userid);
+#endif /* TUS_DB_H */
diff --git a/base/tps/src/main/AttributeSpec.cpp b/base/tps/src/main/AttributeSpec.cpp
new file mode 100644
index 000000000..23c2cd978
--- /dev/null
+++ b/base/tps/src/main/AttributeSpec.cpp
@@ -0,0 +1,115 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/AttributeSpec.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+AttributeSpec::AttributeSpec ()
+{
+}
+
+AttributeSpec::~AttributeSpec ()
+{
+}
+
+AttributeSpec *AttributeSpec::Parse(Buffer *b, int offset)
+{
+ AttributeSpec *o = new AttributeSpec();
+ unsigned long id = (((unsigned char *)*b)[offset+0] << 24) +
+ (((unsigned char *)*b)[offset+1] << 16) +
+ (((unsigned char *)*b)[offset+2] << 8) +
+ (((unsigned char *)*b)[offset+3]);
+ o->SetAttributeID(id);
+ // The following line generates the following known benign warning
+ // message on Windows platforms:
+ //
+ // AttributeSpec.cpp(40) : warning C4244: 'argument' : conversion
+ // from 'unsigned long' to 'unsigned char', possible loss of data
+ //
+ o->SetType((unsigned long)(((unsigned char *)*b)[offset+4]));
+ // DatatypeString contains two bytes for AttributeLen of AttributeData
+ Buffer data;
+ if (o->GetType() == (BYTE) 0)
+ data = b->substr(offset+5+2, b->size() - 5-2);
+ else
+ data = b->substr(offset+5, b->size() - 5);
+
+ o->SetData(data);
+ return o;
+}
+
+void AttributeSpec::SetAttributeID(unsigned long v)
+{
+ m_id = v;
+}
+
+unsigned long AttributeSpec::GetAttributeID()
+{
+ return m_id;
+}
+
+void AttributeSpec::SetType(BYTE v)
+{
+ m_type = v;
+}
+
+BYTE AttributeSpec::GetType()
+{
+ return m_type;
+}
+
+// sets AttributeData (for string type, contains AttributeLen+AttributeValue)
+void AttributeSpec::SetData(Buffer data)
+{
+ m_data = data;
+}
+
+// gets AttributeData
+Buffer AttributeSpec::GetValue()
+{
+ return m_data;
+}
+
+// gets AttributeSpec
+Buffer AttributeSpec::GetData()
+{
+ Buffer data = Buffer();
+ data += Buffer(1, (BYTE)(m_id >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_id >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_id >> 8) & 0xff);
+ data += Buffer(1, (BYTE)m_id & 0xff);
+ data += Buffer(1, m_type);
+ if (m_type == 0) { /* String */
+ data += Buffer(1, (m_data.size() >> 8) & 0xff);
+ data += Buffer(1, m_data.size() & 0xff);
+ }
+ data += m_data;
+ return data;
+}
+
diff --git a/base/tps/src/main/AuthParams.cpp b/base/tps/src/main/AuthParams.cpp
new file mode 100644
index 000000000..3a124252e
--- /dev/null
+++ b/base/tps/src/main/AuthParams.cpp
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "authentication/AuthParams.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC AuthParams::AuthParams () {
+}
+
+/**
+ * Destructs processor.
+ */
+AuthParams::~AuthParams () {
+}
+
+TPS_PUBLIC void AuthParams::SetUID(char *uid) {
+ Add("UID", uid);
+}
+
+TPS_PUBLIC char *AuthParams::GetUID() {
+ return GetValue("UID");
+}
+
+TPS_PUBLIC void AuthParams::SetPassword(char *pwd) {
+ Add("PASSWORD", pwd);
+}
+
+TPS_PUBLIC char *AuthParams::GetPassword() {
+ return GetValue("PASSWORD");
+}
+
+void AuthParams::SetSecuridValue(char *securidValue) {
+ Add("SECURID_VALUE", securidValue);
+}
+
+TPS_PUBLIC char *AuthParams::GetSecuridValue() {
+ return GetValue("SECURID_VALUE");
+}
+
+void AuthParams::SetSecuridPin(char *securidPin) {
+ Add("SECURID_PIN", securidPin);
+}
+
+TPS_PUBLIC char *AuthParams::GetSecuridPin() {
+ return GetValue("SECURID_PIN");
+}
+
diff --git a/base/tps/src/main/Authentication.cpp b/base/tps/src/main/Authentication.cpp
new file mode 100644
index 000000000..34ab76f0a
--- /dev/null
+++ b/base/tps/src/main/Authentication.cpp
@@ -0,0 +1,105 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "main/RA_Session.h"
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/Util.h"
+#include "main/Memory.h"
+#include "authentication/Authentication.h"
+#include "authentication/AuthParams.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a base authentication
+ */
+TPS_PUBLIC Authentication::Authentication ()
+{
+}
+
+/**
+ * Destructs processor.
+ */
+TPS_PUBLIC Authentication::~Authentication ()
+{
+}
+
+void Authentication::Initialize(int index)
+{
+}
+
+int Authentication::Authenticate(AuthParams *params)
+{
+ return -1;
+}
+
+int Authentication::GetNumOfRetries() {
+ return m_retries;
+}
+
+const char *Authentication::GetTitle(char *locale)
+{
+ return NULL;
+}
+
+const char *Authentication::GetDescription(char *locale)
+{
+ return NULL;
+}
+
+int Authentication::GetNumOfParamNames()
+{
+ return 0;
+}
+
+char *Authentication::GetParamID(int index)
+{
+ return NULL;
+}
+
+const char *Authentication::GetParamName(int index, char *locale)
+{
+ return NULL;
+}
+
+char *Authentication::GetParamType(int index)
+{
+ return NULL;
+}
+
+const char *Authentication::GetParamDescription(int index, char *locale)
+{
+ return NULL;
+}
+
+char *Authentication::GetParamOption(int index)
+{
+ return NULL;
+}
+
diff --git a/base/tps/src/main/AuthenticationEntry.cpp b/base/tps/src/main/AuthenticationEntry.cpp
new file mode 100644
index 000000000..eb7f75419
--- /dev/null
+++ b/base/tps/src/main/AuthenticationEntry.cpp
@@ -0,0 +1,91 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plstr.h"
+#include "main/AuthenticationEntry.h"
+
+/**
+ * Constructs a base authentication
+ */
+AuthenticationEntry::AuthenticationEntry ()
+{
+ m_lib = NULL;
+ m_Id = NULL;
+ m_type = NULL;
+ m_authentication = NULL;
+}
+
+/**
+ * Destructs processor.
+ */
+AuthenticationEntry::~AuthenticationEntry ()
+{
+ if (m_lib != NULL) {
+ PR_UnloadLibrary(m_lib);
+ m_lib = NULL;
+ }
+
+ if( m_Id != NULL ) {
+ PL_strfree( m_Id );
+ m_Id = NULL;
+ }
+
+ if( m_type != NULL ) {
+ PL_strfree( m_type );
+ m_type = NULL;
+ }
+
+ m_authentication = NULL;
+}
+
+void AuthenticationEntry::SetLibrary(PRLibrary* lib) {
+ m_lib = lib;
+}
+
+PRLibrary *AuthenticationEntry::GetLibrary() {
+ return m_lib;
+}
+
+void AuthenticationEntry::SetId(const char *id) {
+ m_Id = PL_strdup(id);
+}
+
+char *AuthenticationEntry::GetId() {
+ return m_Id;
+}
+
+void AuthenticationEntry::SetAuthentication(Authentication *auth) {
+ m_authentication = auth;
+}
+
+Authentication *AuthenticationEntry::GetAuthentication() {
+ return m_authentication;
+}
+
+void AuthenticationEntry::SetType(const char *type) {
+ m_type = PL_strdup(type);
+}
+
+char *AuthenticationEntry::GetType() {
+ return m_type;
+}
diff --git a/base/tps/src/main/Buffer.cpp b/base/tps/src/main/Buffer.cpp
new file mode 100644
index 000000000..2a547feea
--- /dev/null
+++ b/base/tps/src/main/Buffer.cpp
@@ -0,0 +1,243 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "main/Buffer.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC Buffer::Buffer(const BYTE *buf_, unsigned int len_) : len(len_), res(len_)
+{
+ buf = new BYTE[len];
+ memcpy(buf, buf_, len);
+}
+
+TPS_PUBLIC Buffer::Buffer(const Buffer& cpy)
+{
+ buf = 0;
+ *this = cpy;
+}
+
+TPS_PUBLIC Buffer::Buffer(unsigned int len_) : len(len_), res(len_)
+{
+ buf = new BYTE[res];
+ memset(buf, 0, len_);
+}
+
+TPS_PUBLIC Buffer::Buffer(unsigned int len_, BYTE b) : len(len_), res(len_)
+{
+ if (len_ == 0) {
+ buf = NULL;
+ } else {
+ buf = new BYTE[res];
+ memset(buf, b, len);
+ }
+}
+
+TPS_PUBLIC Buffer::~Buffer()
+{
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+}
+
+TPS_PUBLIC bool
+Buffer::operator==(const Buffer& cmp) const
+{
+ if( len != cmp.len ) return false;
+ for( unsigned int i=0; i < len; ++i ) {
+ if( buf[i] != cmp.buf[i] ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator=(const Buffer& cpy)
+{
+ if( this == &cpy ) return *this;
+ len = cpy.len;
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ if (cpy.len == 0) {
+ buf = NULL;
+ } else {
+ buf = new BYTE[len];
+ memcpy(buf, cpy.buf, len);
+ }
+ res = len;
+
+ return *this;
+}
+
+TPS_PUBLIC void
+Buffer::zeroize()
+{
+ if( len > 0 ) {
+ memset( buf, 0, len );
+ }
+}
+
+TPS_PUBLIC Buffer
+Buffer::operator+(const Buffer& addend) const
+{
+ Buffer result(len + addend.len);
+ memcpy(result.buf, buf, len);
+ memcpy(result.buf+len, addend.buf, addend.len);
+ return result;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator+=(const Buffer& addend)
+{
+ unsigned int oldLen = len;
+ resize(len + addend.len);
+ memcpy(buf+oldLen, addend.buf, addend.len);
+ return *this;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator+=(BYTE b)
+{
+ resize(len+1);
+ buf[len-1] = b;
+ return *this;
+}
+
+TPS_PUBLIC void
+Buffer::reserve(unsigned int n)
+{
+ if( n > res ) {
+ BYTE *newBuf = new BYTE[n];
+ memcpy(newBuf, buf, len);
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ buf = newBuf;
+ res = n;
+ }
+}
+
+TPS_PUBLIC void
+Buffer::resize(unsigned int newLen)
+{
+ if( newLen == len ) {
+ return;
+ } else if( newLen < len ) {
+ len = newLen;
+ } else if( newLen <= res ) {
+ assert( newLen > len );
+ memset(buf+len, 0, newLen-len);
+ len = newLen;
+ } else {
+ assert( newLen > len && newLen > res );
+ BYTE *newBuf = new BYTE[newLen];
+ memcpy(newBuf, buf, len);
+ memset(newBuf+len, 0, newLen-len);
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ buf = newBuf;
+ len = newLen;
+ res = newLen;
+ }
+}
+
+TPS_PUBLIC Buffer
+Buffer::substr(unsigned int i, unsigned int n) const
+{
+ assert( i < len && (i+n) <= len );
+ return Buffer( buf+i, n );
+}
+
+TPS_PUBLIC void
+Buffer::replace(unsigned int i, const BYTE* cpy, unsigned int n)
+{
+ if (len > i+n) {
+ resize( len);
+ }else {
+ resize( i+n );
+ }
+ memcpy(buf+i, cpy, n);
+}
+
+TPS_PUBLIC void
+Buffer::dump() const
+{
+ unsigned int i;
+
+ for( i=0; i < len; ++i ) {
+ printf("%02x ", buf[i]);
+ if( i % 16 == 15 ) printf("\n");
+ }
+ printf("\n");
+}
+
+/*
+ * if caller knows it's a string, pad with ending 0 and return.
+ * note:
+ * It is the caller's responsibility to make sure it's a string.
+ * Memory needs to be released by the caller.
+ */
+TPS_PUBLIC char *
+Buffer::string()
+{
+ unsigned int i;
+ char *s = (char *) PR_Malloc(len+1);
+ for (i = 0; i < len; i++) {
+ s[i] = buf[i];
+ }
+ s[i] = '\0';
+ return s;
+}
+
+TPS_PUBLIC char *
+Buffer::toHex()
+{
+ unsigned int i;
+
+ char *hx = (char *)PR_Malloc(1024);
+ if (hx == NULL)
+ return NULL;
+ for( i=0; i < len; ++i ) {
+ PR_snprintf(hx+(i*2),1024-(i*2),"%02x", (unsigned char)buf[i]);
+ }
+
+ return hx;
+}
+
+static const char hextbl[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
diff --git a/base/tps/src/main/ConfigStore.cpp b/base/tps/src/main/ConfigStore.cpp
new file mode 100644
index 000000000..e526b4039
--- /dev/null
+++ b/base/tps/src/main/ConfigStore.cpp
@@ -0,0 +1,893 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include <regex.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "main/ConfigStore.h"
+#include "main/Memory.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PR_CALLBACK void*
+_AllocTable(void* pool, PRSize size)
+{
+ return PR_MALLOC(size);
+}
+
+static PR_CALLBACK void
+_FreeTable(void* pool, void* item)
+{
+ PR_DELETE(item);
+}
+
+static PR_CALLBACK PLHashEntry*
+_AllocEntry(void* pool, const void* key)
+{
+ return PR_NEW(PLHashEntry);
+}
+
+static PR_CALLBACK void
+_FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
+{
+ if( he == NULL ) {
+ return;
+ }
+
+ if (flag == HT_FREE_VALUE) {
+ if( he->value != NULL ) {
+ PL_strfree( (char*) he->value );
+ he->value = NULL;
+ }
+ } else if (flag == HT_FREE_ENTRY) {
+ if( he->key != NULL ) {
+ PL_strfree( (char*) he->key );
+ he->key = NULL;
+ }
+ if( he->value != NULL ) {
+ PL_strfree( (char*) he->value );
+ he->value = NULL;
+ }
+ PR_DELETE(he);
+ }
+}
+
+static PLHashAllocOps _AllocOps = {
+ _AllocTable,
+ _FreeTable,
+ _AllocEntry,
+ _FreeEntry
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+///// ConfigStoreRoot
+
+ConfigStoreRoot::ConfigStoreRoot()
+{
+ m_set = PL_NewHashTable(3, PL_HashString,
+ PL_CompareStrings, PL_CompareValues,
+ &_AllocOps, NULL);
+
+ m_set_refcount = 0;
+}
+
+// If the ConfigStoreRoot goes out of scope, we can't destroy
+// the Hashtable because others maybe depending on the values
+// inside.
+ConfigStoreRoot::~ConfigStoreRoot ()
+{
+ if( m_set != NULL ) {
+ if (m_set_refcount==0) {
+ PL_HashTableDestroy( m_set );
+ m_set = NULL;
+ }
+ }
+}
+
+void ConfigStoreRoot::addref()
+{
+ m_set_refcount++;
+}
+
+void ConfigStoreRoot::release()
+{
+ m_set_refcount--;
+}
+
+PLHashTable *ConfigStoreRoot::getSet()
+{
+ return m_set;
+}
+
+
+// ConfigureStore
+
+ConfigStore::ConfigStore(ConfigStoreRoot* root, const char *subStoreName)
+{
+ m_substore_name = PL_strdup(subStoreName);
+ m_root = root;
+ root->addref();
+ m_lock = PR_NewLock();
+}
+
+ConfigStore::~ConfigStore ()
+{
+ if (m_substore_name != NULL) {
+ PR_Free(m_substore_name);
+ }
+ if (m_cfg_file_path != NULL) {
+ PR_Free(m_cfg_file_path);
+ }
+ m_root->release();
+ delete m_root;
+
+ if (m_lock != NULL )
+ PR_DestroyLock(m_lock);
+}
+
+
+
+/*
+ConfigStore::ConfigStore(const ConfigStore &X)
+{
+ m_substore_name = X.m_substore_name;
+ m_root = X.m_root;
+ m_root.addref();
+}
+
+*/
+
+
+
+ConfigStore ConfigStore::GetSubStore(const char *substore)
+{
+ char *newname=NULL;
+ const char *name = m_substore_name;
+ if (strlen(name)==0) { // this is the root
+ newname = PL_strdup(substore);
+ } else {
+ newname = PR_smprintf("%s.%s",name,substore);
+ }
+ return ConfigStore(m_root,newname);
+}
+
+/**
+ * Reads configuration file and puts name value
+ * pair into the global hashtable.
+ */
+static int ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return)
+{
+ char *cur = buf;
+ int sum = 0;
+ PRInt32 rc;
+
+ *removed_return = 0;
+ while (1) {
+ rc = PR_Read(f, cur, 1);
+ if (rc == -1 || rc == 0)
+ break;
+ if (*cur == '\r') {
+ continue;
+ }
+ if (*cur == '\n') {
+ *cur = '\0';
+ *removed_return = 1;
+ break;
+ }
+ sum++;
+ cur++;
+ }
+ return sum;
+}
+
+#define MAX_CFG_LINE_LEN 4096
+
+ConfigStore *ConfigStore::CreateFromConfigFile(const char *cfg_path)
+{
+ PRFileDesc *f = NULL;
+ int removed_return;
+ char line[MAX_CFG_LINE_LEN];
+ ConfigStoreRoot *root = NULL;
+ ConfigStore *cfg = NULL;
+
+ f = PR_Open(cfg_path, PR_RDWR, 00400|00200);
+ if (f == NULL)
+ goto loser;
+
+ root = new ConfigStoreRoot();
+ cfg = new ConfigStore(root,"");
+
+ while (1) {
+ int n = ReadLine(f, line, MAX_CFG_LINE_LEN, &removed_return);
+ if (n > 0) {
+ if (line[0] == '#') // handle comment line
+ continue;
+ int c = 0;
+ while ((c < n) && (line[c] != '=')) {
+ c++;
+ }
+ if (c < n) {
+ line[c] = '\0';
+ } else {
+ continue; /* no '=', skip this line */
+ }
+ cfg->Add(line, &line[c+1]);
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ if( f != NULL ) {
+ PR_Close( f );
+ f = NULL;
+ }
+ cfg->SetFilePath(cfg_path);
+
+loser:
+ return cfg;
+}
+
+/**
+ * Parses string of format "n1=v1&n2=v2..."
+ * into a ConfigStore.
+ */
+ConfigStore *ConfigStore::Parse(const char *s, const char *separator)
+{
+ char *pair;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+
+ if (s == NULL)
+ return NULL;
+ ConfigStoreRoot *root = new ConfigStoreRoot();
+ ConfigStore *set= new ConfigStore(root,"");
+
+ line = PL_strdup(s);
+ pair = PL_strtok_r(line, separator, &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip;
+ }
+ if (pair[i] == '\0') {
+ goto skip;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+ set->Add(&pair[0], &pair[i+1]);
+skip:
+ pair = PL_strtok_r(NULL, separator, &lasts);
+ }
+ if( line != NULL ) {
+ PL_strfree( line );
+ line = NULL;
+ }
+ return set;
+}
+
+typedef struct {
+ int index;
+ char *key;
+} Criteria;
+
+typedef struct {
+ PRCList list;
+ char *key;
+} OrderedEntry_t;
+
+typedef struct {
+ regex_t *regex;
+ ConfigStore *store;
+} PatternEntry_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PRIntn CountLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ criteria->index++;
+ return HT_ENUMERATE_NEXT;
+}
+
+static PRIntn Loop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ if (criteria != NULL && index == criteria->index) {
+ criteria->key = (char *)he->key;
+ return HT_ENUMERATE_STOP;
+ } else {
+ return HT_ENUMERATE_NEXT;
+ }
+}
+
+/**
+ * Called from PL_HashTableEnumerateEntries
+ * A pointer to a PRCList (circular linked list) is passed in.
+ * Once enumeration is complete, the PRCList will contain a lexically
+ * ordered list of a copy of the keys in the hash.
+ * The caller needs to free the copies
+ */
+static PRIntn OrderLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ PRCList *qp = (PRCList *)arg;
+ OrderedEntry_t *entry;
+
+ if (he != NULL) {
+ entry = (OrderedEntry_t *) PR_Malloc(sizeof(OrderedEntry_t));
+ entry->key = PL_strdup((char *) he->key);
+ if (index ==0) {
+ PR_APPEND_LINK((PRCList *)entry, qp);
+ return HT_ENUMERATE_NEXT;
+ }
+ PRCList *head = PR_LIST_HEAD(qp);
+ PRCList *next;
+ while (head != qp) {
+ OrderedEntry_t *current = (OrderedEntry_t *) head;
+ if (strcmp((char *) he->key, (char *) current->key) <=0)
+ break;
+ next = PR_NEXT_LINK(head);
+ head = next;
+ }
+ PR_INSERT_BEFORE((PRCList*) entry, head);
+ return HT_ENUMERATE_NEXT;
+ } else {
+ return HT_ENUMERATE_STOP;
+ }
+}
+
+/**
+ * Called from PL_HashTableEnumerateEntries
+ * A pointer to a PatternEntry is passed in. A PatternEntry consists of
+ * a pointer a regex_t and a pointer to a new config store.
+ * Once enumeration is complete, the new config store will contain
+ * all the parameters (key and values) whose keys match the regex.
+ */
+static PRIntn PatternLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ PatternEntry_t *entry = (PatternEntry_t *) arg;
+
+ if (entry == NULL) {
+ return HT_ENUMERATE_STOP;
+ }
+
+ regex_t *r = entry->regex;
+ ConfigStore *store = entry->store;
+
+ if ((r == NULL) || (store == NULL)) {
+ return HT_ENUMERATE_STOP;
+ }
+
+ size_t no_sub = r->re_nsub+1;
+ regmatch_t *result = NULL;
+
+ result = (regmatch_t *) PR_Malloc(sizeof(regmatch_t) * no_sub);
+
+ if ((he != NULL) && (he->key != NULL) && (he->value != NULL)) {
+ if (regexec(r, (char *) he->key, no_sub, result, 0)==0) {
+ // Found a match
+ store->Add((const char*) he->key, (const char *) he->value);
+ }
+ } else {
+ return HT_ENUMERATE_STOP;
+ }
+
+ if (result != NULL) PR_Free(result);
+ return HT_ENUMERATE_NEXT;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+int ConfigStore::Size()
+{
+ Criteria criteria;
+ criteria.index = 0;
+ criteria.key = NULL;
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &CountLoop, &criteria);
+ PR_Unlock(m_lock);
+
+ return criteria.index;
+}
+
+const char *ConfigStore::GetNameAt(int pos)
+{
+ Criteria criteria;
+ criteria.index = pos;
+ criteria.key = NULL;
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &Loop, &criteria);
+ PR_Unlock(m_lock);
+
+ return criteria.key;
+}
+
+/**
+ * Checks if a key is defined.
+ */
+int ConfigStore::IsNameDefined(const char *name)
+{
+ if (m_root->getSet()!= NULL) {
+ if (GetConfig(name) != NULL)
+ return 1;
+ }
+ return 0;
+}
+
+void ConfigStore::SetFilePath(const char* cfg_file_path)
+{
+ m_cfg_file_path = PL_strdup(cfg_file_path);
+}
+
+void ConfigStore::Add(const char *name, const char *value)
+{
+ if (IsNameDefined(name)) {
+ PR_Lock(m_lock);
+ PL_HashTableRemove(m_root->getSet(), name);
+ PL_HashTableAdd(m_root->getSet(), PL_strdup(name), PL_strdup(value));
+ PR_Unlock(m_lock);
+ } else {
+ PR_Lock(m_lock);
+ PL_HashTableAdd(m_root->getSet(), PL_strdup(name), PL_strdup(value));
+ PR_Unlock(m_lock);
+ }
+}
+
+void ConfigStore::Remove(const char *name)
+{
+ if (IsNameDefined(name)) {
+ PR_Lock(m_lock);
+ PL_HashTableRemove(m_root->getSet(), name);
+ PR_Unlock(m_lock);
+ }
+}
+
+const char *ConfigStore::GetConfig(const char *name)
+{
+ char buf[256];
+ char *ret;
+ if (m_root->getSet() ==NULL) {
+ return NULL;
+ }
+ if (PL_strlen(m_substore_name) == 0) {
+ PL_strncpy(buf,name,256);
+ } else {
+ PR_snprintf(buf,256,"%s.%s",m_substore_name,name);
+ }
+
+ PR_Lock(m_lock);
+ ret = (char *)PL_HashTableLookupConst(m_root->getSet(), buf);
+ PR_Unlock(m_lock);
+
+ return ret;
+}
+
+/**
+ * Retrieves configuration value as integer.
+ */
+int ConfigStore::GetConfigAsInt(const char *name)
+{
+ char *value = NULL;
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return 0;
+ return atoi(value);
+}
+
+/**
+ * Retrieves configuration value as integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int ConfigStore::GetConfigAsInt(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+ return atoi(value);
+}
+
+
+/**
+ * Retrieves configuration value as unsigned integer.
+ */
+unsigned int ConfigStore::GetConfigAsUnsignedInt(const char *name)
+{
+ char *value = NULL;
+ int i = 0;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL) {
+ return 0;
+ }
+
+ i = atoi(value);
+ if (i < 0) {
+ return 0;
+ }
+ return i;
+}
+
+/**
+ * Retrieves configuration value as unsigned integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC unsigned int ConfigStore::GetConfigAsUnsignedInt(const char *name, unsigned int def)
+{
+ char *value = NULL;
+ int i = 0;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL) {
+ return def;
+ }
+
+ i = atoi(value);
+ if (i < 0) {
+ return def;
+ }
+ return i;
+}
+
+
+/**
+ * Retrieves configuration value as boolean.
+ */
+bool ConfigStore::GetConfigAsBool(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return false;
+ if (PL_CompareStrings("true", value) != 0)
+ return true;
+ else
+ return false;
+}
+
+/**
+ * Retrieves configuration value as boolean. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC bool ConfigStore::GetConfigAsBool(const char *name, bool def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+
+ if (PL_CompareStrings("true", value) != 0)
+ return true;
+ else if (PL_CompareStrings("false", value) != 0)
+ return false;
+ else
+ return def;
+}
+
+/**
+ * Retrieves configuration value as string. If key is
+ * not defined, default value is returned.
+ */
+TOKENDB_PUBLIC const char *ConfigStore::GetConfigAsString(const char *name, const char *def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+ return value;
+}
+
+/**
+ * Retrieves configuration value as string.
+ */
+TPS_PUBLIC const char *ConfigStore::GetConfigAsString(const char *name)
+{
+ return (char *)GetConfig(name);
+}
+
+
+/**
+ * Allow operator[] overloading for retrieval of config strings
+ */
+const char* ConfigStore::operator[](const char*name)
+{
+ return GetConfigAsString(name);
+}
+
+
+Buffer *ConfigStore::GetConfigAsBuffer(const char *key)
+{
+ return GetConfigAsBuffer(key, NULL);
+}
+
+Buffer *ConfigStore::GetConfigAsBuffer(const char *key, const char *def)
+{
+ const char *value = NULL;
+
+ value = (char *)GetConfig(key);
+ if (value == NULL) {
+ if (def == NULL) {
+ return NULL;
+ } else {
+ return Util::Str2Buf(def);
+ }
+ } else {
+ return Util::Str2Buf(value);
+ }
+}
+
+/**
+ * returns a string containing all the parameters in the ConfigStore hash set in the
+ * format key1=value1&&key2=value2&& ...
+ * The list will be lexically ordered by parameter key values.
+ * The string needs to be freed by the caller.
+ **/
+TPS_PUBLIC const char* ConfigStore::GetOrderedList()
+{
+ char *outstr = NULL;
+ char *new_string = NULL;
+ PRCList order_list;
+ PR_INIT_CLIST(&order_list);
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &OrderLoop, &order_list);
+ PR_Unlock(m_lock);
+
+ PRCList *current = PR_LIST_HEAD(&order_list);
+ PRCList *next;
+
+ outstr = (char*) PR_Malloc(128);
+ int allocated = 128;
+ int needed = 0;
+ PR_snprintf(outstr, 128, "");
+
+ while (current != &order_list) {
+ OrderedEntry_t *entry = (OrderedEntry_t *) current;
+ const char *value = GetConfigAsString(entry->key, "");
+
+ if ((entry != NULL) && (entry->key != NULL)) {
+ needed = PL_strlen(outstr) + PL_strlen(entry->key) + PL_strlen(value) + 4;
+ if (allocated <= needed) {
+ while (allocated <= needed) {
+ allocated = allocated * 2;
+ }
+ new_string = (char *)PR_Malloc(allocated);
+ PR_snprintf(new_string, allocated, "%s", outstr);
+ PR_Free(outstr);
+ outstr = new_string;
+ }
+
+ PL_strcat(outstr, entry->key);
+ PL_strcat(outstr, "=");
+ PL_strcat(outstr, value);
+
+ // free the memory for the Ordered Entry
+ PL_strfree(entry->key);
+ }
+
+ next = PR_NEXT_LINK(current);
+ PR_REMOVE_AND_INIT_LINK(current);
+ if (current != NULL) {
+ PR_Free(current);
+ }
+ current = next;
+
+ if (current != &order_list) PL_strcat(outstr, "&&");
+ }
+ return outstr;
+}
+
+/**
+ * Commits changes to the config file
+ */
+TPS_PUBLIC int ConfigStore::Commit(const bool backup, char *error_msg, int len)
+{
+ char name_tmp[256], cdate[256], name_bak[256], bak_dir[256];
+ char basename[256], dirname[256];
+ PRFileDesc *ftmp = NULL;
+ PRExplodedTime time;
+ PRTime now;
+ PRStatus status;
+
+ if (m_cfg_file_path == NULL) {
+ PR_snprintf(error_msg, len, "ConfigStore::Commit(): m_cfg_file_path is NULL!");
+ return 1;
+ }
+
+ if (strrchr(m_cfg_file_path, '/') != NULL) {
+ PR_snprintf((char *) basename, 256, "%s", strrchr(m_cfg_file_path, '/') +1);
+ PR_snprintf((char *) dirname, PL_strlen(m_cfg_file_path) - PL_strlen(basename), "%s", m_cfg_file_path);
+ PL_strcat(dirname, '\0');
+ } else {
+ PR_snprintf((char *) basename, 256, "%s", m_cfg_file_path);
+ PR_snprintf((char *) dirname, 256, ".");
+ }
+ PR_snprintf(bak_dir, 256, "%s/bak", dirname);
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+ PR_snprintf(name_tmp, 256, "%s.%s.tmp", m_cfg_file_path,cdate);
+ PR_snprintf(name_bak, 256, "%s/%s.%s", bak_dir, basename, cdate);
+
+ ftmp = PR_Open(name_tmp, PR_WRONLY| PR_CREATE_FILE, 00400|00200);
+ if (ftmp == NULL) {
+ // unable to create temporary config file
+ PR_snprintf(error_msg, len, "ConfigStore::Commit(): unable to create temporary config file");
+ return 1;
+ }
+
+ PRCList order_list;
+ PR_INIT_CLIST(&order_list);
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &OrderLoop, &order_list);
+ PR_Unlock(m_lock);
+
+ PRCList *current = PR_LIST_HEAD(&order_list);
+ PRCList *next;
+
+ while (current != &order_list) {
+ OrderedEntry_t *entry = (OrderedEntry_t *) current;
+ PR_Write(ftmp, entry->key, PL_strlen(entry->key));
+ PR_Write(ftmp, "=", 1);
+ const char *value = GetConfigAsString(entry->key, "");
+ PR_Write(ftmp, value, PL_strlen(value));
+ PR_Write(ftmp, "\n", 1);
+
+ // free the memory for the Ordered Entry
+ if (entry->key != NULL) PL_strfree(entry->key);
+
+ next = PR_NEXT_LINK(current);
+ PR_REMOVE_AND_INIT_LINK(current);
+ if (current != NULL) {
+ PR_Free(current);
+ }
+ current = next;
+ }
+
+ PR_Close(ftmp);
+
+ if (backup) {
+ // create the backup directory if it does not exist
+ if (PR_Access(bak_dir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
+ PR_MkDir(bak_dir, 00770);
+ }
+ status = PR_Rename(m_cfg_file_path, name_bak);
+ if (status != PR_SUCCESS) {
+ // failed to back up CS.cfg
+ }
+ }
+ if (PR_Access(m_cfg_file_path, PR_ACCESS_EXISTS) == PR_SUCCESS) {
+ // backup is false, or backup failed
+ status = PR_Delete(m_cfg_file_path);
+ if (status != PR_SUCCESS) {
+ // failed to delete old CS.cfg file
+ PR_snprintf(error_msg, len, "ConfigStore::Commit(): unable to delete old CS.cfg file");
+ return 1;
+ }
+ }
+
+ status = PR_Rename(name_tmp, m_cfg_file_path);
+ if (status != PR_SUCCESS) {
+ // failed to move tmp to CS.cfg
+ // major badness - we now have only tmp file, no CS.cfg
+ PR_snprintf(error_msg, len, "ConfigStore::Commit(): failed to move tmp file to CS.cfg");
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Takes in a string containing a regular expression.
+ * Returns a new ConfigStore which contains only those parameters whose
+ * keys match the pattern.
+ * The new Configstore must of course be freed by the caller.
+ **/
+ConfigStore *ConfigStore::GetPatternSubStore(const char *pattern)
+{
+
+ ConfigStoreRoot *root = NULL;
+ ConfigStore *ret = NULL;
+ PatternEntry_t entry;
+ regex_t *regex = NULL;
+ int err_no=0; /* For regerror() */
+
+ regex = (regex_t *) malloc(sizeof(regex_t));
+ memset(regex, 0, sizeof(regex_t));
+
+ if((err_no=regcomp(regex, pattern, 0))!=0) /* Compile the regex */
+ {
+ // Error in computing the regex
+ size_t length;
+ char *buffer;
+ length = regerror (err_no, regex, NULL, 0);
+ buffer = (char *) PR_Malloc(length);
+ regerror (err_no, regex, buffer, length);
+ // PR_fprintf(m_dump_f, "%s\n", buffer); /* Print the error */
+ PR_Free(buffer);
+ regfree(regex);
+ return NULL;
+ }
+
+ entry.regex = regex;
+ root = new ConfigStoreRoot();
+ ret = new ConfigStore(root, "");
+ entry.store = ret;
+
+ PR_Lock(m_lock);
+ PL_HashTableEnumerateEntries(m_root->getSet(), &PatternLoop, &entry);
+ PR_Unlock(m_lock);
+
+ /* cleanup */
+ //regfree(entry.regex);
+ //entry.store = NULL;
+
+ ret->SetFilePath("");
+ return ret;
+}
+
diff --git a/base/tps/src/main/LogFile.cpp b/base/tps/src/main/LogFile.cpp
new file mode 100644
index 000000000..d908ca0c5
--- /dev/null
+++ b/base/tps/src/main/LogFile.cpp
@@ -0,0 +1,298 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "main/ConfigStore.h"
+#include "engine/RA.h"
+#include "main/LogFile.h"
+#include "main/RA_Context.h"
+#include "main/Util.h"
+
+//default constructor
+LogFile::LogFile():
+ m_fd(NULL),
+ m_fname(NULL),
+ m_signed_log(false),
+ m_bytes_written(0),
+ m_signed(false),
+ m_monitor(NULL),
+ m_ctx(NULL) { }
+
+int LogFile::startup(RA_Context *ctx, const char* prefix, const char *fname, bool signed_audit)
+{
+ if (ctx == NULL) {
+ return PR_FAILURE;
+ }
+
+ if (fname == NULL) {
+ ctx->LogError("LogFile::startup",
+ __LINE__,
+ "startup error, fname is NULL");
+ return PR_FAILURE;
+ }
+
+ m_ctx = ctx;
+ m_signed_log = signed_audit;
+ m_fname = PL_strdup(fname);
+ m_bytes_written =0;
+ m_signed = false;
+ m_fd = (PRFileDesc*) NULL;
+ m_monitor = PR_NewMonitor();
+
+ m_ctx->LogInfo( "LogFile::startup",
+ __LINE__,
+ "thread = 0x%lx: Logfile %s startup complete",
+ PR_GetCurrentThread(), m_fname);
+ return PR_SUCCESS;
+}
+
+bool LogFile::isOpen()
+{
+ if (m_fd != NULL) return true;
+ return false;
+}
+
+void LogFile::shutdown()
+{
+ m_ctx->LogInfo( "LogFile::shutdown",
+ __LINE__,
+ "thread = 0x%lx: Logfile %s shutting down pid: %d",
+ PR_GetCurrentThread(), m_fname,getpid());
+
+ PR_EnterMonitor(m_monitor);
+ if (m_fd != NULL) {
+ close();
+ m_fd = (PRFileDesc *) NULL;
+ }
+
+ if (m_fname != NULL) {
+ PR_Free(m_fname);
+ m_fname = NULL;
+ }
+
+ PR_ExitMonitor(m_monitor);
+
+ if (m_monitor != NULL) {
+ PR_DestroyMonitor(m_monitor);
+ m_monitor = (PRMonitor *) NULL;
+ }
+}
+
+int LogFile::open()
+{
+ PRFileInfo info;
+ PR_EnterMonitor(m_monitor);
+
+ m_ctx->LogInfo( "LogFile::open",
+ __LINE__,
+ "Opening Log File: %s pid: %d",
+ m_fname,getpid());
+
+ if (m_fd == NULL) {
+ m_fd = PR_Open(m_fname, PR_RDWR | PR_CREATE_FILE | PR_APPEND, 440|200);
+ if (m_fd == NULL) {
+ m_ctx->LogError( "LogFile::open",
+ __LINE__,
+ "Unable to open log file %s error no: %d",
+ m_fname,PR_GetError());
+
+
+ goto loser;
+ }
+ PRStatus status = PR_GetOpenFileInfo(m_fd, &info);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "LogFile::open",
+ __LINE__,
+ "Unable to get file information for log file %s",
+ m_fname);
+ goto loser;
+ }
+
+ set_bytes_written(info.size);
+ }
+ PR_ExitMonitor(m_monitor);
+ return PR_SUCCESS;
+
+ loser:
+ if (m_fd != NULL) {
+ PR_Close(m_fd);
+ m_fd = (PRFileDesc *)NULL;
+ }
+ set_bytes_written(0);
+ PR_ExitMonitor(m_monitor);
+ return PR_FAILURE;
+}
+
+int LogFile::close()
+{
+ PRStatus status;
+ PR_EnterMonitor(m_monitor);
+ status = PR_Close(m_fd);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "LogFile::close",
+ __LINE__,
+ "Failed to close log file %s",
+ m_fname);
+ }
+ PR_ExitMonitor(m_monitor);
+ return status;
+}
+
+int LogFile::ReadLine(char *buf, int buf_len, int *removed_return)
+{
+ return Util::ReadLine(m_fd, buf,buf_len, removed_return);
+}
+
+int LogFile::printf(const char* fmt, ...)
+{
+ PRInt32 status;
+ char msg[4096];
+ va_list ap;
+ va_start(ap, fmt);
+ PR_vsnprintf((char *) msg, 4096, fmt, ap);
+ status = this->write(msg);
+ va_end(ap);
+ return status;
+}
+
+int LogFile::write(char *msg_in, size_t n)
+{
+ char msg[4096];
+ PRInt32 status;
+
+ if (n > 4096) {
+ m_ctx->LogError("LogFile::write",
+ __LINE__,
+ "Trying to write more than 4096 bytes in one write to log file %s. Truncating ...",
+ m_fname);
+ n=4096;
+ }
+
+ PR_snprintf(msg, n, "%s", msg_in);
+ status = this->write(msg);
+ return status;
+}
+
+int LogFile::vfprintf(const char* fmt, va_list ap)
+{
+ char msg[4096];
+ PRInt32 status;
+
+ PR_vsnprintf((char *) msg, 4096, fmt, ap);
+ status = this->write(msg);
+ return status;
+}
+
+int LogFile::write(const char * msg)
+{
+ PRErrorCode error;
+ PRInt32 status;
+ int len;
+
+ if (msg == NULL) {
+ return PR_SUCCESS;
+ }
+
+ PR_EnterMonitor(m_monitor);
+ len = PL_strlen(msg);
+ if (m_fd != NULL) {
+ status = PR_Write(m_fd, msg, len);
+ if (status != len) {
+ m_ctx->LogError( "LogFile::write",
+ __LINE__,
+ "Too few or too many bytes written to log file %s",
+ m_fname);
+ goto loser;
+ } else if (status < 0) {
+ // write failed
+ error = PR_GetError();
+ m_ctx->LogError( "LogFile::write",
+ __LINE__,
+ "Write to log file %s failed: code %d",
+ m_fname, error);
+ goto loser;
+ } else {
+ set_bytes_written(get_bytes_written() + len);
+ }
+ }
+ PR_ExitMonitor(m_monitor);
+ return PR_SUCCESS;
+ loser:
+ PR_ExitMonitor(m_monitor);
+ return PR_FAILURE;
+}
+
+void LogFile::setSigned(bool val) {
+ m_signed = val;
+}
+
+bool LogFile::getSigned() {
+ return m_signed;
+}
+
+int LogFile::get_bytes_written() {
+ return m_bytes_written;
+}
+
+void LogFile::set_bytes_written(int val) {
+ if (val >=0) {
+ m_bytes_written = val;
+ } else {
+ m_ctx->LogError("LogFile::set_bytes_written",
+ __LINE__,
+ "Attempt to set m_bytes_written to a negative value. Ignoring");
+ }
+}
+
+RA_Context * LogFile::get_context() {
+ return m_ctx;
+}
+
+void LogFile::set_context(RA_Context *ctx) {
+ m_ctx = ctx;
+}
+
+
diff --git a/base/tps/src/main/Login.cpp b/base/tps/src/main/Login.cpp
new file mode 100644
index 000000000..116ac7769
--- /dev/null
+++ b/base/tps/src/main/Login.cpp
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "main/Base.h"
+#include "main/Login.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a login object.
+ */
+Login::Login (char *uid, char *pwd)
+{
+ if (uid == NULL) {
+ m_uid = NULL;
+ } else {
+ m_uid = PL_strdup(uid);
+ }
+ if (pwd == NULL) {
+ m_pwd = NULL;
+ } else {
+ m_pwd = PL_strdup(pwd);
+ }
+}
+
+/**
+ * Destructs login object.
+ */
+Login::~Login ()
+{
+ if( m_uid != NULL ) {
+ PL_strfree( m_uid );
+ m_uid = NULL;
+ }
+ if( m_pwd != NULL ) {
+ PL_strfree( m_pwd );
+ m_pwd = NULL;
+ }
+}
+
+/**
+ * Retrieves user id.
+ */
+char *Login::GetUID()
+{
+ return m_uid;
+}
+
+/**
+ * Retrieves password.
+ */
+char *Login::GetPassword()
+{
+ return m_pwd;
+}
diff --git a/base/tps/src/main/Memory.cpp b/base/tps/src/main/Memory.cpp
new file mode 100644
index 000000000..1ee5027d0
--- /dev/null
+++ b/base/tps/src/main/Memory.cpp
@@ -0,0 +1,268 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "plhash.h"
+#include "pk11func.h"
+
+#include "main/MemoryMgr.h"
+
+#ifdef MEM_PROFILING
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct _ref_block
+{
+ int id;
+ void *ptr;
+ const char *file;
+ const char *func;
+ const char *type;
+ int line;
+ int size;
+ int used;
+ PRTime time;
+} ref_block;
+
+#define MAX_BLOCKS 8096
+static ref_block m_rb[MAX_BLOCKS];
+
+static PRLock *m_free_block_lock = NULL;
+static PRLock *m_dump_lock = NULL;
+static PRLock *m_audit_lock = NULL;
+
+ref_block *get_free_block()
+{
+ int i;
+ PR_Lock(m_free_block_lock);
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (m_rb[i].used == 0) {
+ // lock
+ m_rb[i].used = 1;
+ m_rb[i].time = PR_Now();
+ PR_Unlock(m_free_block_lock);
+ return &m_rb[i];
+ }
+ }
+ PR_Unlock(m_free_block_lock);
+ return NULL;
+}
+
+ref_block *find_block(void *ptr)
+{
+ int i;
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (m_rb[i].used == 1 && m_rb[i].ptr == ptr) {
+ return &m_rb[i];
+ }
+ }
+ return NULL;
+}
+
+void free_block(ref_block *rb)
+{
+ rb->used = 0;
+}
+
+static PRFileDesc *m_audit_f = NULL;
+static PRFileDesc *m_dump_f = NULL;
+
+void MEM_init(char *audit_file, char *dump_file)
+{
+ m_audit_f = PR_Open(audit_file, PR_RDWR|PR_CREATE_FILE|PR_APPEND,
+ 00200|00400);
+ m_dump_f = PR_Open(dump_file, PR_RDWR|PR_CREATE_FILE|PR_APPEND,
+ 00200|00400);
+
+ int i;
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ m_rb[i].id = i;
+ m_rb[i].used = 0;
+ }
+ m_free_block_lock = PR_NewLock();
+ m_dump_lock = PR_NewLock();
+ m_audit_lock = PR_NewLock();
+}
+
+void MEM_shutdown()
+{
+ PR_DestroyLock(m_free_block_lock);
+ PR_DestroyLock(m_dump_lock);
+ PR_DestroyLock(m_audit_lock);
+ if (m_dump_f != NULL) {
+ PR_Close(m_dump_f);
+ }
+ if (m_audit_f != NULL) {
+ PR_Close(m_audit_f);
+ }
+}
+
+static void MEM_audit_block(ref_block *ref, const char *type, const char *func, const char *file, int line, PRFileDesc *f)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ char datetime1[1024];
+ PRExplodedTime time1;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+
+ PR_ExplodeTime(ref->time, PR_LocalTimeParameters, &time1);
+ PR_FormatTimeUSEnglish(datetime1, 1024, time_fmt, &time1);
+
+ PR_Lock(m_audit_lock);
+ PR_fprintf(f, "[%s] ID='%d' Size='%d' Type='%s' Func='%s' File='%s' Line='%d' Time='%s'\n",
+ datetime, ref->id, ref->size, type, func, file, line, datetime1);
+ PR_Sync(f);
+ PR_Unlock(m_audit_lock);
+}
+
+void MEM_dump_unfree()
+{
+ int i;
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ char datetime1[1024];
+ PRExplodedTime time1;
+ int sum_count = 0;
+ int sum_mem = 0;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+
+ PR_Lock(m_dump_lock);
+ PR_fprintf(m_dump_f, "--------------------------------------------\n");
+ PR_fprintf(m_dump_f, "Memory Report - '%s'\n", datetime);
+ PR_fprintf(m_dump_f, "1) Unfree Blocks:\n");
+ PR_fprintf(m_dump_f, "\n");
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (!m_rb[i].used)
+ continue;
+ PR_ExplodeTime(m_rb[i].time, PR_LocalTimeParameters, &time1);
+ PR_FormatTimeUSEnglish(datetime1, 1024, time_fmt, &time1);
+ PR_fprintf(m_dump_f, " ID='%d' Size='%d' Type='%s' Func='%s' File='%s' Line='%d' Time='%s'\n", m_rb[i].id, m_rb[i].size, m_rb[i].type, m_rb[i].func, m_rb[i].file, m_rb[i].line, datetime1);
+ sum_mem += m_rb[i].size;
+ sum_count += 1;
+ }
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "2) Total Unfree Memory Size:\n");
+ PR_fprintf(m_dump_f, " %d bytes\n", sum_mem);
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "3) Total Unfree Memory Blocks:\n");
+ PR_fprintf(m_dump_f, " %d\n", sum_count);
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "--------------------------------------------\n");
+ PR_Sync(m_dump_f);
+ PR_Unlock(m_dump_lock);
+}
+
+char *MEM_strdup(const char *s, const char *type, const char *func, const char *file, int line)
+{
+ ref_block *rb = get_free_block();
+ if (rb == NULL)
+ return NULL;
+
+ char *buf = strdup(s);
+
+ rb->ptr = buf;
+ rb->func = func;
+ rb->file = file;
+ rb->line = line;
+ rb->type = type;
+ rb->size = strlen(s) + 1;
+ MEM_audit_block(rb, rb->type, rb->func, rb->file, rb->line, m_audit_f);
+
+ return buf;
+}
+
+void *MEM_malloc(int size, const char *type, const char *func, const char *file, int line)
+{
+ ref_block *rb = get_free_block();
+ if (rb == NULL)
+ return NULL;
+ void *buf = malloc(size);
+
+ rb->ptr = buf;
+ rb->func = func;
+ rb->file = file;
+ rb->line = line;
+ rb->type = type;
+ rb->size = size;
+ MEM_audit_block(rb, rb->type, rb->func, rb->file, rb->line, m_audit_f);
+
+ return buf;
+}
+
+void MEM_free(void *p, const char *type, const char *func, const char *file, int line)
+{
+ if (p == NULL)
+ return;
+ ref_block *rb = find_block(p);
+ if (rb == NULL)
+ return;
+ MEM_audit_block(rb, type, func, file, line, m_audit_f);
+ free(p);
+ free_block(rb);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#if 0
+void *operator new(size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, func, file, line);
+}
+
+void *operator new[](size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, func, file, line);
+}
+
+#endif
+void operator delete(void *p)
+{
+ MEM_free(p,"delete","", "", 0);
+}
+
+void operator delete[](void *p)
+{
+ MEM_free(p,"delete[]","", "", 0);
+}
+
+#endif /* MEM_PROFILING */
+
diff --git a/base/tps/src/main/NameValueSet.cpp b/base/tps/src/main/NameValueSet.cpp
new file mode 100644
index 000000000..bd95a8e4a
--- /dev/null
+++ b/base/tps/src/main/NameValueSet.cpp
@@ -0,0 +1,322 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "main/NameValueSet.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PR_CALLBACK void*
+_AllocTable(void* pool, PRSize size)
+{
+ return PR_MALLOC(size);
+}
+
+static PR_CALLBACK void
+_FreeTable(void* pool, void* item)
+{
+ PR_DELETE(item);
+}
+
+static PR_CALLBACK PLHashEntry*
+_AllocEntry(void* pool, const void* key)
+{
+ return PR_NEW(PLHashEntry);
+}
+
+static PR_CALLBACK void
+_FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
+{
+ if( he == NULL ) {
+ return;
+ }
+
+ if (flag == HT_FREE_VALUE) {
+ if( he->value != NULL ) {
+ PL_strfree( ( char* ) he->value );
+ he->value = NULL;
+ }
+ } else if (flag == HT_FREE_ENTRY) {
+ if( he->key != NULL ) {
+ PL_strfree( ( char* ) he->key );
+ he->key = NULL;
+ }
+ if( he->value != NULL ) {
+ PL_strfree( ( char* ) he->value );
+ he->value = NULL;
+ }
+ PR_DELETE(he);
+ }
+}
+
+static PLHashAllocOps _AllocOps = {
+ _AllocTable,
+ _FreeTable,
+ _AllocEntry,
+ _FreeEntry
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+TPS_PUBLIC NameValueSet::NameValueSet()
+{
+ m_set = PL_NewHashTable(3, PL_HashString,
+ PL_CompareStrings, PL_CompareValues,
+ &_AllocOps, NULL);
+}
+
+TPS_PUBLIC NameValueSet::~NameValueSet ()
+{
+ if( m_set != NULL ) {
+ PL_HashTableDestroy( m_set );
+ m_set = NULL;
+ }
+
+ return;
+}
+
+/**
+ * Parsers string of format "n1=v1&n2=v2..."
+ * into a NameValueSet.
+ */
+TPS_PUBLIC NameValueSet *NameValueSet::Parse(const char *s, const char *separator)
+{
+ NameValueSet *set = NULL;
+ char *pair;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+
+ if (s == NULL)
+ return NULL;
+ set = new NameValueSet();
+ line = PL_strdup(s);
+ pair = PL_strtok_r(line, separator, &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip;
+ }
+ if (pair[i] == '\0') {
+ goto skip;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+ set->Add(&pair[0], &pair[i+1]);
+skip:
+ pair = PL_strtok_r(NULL, separator, &lasts);
+ }
+ if( line != NULL ) {
+ PL_strfree( line );
+ line = NULL;
+ }
+ return set;
+}
+
+typedef struct {
+ int index;
+ char *key;
+} Criteria;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PRIntn CountLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ criteria->index++;
+ return HT_ENUMERATE_NEXT;
+}
+
+static PRIntn Loop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ if (criteria != NULL && index == criteria->index) {
+ criteria->key = (char *)he->key;
+ return HT_ENUMERATE_STOP;
+ } else {
+ return HT_ENUMERATE_NEXT;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+TPS_PUBLIC int NameValueSet::Size()
+{
+ Criteria criteria;
+ criteria.index = 0;
+ criteria.key = NULL;
+ PL_HashTableEnumerateEntries(m_set, &CountLoop, &criteria);
+ return criteria.index;
+}
+
+TPS_PUBLIC char *NameValueSet::GetNameAt(int pos)
+{
+ Criteria criteria;
+ criteria.index = pos;
+ criteria.key = NULL;
+ PL_HashTableEnumerateEntries(m_set, &Loop, &criteria);
+ return criteria.key;
+}
+
+/**
+ * Checks if a key is defined.
+ */
+TPS_PUBLIC int NameValueSet::IsNameDefined(const char *name)
+{
+ if (GetValue(name) == NULL)
+ return 0;
+ else
+ return 1;
+}
+
+TPS_PUBLIC void NameValueSet::Add(const char *name, const char *value)
+{
+ if (IsNameDefined(name)) {
+ PL_HashTableAdd(m_set, PL_strdup(name), PL_strdup(value));
+ } else {
+ PL_HashTableAdd(m_set, PL_strdup(name), PL_strdup(value));
+ }
+}
+
+TPS_PUBLIC void NameValueSet::Remove(const char *name)
+{
+ if (IsNameDefined(name)) {
+ PL_HashTableRemove(m_set, name);
+ }
+}
+
+TPS_PUBLIC char *NameValueSet::GetValue(const char *name)
+{
+ return (char *)PL_HashTableLookupConst(m_set, name);
+}
+
+/**
+ * Retrieves configuration value as integer.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsInt(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return 0;
+ return atoi(value);
+}
+
+/**
+ * Retrieves configuration value as integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsInt(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ return atoi(value);
+}
+
+
+/**
+ * Retrieves configuration value as boolean.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsBool(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return 0;
+ if (PL_CompareStrings("true", value) != 0)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * Retrieves configuration value as boolean. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsBool(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ if (PL_CompareStrings("true", value) != 0)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * Retrieves configuration value as string. If key is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC char *NameValueSet::GetValueAsString(const char *name, char *def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ return value;
+}
+
+/**
+ * Retrieves configuration value as string.
+ */
+TPS_PUBLIC char *NameValueSet::GetValueAsString(const char *name)
+{
+ return (char *)GetValue(name);
+}
+
diff --git a/base/tps/src/main/ObjectSpec.cpp b/base/tps/src/main/ObjectSpec.cpp
new file mode 100644
index 000000000..2896a85f0
--- /dev/null
+++ b/base/tps/src/main/ObjectSpec.cpp
@@ -0,0 +1,515 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/ObjectSpec.h"
+#include "engine/RA.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+ObjectSpec::ObjectSpec ()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ m_attributeSpec[i] = NULL;
+ }
+ m_fixedAttributes = 0;
+}
+
+ObjectSpec::~ObjectSpec ()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] != NULL) {
+ delete m_attributeSpec[i];
+ m_attributeSpec[i] = NULL;
+ }
+ }
+}
+
+#define DATATYPE_STRING 0
+#define DATATYPE_INTEGER 1
+#define DATATYPE_BOOL_FALSE 2
+#define DATATYPE_BOOL_TRUE 3
+
+/**
+ * Parse 'c' object.
+ */
+void ObjectSpec::ParseAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ int curpos = 7;
+ unsigned long fixedAttrs = 0;
+ unsigned int xclass = 0;
+ unsigned int id = 0;
+
+ /* skip first 7 bytes */
+
+ while (curpos < ((int)(b->size()))) {
+ unsigned long attribute_id =
+ (((BYTE*)*b)[curpos] << 24) +
+ (((BYTE*)*b)[curpos+1] << 16) +
+ (((BYTE*)*b)[curpos+2] << 8) +
+ ((BYTE*)*b)[curpos+3];
+ unsigned short attribute_size =
+ (((BYTE*)*b)[curpos+4] << 8) +
+ ((BYTE*)*b)[curpos+5];
+ BYTE type = 0;
+ Buffer data;
+ int found = 0;
+ /* modify fixed attributes */
+
+ switch (attribute_id) {
+ case CKA_TOKEN:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000080;
+ }
+ break;
+ case CKA_PRIVATE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000100;
+ } else {
+ }
+ break;
+ case CKA_MODIFIABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000200;
+ }
+ break;
+ case CKA_DERIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000400;
+ }
+ break;
+ case CKA_LOCAL:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000800;
+ }
+ break;
+ case CKA_ENCRYPT:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00001000;
+ }
+ break;
+ case CKA_DECRYPT:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00002000;
+ }
+ break;
+ case CKA_WRAP:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00004000;
+ }
+ break;
+ case CKA_UNWRAP:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00008000;
+ }
+ break;
+ case CKA_SIGN:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00010000;
+ }
+ break;
+ case CKA_SIGN_RECOVER:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00020000;
+ }
+ break;
+ case CKA_VERIFY:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00040000;
+ }
+ break;
+ case CKA_VERIFY_RECOVER:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00080000;
+ }
+ break;
+ case CKA_SENSITIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00100000;
+ }
+ break;
+ case CKA_ALWAYS_SENSITIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00200000;
+ }
+ break;
+ case CKA_EXTRACTABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00400000;
+ }
+ break;
+ case CKA_NEVER_EXTRACTABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00800000;
+ }
+ break;
+ case CKA_SUBJECT:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_LABEL:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ found = 1;
+ break;
+ case CKA_MODULUS:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_ID:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_KEY_TYPE:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ /* build by PKCS11 */
+ break;
+ case CKA_CLASS:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ xclass = ((BYTE*)data)[0];
+ /* build by PKCS11 */
+ break;
+ case CKA_PUBLIC_EXPONENT:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_CERTIFICATE_TYPE:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ /* build by PKCS11 */
+ break;
+ default:
+ RA::Debug("ObjectSpec::ParseKeyBlob",
+ "skipped attribute_id = %lx",
+ attribute_id);
+ break;
+ }
+
+
+ if (found) {
+ /* add attribute spec */
+ AttributeSpec *attrSpec = new AttributeSpec();
+ attrSpec->SetAttributeID(attribute_id);
+ attrSpec->SetType(type);
+
+ switch (type) {
+ case DATATYPE_STRING:
+ attrSpec->SetData(data);
+ break;
+ case DATATYPE_INTEGER:
+ attrSpec->SetData(data);
+ break;
+ case DATATYPE_BOOL_FALSE:
+ break;
+ case DATATYPE_BOOL_TRUE:
+ break;
+ default:
+ break;
+ }
+
+ ObjectSpec->AddAttributeSpec(attrSpec);
+ }
+
+
+ curpos += 4 + 2 + attribute_size;
+ }
+
+ //Here the objectID fixed attribute gets massaged. Here's how:
+ // The objectID becomes the cert container id, ex: 01
+ // Each key pair associated with the cert must have the same ID.
+ // This is done by math using the following formula:
+ // Given a cert id of "2", the keyAttrIds of the keys are originally
+ // configured as k4 and k5. Note that one is twice the cert id, and
+ // the other is twice the cert id plus 1. In order to map the key ids
+ // down to the cert's id, the code below changes both "4" and "5" back
+ // to "2".
+
+ int val = (objectID[1] - '0');
+ switch (objectID[0]) {
+ case 'c':
+ id = val;
+#if 0
+ fixedAttrs |=
+ 0x00000080 /* CKA_TOKEN */
+ ;
+#endif
+ break;
+ case 'k':
+ if (val % 2) {
+ id = (val-1)/2;
+ } else {
+ id = (val/2);
+ }
+#if 0
+ if (xclass == CKO_PUBLIC_KEY) {
+ fixedAttrs |=
+ 0x00000800 /* CKA_LOCAL */ |
+ 0x00000080 /* CKA_TOKEN */
+ ;
+ }
+ if (xclass == CKO_PRIVATE_KEY) {
+ fixedAttrs |=
+ 0x00000800 /* CKA_LOCAL */ |
+ 0x00000080 /* CKA_TOKEN */
+ ;
+ }
+#endif
+ break;
+ }
+
+ ObjectSpec->SetFixedAttributes(fixedAttrs | (xclass << 4) | id);
+}
+
+/**
+ * Parse 'c' object.
+ */
+void ObjectSpec::ParseCertificateAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ ParseAttributes(objectID, ObjectSpec, b);
+}
+
+/**
+ * Parse 'k' object.
+ */
+void ObjectSpec::ParseKeyAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ ParseAttributes(objectID, ObjectSpec, b);
+}
+
+/**
+ * Parse 'C' object.
+ */
+void ObjectSpec::ParseCertificateBlob(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ unsigned long fixedAttrs = 0;
+ unsigned int xclass = 0;
+ unsigned int id = 0;
+
+ AttributeSpec *value = new AttributeSpec();
+ value->SetAttributeID(CKA_VALUE);
+ value->SetType(DATATYPE_STRING);
+ value->SetData(*b);
+ ObjectSpec->AddAttributeSpec(value);
+
+ fixedAttrs = 0x00000080; /* CKA_TOKEN */
+ xclass = CKO_CERTIFICATE;
+ id = objectID[1] - '0';
+
+ ObjectSpec->SetFixedAttributes(fixedAttrs| (xclass << 4) | id);
+}
+
+/**
+ * Convert object from token into object spec.
+ *
+ * Reference:
+ * http://netkey/design/applet_readable_object_spec-0.1.txt
+ * http://netkey/design/pkcs11obj.txt
+ */
+ObjectSpec *ObjectSpec::ParseFromTokenData(unsigned long objid, Buffer *b)
+{
+ char objectID[4];
+
+ ObjectSpec *o = new ObjectSpec();
+ o->SetObjectID(objid);
+
+ objectID[0] = (char)((objid >> 24) & 0xff);
+ objectID[1] = (char)((objid >> 16) & 0xff);
+ objectID[2] = (char)((objid >> 8) & 0xff);
+ objectID[3] = (char)((objid) & 0xff);
+
+ switch (objectID[0]) {
+ case 'c': /* certificate attributes */
+ ParseCertificateAttributes(objectID, o, b);
+ break;
+ case 'k': /* public key or private key attributes */
+ ParseKeyAttributes(objectID, o, b);
+ break;
+ case 'C': /* certificate in DER */
+ ParseCertificateBlob(objectID, o, b);
+ break;
+ default:
+ RA::Debug("ObjectSpec::ParseKeyBlob",
+ "unknown objectID = %c", objectID[0]);
+ /* error */
+ break;
+ }
+
+ return o;
+}
+
+ObjectSpec *ObjectSpec::Parse(Buffer *b, int offset, int *nread)
+{
+ int sum = 0;
+
+
+ if((b->size() - offset) < 10)
+ return NULL;
+
+ ObjectSpec *o = new ObjectSpec();
+ unsigned long id =
+ (((unsigned char *)*b)[offset + 0] << 24) +
+ (((unsigned char *)*b)[offset + 1] << 16) +
+ (((unsigned char *)*b)[offset + 2] << 8) +
+ (((unsigned char *)*b)[offset + 3]);
+
+ o->SetObjectID(id);
+ unsigned long attribute =
+ (((unsigned char *)*b)[offset + 4] << 24) +
+ (((unsigned char *)*b)[offset + 5] << 16) +
+ (((unsigned char *)*b)[offset + 6] << 8) +
+ (((unsigned char *)*b)[offset + 7]);
+ o->SetFixedAttributes(attribute);
+ unsigned short count = (((unsigned char *)*b)[offset + 8] << 8) +
+ ((unsigned char *)*b)[offset + 9];
+ sum += 10;
+ int curpos = offset + 10;
+ for (int i = 0; i < count; i++) {
+ int len = 0;
+ switch (((unsigned char *)*b)[curpos+4]) {
+ case DATATYPE_STRING:
+ len = 4 + 1 + 2 + (((unsigned char *)*b)[curpos+5]<<8) + ((unsigned char *)*b)[curpos+6];
+ break;
+ case DATATYPE_INTEGER:
+ len = 4 + 1 + 4;
+ break;
+ case DATATYPE_BOOL_FALSE:
+ len = 4 + 1;
+ break;
+ case DATATYPE_BOOL_TRUE:
+ len = 4 + 1;
+ break;
+ }
+ Buffer attr = b->substr(curpos, len);
+ AttributeSpec *attrSpec = AttributeSpec::Parse(&attr, 0);
+ o->AddAttributeSpec(attrSpec);
+ curpos += len;
+ sum += len;
+ }
+ *nread = sum;
+ return o;
+}
+
+void ObjectSpec::SetObjectID(unsigned long v)
+{
+ m_objectID = v;
+}
+
+unsigned long ObjectSpec::GetObjectID()
+{
+ return m_objectID;
+}
+
+void ObjectSpec::SetFixedAttributes(unsigned long v)
+{
+ m_fixedAttributes = v;
+}
+
+unsigned long ObjectSpec::GetFixedAttributes()
+{
+ return m_fixedAttributes;
+}
+
+
+int ObjectSpec::GetAttributeSpecCount()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] == NULL) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+AttributeSpec *ObjectSpec::GetAttributeSpec(int p)
+{
+ if (p < MAX_ATTRIBUTE_SPEC) {
+ if (m_attributeSpec[p] != NULL) {
+ return m_attributeSpec[p];
+ }
+ }
+ return NULL;
+}
+
+void ObjectSpec::AddAttributeSpec(AttributeSpec *p)
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] == NULL) {
+ m_attributeSpec[i] = p;
+ return;
+ }
+ }
+}
+
+void ObjectSpec::RemoveAttributeSpec(int p)
+{
+ if (p < MAX_ATTRIBUTE_SPEC) {
+ if (m_attributeSpec[p] != NULL) {
+ delete m_attributeSpec[p];
+ m_attributeSpec[p] = NULL;
+ }
+ // fill hole
+ int empty = p;
+ for (int x = p+1; x < MAX_ATTRIBUTE_SPEC; x++) {
+ if (m_attributeSpec[x] != NULL) {
+ m_attributeSpec[empty] = m_attributeSpec[x];
+ m_attributeSpec[x] = NULL;
+ empty++;
+ }
+ }
+ }
+
+}
+
+Buffer ObjectSpec::GetData()
+{
+ Buffer data = Buffer();
+
+ data += Buffer(1, (BYTE)(m_objectID >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID >> 8) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID & 0xff));
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 8) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes & 0xff));
+
+ unsigned short attributeCount = GetAttributeSpecCount();
+ data += Buffer(1, (attributeCount >> 8) & 0xff);
+ data += Buffer(1, attributeCount & 0xff);
+ for (int i = 0; i < attributeCount; i++) {
+ AttributeSpec *spec = GetAttributeSpec(i);
+ data += spec->GetData();
+ }
+
+ return data;
+}
diff --git a/base/tps/src/main/PKCS11Obj.cpp b/base/tps/src/main/PKCS11Obj.cpp
new file mode 100644
index 000000000..061dc7a91
--- /dev/null
+++ b/base/tps/src/main/PKCS11Obj.cpp
@@ -0,0 +1,491 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "zlib.h"
+#include "engine/RA.h"
+#include "main/Buffer.h"
+#include "main/PKCS11Obj.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+PKCS11Obj::PKCS11Obj ()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ m_objSpec[i] = NULL;
+ }
+}
+
+PKCS11Obj::~PKCS11Obj ()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] != NULL) {
+ delete m_objSpec[i];
+ m_objSpec[i] = NULL;
+ }
+ }
+}
+
+PKCS11Obj *PKCS11Obj::Parse(Buffer *b, int offset)
+{
+ PKCS11Obj *o = new PKCS11Obj();
+
+ unsigned short formatVersion = (((BYTE *)*b)[offset + 0] << 8) +
+ (((BYTE *)*b)[offset + 1]);
+ o->SetFormatVersion(formatVersion);
+ unsigned short objectVersion = (((BYTE *)*b)[offset + 2] << 8) +
+
+ (((BYTE *)*b)[offset + 3]);
+ o->SetObjectVersion(objectVersion);
+ o->SetCUID(b->substr(offset + 4, 10));
+
+ unsigned short compressionType =
+ (((BYTE *)*b)[offset + 14] << 8) + (((BYTE *)*b)[offset + 15]);
+ unsigned short compressedDataSize =
+ (((BYTE *)*b)[offset + 16] << 8) + (((BYTE *)*b)[offset + 17]);
+#if 0
+ unsigned short compressedDataOffset =
+ (unsigned short)(((unsigned char *)*b)[offset + 18] << 8) + (((unsigned char *)*b)[offset + 19]);
+#endif
+
+ Buffer data;
+ if (compressionType == 0) { /* no compression */
+ data = b->substr(offset + 20, compressedDataSize);
+ } else if (compressionType == 1) { /* zlib */
+ Buffer compressedData = b->substr(offset + 20, compressedDataSize);
+
+#define MAX_UNCOMPRESS_SIZE 20000
+ unsigned char buf[MAX_UNCOMPRESS_SIZE];
+ int rc = 0;
+ uLong len = MAX_UNCOMPRESS_SIZE;
+ rc = uncompress((Bytef*)buf, (uLongf*)&len,
+ (Bytef*)((BYTE*)compressedData),
+ (uLong)compressedData.size());
+ RA::Debug("PKCS11Obj::Parse","uncompress ret=%d",rc);
+ data = Buffer(buf,(unsigned int) len);
+ } else {
+ /* error */
+ }
+
+
+ unsigned short objOffset = (((BYTE *)data)[0] << 8) +
+ ((BYTE *)data)[1];
+ unsigned short objCount = (((BYTE *)data)[2] << 8) +
+ ((BYTE *)data)[3];
+ Buffer tokenName = data.substr(5, ((BYTE *)data)[4]);
+ o->SetTokenName(tokenName);
+
+ RA::Debug("PKCS11Obj::Parse", "objcount = %d", objCount);
+
+ int curpos = (int)objOffset;
+ int nread = 0;
+ for (int i = 0; i < objCount; i++) {
+ RA::Debug("PKCS11Obj::Parse", "working on object %d", i);
+ ObjectSpec *objSpec = ObjectSpec::Parse(&data, curpos, &nread);
+ if(!objSpec)
+ continue;
+ o->AddObjectSpec(objSpec);
+
+ unsigned long oid = objSpec->GetObjectID();
+ char b[2];
+
+ b[0] = (char)((oid >> 24) & 0xff);
+ b[1] = (char)((oid >> 16) & 0xff);
+
+ RA::Debug("PKCS11Obj::Parse", "About to parse = %c%c", b[0],b[1]);
+
+ // add corresponding 'C' object for 'c'
+ if (b[0] == 'c') {
+ for (int j = 0; j < objSpec->GetAttributeSpecCount();
+ j++) {
+ AttributeSpec *as = objSpec->GetAttributeSpec(j);
+ if (as->GetAttributeID() == CKA_VALUE) {
+ if (as->GetType() == (BYTE) 0) {
+ Buffer cert = as->GetValue();
+
+ unsigned long certid =
+ ('C' << 24) + (b[1] << 16);
+ ObjectSpec *certSpec =
+ ObjectSpec::ParseFromTokenData(
+ certid, &cert);
+ o->AddObjectSpec(certSpec);
+
+ objSpec->RemoveAttributeSpec(j);
+ break;
+ }
+ }
+ }
+
+ }
+
+ Buffer objSpecData = objSpec->GetData();
+ curpos += nread;
+ }
+
+ return o;
+}
+
+
+void PKCS11Obj::SetFormatVersion(unsigned short v)
+{
+ m_formatVersion = v;
+}
+
+void PKCS11Obj::SetObjectVersion(unsigned short v)
+{
+ m_objectVersion = v;
+}
+
+unsigned short PKCS11Obj::GetFormatVersion()
+{
+ return m_formatVersion;
+}
+
+unsigned short PKCS11Obj::GetObjectVersion()
+{
+ return m_objectVersion;
+}
+
+void PKCS11Obj::SetCUID(Buffer CUID)
+{
+ m_CUID = CUID;
+}
+
+Buffer PKCS11Obj::GetCUID()
+{
+ return m_CUID;
+}
+
+void PKCS11Obj::SetTokenName(Buffer tokenName)
+{
+ m_tokenName = tokenName;
+}
+
+Buffer PKCS11Obj::GetTokenName()
+{
+ return m_tokenName;
+}
+
+int PKCS11Obj::GetObjectSpecCount()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] == NULL) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+ObjectSpec *PKCS11Obj::GetObjectSpec(int p)
+{
+ if (p < MAX_OBJECT_SPEC) {
+ if (m_objSpec[p] != NULL) {
+ return m_objSpec[p];
+ }
+ }
+ return NULL;
+}
+
+void PKCS11Obj::AddObjectSpec(ObjectSpec *p)
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] == NULL) {
+ m_objSpec[i] = p;
+ return;
+ } else {
+ // check duplicated
+ if (p->GetObjectID() == m_objSpec[i]->GetObjectID()) {
+ delete m_objSpec[i];
+ m_objSpec[i] = p;
+ return;
+ }
+ }
+ }
+}
+
+void PKCS11Obj::RemoveObjectSpec(int p)
+{
+ if (p < MAX_OBJECT_SPEC) {
+ if (m_objSpec[p] != NULL) {
+ delete m_objSpec[p];
+ m_objSpec[p] = NULL;
+ }
+ // fill hole
+ int empty = p;
+ for (int x = p+1; x < MAX_OBJECT_SPEC; x++) {
+ if (m_objSpec[x] != NULL) {
+ m_objSpec[empty] = m_objSpec[x];
+ m_objSpec[x] = NULL;
+ empty++;
+ }
+ }
+ }
+}
+
+Buffer PKCS11Obj::GetData()
+{
+ Buffer data = Buffer();
+
+ unsigned short objectOffset = m_tokenName.size() + 2 + 3;
+ data += Buffer(1, (objectOffset >> 8) & 0xff);
+ data += Buffer(1, objectOffset & 0xff);
+ unsigned short objectCount = GetObjectSpecCount();
+ unsigned short objectCountX = objectCount;
+ if (objectCountX == 0) {
+ objectCountX = 0;
+ } else {
+ objectCountX = objectCountX - (objectCountX / 4);
+ }
+ data += Buffer(1, (objectCountX >> 8) & 0xff);
+ data += Buffer(1, objectCountX & 0xff);
+ data += Buffer(1, m_tokenName.size() & 0xff);
+ data += m_tokenName;
+ for (int i = 0; i < objectCount; i++) {
+ ObjectSpec *spec = GetObjectSpec(i);
+ unsigned long objectID = spec->GetObjectID();
+ char c = (char)((objectID >> 24) & 0xff);
+ unsigned long fixedAttrs = spec->GetFixedAttributes();
+ unsigned int xclass = (fixedAttrs & 0x70) >> 4;
+ char cont_id = (char) ((objectID >> 16) & 0xff);
+ unsigned int id = (fixedAttrs & 0x0f);
+ /* locate all certificate objects */
+ if (c == 'c' && xclass == CKO_CERTIFICATE) {
+
+ //We need to use the container id, there may be more than one cert
+ //with the same CKA_ID byte
+
+ id = (unsigned int) (cont_id - '0');
+
+ /* locate the certificate object */
+ for (int u = 0; u < objectCount; u++) {
+ ObjectSpec *u_spec = GetObjectSpec(u);
+ unsigned long u_objectID = u_spec->GetObjectID();
+ char u_c = (char)((u_objectID >> 24) & 0xff);
+ unsigned long u_fixedAttrs =
+ u_spec->GetFixedAttributes();
+ unsigned int u_xclass = (u_fixedAttrs & 0x70) >> 4;
+ unsigned int u_id = (u_fixedAttrs & 0x0f);
+ if (u_c == 'C' && u_xclass == CKO_CERTIFICATE && u_id == id) {
+ AttributeSpec * u_attr =
+ u_spec->GetAttributeSpec(0);
+ AttributeSpec * n_attr = new AttributeSpec();
+ n_attr->SetAttributeID(u_attr->GetAttributeID());
+ n_attr->SetType(u_attr->GetType());
+ n_attr->SetData(u_attr->GetValue());
+ spec->AddAttributeSpec(n_attr);
+ }
+ }
+
+ data += spec->GetData();
+
+ /* locate public object */
+ for (int x = 0; x < objectCount; x++) {
+ ObjectSpec *x_spec = GetObjectSpec(x);
+ unsigned long x_fixedAttrs =
+ x_spec->GetFixedAttributes();
+ unsigned int x_xclass = (x_fixedAttrs & 0x70) >> 4;
+ unsigned int x_id = (x_fixedAttrs & 0x0f);
+ if (x_xclass == CKO_PUBLIC_KEY && x_id == id) {
+ data += x_spec->GetData();
+ }
+ }
+
+ /* locate private object */
+ for (int y = 0; y < objectCount; y++) {
+ ObjectSpec *y_spec = GetObjectSpec(y);
+ unsigned long y_fixedAttrs =
+ y_spec->GetFixedAttributes();
+ unsigned int y_xclass = (y_fixedAttrs & 0x70) >> 4;
+ unsigned int y_id = (y_fixedAttrs & 0x0f);
+ if (y_xclass == CKO_PRIVATE_KEY && y_id == id) {
+ data += y_spec->GetData();
+ }
+ }
+ }
+ }
+
+ Buffer header = Buffer();
+ header += Buffer(1, (m_formatVersion >> 8) & 0xff);
+ header += Buffer(1, m_formatVersion & 0xff);
+ header += Buffer(1, (m_objectVersion >> 8) & 0xff);
+ header += Buffer(1, m_objectVersion & 0xff);
+ header += m_CUID;
+ // COMP_NONE = 0x00
+ // COMP_ZLIB = 0x01
+ unsigned short compressionType = 0x00;
+ header += Buffer(1, (compressionType >> 8) & 0xff);
+ header += Buffer(1, compressionType & 0xff);
+ unsigned short compressedDataSize = data.size();
+ header += Buffer(1, (compressedDataSize >> 8) & 0xff);
+ header += Buffer(1, compressedDataSize & 0xff);
+ unsigned short compressedDataOffset = 20;
+ header += Buffer(1, (compressedDataOffset >> 8) & 0xff);
+ header += Buffer(1, compressedDataOffset & 0xff);
+
+ return header + data;
+}
+
+Buffer PKCS11Obj::GetCompressedData()
+{
+ Buffer data = Buffer();
+ Buffer error = Buffer(0);
+
+ unsigned short objectOffset = m_tokenName.size() + 2 + 3;
+ data += Buffer(1, (objectOffset >> 8) & 0xff);
+ data += Buffer(1, objectOffset & 0xff);
+ unsigned short objectCount = GetObjectSpecCount();
+ unsigned short objectCountX = objectCount;
+ if (objectCountX == 0) {
+ objectCountX = 0;
+ } else {
+ objectCountX = objectCountX - (objectCountX / 4);
+ }
+ data += Buffer(1, (objectCountX >> 8) & 0xff);
+ data += Buffer(1, objectCountX & 0xff);
+ data += Buffer(1, m_tokenName.size() & 0xff);
+ data += m_tokenName;
+ RA::Debug("PKCS11Obj::GetCompressedData", "object count = %d", objectCount);
+ for (int i = 0; i < objectCount; i++) {
+ ObjectSpec *spec = GetObjectSpec(i);
+ unsigned long objectID = spec->GetObjectID();
+ RA::Debug("PKCS11Obj::GetCompressedData", "objid = %lu", objectID);
+ char c = (char)((objectID >> 24) & 0xff);
+ unsigned long fixedAttrs = spec->GetFixedAttributes();
+ unsigned int xclass = (fixedAttrs & 0x70) >> 4;
+ char cont_id = (char) ((objectID >> 16) & 0xff);
+ unsigned int id = (fixedAttrs & 0x0f);
+
+ /* locate all certificate objects */
+ if (c == 'c' && xclass == CKO_CERTIFICATE) {
+
+ //We need to use the container id, there may be more than one cert
+ //with the same CKA_ID byte
+
+ id = (unsigned int) (cont_id - '0');
+
+ /* locate the certificate object */
+ for (int u = 0; u < objectCount; u++) {
+ ObjectSpec *u_spec = GetObjectSpec(u);
+ unsigned long u_objectID = u_spec->GetObjectID();
+ char u_c = (char)((u_objectID >> 24) & 0xff);
+ unsigned long u_fixedAttrs =
+ u_spec->GetFixedAttributes();
+ unsigned int u_xclass = (u_fixedAttrs & 0x70) >> 4;
+ unsigned int u_id = (u_fixedAttrs & 0x0f);
+ char cont_u_id = (char) ((u_objectID >> 16) & 0xff);
+ if (u_c == 'C' && u_xclass == CKO_CERTIFICATE && u_id == id) {
+ RA::Debug("PKCS11Obj::GetCompressedData", "located Certificate id = %d cont_u_id = %c", u_id,cont_u_id);
+ AttributeSpec * u_attr =
+ u_spec->GetAttributeSpec(0);
+ AttributeSpec * n_attr = new AttributeSpec();
+ n_attr->SetAttributeID(u_attr->GetAttributeID());
+ n_attr->SetType(u_attr->GetType());
+ n_attr->SetData(u_attr->GetValue());
+ spec->AddAttributeSpec(n_attr);
+ }
+ }
+
+ /* output certificate attribute object */
+ data += spec->GetData();
+
+ /* locate public object */
+ for (int x = 0; x < objectCount; x++) {
+ ObjectSpec *x_spec = GetObjectSpec(x);
+ unsigned long x_fixedAttrs =
+ x_spec->GetFixedAttributes();
+ unsigned int x_xclass = (x_fixedAttrs & 0x70) >> 4;
+ unsigned int x_id = (x_fixedAttrs & 0x0f);
+ if (x_xclass == CKO_PUBLIC_KEY && x_id == id) {
+ RA::Debug("PKCS11Obj::GetCompressedData", "located Public Key = %d", x_id);
+ data += x_spec->GetData();
+ }
+
+ }
+
+ /* locate private object */
+ for (int y = 0; y < objectCount; y++) {
+ ObjectSpec *y_spec = GetObjectSpec(y);
+ unsigned long y_fixedAttrs =
+ y_spec->GetFixedAttributes();
+ unsigned int y_xclass = (y_fixedAttrs & 0x70) >> 4;
+ unsigned int y_id = (y_fixedAttrs & 0x0f);
+ if (y_xclass == CKO_PRIVATE_KEY && y_id == id) {
+ RA::Debug("PKCS11Obj::GetCompressedData", "located Private Key = %d", y_id);
+ data += y_spec->GetData();
+ }
+ }
+ }
+ }
+
+#define MAX_COMPRESS_SIZE 50000
+ char buffer[MAX_COMPRESS_SIZE];
+ unsigned long len = MAX_COMPRESS_SIZE ;
+
+ int rc = 0;
+
+ RA::Debug("PKCS11Obj", "before compress length = %d", len);
+
+ BYTE *src_buffer = (BYTE*)data;
+
+ RA::Debug("PKCS11Obj", "sizeof src_buffer = %d", sizeof(src_buffer));
+ RA::Debug("PKCS11Obj", "data size = %d", data.size());
+
+ rc = compress((Bytef*)buffer, (uLongf*)&len, (Bytef*)src_buffer,
+ (uLong)data.size());
+
+
+ if(rc != Z_OK) {
+ RA::Debug("PKCS11Obj", "failure compressing data, possibly buffer overrun! Error: %d ",rc);
+
+ return error;
+ }
+
+ RA::Debug("PKCS11Obj", "after compress length = %d", len);
+ RA::Debug("PKCS11Obj", "rc = %d", rc);
+
+ Buffer compressedData = Buffer((BYTE*)buffer, len);
+
+ Buffer header = Buffer();
+ header += Buffer(1, (m_formatVersion >> 8) & 0xff);
+ header += Buffer(1, m_formatVersion & 0xff);
+ header += Buffer(1, (m_objectVersion >> 8) & 0xff);
+ header += Buffer(1, m_objectVersion & 0xff);
+ header += m_CUID;
+ // COMP_NONE = 0x00
+ // COMP_ZLIB = 0x01
+ unsigned short compressionType = 0x01;
+ header += Buffer(1, (compressionType >> 8) & 0xff);
+ header += Buffer(1, compressionType & 0xff);
+ unsigned short compressedDataSize = compressedData.size();
+ header += Buffer(1, (compressedDataSize >> 8) & 0xff);
+ header += Buffer(1, compressedDataSize & 0xff);
+ unsigned short compressedDataOffset = 20;
+ header += Buffer(1, (compressedDataOffset >> 8) & 0xff);
+ header += Buffer(1, compressedDataOffset & 0xff);
+
+ return header + compressedData;
+}
+
diff --git a/base/tps/src/main/RA_Context.cpp b/base/tps/src/main/RA_Context.cpp
new file mode 100644
index 000000000..e3a66cdbb
--- /dev/null
+++ b/base/tps/src/main/RA_Context.cpp
@@ -0,0 +1,56 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "main/RA_Msg.h"
+#include "main/RA_Context.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a session that represents the
+ * connection between RA and the netkey client.
+ */
+TPS_PUBLIC RA_Context::RA_Context ()
+{
+}
+
+/**
+ * Destructs the session.
+ */
+TPS_PUBLIC RA_Context::~RA_Context ()
+{
+}
+
+void RA_Context::LogError(const char *func, int line, const char *fmt,...)
+{
+}
+
+void RA_Context::LogInfo(const char *func, int line, const char *fmt,...)
+{
+}
+
+void RA_Context::InitializationError(const char *func, int line)
+{
+}
+
diff --git a/base/tps/src/main/RA_Msg.cpp b/base/tps/src/main/RA_Msg.cpp
new file mode 100644
index 000000000..d54db69fb
--- /dev/null
+++ b/base/tps/src/main/RA_Msg.cpp
@@ -0,0 +1,45 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "main/RA_Msg.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a message that represents the
+ * message between RA and the netkey client.
+ */
+RA_Msg::RA_Msg ()
+{
+}
+
+/**
+ * Destructs the message.
+ */
+RA_Msg::~RA_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+RA_Msg_Type RA_Msg::GetType ()
+{
+ return MSG_UNDEFINED;
+}
diff --git a/base/tps/src/main/RA_Session.cpp b/base/tps/src/main/RA_Session.cpp
new file mode 100644
index 000000000..57f7e4efa
--- /dev/null
+++ b/base/tps/src/main/RA_Session.cpp
@@ -0,0 +1,75 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "engine/RA.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a session that represents the
+ * connection between RA and the netkey client.
+ */
+TPS_PUBLIC RA_Session::RA_Session ()
+{
+}
+
+/**
+ * Destructs the session.
+ */
+TPS_PUBLIC RA_Session::~RA_Session ()
+{
+}
+
+char *RA_Session::GetRemoteIP()
+{
+ return NULL;
+}
+
+RA_pblock *RA_Session::create_pblock( char *data )
+{
+ // Since this method is virtual,
+ // report an error if no subclass method has been defined.
+ RA::Error( "RA_pblock::find_val",
+ "No subclass method has been defined for this virtual method!" );
+ return NULL;
+}
+
+/**
+ * Reads a message that is sent by
+ * the client.
+ */
+RA_Msg *RA_Session::ReadMsg()
+{
+ return NULL;
+}
+
+/**
+ * Sends a message to the client.
+ */
+void RA_Session::WriteMsg(RA_Msg *msg)
+{
+}
diff --git a/base/tps/src/main/RA_pblock.cpp b/base/tps/src/main/RA_pblock.cpp
new file mode 100644
index 000000000..e59e4c7f1
--- /dev/null
+++ b/base/tps/src/main/RA_pblock.cpp
@@ -0,0 +1,176 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "prmem.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <string.h>
+#include "engine/RA.h"
+#include "main/Buffer.h"
+#include "main/Memory.h"
+#include "main/Util.h"
+#include "main/RA_pblock.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC RA_pblock::RA_pblock( int tm_nargs, Buffer_nv** tm_nvs )
+{
+ m_nargs = tm_nargs;
+
+ if( tm_nvs != NULL ) {
+ for( int i = 0; i < MAX_NVS; i++ ) {
+ m_nvs[i] = tm_nvs[i];
+ }
+ } else {
+ for( int i = 0; i < MAX_NVS; i++ ) {
+ m_nvs[i] = NULL;
+ }
+ }
+}
+
+TPS_PUBLIC RA_pblock::~RA_pblock()
+{
+ free_pblock();
+}
+
+Buffer_nv **RA_pblock::GetNVs()
+{
+ return m_nvs;
+}
+
+// returns url-decoded value
+TPS_PUBLIC Buffer *RA_pblock::find_val( const char * name )
+{
+ for( int i = 0; i < m_nargs; i++ ) {
+ if( i >= MAX_NVS ) {
+ continue;
+ }
+
+ if( ( m_nvs[i] == NULL ) ||
+ ( m_nvs[i]->name == NULL ) ||
+ ( m_nvs[i]->value == NULL ) ) {
+ continue;
+ }
+
+ if( PR_CompareStrings( m_nvs[i]->name, name ) == 1 ) {
+ return m_nvs[i]->value;
+ }
+ }
+
+ return NULL;
+}
+
+TPS_PUBLIC char *RA_pblock::get_name( int i )
+{
+ return m_nvs[i]->name;
+}
+
+TPS_PUBLIC int RA_pblock::get_num_of_names()
+{
+ return m_nargs;
+}
+
+// returns non-urldecoded value
+TPS_PUBLIC char* RA_pblock::find_val_s( const char * name )
+{
+ RA::Debug( LL_PER_PDU, "RA_pblock::find_val_s",
+ "searching for name= %s", name );
+
+ int end = m_nargs;
+
+ if( MAX_NVS < m_nargs ) {
+ RA::Error( "RA_pblock::find_val_s",
+ "MAX_NVS too small, needs increasing... "
+ "m_nargs= %d, MAX_NVS=%d", m_nargs, MAX_NVS );
+ end = MAX_NVS;
+ }
+
+ for( int i = 0; i < end; i++ ) {
+ if( ( m_nvs[i] == NULL ) ||
+ ( m_nvs[i]->name == NULL ) ||
+ ( m_nvs[i]->value_s == NULL ) ) {
+ continue;
+ }
+
+ /* RA::Debug( LL_PER_PDU, "RA_pblock::find_val_s", */
+ /* "found %s", m_nvs[i]->name ); */
+
+ if( PR_CompareStrings( m_nvs[i]->name, name ) == 1 ) {
+ return m_nvs[i]->value_s;
+ }
+ }
+
+ return NULL;
+}
+
+void RA_pblock::free_pblock()
+{
+ RA::Debug( LL_PER_PDU, "RA_pblock::free_pblock", "in free_pblock" );
+
+ int end = m_nargs;
+
+ if( MAX_NVS < m_nargs ) {
+ RA::Error( "RA_pblock::free_pblock",
+ "MAX_NVS too small, needs increasing... "
+ "m_nargs= %d, MAX_NVS=%d", m_nargs, MAX_NVS );
+ end = MAX_NVS;
+ }
+
+ for( int i = 0; i < end ; i++ ) {
+ if( m_nvs[i] == NULL ) {
+ continue;
+ }
+
+ if( m_nvs[i]->value ) {
+ delete( m_nvs[i]->value );
+ m_nvs[i]->value = NULL;
+ }
+
+ if( m_nvs[i]->value_s ) {
+ PL_strfree( m_nvs[i]->value_s );
+ m_nvs[i]->value_s = NULL;
+ }
+
+ if( m_nvs[i]->name != NULL ) {
+ PL_strfree( m_nvs[i]->name );
+ m_nvs[i]->name = NULL;
+ }
+
+ if( m_nvs[i] != NULL ) {
+ PR_Free( m_nvs[i] );
+ m_nvs[i] = NULL;
+ }
+ }
+
+ RA::Debug( LL_PER_PDU, "RA_pblock::free_pblock", "in free_pblock done" );
+}
+
diff --git a/base/tps/src/main/RollingLogFile.cpp b/base/tps/src/main/RollingLogFile.cpp
new file mode 100644
index 000000000..692a94334
--- /dev/null
+++ b/base/tps/src/main/RollingLogFile.cpp
@@ -0,0 +1,493 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "main/ConfigStore.h"
+#include "engine/RA.h"
+#include "main/RA_Context.h"
+#include "main/LogFile.h"
+#include "main/RollingLogFile.h"
+
+const char *RollingLogFile::CFG_MAX_FILE_SIZE= "maxFileSize";
+const char *RollingLogFile::CFG_ROLLOVER_INTERVAL= "rolloverInterval";
+const char *RollingLogFile::CFG_EXPIRATION_INTERVAL= "expirationTime";
+const int RollingLogFile::MAX_SLEEP = 21600; /* 6 hours */
+
+RollingLogFile::RollingLogFile() :
+ m_max_file_size(2000),
+ m_rollover_interval(0),
+ m_expiration_time(0),
+ m_expiration_sleep_time(0),
+ m_rotation_needed(false),
+ m_rollover_thread(NULL),
+ m_expiration_thread(NULL) { }
+
+int RollingLogFile::startup(RA_Context *ctx, const char* prefix, const char *fname, bool signed_audit)
+{
+ char configname[256];
+
+ if (ctx == NULL) {
+ return PR_FAILURE;
+ }
+
+ if (fname == NULL) {
+ ctx->LogError("RollingLogFile::startup",
+ __LINE__,
+ "startup error, fname is NULL");
+ return PR_FAILURE;
+ }
+
+ if (prefix == NULL) {
+ ctx->LogError("RollingLogFile::startup",
+ __LINE__,
+ "startup error for file %s: prefix is NULL",
+ fname);
+ return PR_FAILURE;
+ }
+
+ ConfigStore* store = RA::GetConfigStore();
+
+ if (store == NULL) {
+ ctx->LogError("RollingLogFile::startup",
+ __LINE__,
+ "Error in obtaining config store to set up rolling log for %s",
+ fname);
+ return PR_FAILURE;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s", prefix, CFG_MAX_FILE_SIZE);
+ m_max_file_size = store->GetConfigAsInt(configname, 2000); /* 2 MB */
+
+ PR_snprintf((char *)configname, 256, "%s.%s", prefix, CFG_ROLLOVER_INTERVAL);
+ m_rollover_interval = store->GetConfigAsInt(configname, 2592000); /* 30 days */
+
+ PR_snprintf((char *)configname, 256, "%s.%s", prefix, CFG_EXPIRATION_INTERVAL);
+ m_expiration_time = store->GetConfigAsInt(configname, 0); /* disabled, by default */
+
+ m_rollover_thread = (PRThread *) NULL;
+ m_expiration_thread = (PRThread*) NULL;
+ m_rotation_needed = false;
+
+ LogFile::startup(ctx, prefix, fname, signed_audit);
+
+ m_ctx->LogInfo( "RollingLogFile::startup",
+ __LINE__,
+ "thread = 0x%lx: Rolling log file %s startup complete",
+ PR_GetCurrentThread(), m_fname);
+ return PR_SUCCESS;
+}
+
+void RollingLogFile::shutdown()
+{
+ m_ctx->LogInfo( "RollingLogFile::shutdown",
+ __LINE__,
+ "thread = 0x%lx: Rolling log file %s shutting down",
+ PR_GetCurrentThread(), m_fname);
+
+ // interrupt and join threads
+
+ set_expiration_time(0);
+ if (m_expiration_thread != NULL) {
+ PR_Interrupt(m_expiration_thread);
+ PR_JoinThread(m_expiration_thread);
+ m_expiration_thread = (PRThread*) NULL;
+ }
+
+ set_rollover_interval(0);
+ if (m_rollover_thread != NULL) {
+ PR_Interrupt(m_rollover_thread);
+ PR_JoinThread(m_rollover_thread);
+ m_rollover_thread = (PRThread*) NULL;
+ }
+
+ LogFile::shutdown();
+}
+
+int RollingLogFile::write(char *msg) {
+ int status;
+ PR_EnterMonitor(m_monitor);
+
+ if (m_rotation_needed && m_signed && m_signed_log) {
+ rotate();
+ m_rotation_needed = false;
+ }
+
+ status = LogFile::write(msg);
+ if ((get_bytes_written() >= ((int) m_max_file_size*1024)) && (m_max_file_size >0)) {
+ if (! m_signed_log) {
+ rotate();
+ m_rotation_needed = false;
+ } else {
+ m_rotation_needed = true;
+ }
+ }
+ PR_ExitMonitor(m_monitor);
+ return status;
+}
+
+/* this is always called under a monitor */
+void RollingLogFile::rotate() {
+ PRTime now;
+ const char* time_fmt = "%Y%m%d-%H%M%S";
+ char datetime[1024];
+ char backup_fname[1024];
+ char *first_sig = (char *) NULL;
+ PRExplodedTime time;
+ int status;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ PR_snprintf((char *) backup_fname, 1024, "%s.%s", m_fname, datetime);
+
+ /* close the old file */
+ status = LogFile::close();
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "RollingLogFile::rotate",
+ __LINE__,
+ "Failed to close log file %s",
+ m_fname);
+ goto loser;
+ } else {
+ m_fd = (PRFileDesc *) NULL;
+ }
+
+ status = PR_Rename(m_fname, backup_fname);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "RollingLogFile::rotate",
+ __LINE__,
+ "Failed to rename %s to %s",
+ m_fname, backup_fname);
+
+ status = LogFile::open();
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError("RollingLogFile::rotate",
+ __LINE__,
+ "Failed to reopen log file %s",
+ m_fname);
+ }
+ goto loser;
+ }
+
+ /* open the new file */
+ m_fd = PR_Open(m_fname, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 440|200);
+ set_bytes_written(0);
+ if (m_fd == NULL) {
+ m_ctx->LogError( "RollingLogFile::rotate",
+ __LINE__,
+ "Failed to reopen log file %s",
+ m_fname);
+ } else {
+ if (m_signed_log) {
+ first_sig = RA::GetAuditSigningMessage("");
+ if (first_sig != NULL) {
+ status = LogFile::write(first_sig);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError("RollingLogFile::rotate",
+ __LINE__,
+ "Failed to write signature to new (rotated) log file %s",
+ m_fname);
+ } else {
+ status = LogFile::write("\n");
+ if (RA::m_last_audit_signature != NULL) {
+ PR_Free( RA::m_last_audit_signature );
+ }
+ RA::m_last_audit_signature = PL_strdup(first_sig);
+ m_signed = true;
+ }
+ PR_Free(first_sig);
+ } else {
+ m_ctx->LogError("RollingLogFile::rotate",
+ __LINE__,
+ "Failed to generate signature for new (rotated) log file %s",
+ m_fname);
+ }
+ }
+ }
+
+
+ loser:
+ m_rotation_needed = false;
+}
+
+void RollingLogFile::child_init()
+{
+ set_rollover_interval(m_rollover_interval);
+ set_expiration_time(m_expiration_time);
+}
+
+
+void RollingLogFile::set_rollover_interval(int interval)
+{
+ m_rollover_interval = interval;
+ if ((m_rollover_interval>0) && (m_rollover_thread == NULL)) {
+ m_rollover_thread = PR_CreateThread( PR_USER_THREAD,
+ start_rollover_thread,
+ (void *) this,
+ PR_PRIORITY_NORMAL, /* Priority */
+ PR_LOCAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */);
+
+ } else {
+ if (m_rollover_thread != NULL) PR_Interrupt(m_rollover_thread);
+ }
+}
+
+void RollingLogFile::start_rollover_thread(void *args) {
+ RollingLogFile *rf;
+ if (args != NULL) {
+ rf = (RollingLogFile *) args;
+ rf->run_rollover_thread();
+ }
+}
+
+void RollingLogFile::run_rollover_thread() {
+
+ m_ctx->LogInfo( "RollingLogFile::run_rollover_thread",
+ __LINE__,
+ "thread = 0x%lx: Rollover thread for %s starting",
+ PR_GetCurrentThread(), m_fname);
+
+ while (m_rollover_interval > 0) {
+ PR_Sleep(PR_SecondsToInterval(m_rollover_interval));
+
+ PR_EnterMonitor(m_monitor);
+ if (m_rollover_interval == 0) break;
+ if (get_bytes_written()>0) {
+ if (! m_signed_log) {
+ rotate();
+ } else {
+ m_rotation_needed = true;
+ }
+ }
+ PR_ExitMonitor(m_monitor);
+ }
+
+ m_ctx->LogInfo( "RollingLogFile::run_rollover_thread",
+ __LINE__,
+ "thread = 0x%lx: Rollover thread for %s ending",
+ PR_GetCurrentThread(), m_fname);
+
+ PR_ExitMonitor(m_monitor);
+}
+
+void RollingLogFile::set_expiration_time(int interval)
+{
+ m_expiration_time = interval;
+ m_expiration_sleep_time = interval;
+
+ if ((interval>0) && (m_expiration_thread == NULL)) {
+ m_expiration_thread = PR_CreateThread( PR_USER_THREAD,
+ start_expiration_thread,
+ (void *) this,
+ PR_PRIORITY_NORMAL, /* Priority */
+ PR_GLOBAL_THREAD, /* Scope */
+ PR_JOINABLE_THREAD, /* State */
+ 0 /* Stack Size */);
+
+ } else {
+ if (m_expiration_thread != NULL) PR_Interrupt(m_expiration_thread);
+ }
+}
+
+void RollingLogFile::start_expiration_thread(void *args) {
+ RollingLogFile *rf;
+ if (args != NULL) {
+ rf = (RollingLogFile *) args;
+ rf->run_expiration_thread();
+ }
+}
+
+/* wait for a bit and then call expire().
+ Note that PR_Sleep() requires a small interval
+ (about 6 hrs to prevent overflow) */
+void RollingLogFile::run_expiration_thread() {
+ int interval;
+
+ m_ctx->LogInfo( "RollingLogFile::run_expiration_thread",
+ __LINE__,
+ "thread = 0x%lx: Expiration thread for %s starting",
+ PR_GetCurrentThread(), m_fname);
+
+ while (m_expiration_time > 0) {
+ expire();
+ while (m_expiration_sleep_time > 0) {
+ if (m_expiration_sleep_time > MAX_SLEEP) {
+ interval = MAX_SLEEP;
+ } else {
+ interval = m_expiration_sleep_time;
+ }
+
+ PR_Sleep(PR_SecondsToInterval(interval));
+ m_expiration_sleep_time = m_expiration_sleep_time - interval;
+
+ if (m_expiration_time == 0) break;
+ }
+
+ if (m_expiration_time == 0) break;
+ }
+
+ m_ctx->LogInfo( "RollingLogFile::run_expiration_thread",
+ __LINE__,
+ "thread = 0x%lx: Expiration thread for %s ending",
+ PR_GetCurrentThread(), m_fname);
+}
+
+/* remove log files that have not been modified in specified time */
+void RollingLogFile::expire() {
+ char basename[256];
+ char dirname[256];
+ char searchStr[256];
+ char full_search_name[256];
+ PRDir *dir;
+ PRDirEntry *entry;
+ PRFileInfo info;
+ PRTime expireTime;
+ PRTime now;
+ PRTime earliestModTime;
+ PRInt64 expiration_interval;
+ PRInt64 usec_per_sec;
+ PRInt64 tmp, tmp1;
+ PRStatus status;
+
+ if (m_expiration_time == 0) {
+ return;
+ }
+
+ if (strrchr(m_fname, '/') != NULL) {
+ PR_snprintf((char *) basename, 256, "%s", strrchr(m_fname, '/') +1);
+ PR_snprintf((char *) dirname, PL_strlen(m_fname) - PL_strlen(basename), "%s", m_fname);
+ PL_strcat(dirname, '\0');
+ } else {
+ PR_snprintf((char *) basename, 256, "%s", m_fname);
+ PR_snprintf((char *) dirname, 256, ".");
+ }
+
+ LL_I2L(tmp, m_expiration_time);
+ LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
+ LL_MUL(expiration_interval, tmp, usec_per_sec);
+
+ now = PR_Now();
+ earliestModTime=now;
+ LL_SUB(expireTime, now, expiration_interval);
+
+ dir = PR_OpenDir(dirname);
+
+ if (dir == NULL) {
+ m_ctx->LogError( "RollingLogFile::expire",
+ __LINE__,
+ "Failed to open log file directory %s",
+ dirname);
+ return;
+ }
+
+ PR_snprintf(searchStr, 256, "%s.", basename);
+
+ while ((entry=PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
+ /* look only for entries of form basename. */
+
+ if (PL_strstr(entry->name, searchStr) != NULL) {
+ PR_snprintf(full_search_name, 256, "%s/%s", dirname, entry->name);
+ status = PR_GetFileInfo(full_search_name, &info);
+
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "RollingLogFile::expire",
+ __LINE__,
+ "Failed to get file info for log file %s",
+ full_search_name);
+ // log failure to get file info
+ } else {
+ if (LL_CMP(info.modifyTime,<, expireTime)) {
+ status = PR_Delete(full_search_name);
+ if (status != PR_SUCCESS) {
+ m_ctx->LogError( "RollingLogFile::expire",
+ __LINE__,
+ "Failed to delete expired log file %s",
+ full_search_name);
+ } else {
+ RA::Debug("RollingLogFile::expire", "Deleted expired file: %s",
+ full_search_name);
+ }
+ } else {
+ if (LL_CMP(info.modifyTime,<,earliestModTime)) {
+ earliestModTime = info.modifyTime;
+ }
+ }
+ }
+ }
+ }
+
+ PR_CloseDir(dir);
+
+ /* set next wakeup interval */
+ /* A complicated 64-bit way of calculating :
+ m_expiration_sleep_time = (earliestModTime + m_expiration_time * 1000000 - PR_Now())/1000000;
+ */
+
+ LL_ADD(tmp, earliestModTime, expiration_interval);
+ LL_SUB(tmp1, tmp, now);
+ LL_DIV(tmp, tmp1, usec_per_sec);
+ LL_L2I(m_expiration_sleep_time, tmp);
+
+}
+
+int RollingLogFile::get_rollover_interval() {
+ return m_rollover_interval;
+}
+
+void RollingLogFile::set_rotation_needed(bool val) {
+ m_rotation_needed = val;
+}
+
+bool RollingLogFile::get_rotation_needed() {
+ return m_rotation_needed;
+}
+
+int RollingLogFile::get_expiration_time() {
+ return m_expiration_time;
+}
+
+
diff --git a/base/tps/src/main/SecureId.cpp b/base/tps/src/main/SecureId.cpp
new file mode 100644
index 000000000..46394100e
--- /dev/null
+++ b/base/tps/src/main/SecureId.cpp
@@ -0,0 +1,71 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "main/SecureId.h"
+#include "main/Memory.h"
+
+/**
+ * Creates a Secure ID object.
+ */
+SecureId::SecureId (char *value, char *pin)
+{
+ if (value == NULL) {
+ m_value = NULL;
+ } else {
+ m_value = PL_strdup(value);
+ }
+ if (pin == NULL) {
+ m_pin = NULL;
+ } else {
+ m_pin = PL_strdup(pin);
+ }
+}
+
+/**
+ * Destructs a Secure ID object.
+ */
+SecureId::~SecureId ()
+{
+ if( m_value != NULL ) {
+ PL_strfree( m_value );
+ m_value = NULL;
+ }
+ if( m_pin != NULL ) {
+ PL_strfree( m_pin );
+ m_pin = NULL;
+ }
+}
+
+/**
+ * Retrieves the optional Secure ID value.
+ */
+char *SecureId::GetValue()
+{
+ return m_value;
+}
+
+/**
+ * Retrieves the Secure ID PIN.
+ */
+char *SecureId::GetPIN()
+{
+ return m_pin;
+}
diff --git a/base/tps/src/main/Util.cpp b/base/tps/src/main/Util.cpp
new file mode 100644
index 000000000..2849121e4
--- /dev/null
+++ b/base/tps/src/main/Util.cpp
@@ -0,0 +1,1168 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+#include "prmem.h"
+#include "prio.h"
+#include "pk11func.h"
+#include "main/Util.h"
+#include "main/Buffer.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC Util::Util ()
+{
+}
+
+TPS_PUBLIC Util::~Util ()
+{
+}
+
+/*
+ * Reads a line from file
+ */
+TPS_PUBLIC int Util::ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return)
+{
+ char *cur = buf;
+ int sum = 0;
+ PRInt32 rc;
+
+ *removed_return = 0;
+ while (1) {
+ rc = PR_Read(f, cur, 1);
+ if (rc == -1 || rc == 0)
+ break;
+ if (*cur == '\r') {
+ continue;
+ }
+ if (*cur == '\n') {
+ *cur = '\0';
+ *removed_return = 1;
+ break;
+ }
+ sum++;
+ cur++;
+ }
+ return sum;
+}
+
+TPS_PUBLIC int Util::ascii2numeric (char c)
+{
+ int num;
+ switch (c) {
+ case '0': case '1': case '2':case '3':case '4':case '5':
+ case '6': case '7': case '8': case '9':
+ num = c - '0';
+ break;
+ default:
+ num = -1;
+ break;
+ }
+ return num;
+}
+
+static BYTE ZERO[1] = { 0 };
+static BYTE ONE[1] = { 1 };
+
+TPS_PUBLIC BYTE* Util::bool2byte(bool b) {
+ if (b)
+ return ONE;
+ else
+ return ZERO;
+}
+
+static int isAlphaNumeric (char ch)
+{
+ return (((ch >='a') && (ch <= 'z')) || /* logical AND &&, OR || */
+ ((ch >='A') && (ch <= 'Z')) ||
+ ((ch >='0') && (ch <= '9')) );
+}
+
+static char bin2hex (BYTE ch)
+{
+ ch = ch & 0x0f;
+ ch += '0';
+ if (ch > '9')
+ ch += 7;
+ return (ch);
+}
+
+static BYTE hex2bin (BYTE ch)
+{
+ if (ch > '9')
+ ch = ch - 'A' + 10;
+ else
+ ch = ch - '0';
+ return (ch);
+}
+
+
+TPS_PUBLIC char *Util::SpecialURLEncode(Buffer &data) {
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ char *ret = NULL;
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ sum+=1;
+ } else if (isAlphaNumeric(buf[i])) {
+ sum+=1;
+ } else {
+ sum+=3;
+ }
+ }
+ ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ if (ret == NULL)
+ return NULL;
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ *cur++ = '+';
+ } else if (isAlphaNumeric(buf[i])) {
+ *cur++ = buf[i];
+ } else {
+ *cur++ = '#';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char *Util::URLEncode (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ sum+=1;
+ } else if (isAlphaNumeric(buf[i])) {
+ sum+=1;
+ } else {
+ sum+=3;
+ }
+ }
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ *cur++ = '+';
+ } else if (isAlphaNumeric(buf[i])) {
+ *cur++ = buf[i];
+ } else {
+ *cur++ = '%';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char *Util::URLEncodeInHex (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ sum+=3;
+ }
+
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ *cur++ = '%';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char * Util::URLEncode1(const char *str)
+{
+ int sum = 0;
+ if (str == NULL)
+ return NULL;
+
+ // URL-encode the base-64 encoded public key. This code copies
+ // From input buffer str[] to output buffer encoded_str[]
+ int i = 0;
+ int j = 0;
+ char c;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ sum+=3;
+ } else if (c == '=') {
+ sum+=3;
+ } else if (c == '\r') {
+ sum+=3;
+ } else if (c == '\n') {
+ sum+=3;
+ } else if (c == '+') {
+ sum+=3;
+ } else if (c == '&') {
+ sum+=3;
+ } else if (c == ' ') {
+ sum+=1;
+ } else {
+ sum+=1;
+ }
+ if (c == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+
+ char *encoded_str = (char *)PR_Malloc(sum); //allocate more than we may need
+
+ if (encoded_str == NULL)
+ return NULL;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'F';
+ } else if (c == '&') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = '6';
+ } else if (c == '=') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '3';
+ encoded_str[i] = 'D';
+ } else if (c == '\r') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'D';
+ } else if (c == '\n') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'A';
+ } else if (c == '+') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'B';
+ } else if (c == ' ') {
+ encoded_str[i] = '+';
+ } else {
+ encoded_str[i] = str[j];
+ }
+ if (encoded_str[i] == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+ encoded_str[i] = '\0';
+
+ // DONT print, some of the sensitive information get printed.
+ /*
+ RA::Debug(LL_PER_PDU, "CertEnroll::urlEncode",
+ "URL-encoded encoded_str =%s",encoded_str);
+ */
+
+ return encoded_str;
+}
+/**
+ * this urlEncode function takes a char string
+ */
+TPS_PUBLIC char * Util::URLEncode(const char *str)
+{
+ int sum = 0;
+ if (str == NULL)
+ return NULL;
+
+ // URL-encode the base-64 encoded public key. This code copies
+ // From input buffer str[] to output buffer encoded_str[]
+ int i = 0;
+ int j = 0;
+ char c;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ sum+=3;
+ } else if (c == '=') {
+ sum+=3;
+ } else if (c == '\r') {
+ sum+=3;
+ } else if (c == '\n') {
+ sum+=3;
+ } else if (c == '+') {
+ sum+=3;
+ } else if (c == ' ') {
+ sum+=1;
+ } else {
+ sum+=1;
+ }
+ if (c == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+
+ char *encoded_str = (char *)PR_Malloc(sum); //allocate more than we may need
+
+ if (encoded_str == NULL)
+ return NULL;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'F';
+ } else if (c == '=') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '3';
+ encoded_str[i] = 'D';
+ } else if (c == '\r') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'D';
+ } else if (c == '\n') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'A';
+ } else if (c == '+') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'B';
+ } else if (c == ' ') {
+ encoded_str[i] = '+';
+ } else {
+ encoded_str[i] = str[j];
+ }
+ if (encoded_str[i] == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+ encoded_str[i] = '\0';
+
+ // DONT print, some of the sensitive information get printed.
+ /*
+ RA::Debug(LL_PER_PDU, "CertEnroll::urlEncode",
+ "URL-encoded encoded_str =%s",encoded_str);
+ */
+
+ return encoded_str;
+}
+
+/* s Format: 01AFEE */
+TPS_PUBLIC Buffer *Util::Str2Buf (const char *s)
+{
+ int len = strlen(s) / 2;
+ BYTE *ret = (BYTE *)PR_Malloc(len);
+ if (ret == NULL)
+ return NULL;
+
+ for (int i = 0; i < len; i ++) {
+ ret[i] = hex2bin(s[i*2]) * 16 + hex2bin(s[i*2+1]);
+ }
+
+ Buffer *newbuf = new Buffer(ret, len);
+ if( ret != NULL ) {
+ PR_Free( ret );
+ ret = NULL;
+ }
+ return newbuf;
+}
+
+TPS_PUBLIC char *Util::Buffer2String (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ sum+=2;
+ }
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ if (ret == NULL)
+ return NULL;
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC Buffer *Util::SpecialURLDecode(const char *data)
+{
+ int i;
+ Buffer buf;
+ Buffer *ret = NULL;
+ int len = strlen(data);
+ BYTE *tmp = NULL;
+ int sum = 0;
+
+ if (len == 0)
+ return NULL;
+ tmp = (BYTE *)malloc(len);
+ if (tmp == NULL)
+ return NULL;
+ for (i = 0; i < len; i++) {
+ if (data[i] == '+') {
+ tmp[sum++] = ' ';
+ } else if (data[i] == '#') {
+ tmp[sum++] = (hex2bin(data[i+1]) << 4) + hex2bin(data[i+2]);
+ i+=2;
+ } else {
+ tmp[sum++] = (BYTE)data[i];
+ }
+ }
+
+ ret = new Buffer(tmp, sum);
+ if( tmp != NULL ) {
+ free( tmp );
+ tmp = NULL;
+ }
+ return ret;
+}
+
+TPS_PUBLIC Buffer *Util::URLDecode(const char *data)
+{
+ int i;
+ Buffer buf;
+ Buffer *ret = NULL;
+ int len = strlen(data);
+ BYTE *tmp = NULL;
+ int sum = 0;
+
+ if (len == 0)
+ return NULL;
+ tmp = (BYTE *)PR_Malloc(len);
+ for (i = 0; i < len; i++) {
+ if (data[i] == '+') {
+ tmp[sum++] = ' ';
+ } else if (data[i] == '%') {
+ tmp[sum++] = (hex2bin(data[i+1]) << 4) + hex2bin(data[i+2]);
+ i+=2;
+ } else {
+ tmp[sum++] = (BYTE)data[i];
+ }
+ }
+
+ ret = new Buffer(tmp, sum);
+ if( tmp != NULL ) {
+ PR_Free( tmp );
+ tmp = NULL;
+ }
+ return ret;
+}
+
+
+TPS_PUBLIC PRStatus Util::GetRandomChallenge(Buffer &random)
+{
+ PRStatus rv = PR_FAILURE;
+ SECStatus status;
+
+ status = PK11_GenerateRandom(random, random.size());
+ if (status != SECSuccess) {
+ goto loser;
+ }
+ rv = PR_SUCCESS;
+loser:
+ return rv;
+} /* GetRandomChallenge */
+
+#define DES2_WORKAROUND
+
+TPS_PUBLIC PK11SymKey *Util::DiversifyKey(PK11SymKey *masterKey, Buffer &data, PK11SlotInfo *slot)
+{
+ PK11SymKey *key = NULL;
+ PRStatus status = PR_FAILURE ;
+ PK11Context *context = NULL;
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ SECItem keyItem = { siBuffer, keyData, sizeof keyData };
+ SECStatus s;
+ int i;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+
+ /* XXX
+ - masterKey could be just a double-length
+ DES Key (16 bytes).
+ - we may need to add the first 8 bytes to
+ the end to make the key 24 bytes long (DES3 Key)
+ */
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT,
+ masterKey,
+ &noParams);
+ if (!context) goto done;
+
+ /* Part 1 */
+ s = PK11_CipherOp(context, &keyData[0], &len, 8, &((BYTE*)data)[0], 8);
+ if (s != SECSuccess) goto done;
+
+ /* Part 2 */
+ s = PK11_CipherOp(context, &keyData[8], &len, 8, &((BYTE*)data)[8], 8);
+ if (s != SECSuccess) goto done;
+
+#ifdef DES2_WORKAROUND
+ /* Part 3 */
+ for(i = 0;i < 8;i++)
+ {
+ keyData[i+16] = keyData[i];
+ }
+#endif
+
+ key = PK11_ImportSymKeyWithFlags(
+ slot,
+ CKM_DES3_ECB,
+ PK11_OriginGenerated,
+ CKA_ENCRYPT,
+ &keyItem, CKF_SIGN | CKF_ENCRYPT, PR_FALSE, 0);
+
+ status = PR_SUCCESS;
+
+done:
+
+ return key;
+}
+
+TPS_PUBLIC PRStatus Util::ComputeKeyCheck(const Buffer& newKey, Buffer& output)
+{
+ PK11SymKey *key = NULL;
+ PRStatus status = PR_FAILURE ;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ SECItem keyItem = {siBuffer, keyData, sizeof(keyData) };
+ unsigned char value[8];
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(keyData, newKey, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(keyData+16, newKey, 8);
+#endif
+
+ memset(value, 0, sizeof value);
+
+ key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &keyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! key ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+ s = PK11_CipherOp(context, &value[0], &len, 8, &value[0], 8);
+ if (s != SECSuccess) {
+ goto done;
+ }
+
+ output.resize(3);
+ output.replace(0, value, 3);
+
+ status = PR_SUCCESS;
+done:
+ memset(keyData, 0, sizeof keyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( key != NULL ) {
+ PK11_FreeSymKey( key );
+ key = NULL;
+ }
+
+ return status;
+}
+
+TPS_PUBLIC PRStatus Util::ComputeCryptogram(PK11SymKey *key,
+ const Buffer &card_challenge, const Buffer &host_challenge,
+ Buffer &output)
+{
+ Buffer icv(8, (BYTE)0);
+ Buffer input = card_challenge + host_challenge;
+
+ return ComputeMAC(key, input, icv, output);
+} /* ComputeCryptogram */
+
+
+TPS_PUBLIC PRStatus Util::ComputeMAC(PK11SymKey *key, Buffer &x_input,
+ const Buffer &icv, Buffer &output)
+{
+ PRStatus rv = PR_SUCCESS;
+ PK11Context *context = NULL;
+// NetkeyICV temp;
+ unsigned char result[8];
+ int i;
+ SECStatus s;
+ int len;
+#ifdef USE_DESMAC
+ CK_ULONG macLen = sizeof result;
+ SECItem params = { siBuffer, (unsigned char *)&macLen, sizeof macLen };
+#endif
+ static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char macPad[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ BYTE *input = (BYTE *) x_input;
+ int inputLen = x_input.size();
+
+#ifdef USE_DESMAC
+ context = PK11_CreateContextBySymKey(CKM_DES3_MAC_GENERAL, CKA_SIGN,
+ key, &params);
+ if (!context) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestBegin(context);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestOp(context, icv, 8);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ while(inputLen >= 8)
+ {
+ s = PK11_DigestOp(context, input, 8);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ input += 8;
+ inputLen -= 8;
+ }
+
+ for (i = 0;i < inputLen;i++)
+ {
+ result[i] = input[i];
+ }
+
+ input = macPad;
+ for(;i < 8;i++)
+ {
+ result[i] = *input++;
+ }
+
+ s = PK11_DigestOp(context, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestFinal(context, output, (unsigned int *)&len, sizeof output);
+ if (1 != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+#else
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key, &noParams);
+ if (!context) { rv = PR_FAILURE; goto done; }
+
+ memcpy(result, icv, sizeof result);
+
+ /* Process whole blocks */
+ while(inputLen >= 8)
+ {
+ for(i = 0;i < 8;i++)
+ {
+ result[i] ^= input[i];
+ }
+
+ s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+ if (len != sizeof result) /* assert? */
+ {
+ //PR_SetError(PR_UNKNOWN_ERROR, 0);
+ rv = PR_FAILURE;
+ goto done;
+ }
+
+ input += 8;
+ inputLen -= 8;
+ }
+
+ /*
+ * Fold in remaining data (if any)
+ * Set i to number of bytes processed
+ */
+ for(i = 0;i < inputLen;i++)
+ {
+ result[i] ^= input[i];
+ }
+
+ /*
+ * Fill remainder of last block. There
+ * will be at least one byte handled here.
+ */
+ input = macPad;
+ while(i < 8)
+ {
+ result[i] ^= *input++;
+ i++;
+ }
+
+ s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+ if (len != sizeof result)
+ {
+ //PR_SetError(PR_UNKNOWN_ERROR, 0);
+ rv = PR_FAILURE;
+ goto done;
+ }
+
+ output.replace(0, result, sizeof result);
+#endif
+
+done:
+ if( context != NULL )
+ {
+ PK11_Finalize( context );
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ memset(result, 0, sizeof result);
+
+ return rv;
+} /* ComputeMAC */
+
+TPS_PUBLIC PK11SymKey *Util::DeriveKey(const Buffer& permKey,
+ const Buffer& hostChallenge,
+ const Buffer& cardChallenge)
+{
+ PK11SymKey *key = NULL, *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ unsigned char derivationData[16];
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ int i;
+ SECStatus s;
+ int len;
+ SECItem keyItem = { siBuffer, keyData, sizeof keyData };
+ static SECItem noParams = { siBuffer, 0, 0 };
+ BYTE masterKeyData[24];
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, permKey, 16);
+ memcpy(masterKeyData+16, permKey, 8);
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! master ) goto done;
+
+ for(i = 0;i < 4;i++)
+ {
+ derivationData[i] = cardChallenge[i+4];
+ derivationData[i+4] = hostChallenge[i];
+ derivationData[i+8] = cardChallenge[i];
+ derivationData[i+12] = hostChallenge[i+4];
+ }
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
+ if (!context) goto done;
+
+ /* Part 1 */
+ s = PK11_CipherOp(context, &keyData[0], &len, 8, &derivationData[0], 8);
+ if (s != SECSuccess) goto done;
+
+ /* Part 2 */
+ s = PK11_CipherOp(context, &keyData[8], &len, 8, &derivationData[8], 8);
+ if (s != SECSuccess) goto done;
+
+#ifdef DES2_WORKAROUND
+ /* Part 3 */
+ for(i = 0;i < 8;i++)
+ {
+ keyData[i+16] = keyData[i];
+ }
+#endif
+
+ key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB, PK11_OriginGenerated,
+ CKA_ENCRYPT, &keyItem, CKF_SIGN | CKF_ENCRYPT, PR_FALSE, 0);
+
+done:
+ memset(keyData, 0, sizeof keyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return key;
+}
+
+/**
+ *
+ * 01
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (AUTH KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (MAC KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (KEK KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ *
+ */
+TPS_PUBLIC PRStatus Util::CreateKeySetData(Buffer &newMasterVer, Buffer &old_kek_key, Buffer &new_auth_key, Buffer &new_mac_key, Buffer &new_kek_key, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ Buffer result;
+
+ Buffer encrypted_auth_key(16);
+ Util::EncryptData(old_kek_key, new_auth_key, encrypted_auth_key);
+ Buffer kc_auth_key(3);
+ Util::ComputeKeyCheck(new_auth_key, kc_auth_key);
+ Buffer encrypted_mac_key(16);
+ Util::EncryptData(old_kek_key, new_mac_key, encrypted_mac_key);
+ Buffer kc_mac_key(3);
+ Util::ComputeKeyCheck(new_mac_key, kc_mac_key);
+ Buffer encrypted_kek_key(16);
+ Util::EncryptData(old_kek_key, new_auth_key, encrypted_kek_key);
+ Buffer kc_kek_key(3);
+ Util::ComputeKeyCheck(new_kek_key, kc_kek_key);
+
+ result = newMasterVer +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_auth_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_auth_key +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_mac_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_mac_key +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_kek_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_kek_key;
+
+ output = result;
+
+ rv = PR_SUCCESS;
+ return rv;
+}
+
+
+/*
+ * for Secure Messaging in Secure Channel
+ */
+TPS_PUBLIC PRStatus Util::EncryptData(PK11SymKey *encSessionKey,
+ Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+ SECStatus s = SECFailure;
+ //static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char d[8] = { 0,0,0,0,0,0,0,0 };
+ static SECItem ivParams = { siBuffer, d, 8 };
+ PK11Context *context = NULL;
+ unsigned char result[8];
+ int len;
+ int i;
+
+ /* this is ECB mode
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, encSessionKey,
+ &noParams);
+ */
+ // use CBC mode
+ context = PK11_CreateContextBySymKey(CKM_DES3_CBC, CKA_ENCRYPT, encSessionKey,
+ &ivParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE*)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+// RA::Debug("Util::EncryptData", "success");
+done:
+
+ //#define VRFY_ENC_SESSION_KEY
+ // fix this to use CBC mode later
+#ifdef VRFY_ENC_SESSION_KEY
+ Buffer enc_key_buffer = Buffer((BYTE *) PK11_GetKeyData(encSessionKey)->data, PK11_GetKeyData(encSessionKey)->len);
+ RA::DebugBuffer("Util::EncryptData", "Verifying Encrypted Data",
+ &output);
+ Buffer out1 = Buffer(16, (BYTE)0);
+ PRStatus status = Util::DecryptData(enc_key_buffer, output, out1);
+ RA::DebugBuffer("Util::EncryptData", "Decrypted Data",
+ &out1);
+#endif
+
+
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+
+ return rv;
+}
+
+
+TPS_PUBLIC PRStatus Util::EncryptData(Buffer &kek_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11SymKey *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char masterKeyData[24];
+#else
+ unsigned char masterKeyData[16];
+#endif
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+ unsigned char result[8];
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, (BYTE*)kek_key, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(masterKeyData+16, (BYTE*)kek_key, 8);
+#endif
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! master ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE*)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ memset(masterKeyData, 0, sizeof masterKeyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return rv;
+}
+
+TPS_PUBLIC PRStatus Util::DecryptData(Buffer &kek_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11SymKey *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char masterKeyData[24];
+#else
+ unsigned char masterKeyData[16];
+#endif
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+ unsigned char result[8];
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, (BYTE*)kek_key, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(masterKeyData+16, (BYTE*)kek_key, 8);
+#endif
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_DECRYPT, &masterKeyItem,
+ CKF_DECRYPT, PR_FALSE, 0);
+ if( ! master ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_DECRYPT, master,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE *)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ memset(masterKeyData, 0, sizeof masterKeyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return rv;
+}
+
+// this one takes PK11SymKey instead
+TPS_PUBLIC PRStatus Util::DecryptData(PK11SymKey* enc_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ // static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char d[8] = { 0,0,0,0,0,0,0,0 };
+ static SECItem ivParams = { siBuffer, d, 8 };
+ unsigned char result[8];
+
+ if( ! enc_key ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_CBC, CKA_DECRYPT, enc_key,
+ &ivParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE *)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+
+ return rv;
+}
+
diff --git a/base/tps/src/modules/CMakeLists.txt b/base/tps/src/modules/CMakeLists.txt
new file mode 100644
index 000000000..b72b73c0c
--- /dev/null
+++ b/base/tps/src/modules/CMakeLists.txt
@@ -0,0 +1,2 @@
+add_subdirectory(tokendb)
+add_subdirectory(tps)
diff --git a/base/tps/src/modules/tokendb/CMakeLists.txt b/base/tps/src/modules/tokendb/CMakeLists.txt
new file mode 100644
index 000000000..7b6edae91
--- /dev/null
+++ b/base/tps/src/modules/tokendb/CMakeLists.txt
@@ -0,0 +1,48 @@
+project(tokendb_module CXX)
+
+set(TOKENDB_PRIVATE_INCLUDE_DIRS
+ ${TOKENDB_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${APR_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(TOKENDB_MODULE
+ tokendb_module
+ CACHE INTERNAL "tokendb apache module"
+)
+
+set(TOKENDB_LINK_LIBRARIES
+ ${TOKENDB_SHARED_LIBRARY}
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${APR_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+)
+
+set(tokendb_module_SRCS
+ mod_tokendb.cpp
+)
+
+include_directories(${TOKENDB_PRIVATE_INCLUDE_DIRS})
+
+add_library(${TOKENDB_MODULE} MODULE ${tokendb_module_SRCS})
+target_link_libraries(${TOKENDB_MODULE} ${TOKENDB_LINK_LIBRARIES})
+
+set_target_properties(${TOKENDB_MODULE}
+ PROPERTIES
+ OUTPUT_NAME
+ mod_tokendb
+ PREFIX ""
+)
+
+install(
+ TARGETS
+ ${TOKENDB_MODULE}
+ DESTINATION
+ ${LIB_INSTALL_DIR}/httpd/modules
+)
diff --git a/base/tps/src/modules/tokendb/mod_tokendb.cpp b/base/tps/src/modules/tokendb/mod_tokendb.cpp
new file mode 100644
index 000000000..3e411c99a
--- /dev/null
+++ b/base/tps/src/modules/tokendb/mod_tokendb.cpp
@@ -0,0 +1,7756 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Headers
+** _________________________________________________________________
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef XP_WIN32
+#include <unistd.h> /* sleep */
+#else /* XP_WIN32 */
+#include <windows.h>
+#endif /* XP_WIN32 */
+
+#include "nspr.h"
+#include "prio.h"
+#include "plstr.h"
+#include "prmem.h"
+#include "prtime.h"
+#include "prthread.h"
+#include "cert.h"
+#include "regex.h"
+#include "nss3/base64.h"
+
+#include "httpd/httpd.h"
+#include "httpd/http_config.h"
+#include "httpd/http_log.h"
+#include "httpd/http_protocol.h"
+#include "httpd/http_main.h"
+#include "httpd/http_request.h"
+
+#include "apr_strings.h"
+
+#include "cms/CertEnroll.h"
+#include "engine/RA.h"
+#include "tus/tus_db.h"
+#include "processor/RA_Processor.h"
+#include "selftests/SelfTest.h"
+
+extern TOKENDB_PUBLIC char *nss_var_lookup( apr_pool_t *p, server_rec *s,
+ conn_rec *c, request_rec *r,
+ char *var );
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Definitions
+** _________________________________________________________________
+*/
+
+#define JS_START "<SCRIPT LANGUAGE=\"JavaScript\">\n<!--\n"
+#define JS_STOP "//-->\n</SCRIPT>\n"
+#define CMS_TEMPLATE_TAG "<CMS_TEMPLATE>"
+
+#define MAX_INJECTION_SIZE 5120
+#define MAX_OVERLOAD 20
+#define LOW_INJECTION_SIZE 2048
+#define SHORT_LEN 256
+
+#define BASE64_HEADER "-----BEGIN CERTIFICATE-----\n"
+#define BASE64_FOOTER "-----END CERTIFICATE-----\n"
+
+#define TOKENDB_OPERATORS_IDENTIFIER "TUS Operators"
+#define TOKENDB_AGENTS_IDENTIFIER "TUS Agents"
+#define TOKENDB_ADMINISTRATORS_IDENTIFIER "TUS Administrators"
+
+#define OP_PREFIX "op.format"
+
+#define NUM_PROFILES_TO_DISPLAY 15
+#define NUM_ENTRIES_PER_PAGE 25
+#define MAX_LEN_PROFILES_TO_DISPLAY 1000
+
+#define error_out(msg1,msg2) \
+ PR_snprintf(injection, MAX_INJECTION_SIZE, \
+ "%s%s%s%s%s", JS_START, "var error = \"Error: ", \
+ msg1,"\";\n", JS_STOP ); \
+ buf = getData( errorTemplate, injection ); \
+ ap_log_error( ( const char * ) "tus", __LINE__, \
+ APLOG_ERR, 0, rq->server, \
+ ( const char * ) msg2 ); \
+ ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq );
+
+#define ldap_error_out(msg1,msg2) \
+ PR_snprintf( injection, MAX_INJECTION_SIZE, \
+ "%s%s%s%s%s%s", JS_START, \
+ "var error = \"", msg1, \
+ ldap_err2string( status ), \
+ "\";\n", JS_STOP ); \
+ buf = getData( errorTemplate, injection ); \
+ ap_log_error( ( const char * ) "tus", __LINE__, \
+ APLOG_ERR, 0, rq->server, \
+ ( const char * ) msg2, \
+ ldap_err2string( status ) ); \
+ ( void ) ap_rwrite( ( const void * ) buf, PL_strlen( buf ), rq );
+
+#define post_ldap_error(msg) \
+ ap_log_error( ( const char * ) "tus", __LINE__, \
+ APLOG_ERR, 0, rq->server, \
+ (const char *) msg, ldap_err2string( status ) );
+
+#define get_cfg_string(cname, vname) \
+ if( ( s = PL_strstr( buf, cname ) ) != NULL ) { \
+ s += PL_strlen( cname ); \
+ v = s; \
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && \
+ ( PRUint32 ) ( s - buf ) < size ) { \
+ s++; \
+ } \
+ n = s - v; \
+ s = PL_strndup( v, n ); \
+ if( s != NULL ) { \
+ if( vname != NULL ) { \
+ PL_strfree( vname ); \
+ vname = NULL; \
+ } \
+ vname = s; \
+ } else { \
+ do_free(buf); \
+ return 0; \
+ } \
+ }
+
+#define get_cfg_int(cname, vname) \
+ if( ( s = PL_strstr( buf, cname ) ) != NULL ) { \
+ s += PL_strlen( cname ); \
+ v = s; \
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' && \
+ ( PRUint32 ) ( s - buf ) < size ) { \
+ s++; \
+ } \
+ n = s - v; \
+ s = PL_strndup( v, n ); \
+ if( s != NULL ) { \
+ char *endptr = NULL; \
+ errno = 0; \
+ vname = strtol(s, &endptr, 10);\
+ if ((errno == ERANGE && (vname == LONG_MAX || vname == LONG_MIN)) \
+ || (endptr == s)) { \
+ vname=0; \
+ } \
+ do_free(s); \
+ } else { \
+ do_free(buf); \
+ do_free(s); \
+ return 0; \
+ } \
+ }
+
+/**
+ * Provide reasonable defaults for some defines.
+ */
+enum MOD_TOKENDB_BOOL {
+ MOD_TOKENDB_FALSE = 0,
+ MOD_TOKENDB_TRUE = 1
+};
+
+#define MAX_TOKEN_UI_STATE 6
+
+enum token_ui_states {
+ TOKEN_UNINITIALIZED = 0,
+ TOKEN_DAMAGED =1,
+ TOKEN_PERM_LOST=2,
+ TOKEN_TEMP_LOST=3,
+ TOKEN_FOUND =4,
+ TOKEN_TEMP_LOST_PERM_LOST =5,
+ TOKEN_TERMINATED = 6
+};
+
+/* _________________________________________________________________
+**
+** Tokendb Module Request Data
+** _________________________________________________________________
+*/
+
+#ifdef DEBUG_Tokendb
+static PRFileDesc *debug_fd = NULL;
+#endif
+
+static char *templateDir = NULL;
+static char *errorTemplate = NULL;
+static char *indexTemplate = NULL;
+static char *indexAdminTemplate = NULL;
+static char *indexOperatorTemplate = NULL;
+static char *newTemplate = NULL;
+static char *searchTemplate = NULL;
+static char *searchResultTemplate = NULL;
+static char *searchAdminTemplate = NULL;
+static char *searchAdminResultTemplate = NULL;
+static char *searchActivityTemplate = NULL;
+static char *searchCertificateTemplate = NULL;
+static char *searchCertificateResultTemplate = NULL;
+static char *searchActivityResultTemplate = NULL;
+static char *searchActivityAdminTemplate = NULL;
+static char *searchActivityAdminResultTemplate = NULL;
+static char *editTemplate = NULL;
+static char *editResultTemplate = NULL;
+static char *showTemplate = NULL;
+static char *showCertTemplate = NULL;
+static char *showAdminTemplate = NULL;
+static char *deleteTemplate = NULL;
+static char *doTokenTemplate = NULL;
+static char *doTokenConfirmTemplate = NULL;
+static char *revokeTemplate = NULL;
+static char *addResultTemplate = NULL;
+static char *deleteResultTemplate = NULL;
+static char *editUserTemplate = NULL;
+static char *searchUserResultTemplate = NULL;
+static char *searchUserTemplate = NULL;
+static char *newUserTemplate = NULL;
+static char *userDeleteTemplate = NULL;
+static char *auditAdminTemplate = NULL;
+static char *selfTestTemplate = NULL;
+static char *selfTestResultsTemplate = NULL;
+static char *agentSelectConfigTemplate = NULL;
+static char *selectConfigTemplate = NULL;
+static char *agentViewConfigTemplate = NULL;
+static char *editConfigTemplate = NULL;
+static char *confirmConfigChangesTemplate = NULL;
+static char *addConfigTemplate = NULL;
+static char *confirmDeleteConfigTemplate = NULL;
+static int maxSizeLimit = 0;
+static int defaultSizeLimit = 0;
+static int maxTimeLimit = 0;
+static int defaultTimeLimit = 0;
+static int pwLength = 0;
+
+static char *profileList = NULL;
+static char *transitionList = NULL;
+
+static int sendInPieces = 0;
+static RA_Processor m_processor;
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Command Data
+** _________________________________________________________________
+*/
+
+static const char MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER[] =
+"TokendbConfigPathFile";
+
+static const char MOD_TOKENDB_CONFIGURATION_FILE_USAGE[] =
+"Tokendb Configuration Filename prefixed by a complete path, or\n"
+"a path that is relative to the Apache server root.";
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Server Configuration Creation Data
+** _________________________________________________________________
+*/
+
+typedef struct {
+ char *Tokendb_Configuration_File;
+ MOD_TOKENDB_BOOL enabled;
+} mod_tokendb_server_configuration;
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Registration Data
+** _________________________________________________________________
+*/
+
+#define MOD_TOKENDB_CONFIG_KEY tokendb_module
+
+static const char MOD_TOKENDB_CONFIG_KEY_NAME[] = "tokendb_module";
+
+extern module TOKENDB_PUBLIC MOD_TOKENDB_CONFIG_KEY;
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Helper Functions
+** _________________________________________________________________
+*/
+
+/**
+ * Terminate Apache
+ */
+void tokendb_die( void )
+{
+ /*
+ * This is used for fatal errors and here
+ * it is common module practice to really
+ * exit from the complete program.
+ */
+ exit( 1 );
+}
+
+
+void tokendbDebug( const char* msg )
+{
+ RA::Debug( "mod_tokendb::mod_tokendb_handler",
+ msg);
+#if 0
+ if( debug_fd ) {
+ PR_fprintf( debug_fd, msg );
+ }
+#endif
+}
+
+inline void do_free(char * buf)
+{
+ if (buf != NULL) {
+ PR_Free(buf);
+ buf = NULL;
+ }
+}
+
+inline void do_strfree(char *buf)
+{
+ if (buf != NULL) {
+ PL_strfree(buf);
+ buf = NULL;
+ }
+}
+
+inline bool valid_berval(struct berval** b)
+{
+ return (b != NULL) && (b[0] != NULL) && (b[0]->bv_val != NULL);
+}
+
+/**
+ * unencode
+ * summary: takes a URL encoded string and returns an unencoded string
+ * : must be freed by caller
+ */
+char *unencode(const char *src)
+{
+ char *dest = NULL;
+ char *dp = NULL;
+ dest = (char *) PR_Malloc(PL_strlen(src)* sizeof(char) + 1);
+ dp = dest;
+ for(; PL_strlen(src) > 0 ; src++, dp++)
+ if(*src == '+')
+ *dp = ' ';
+ else if(*src == '%') {
+ int code;
+ if (sscanf(src+1, "%2x", &code) != 1) code = '?';
+ *dp = code;
+ src +=2;
+ }
+ else
+ *dp = *src;
+ *dp = '\0';
+ return dest;
+}
+
+/**
+ * get_field
+ * summary: used to parse query strings in get and post requests
+ * : returns the value of the parameter following fname, in query string s.
+ * must be freed by caller.
+ * example: get_field("op=hello&name=foo&title=bar", "name=") returns foo
+ */
+char *get_field( char *s, const char* fname, int len)
+{
+ char *end = NULL;
+ char *tmp = NULL;
+ char *ret = NULL;
+ int n;
+
+ if( ( s = PL_strstr( s, fname ) ) == NULL ) {
+ return NULL;
+ }
+
+ s += strlen(fname);
+ end = PL_strchr( s, '&' );
+
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if (n == 0) {
+ return NULL;
+ } else if (n > len) {
+ /* string too long */
+ return NULL;
+ } else {
+ tmp = (char *) PL_strndup(s,n);
+ ret = unencode(tmp);
+ do_free(tmp);
+ return ret;
+ }
+}
+
+/**
+ * get_post_field
+ * summary: get value from apr_table containing HTTP-Post values
+ * params: post - apr_table with post data
+ * : fname = name of post-field
+ */
+char *get_post_field( apr_table_t *post, const char *fname, int len)
+{
+ char *ret = NULL;
+ if (post) {
+ ret = unencode(apr_table_get(post, fname));
+ if ((ret != NULL) && ((int) PL_strlen(ret) > len)) {
+ PR_Free(ret);
+ return NULL;
+ } else {
+ return ret;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+char *get_post_field_s( apr_table_t *post, const char *fname)
+{
+ char *ret = NULL;
+ if (post) {
+ ret = unencode(apr_table_get(post, fname));
+ return ret;
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * similar to get_post_field - but returns the original post data
+ * without unencoding - used for userCert
+ */
+char *get_encoded_post_field(apr_table_t *post, const char *fname, int len)
+{
+ char *ret = NULL;
+ if (post) {
+ ret = PL_strdup(apr_table_get(post, fname));
+ if ((ret != NULL) && ((int) PL_strlen(ret) > len)) {
+ PL_strfree(ret);
+ return NULL;
+ } else {
+ return ret;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ * match_profile
+ * summary: returns true if the profile passed in matches an existing profile
+ * in the profileList read from CS.cfg. Called when confirming that
+ * a user entered "other profile" is a real profile
+ */
+bool match_profile(const char *profile)
+{
+ return RA::match_comma_list(profile, profileList);
+}
+
+int get_token_ui_state(char *state, char *reason)
+{
+ int ret = 0;
+ if (strcmp(state, STATE_UNINITIALIZED) == 0) {
+ ret = TOKEN_UNINITIALIZED;
+ } else if (strcasecmp(state, STATE_ACTIVE) == 0) {
+ ret = TOKEN_FOUND;
+ } else if (strcasecmp(state, STATE_LOST) == 0) {
+ if (strcasecmp(reason, "keyCompromise") == 0) {
+ /* perm lost or temp -> perm lost */
+ ret = TOKEN_PERM_LOST;
+ } else if (strcasecmp(reason, "destroyed") == 0) {
+ ret = TOKEN_DAMAGED;
+ } else if (strcasecmp(reason, "onHold") == 0) {
+ ret = TOKEN_TEMP_LOST;
+ }
+ } else if (strcasecmp(state, "terminated") == 0) {
+ ret = TOKEN_TERMINATED;
+ } else {
+ /* state is disabled or otherwise : what to do here? */
+ ret = TOKEN_PERM_LOST;
+ }
+ return ret;
+}
+
+bool transition_allowed(int oldState, int newState)
+{
+ /* parse the allowed transitions string and look for old:new */
+ char search[128];
+
+ if (transitionList == NULL) return true;
+
+ PR_snprintf(search, 128, "%d:%d", oldState, newState);
+ return RA::match_comma_list(search, transitionList);
+}
+
+void add_allowed_token_transitions(int token_ui_state, char *injection)
+{
+ bool first = true;
+ int i=1;
+ char state[128];
+
+ sprintf(state, "var allowed_transitions=\"");
+ PL_strcat(injection, state);
+ for (i=1; i<=MAX_TOKEN_UI_STATE; i++) {
+ if (transition_allowed(token_ui_state, i)) {
+ if (first) {
+ sprintf(state, "%d", i);
+ first = false;
+ } else {
+ sprintf(state, ",%d", i);
+ }
+ PL_strcat(injection, state);
+ }
+ }
+ PL_strcat(injection, "\";\n");
+}
+
+char *getTemplateFile( char *fileName, int *injectionTagOffset )
+{
+ char *buf = NULL;
+ char *s = NULL;
+ PRFileDesc *fd = NULL;
+ char fullFileName[4096];
+ PRFileInfo info;
+ PRUint32 fileSize;
+ PRUint32 size;
+ PRInt32 k, n;
+
+ *injectionTagOffset = -1;
+
+ PR_snprintf( fullFileName, 4096, "%s/%s", templateDir, fileName );
+
+ if( PR_GetFileInfo( fullFileName, &info ) != PR_SUCCESS ) {
+ return buf;
+ }
+
+ fileSize = info.size;
+ size = fileSize + 1;
+
+ buf = ( char * ) PR_Malloc( size );
+ if( buf == NULL ) {
+ return buf;
+ }
+
+ fd = PR_Open( fullFileName, PR_RDONLY, 00400 );
+ if( fd == NULL ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return NULL;
+ }
+
+ k = 0;
+ while( ( n = PR_Read( fd, &buf[k], fileSize-k ) ) > 0 ) {
+ k += n;
+ if( ( PRUint32 ) k >= fileSize ) {
+ break;
+ }
+ }
+
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+
+ if( n < 0 || ( ( PRUint32 ) k > fileSize ) ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return NULL;
+ }
+
+ buf[k] = '\0';
+
+ if( ( s = PL_strstr( buf, CMS_TEMPLATE_TAG ) ) != NULL ) {
+ *injectionTagOffset = PL_strlen( buf ) - PL_strlen( s );
+ }
+
+ return buf;
+}
+
+
+char *getData( char *fileName, char *injection )
+{
+ char *buf = NULL;
+ char *s = NULL;
+ PRFileDesc *fd = NULL;
+ char fullFileName[4096];
+ PRFileInfo info;
+ PRUint32 fileSize;
+ PRUint32 size, len;
+ PRUint32 injectionSize;
+ PRInt32 k, n;
+
+ PR_snprintf( fullFileName, 4096, "%s/%s", templateDir, fileName );
+
+ if( PR_GetFileInfo( fullFileName, &info ) != PR_SUCCESS ) {
+ return buf;
+ }
+
+ fileSize = info.size;
+ size = fileSize;
+ injectionSize = 0;
+
+ if( injection != NULL && PL_strlen( injection ) > 0 ) {
+ injectionSize = PL_strlen( injection );
+ size += injectionSize;
+ }
+
+ size++;
+
+ buf = ( char * ) PR_Malloc( size );
+ if( buf == NULL ) {
+ return buf;
+ }
+
+ fd = PR_Open( fullFileName, PR_RDONLY, 00400 );
+ if( fd == NULL ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return NULL;
+ }
+
+ k = 0;
+ while( ( n = PR_Read( fd, &buf[k], fileSize-k ) ) > 0 ) {
+ k += n;
+ if( ( PRUint32 ) k >= fileSize ) {
+ break;
+ }
+ }
+
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+
+ if( n < 0 || ( ( PRUint32 ) k > fileSize ) ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return NULL;
+ }
+
+ buf[k] = '\0';
+ if( injectionSize > 0 ) {
+ if( ( s = PL_strstr( buf, CMS_TEMPLATE_TAG ) ) != NULL ) {
+ len = PL_strlen( s ) - PL_strlen( CMS_TEMPLATE_TAG );
+ memmove( s + injectionSize,
+ s + PL_strlen( CMS_TEMPLATE_TAG ),
+ len + 1 );
+ memcpy( s, injection, injectionSize );
+ }
+ }
+
+ return buf;
+}
+
+/**
+ * returns string with special characters escaped. Caller must free the contents
+ */
+char *escapeSpecialChars(char* src)
+{
+ char *ret;
+ int i =0;
+
+ if (PL_strlen(src) == 0) {
+ return PL_strdup(src);
+ }
+ ret = (char *)PR_Malloc(PL_strlen(src) * 2 + 1);
+
+ while (*src != '\0') {
+ if (*src == '"') {
+ ret[i++] = '\\';
+ ret[i++] = '"';
+ } else {
+ ret[i++] = *src;
+ }
+ src++;
+ }
+ ret[i]='\0';
+ return ret;
+}
+
+void getCertificateFilter( char *filter, char *query )
+{
+ char *uid = NULL;
+ char *tid = NULL;
+ char *end = NULL;
+ char *cn = NULL;
+ char *view = NULL;
+ int len = 0;
+ int i = 0;
+
+ tid = PL_strstr( query, "tid=" );
+ uid = PL_strstr( query, "uid=" );
+ cn = PL_strstr( query, "cn=" );
+ view = PL_strstr( query, "op=view" );
+
+ if( view == NULL ) {
+ view = PL_strstr( query, "op=show" );
+ }
+
+ filter[0] = '\0';
+
+ if( tid == NULL && uid == NULL && cn == NULL ) {
+ PL_strcat( filter, "(tokenID=*)" );
+ return;
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(&" );
+ }
+
+ if( tid != NULL ) {
+ PL_strcat( filter, "(tokenID=" );
+ end = PL_strchr( tid, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - tid - 4;
+
+ if( i > 0 ) {
+ memcpy( filter+len, tid+4, i );
+ }
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, tid+4 );
+ }
+ if( view != NULL ) {
+ PL_strcat( filter, "*)" );
+ } else {
+ PL_strcat( filter, ")" );
+ }
+ }
+
+ if( uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(tokenUserID=" );
+ end = PL_strchr( uid, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - uid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, uid+4, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, uid+4 );
+ }
+
+ PL_strcat( filter, "*)" );
+ /* PL_strcat( filter, ")" ); */
+ }
+
+ if( cn != NULL ) {
+ PL_strcat( filter, "(cn=" );
+ end = PL_strchr( cn, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - cn - 3;
+ if( i > 0 ) {
+ memcpy( filter+len, cn+3, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, cn+3 );
+ }
+
+ PL_strcat( filter, "*)" );
+ /* PL_strcat( filter, ")" ); */
+ }
+
+ if(tid != NULL && uid != NULL && view != NULL) {
+ PL_strcat( filter, ")" );
+ }
+}
+
+
+void getActivityFilter( char *filter, char *query )
+{
+ char *uid = NULL;
+ char *tid = NULL;
+ char *end = NULL;
+ char *view = NULL;
+ int len = 0;
+ int i = 0;
+
+ tid = PL_strstr( query, "tid=" );
+ uid = PL_strstr( query, "uid=" );
+ view = PL_strstr( query, "op=view" );
+ filter[0] = '\0';
+
+ if( tid == NULL && uid == NULL ) {
+ PL_strcat( filter, "(tokenID=*)" );
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(&" );
+ }
+
+ if( tid != NULL ) {
+ PL_strcat( filter, "(tokenID=" );
+ end = PL_strchr( tid, '&' );
+ len = PL_strlen( filter );
+
+ if( end != NULL ) {
+ i = end - tid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, tid+4, i );
+ }
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, tid+4 );
+ }
+
+ if( view != NULL ) {
+ PL_strcat( filter, "*)" );
+ } else {
+ PL_strcat( filter, ")" );
+ }
+ }
+
+ if( uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(tokenUserID=" );
+ end = PL_strchr( uid, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - uid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, uid+4, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, uid+4 );
+ }
+
+ PL_strcat( filter, "*)" );
+ /* PL_strcat( filter, ")" ); */
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL) {
+ PL_strcat( filter, ")" );
+ }
+}
+
+/**
+ * get_user_filter
+ * summary: returns an ldap search filter used for displaying
+ * user data when searching users based on uid, firstName and lastName
+ * params: filter - ldap search filter. Resu;t returned here.
+ * query - query string passed in
+ */
+void getUserFilter (char *filter, char *query) {
+ char *uid = NULL;
+ char *firstName = NULL;
+ char *lastName = NULL;
+
+ uid = get_field(query, "uid=", SHORT_LEN);
+ firstName = get_field(query, "firstName=", SHORT_LEN);
+ lastName = get_field(query, "lastName=", SHORT_LEN);
+
+ filter[0] = '\0';
+
+ if ((uid == NULL) && (firstName == NULL) && (lastName ==NULL)) {
+ PL_strcat(filter, "(objectClass=Person");
+ } else {
+ PL_strcat(filter, "(&(objectClass=Person)");
+ }
+
+ if (uid != NULL) {
+ PL_strcat(filter, "(uid=");
+ PL_strcat(filter, uid);
+ PL_strcat(filter,")");
+ }
+
+ if (lastName != NULL) {
+ PL_strcat(filter, "(sn=");
+ PL_strcat(filter, lastName);
+ PL_strcat(filter,")");
+ }
+
+ if (firstName != NULL) {
+ PL_strcat(filter, "(givenName=");
+ PL_strcat(filter, firstName);
+ PL_strcat(filter,")");
+ }
+
+ PL_strcat(filter, ")");
+
+ do_free(uid);
+ do_free(firstName);
+ do_free(lastName);
+}
+
+/**
+ * add_profile_filter
+ * summary: returns an ldap search filter which is a concatenation
+ * of the authorized profile search filter and the regular search
+ * filter. To be freed by caller.
+ * params: filter - search filter
+ * auth_filter: authorized profiles filter
+ */
+char *add_profile_filter( char *filter, char *auth_filter)
+{
+ char *ret;
+ int size;
+ char no_auth_filter[] = "(tokenType=\"\")";
+ if (filter == NULL) return NULL;
+ if ((auth_filter == NULL) || (PL_strstr( auth_filter, ALL_PROFILES))) {
+ ret = PL_strdup(filter);
+ } else if (PL_strstr( auth_filter, NO_PROFILES)) {
+ size = (PL_strlen(filter) + PL_strlen(no_auth_filter) + 4) * sizeof(char);
+ ret = (char *) PR_Malloc(size);
+ PR_snprintf(ret, size, "%s%s%s%s",
+ "(&", filter,no_auth_filter, ")");
+ } else {
+ size = (PL_strlen(filter) + PL_strlen(auth_filter) + 4) * sizeof(char);
+ ret = (char *) PR_Malloc(size);
+ PR_snprintf(ret, size, "%s%s%s%s",
+ "(&", filter, auth_filter, ")");
+ }
+ return ret;
+}
+
+
+void getFilter( char *filter, char *query )
+{
+ char *uid = NULL;
+ char *tid = NULL;
+ char *end = NULL;
+ char *view = NULL;
+ int len = 0;
+ int i = 0;
+
+ tid = PL_strstr( query, "tid=" );
+ uid = PL_strstr( query, "uid=" );
+ view = PL_strstr( query, "op=view" );
+ filter[0] = '\0';
+
+ if( tid == NULL && uid == NULL ) {
+ PL_strcat( filter, "(cn=*)" );
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(&" );
+ }
+
+ if( tid != NULL ) {
+ PL_strcat( filter, "(cn=" );
+ end = PL_strchr( tid, '&' );
+ len = PL_strlen( filter );
+
+ if( end != NULL ) {
+ i = end - tid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, tid+4, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, tid+4 );
+ }
+
+ if (view != NULL) {
+ PL_strcat( filter, "*)" );
+ } else {
+ PL_strcat( filter, ")" );
+ }
+ }
+
+ if( uid != NULL && view != NULL ) {
+ PL_strcat( filter, "(tokenUserID=" );
+ end = PL_strchr( uid, '&' );
+ len = PL_strlen( filter );
+ if( end != NULL ) {
+ i = end - uid - 4;
+ if( i > 0 ) {
+ memcpy( filter+len, uid+4, i );
+ }
+
+ filter[len+i] = '\0';
+ } else {
+ PL_strcat( filter, uid+4 );
+ }
+
+ PL_strcat( filter, "*)" );
+ /* PL_strcat( filter, ")" ); */
+ }
+
+ if( tid != NULL && uid != NULL && view != NULL ) {
+ PL_strcat( filter, ")" );
+ }
+}
+
+
+void getCN( char *cn, char *query )
+{
+ char *tid = NULL;
+ char *end = NULL;
+ int i = 0;
+
+ cn[0] = '\0';
+ tid = PL_strstr( query, "tid=" );
+ if( tid != NULL ) {
+ end = PL_strchr( tid, '&' );
+
+ if( end != NULL ) {
+ i = end - tid - 4;
+
+ if( i > 0 ) {
+ memcpy( cn, tid+4, i );
+ }
+
+ cn[i] = '\0';
+ } else {
+ PL_strcat( cn, tid+4 );
+ }
+ }
+}
+
+
+void getTemplateName( char *cn, char *query )
+{
+ char *tid = NULL;
+ char *end = NULL;
+ int i = 0;
+
+ cn[0] = '\0';
+ tid = PL_strstr( query, "template=" );
+
+ if( tid != NULL ) {
+ end = PL_strchr( tid, '&' );
+
+ if( end != NULL ) {
+ i = end - tid - 4;
+
+ if( i > 0 ) {
+ memcpy( cn, tid+4, i );
+ }
+
+ cn[i] = '\0';
+ } else {
+ PL_strcat( cn, tid+4 );
+ }
+ }
+}
+
+
+char *parse_modification_number( char *s )
+{
+ char *end = NULL;
+ int n;
+
+ if( ( s = PL_strstr( s, "m=" ) ) == NULL ) {
+ return NULL;
+ }
+
+ s += 2;
+ end = PL_strchr( s, '&' );
+
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ return PL_strndup( s, n );
+}
+
+
+char **parse_modification_number_change( char *s )
+{
+ char *end = NULL;
+ char **v = NULL;
+ char tmp[32];
+ int n, m;
+
+ end = PL_strchr( s, '&' );
+
+ if( end != NULL ) {
+ n = end - s;
+ if( n > 0 ) {
+ memcpy( tmp, s, n );
+ }
+ tmp[n] = '\0';
+ } else {
+ n = PL_strlen( s );
+ PL_strcpy( tmp, s );
+ }
+
+ m = atoi( tmp );
+ m++;
+ PR_snprintf( tmp, 32, "%d", m );
+ n = PL_strlen( tmp );
+
+ if( ( v = allocate_values( 1, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+
+ PL_strcpy( v[0], tmp );
+
+ return v;
+}
+
+
+char **parse_status_change( char *s )
+{
+ char *end = NULL;
+ char **v = NULL;
+ int n;
+
+ end = PL_strchr( s, '&' );
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if( ( v = allocate_values( 1, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+ PL_strncpy( v[0], s, n );
+
+ return v;
+}
+
+
+char **parse_uid_change( char *s )
+{
+ char *end = NULL;
+ char *p = NULL;
+ char *q = NULL;
+ char **v = NULL;
+ int i, k, n, m;
+
+ end = PL_strchr( s, '&' );
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ k = n;
+ p = s;
+ m = 1;
+
+ while( k > 0 ) {
+ if( ( p = PL_strnchr( p, ',', k ) ) == NULL ) {
+ break;
+ }
+
+ p++;
+ k = n - ( p - s );
+ m++;
+ }
+
+ if( ( v = allocate_values( m, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+
+ if( m > 1 ) {
+ k = n;
+ p = s;
+ i = 0;
+
+ while( k > 0 ) {
+ if( ( q = PL_strnchr( p, ',', k ) ) != NULL ) {
+ PL_strncpy( v[i], p, q-p );
+ q++;
+ p = q;
+ k = n - ( p - s );
+ i++;
+ v[i] = v[i-1] + PL_strlen( v[i-1] ) + 1;
+ } else {
+ PL_strncpy( v[i], p, k );
+ break;
+ }
+ }
+ } else {
+ PL_strncpy( v[0], s, n );
+ }
+
+ return v;
+}
+
+
+char **parse_reason_change( char *s )
+{
+ char *end = NULL;
+ char **v = NULL;
+ int n;
+
+ end = PL_strchr( s, '&' );
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if( ( v = allocate_values( 1, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+ PL_strncpy( v[0], s, n );
+
+ return v;
+}
+
+
+char **parse_policy_change( char *s )
+{
+ char *end = NULL;
+ char **v = NULL;
+ int n;
+
+ end = PL_strchr( s, '&' );
+
+ if( end != NULL ) {
+ n = end - s;
+ } else {
+ n = PL_strlen( s );
+ }
+
+ if( ( v = allocate_values( 1, n+1 ) ) == NULL ) {
+ return NULL;
+ }
+
+ PL_strncpy( v[0], s, n );
+
+ return v;
+}
+
+
+LDAPMod **getModifications( char *query )
+{
+ LDAPMod **mods = NULL;
+ char **v = NULL;
+ int n = 0;
+ int k = 0;
+ char *s;
+
+ s = query;
+
+ while( ( s = PL_strchr( s, '&' ) ) != NULL ) {
+ s++;
+ n++;
+ }
+
+ if( n > 0 && PL_strstr( query, "&tid=" ) != NULL ) {
+ n--;
+ }
+
+ if( n > 0 ) {
+ n++;
+ } else {
+ return NULL;
+ }
+
+
+ mods = allocate_modifications( n );
+
+ if( mods == NULL ) {
+ return NULL;
+ }
+
+ if( ( v = create_modification_date_change() ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = get_modification_date_name();
+ mods[0]->mod_values = v;
+ k = 1;
+
+ if( k < n && ( ( s = PL_strstr( query, "m=" ) ) != NULL ) ) {
+ s += 2;
+ if( ( v = parse_modification_number_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_number_of_modifications_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ if( k < n && ( ( s = PL_strstr( query, "s=" ) ) != NULL ) ) {
+ s += 2;
+
+ if( ( v = parse_status_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_token_status_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ if( k < n && ( ( s = PL_strstr( query, "uid=" ) ) != NULL ) ) {
+ s += 4;
+ if( ( v = parse_uid_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_token_users_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ if( k < n && ( ( s = PL_strstr( query, "tokenPolicy=" ) ) != NULL ) ) {
+ s += 12;
+
+ if( ( v = parse_policy_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_policy_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ if( k < n && ( ( s = PL_strstr( query, "tokenReason=" ) ) != NULL ) ) {
+ s += 12;
+
+ if( ( v = parse_reason_change( s ) ) == NULL ) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return NULL;
+ }
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = get_reason_name();
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ return mods;
+}
+
+int get_tus_config( char *name )
+{
+ PRFileDesc *fd = NULL;
+ char *buf = NULL;
+ char *s = NULL;
+ char *v = NULL;
+ PRFileInfo info;
+ PRUint32 size;
+ int k, n;
+
+ if( PR_GetFileInfo( name, &info ) != PR_SUCCESS ) {
+ return 0;
+ }
+
+ size = info.size;
+ size++;
+ buf = (char *)PR_Malloc( size );
+
+ if( buf == NULL ) {
+ return 0;
+ }
+
+ fd = PR_Open( name, PR_RDONLY, 00400 );
+ if( fd == NULL ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+
+ k = 0;
+ while( ( n = PR_Read( fd, &buf[k], size-k-1 ) ) > 0 ) {
+ k += n;
+ if( ( PRUint32 ) ( k+1 ) >= size ) {
+ break;
+ }
+ }
+
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+
+ if( n < 0 || ( ( PRUint32 ) ( k+1 ) > size ) ) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+
+ buf[k] = '\0';
+
+ if( ( s = PL_strstr( buf, "tokendb.templateDir=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.templateDir=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( templateDir != NULL ) {
+ PL_strfree( templateDir );
+ templateDir = NULL;
+ }
+ templateDir = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.errorTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.errorTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( errorTemplate != NULL ) {
+ PL_strfree( errorTemplate );
+ errorTemplate = NULL;
+ }
+ errorTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.indexTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.indexTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( indexTemplate != NULL ) {
+ PL_strfree( indexTemplate );
+ indexTemplate = NULL;
+ }
+ indexTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.indexAdminTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.indexAdminTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( indexAdminTemplate != NULL ) {
+ PL_strfree( indexAdminTemplate );
+ indexAdminTemplate = NULL;
+ }
+ indexAdminTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.indexOperatorTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.indexOperatorTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( indexOperatorTemplate != NULL ) {
+ PL_strfree( indexOperatorTemplate );
+ indexOperatorTemplate = NULL;
+ }
+ indexOperatorTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.newTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.newTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 )( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( newTemplate != NULL ) {
+ PL_strfree( newTemplate );
+ newTemplate = NULL;
+ }
+ newTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchUserResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchUserResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 )( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ do_free(searchUserResultTemplate);
+ searchUserResultTemplate = s;
+ } else {
+ do_free(buf);
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.newUserTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.newUserTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 )( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ do_free(newUserTemplate);
+ newUserTemplate = s;
+ } else {
+ do_free(buf);
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchTemplate != NULL ) {
+ PL_strfree( searchTemplate );
+ searchTemplate = NULL;
+ }
+ searchTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchCertificateTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchCertificateTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchCertificateTemplate != NULL ) {
+ PL_strfree( searchCertificateTemplate );
+ searchCertificateTemplate = NULL;
+ }
+ searchCertificateTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchAdminTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchAdminTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchAdminTemplate != NULL ) {
+ PL_strfree( searchAdminTemplate );
+ searchAdminTemplate = NULL;
+ }
+ searchAdminTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchUserTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchUserTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchUserTemplate != NULL ) {
+ PL_strfree( searchUserTemplate );
+ searchUserTemplate = NULL;
+ }
+ searchUserTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchActivityTemplate=" ) ) != NULL) {
+ s += PL_strlen( "tokendb.searchActivityTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchActivityTemplate != NULL ) {
+ PL_strfree( searchActivityTemplate );
+ searchActivityTemplate = NULL;
+ }
+ searchActivityTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchActivityAdminTemplate=" ) ) != NULL) {
+ s += PL_strlen( "tokendb.searchActivityAdminTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchActivityAdminTemplate != NULL ) {
+ PL_strfree( searchActivityAdminTemplate );
+ searchActivityAdminTemplate = NULL;
+ }
+ searchActivityAdminTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchCertificateResultTemplate=" ) ) !=
+ NULL ) {
+ s += PL_strlen( "tokendb.searchCertificateResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchCertificateResultTemplate != NULL ) {
+ PL_strfree( searchCertificateResultTemplate );
+ searchCertificateResultTemplate = NULL;
+ }
+ searchCertificateResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchActivityResultTemplate=" ) ) !=
+ NULL ) {
+ s += PL_strlen( "tokendb.searchActivityResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchActivityResultTemplate != NULL ) {
+ PL_strfree( searchActivityResultTemplate );
+ searchActivityResultTemplate = NULL;
+ }
+ searchActivityResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchAdminResultTemplate=" ) ) !=
+ NULL ) {
+ s += PL_strlen( "tokendb.searchAdminResultTemplate=" );
+ v = s;
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchAdminResultTemplate != NULL ) {
+ PL_strfree( searchAdminResultTemplate );
+ searchAdminResultTemplate = NULL;
+ }
+ searchAdminResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchResultTemplate != NULL ) {
+ PL_strfree( searchResultTemplate );
+ searchResultTemplate = NULL;
+ }
+ searchResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.deleteTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.deleteTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( deleteTemplate != NULL ) {
+ PL_strfree( deleteTemplate );
+ deleteTemplate = NULL;
+ }
+ deleteTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.userDeleteTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.userDeleteTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( userDeleteTemplate != NULL ) {
+ PL_strfree( userDeleteTemplate );
+ userDeleteTemplate = NULL;
+ }
+ userDeleteTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.doTokenConfirmTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.doTokenConfirmTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( doTokenConfirmTemplate != NULL ) {
+ PL_strfree( doTokenConfirmTemplate );
+ revokeTemplate = NULL;
+ }
+ doTokenConfirmTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.doTokenTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.doTokenTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( doTokenTemplate != NULL ) {
+ PL_strfree( doTokenTemplate );
+ revokeTemplate = NULL;
+ }
+ doTokenTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.revokeTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.revokeTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( revokeTemplate != NULL ) {
+ PL_strfree( revokeTemplate );
+ revokeTemplate = NULL;
+ }
+ revokeTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.showAdminTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.showAdminTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( showAdminTemplate != NULL ) {
+ PL_strfree( showAdminTemplate );
+ showAdminTemplate = NULL;
+ }
+ showAdminTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.showCertTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.showCertTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if (s != NULL) {
+ if( showCertTemplate != NULL ) {
+ PL_strfree( showCertTemplate );
+ showCertTemplate = NULL;
+ }
+ showCertTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.showTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.showTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( showTemplate != NULL ) {
+ PL_strfree( showTemplate );
+ showTemplate = NULL;
+ }
+ showTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.searchActivityAdminResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.searchActivityAdminResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( searchActivityAdminResultTemplate != NULL ) {
+ PL_strfree( searchActivityAdminResultTemplate );
+ searchActivityAdminResultTemplate = NULL;
+ }
+ searchActivityAdminResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.editUserTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.editUserTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( editUserTemplate != NULL ) {
+ PL_strfree( editUserTemplate );
+ editUserTemplate = NULL;
+ }
+ editUserTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.editTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.editTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( editTemplate != NULL ) {
+ PL_strfree( editTemplate );
+ editTemplate = NULL;
+ }
+ editTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.editResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.editResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( editResultTemplate != NULL ) {
+ PL_strfree( editResultTemplate );
+ editResultTemplate = NULL;
+ }
+ editResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.addResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.addResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( addResultTemplate != NULL ) {
+ PL_strfree( addResultTemplate );
+ addResultTemplate = NULL;
+ }
+ addResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.deleteResultTemplate=" ) ) != NULL ) {
+ s += PL_strlen( "tokendb.deleteResultTemplate=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( deleteResultTemplate != NULL ) {
+ PL_strfree( deleteResultTemplate );
+ deleteResultTemplate = NULL;
+ }
+ deleteResultTemplate = s;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( ( s = PL_strstr( buf, "tokendb.tokendb.sendInPieces=" ) ) != NULL ) {
+ s += 13;
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ sendInPieces = atoi( s );
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ /* keep this assignment to profileList for backwards compatibility.
+ It has been superseded by target.Profiles.list.
+ This should be removed in a future release */
+ if( ( s = PL_strstr( buf, "target.tokenType.list=" ) ) != NULL ) {
+ s += PL_strlen( "target.tokenType.list=" );
+ v = s;
+
+ while( *s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ ( PRUint32 ) ( s - buf ) < size ) {
+ s++;
+ }
+
+ n = s - v;
+
+ s = PL_strndup( v, n );
+ if( s != NULL ) {
+ if( profileList != NULL ) {
+ PL_strfree( profileList );
+ profileList = NULL;
+ }
+ profileList = s;
+ } else {
+ do_free(buf);
+ return 0;
+ }
+ }
+
+ get_cfg_string("tokendb.allowedTransitions=", transitionList);
+ get_cfg_string("tokendb.auditAdminTemplate=", auditAdminTemplate);
+ get_cfg_string("tokendb.selfTestTemplate=", selfTestTemplate);
+ get_cfg_string("tokendb.selfTestResultsTemplate=", selfTestResultsTemplate);
+ get_cfg_string("tokendb.selectConfigTemplate=", selectConfigTemplate);
+ get_cfg_string("tokendb.agentSelectConfigTemplate=", agentSelectConfigTemplate);
+ get_cfg_string("tokendb.editConfigTemplate=", editConfigTemplate);
+ get_cfg_string("tokendb.agentViewConfigTemplate=", agentViewConfigTemplate);
+ get_cfg_string("tokendb.confirmConfigChangesTemplate=", confirmConfigChangesTemplate);
+ get_cfg_string("tokendb.addConfigTemplate=", addConfigTemplate);
+ get_cfg_string("tokendb.confirmDeleteConfigTemplate=", confirmDeleteConfigTemplate);
+ get_cfg_string("target.Profiles.list=", profileList);
+ get_cfg_int("general.search.sizelimit.max=", maxSizeLimit);
+ get_cfg_int("general.search.sizelimit.default=", defaultSizeLimit);
+ get_cfg_int("general.search.timelimit.max=", maxTimeLimit);
+ get_cfg_int("general.search.timelimit.min=", defaultTimeLimit);
+ get_cfg_int("general.pwlength.min=", pwLength);
+
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+
+ tus_db_end();
+
+ return 1;
+}
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Request Phase
+** _________________________________________________________________
+*/
+
+/**
+ * Terminate the Tokendb module
+ */
+static apr_status_t
+mod_tokendb_terminate( void *data )
+{
+ /* This routine is ONLY called when this server's */
+ /* pool has been cleared or destroyed. */
+
+ /* Log Tokendb module debug information. */
+ RA::Debug( "mod_tokendb::mod_tokendb_terminate",
+ "The Tokendb module has been terminated!" );
+
+ tus_db_end();
+ tus_db_cleanup();
+
+ /* Since all members of mod_tokendb_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ /* Allow the TPS/NSS Modules to perform this task. */
+ /* apr_terminate(); */
+
+ /* Terminate the entire Apache server */
+ /* NOTE: Allow the TPS/NSS Modules to perform this task. */
+
+ return OK;
+}
+
+
+/**
+ * Initialize the Tokendb module
+ */
+static int
+mod_tokendb_initialize( apr_pool_t *p,
+ apr_pool_t *plog,
+ apr_pool_t *ptemp,
+ server_rec *sv )
+{
+ mod_tokendb_server_configuration *sc = NULL;
+ char *cfg_path_file = NULL;
+ char *error = NULL;
+ int status;
+
+ /* Retrieve the Tokendb module. */
+ sc = ( ( mod_tokendb_server_configuration * )
+ ap_get_module_config( sv->module_config,
+ &MOD_TOKENDB_CONFIG_KEY ) );
+
+ /* Check to see if the Tokendb module has been loaded. */
+ if( sc->enabled == MOD_TOKENDB_TRUE ) {
+ return OK;
+ }
+
+ /* Load the Tokendb module. */
+
+#ifdef DEBUG_Tokendb
+ debug_fd = PR_Open( "/tmp/tus-debug.log",
+ PR_RDWR | PR_CREATE_FILE | PR_APPEND,
+ 00400 | 00200 );
+#endif
+
+ /* Retrieve the path to where the configuration files are located, and */
+ /* insure that the Tokendb module configuration file is located here. */
+ if( sc->Tokendb_Configuration_File != NULL ) {
+ /* provide Tokendb Config File from */
+ /* <apache_server_root>/conf/httpd.conf */
+ if( sc->Tokendb_Configuration_File[0] == '/' ) {
+ /* Complete path to Tokendb Config File is denoted */
+ cfg_path_file = apr_psprintf( p,
+ "%s",
+ ( char * )
+ sc->Tokendb_Configuration_File );
+ } else {
+ /* Tokendb Config File is located relative */
+ /* to the Apache server root */
+ cfg_path_file = apr_psprintf( p,
+ "%s/%s",
+ ( char * ) ap_server_root,
+ ( char * )
+ sc->Tokendb_Configuration_File );
+ }
+ } else {
+ /* Log information regarding this failure. */
+ ap_log_error( "mod_tokendb_initialize",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tokendb module was installed incorrectly since the "
+ "parameter named '%s' is missing from the Apache "
+ "Configuration file!",
+ ( char * ) MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER );
+
+ /* Display information on the screen regarding this failure. */
+ printf( "\nUnable to start Apache:\n"
+ " The tokendb module is missing the required parameter named"
+ " \n'%s' in the Apache Configuration file!\n",
+ ( char * ) MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER );
+
+ goto loser;
+ }
+
+ /* Initialize the Token DB. */
+ if( get_tus_config( cfg_path_file ) &&
+ get_tus_db_config( cfg_path_file ) ) {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Initializing TUS database");
+ if( ( status = tus_db_init( &error ) ) != LDAP_SUCCESS ) {
+ if( error != NULL ) {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Token DB initialization failed: '%s'",
+ error );
+ PR_smprintf_free( error );
+ error = NULL;
+ } else {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Token DB initialization failed" );
+ }
+
+#if 0
+ goto loser;
+#endif
+ } else {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Token DB initialization succeeded" );
+ }
+ } else {
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Error reading tokendb config file: '%s'",
+ cfg_path_file );
+ }
+
+ /* Initialize the "server" member of mod_tokendb_server_configuration. */
+ sc->enabled = MOD_TOKENDB_TRUE;
+
+ /* Register a server termination routine. */
+ apr_pool_cleanup_register( p,
+ sv,
+ mod_tokendb_terminate,
+ apr_pool_cleanup_null );
+
+ /* Log Tokendb module debug information. */
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "The Tokendb module has been successfully loaded!" );
+
+ return OK;
+
+loser:
+ /* Log Tokendb module debug information. */
+ RA::Debug( "mod_tokendb::mod_tokendb_initialize",
+ "Failed loading the Tokendb module!" );
+
+ /* Since all members of mod_tokendb_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ apr_terminate();
+
+ /* Terminate the entire Apache server */
+ tokendb_die();
+
+ return DECLINED;
+}
+
+
+char *stripBase64HeaderAndFooter( char *cert )
+{
+ char *base64_data = NULL;
+ char *data = NULL;
+ char *footer = NULL;
+
+ if( ( cert != NULL ) &&
+ ( strlen( cert ) > strlen( BASE64_HEADER ) ) ) {
+ /* Strip off the base64 header. */
+ data = ( char * ) ( cert + strlen( BASE64_HEADER ) );
+
+ /* Find base64 footer. */
+ footer = ( char * ) strstr( ( const char * ) data,
+ ( const char * ) BASE64_FOOTER );
+ if( footer != NULL ) {
+ /* Strip off the base64 footer. */
+ footer[0] = '\0';
+ }
+
+ /* Finally, store data in the base64_data storage area. */
+ base64_data = strdup( data );
+ }
+
+ return base64_data;
+}
+
+/**
+ * util_read
+ * summary: called from read_post. reads posted data
+ */
+static int util_read(request_rec *r, const char **rbuf)
+{
+ int rc = OK;
+
+ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
+ return rc;
+ }
+
+ if (ap_should_client_block(r)) {
+ char argsbuffer[HUGE_STRING_LEN];
+ int rsize, len_read, rpos=0;
+ long length = r->remaining;
+ *rbuf = (const char*) apr_pcalloc(r->pool, length + 1);
+
+
+ while ((len_read =
+ ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0) {
+ if ((rpos + len_read) > length) {
+ rsize = length - rpos;
+ }
+ else {
+ rsize = len_read;
+ }
+ memcpy((char*)*rbuf + rpos, argsbuffer, rsize);
+ rpos += rsize;
+ }
+
+ }
+
+ return rc;
+}
+
+/**
+ * read_post
+ * read data in a post request and store it in an apr_table
+ */
+static int read_post(request_rec *r, apr_table_t **tab)
+{
+ const char *data;
+ const char *key, *val;
+ int rc = OK;
+
+ if((rc = util_read(r, &data)) != OK) {
+ return rc;
+ }
+
+ if(*tab) {
+ apr_table_clear(*tab);
+ }
+ else {
+ *tab = apr_table_make(r->pool, 8);
+ }
+
+ while(*data && (val = ap_getword(r->pool, &data, '&'))) {
+ key = ap_getword(r->pool, &val, '=');
+
+ ap_unescape_url((char*)key);
+ ap_unescape_url((char*)val);
+
+ apr_table_merge(*tab, key, val);
+ }
+
+ return OK;
+}
+
+/**
+ * add_authorization_data
+ * writes variable that describe whether the user is an admin, agent or operator to the
+ * injection data. Used by templates to determine which tabs to display
+ */
+void add_authorization_data(const char *userid, int is_admin, int is_operator, int is_agent, char *injection)
+{
+ if (is_agent) {
+ PL_strcat(injection, "var agentAuth = \"true\";\n");
+ }
+ if (is_operator) {
+ PL_strcat(injection, "var operatorAuth = \"true\";\n");
+ }
+ if (is_admin) {
+ PL_strcat(injection, "var adminAuth = \"true\";\n");
+ }
+}
+
+/**
+ * check_injection_size
+ * Used when the injection size can become large - as in the case where lists of tokens, certs or activities are being returned.
+ * If the free space in injection drops below a threshold, more space is allocated. Fails if injection exceeds a certain size.
+ * This should not happen because the number of entries to return per page is limited.
+ *
+ * returns 0 on success,1 on failure
+ */
+int check_injection_size(char **injection, int *psize, char *fixed_injection)
+{
+ char *new_ptr = NULL;
+ if (((*psize) - PL_strlen(*injection)) <= LOW_INJECTION_SIZE) {
+ if ((*psize) > MAX_OVERLOAD * MAX_INJECTION_SIZE) {
+ tokendbDebug("Error: Injection exceeds maximum size. Output will be truncated");
+ return 1;
+ }
+ if (*injection == fixed_injection) {
+ *injection = (char *) PR_Malloc(MAX_INJECTION_SIZE + (*psize));
+ if (*injection != NULL) {
+ PL_strcpy(*injection, fixed_injection);
+ (*psize) += MAX_INJECTION_SIZE;
+ } else {
+ tokendbDebug("Error: Unable to allocate memory for injection. Output will be truncated");
+ *injection = fixed_injection;
+ return 1;
+ }
+ } else {
+ new_ptr = (char *) PR_Realloc(*injection, (*psize) + MAX_INJECTION_SIZE);
+ if (new_ptr != NULL) {
+ //allocation successful
+ *injection = new_ptr;
+ (*psize) += MAX_INJECTION_SIZE;
+ } else {
+ tokendbDebug("Error: Failed to reallocate memory for injection. Output will be truncated");
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * We need to compare current values in the database entry e with new values.
+ * If they are different, then we need to provide the audit message
+ */
+int audit_attribute_change(LDAPMessage *e, const char *fname, char *fvalue, char *msg)
+{
+ struct berval **attr_values = NULL;
+ char pString[512]="";
+
+ attr_values = get_attribute_values( e, fname );
+ if (attr_values != NULL) {
+ if (fvalue == NULL) {
+ // value has been deleted
+ PR_snprintf(pString, 512, "%s;;no_value", fname);
+ } else if (valid_berval(attr_values) &&
+ (strcmp(fvalue, attr_values[0]->bv_val) != 0)) {
+ // value has been changed
+ PR_snprintf(pString, 512, "%s;;%s", fname, fvalue);
+ }
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else if (fvalue != NULL) {
+ // value has been added
+ PR_snprintf(pString, 512, "%s;;%s", fname, fvalue);
+ }
+
+ if (strlen(pString) > 0) {
+ if (strlen(msg) != 0) PL_strncat(msg, "+", 4096 - strlen(msg));
+ PL_strncat(msg, pString, 4096 - strlen(msg));
+ }
+ return 0;
+}
+
+/**
+ * replaces all instances of a substring oldstr with newstr
+ * must be freed by caller
+ **/
+char *replace(const char *s, const char *oldstr, const char *newstr)
+{
+ char *ret = NULL;
+ int i, count = 0;
+ size_t newlen = PL_strlen(newstr);
+ size_t oldlen = PL_strlen(oldstr);
+
+ for (i = 0; s[i] != '\0'; i++) {
+ if (PL_strstr(&s[i], oldstr) == &s[i]) {
+ count++;
+ i += oldlen - 1;
+ }
+ }
+
+ ret = (char *) PR_Malloc(PL_strlen(s) + count * (newlen - oldlen) + 1);
+
+ i = 0;
+ while (*s) {
+ if (PL_strstr(s, oldstr) == s) {
+ PL_strncpy(&ret[i], newstr, newlen);
+ i += newlen;
+ s += oldlen;
+ } else
+ ret[i++] = *s++;
+ }
+ ret[i] = '\0';
+
+ return ret;
+}
+
+char *escapeString(const char *s)
+{
+ char *ret, *ret1, *ret2, *ret3;
+
+ ret1 = replace(s, "\"", "&dbquote");
+ ret2 = replace(ret1, "\'", "&singlequote");
+ ret3 = replace(ret2, "<", "&lessthan");
+ ret = replace(ret3, ">", "&greaterthan");
+ do_free(ret1);
+ do_free(ret2);
+ do_free(ret3);
+ return ret;
+}
+
+char *unescapeString(const char *s)
+{
+ char *ret, *ret1, *ret2, *ret3;
+
+ ret1 = replace(s, "&dbquote", "\"");
+ ret2 = replace(ret1,"&singlequote", "\'");
+ ret3 = replace(ret2, "&lessthan", "<");
+ ret = replace(ret3, "&greaterthan", ">");
+ do_free(ret1);
+ do_free(ret2);
+ do_free(ret3);
+ return ret;
+}
+
+
+/**
+ * determines if the parameter set named pname of type ptype
+ * has been defined.
+ **/
+bool config_param_exists(char *ptype, char* pname)
+{
+ char configname[256]="";
+ PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype );
+ const char* conf_list = RA::GetConfigStore()->GetConfigAsString( configname );
+ return RA::match_comma_list((const char*) pname, (char *) conf_list);
+}
+
+/**
+ * takes in the type and name of the parameter set.
+ * returns the current state and timestamp of this parameter set.
+ *
+ * If a parameter set is being viewed in the UI for the first time, the state is returned
+ * as "Enabled" and the timestamp is set to the current timestamp.
+ **/
+void get_config_state_timestamp(char *type, char *name, char **pstate, char **ptimestamp)
+{
+ char configname[256] = "";
+ bool commit_needed = false;
+ const char *tmp_state = NULL;
+ const char *tmp_timestamp = NULL;
+ int status;
+ PRLock *config_lock = RA::GetConfigLock();
+
+ PR_Lock(config_lock);
+ PR_snprintf(configname, 256, "config.%s.%s.state", type, name);
+
+ tmp_state = RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((tmp_state == NULL) && (config_param_exists(type, name))) {
+ RA::GetConfigStore()->Add(configname, "Enabled");
+ commit_needed = true;
+ *pstate = (char *) PL_strdup("Enabled");
+ } else {
+ *pstate = (char *) PL_strdup(tmp_state);
+ }
+
+ PR_snprintf(configname, 256, "config.%s.%s.timestamp", type, name);
+ tmp_timestamp = RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((tmp_timestamp == NULL) && (config_param_exists(type, name))) {
+ char new_ts[256];
+ PR_snprintf(new_ts, 256, "%lld", PR_Now());
+ RA::GetConfigStore()->Add(configname, new_ts);
+ commit_needed = true;
+ *ptimestamp = (char *) PL_strdup(new_ts);
+ } else {
+ *ptimestamp = (char *) PL_strdup(tmp_timestamp);
+ }
+
+ PR_Unlock(config_lock);
+ if (commit_needed) {
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(false, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+ }
+}
+
+/**
+ * takes in a parameter set type and name
+ * removes any variables defining the state and timestamp.
+ * Called when a parameter set is deleted.
+ **/
+void remove_config_state_timestamp(char *type, char *name)
+{
+ char configname[256] = "";
+ PRLock *config_lock = RA::GetConfigLock();
+
+ PR_Lock(config_lock);
+ PR_snprintf(configname, 256, "config.%s.%s.state", type, name);
+ RA::GetConfigStore()->Remove(configname);
+
+ PR_snprintf(configname, 256, "config.%s.%s.timestamp", type, name);
+ RA::GetConfigStore()->Remove(configname);
+ PR_Unlock(config_lock);
+
+}
+
+/**
+ * takes in a parameter set type
+ * returns true if this parameter set type must be approved/ disabled by an agent
+ **/
+bool agent_must_approve(char *conf_type)
+{
+ const char* agent_list = RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list");
+ return RA::match_comma_list((const char*) conf_type, (char *) agent_list);
+}
+
+/**
+ * This is the main function used to set the state and timestamp for parameter sets
+ * managed by the UI. The function includes checks to enforce only allowed transitions.
+ *
+ * Arguments are as follows:
+ * type: parameter set type
+ * name: parameter set name
+ * old_ts: old timestamp of parameter set. Used to check for concurrency conflicts.
+ * new_state: state to transition to: one of "Enabled", "Disabled", "Pending_Approval" or "Writing"
+ * who: role requesting the transition, one of "Agent" or "Admin"
+ * new_config: true if this is a new parameter set, false otherwise
+ * userid: userid of user requesting the transition, used for audit log message
+ *
+ * function will return 0 on success, non-zero otherwise
+ **/
+int set_config_state_timestamp(char *type, char* name, char *old_ts, const char *new_state, const char *who, bool new_config, char *userid)
+{
+ char ts_name[256] = "";
+ char state_name[256] = "";
+ char writer_name[256] = "";
+ char new_ts[256] ="";
+ char final_state[256] = "";
+ char me[256]="";
+ int ret =0;
+ PRTime now;
+ PRThread *ct = NULL;
+ PRLock *config_lock = RA::GetConfigLock();
+
+ PR_snprintf(ts_name, 256, "config.%s.%s.timestamp", type, name);
+ PR_snprintf(state_name, 256, "config.%s.%s.state", type, name);
+ PR_snprintf(writer_name, 256, "config.%s.%s.writer", type, name);
+
+ ct = PR_GetCurrentThread();
+ PR_snprintf(me, 256, "%x", ct);
+
+ PR_Lock(config_lock);
+ if (new_config) {
+ if (agent_must_approve(type)) {
+ RA::GetConfigStore()->Add(state_name, "Disabled");
+ } else {
+ RA::GetConfigStore()->Add(state_name, "Enabled");
+ }
+ now = PR_Now();
+ PR_snprintf(new_ts, 256, "%lld", now);
+ RA::GetConfigStore()->Add(ts_name, new_ts);
+ }
+
+ // used to make sure auditing is correct
+ PR_snprintf(final_state, 256, "%s", new_state);
+
+ const char *cur_state = RA::GetConfigStore()->GetConfigAsString(state_name);
+ const char *cur_writer = RA::GetConfigStore()->GetConfigAsString(writer_name, "");
+ const char *cur_ts = RA::GetConfigStore()->GetConfigAsString(ts_name);
+
+ if ((cur_state == NULL) || (cur_ts == NULL)) {
+ // this item has likely been deleted
+ ret=20;
+ goto release_and_exit;
+ }
+
+ if ((PL_strcmp(cur_ts, old_ts) != 0) && (!new_config)) {
+ // version out of date
+ ret=1;
+ goto release_and_exit;
+ }
+
+ if (PL_strcmp(cur_state, new_state) == 0) {
+ ret=0;
+ goto release_and_exit;
+ }
+
+ if (PL_strcmp(who, "Admin")==0) {
+ if (PL_strcmp(new_state, "Disabled")==0) {
+ if ((PL_strcmp(cur_state, "Writing") == 0) && (PL_strcmp(me, cur_writer) == 0)) {
+ // "Writing" to "Disabled", with me as writer, admin finishes writes after "Save"
+ now = PR_Now();
+ PR_snprintf(new_ts, 256, "%lld", now);
+ RA::GetConfigStore()->Add(ts_name, new_ts);
+ if (agent_must_approve(type)) {
+ RA::GetConfigStore()->Add(state_name, new_state);
+ } else {
+ PR_snprintf(final_state, 256, "Enabled");
+ RA::GetConfigStore()->Add(state_name, "Enabled");
+ }
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=2;
+ goto release_and_exit;
+ }
+ } else if (PL_strcmp(new_state, "Enabled")==0) {
+ if ((!agent_must_approve(type)) && (PL_strcmp(cur_state, "Writing") == 0)
+ && (PL_strcmp(me, cur_writer) == 0)) {
+ now = PR_Now();
+ PR_snprintf(new_ts, 256, "%lld", now);
+ RA::GetConfigStore()->Add(ts_name, new_ts);
+ ret = 0;
+ goto release_and_exit;
+ }
+
+ // no valid transitions for admin (if agent approval required)
+ ret=3;
+ goto release_and_exit;
+ } else if (PL_strcmp(new_state, "Pending_Approval")==0) {
+ if (PL_strcmp(cur_state, "Disabled") == 0) {
+ // Disabled -> Pending (admin submits for approval with no changes)
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else if ((PL_strcmp(cur_state, "Writing") == 0) && (PL_strcmp(me, cur_writer) == 0)) {
+ // Writing -> Pending. (admin finishes writes after "Submit for Approval")
+ now = PR_Now();
+ PR_snprintf(new_ts, 256, "%lld", now);
+ RA::GetConfigStore()->Add(ts_name, new_ts);
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=4;
+ goto release_and_exit;
+ }
+ } else if (PL_strcmp(new_state, "Writing")==0) {
+ if (PL_strcmp(cur_state, "Disabled") == 0) {
+ // Disabled -> Writing (admin start to write changes - need to save writer)
+ RA::GetConfigStore()->Add(writer_name, me);
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } if ((!agent_must_approve(type)) && (PL_strcmp(cur_state, "Enabled") == 0)) {
+ // Enabled -> Writing (admin start to write changes for case where agent need not approve - need to save writer)
+ RA::GetConfigStore()->Add(writer_name, me);
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=5;
+ goto release_and_exit;
+ }
+ }
+ }
+
+ if (PL_strcmp(who, "Agent")==0) {
+ if (PL_strcmp(new_state, "Disabled")==0) {
+ if ((PL_strcmp(cur_state, "Enabled") == 0) || (PL_strcmp(cur_state, "Pending_Approval") == 0)) {
+ // "Enabled or Pending" to "Disabled", agent disables or rejects
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=6;
+ goto release_and_exit;
+ }
+ } else if (PL_strcmp(new_state, "Enabled")==0) {
+ if ((PL_strcmp(cur_state, "Disabled") == 0) || (PL_strcmp(cur_state, "Pending_Approval") == 0)) {
+ // "Disabled or Pending" to "Enabled", agent approves
+ RA::GetConfigStore()->Add(state_name, new_state);
+ ret=0;
+ goto release_and_exit;
+ } else {
+ ret=7;
+ goto release_and_exit;
+ }
+ } else if (PL_strcmp(new_state, "Pending_Approval")==0) {
+ // no valid transitions for agent
+ ret=8;
+ goto release_and_exit;
+ } else if (PL_strcmp(new_state, "Writing")==0) {
+ // no valid transitions for agent
+ ret=9;
+ goto release_and_exit;
+ }
+ }
+
+release_and_exit:
+ PR_Unlock(config_lock);
+
+ //audit changes
+ char pString[256]="";
+ char msg[256] = "";
+
+ if (PL_strcmp(new_ts, "") != 0) {
+ PR_snprintf(pString, 256, "%s;;%s+%s;;%s", state_name, final_state, ts_name, new_ts);
+ PR_snprintf(msg, 256, "config item state and timestamp changed");
+ } else {
+ PR_snprintf(pString, 256, "%s;;%s", state_name, final_state);
+ PR_snprintf(msg, 256, "config item state changed");
+ }
+ if (ret == 0) {
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, who, "Success", type, pString, msg);
+ } else {
+ PR_snprintf(msg, 256, "config item state or timestamp change failed, return value is %d", ret);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, who, "Failure", type, pString, msg);
+ }
+ return ret;
+}
+
+/**
+ * takes in the type and name of the parameter set
+ * looks up the regular expression pattern for this parameter set in CS.cfg and substitutes
+ * $name with the name of the parameter set.
+ * returns this "fixed" pattern as a string (that must be freed by caller)
+ **/
+char *get_fixed_pattern(char *ptype, char *pname)
+{
+ char configname[256]="";
+ char tmpc[256]="";
+ char *p = NULL;
+ char *fixed_pattern = NULL;
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype );
+ const char* pattern = RA::GetConfigStore()->GetConfigAsString( configname );
+
+ if (pattern == NULL) {
+ tokendbDebug("get_pattern_substore: pattern is NULL");
+ return NULL;
+ }
+
+ if ((p = PL_strstr(pattern, "$name"))) {
+ PL_strncpy(tmpc, pattern, p-pattern);
+ tmpc[p-pattern] = '\0';
+ sprintf(tmpc+(p-pattern), "%s%s", pname, p+PL_strlen("$name"));
+ fixed_pattern = (char *) PL_strdup(tmpc);
+ p = NULL;
+ } else {
+ fixed_pattern=PL_strdup(pattern);
+ }
+
+ tokendbDebug(fixed_pattern);
+
+ return fixed_pattern;
+}
+
+/**
+ * get ConfigStore with entries that match the relevant pattern
+ * must be freed by caller
+ **/
+ConfigStore *get_pattern_substore(char *ptype, char *pname)
+{
+ char *fixed_pattern = NULL;
+ ConfigStore *store = NULL;
+
+ fixed_pattern=get_fixed_pattern(ptype, pname);
+ if (fixed_pattern == NULL) {
+ return NULL;
+ }
+ store = RA::GetConfigStore()->GetPatternSubStore(fixed_pattern);
+
+ do_strfree(fixed_pattern);
+ return store;
+}
+
+/***
+ * parse the parameter string of form foo=bar&&foo2=baz&& ...
+ * and perform (and audit) the changes
+ **/
+void parse_and_apply_changes(char* userid, char* ptype, char* pname, const char *operation, char *params) {
+ char *pair;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+ int op=0;
+ char audit_str[4096] = "";
+ char *fixed_pattern = NULL;
+ regex_t *regex=NULL;
+ int err_no;
+
+ if (PL_strstr(operation, "ADD")) {
+ op=1;
+ } else if (PL_strstr(operation, "DELETE")) {
+ op=2;
+ } else if (PL_strstr(operation, "MODIFY")) {
+ op=3;
+ }
+
+ tokendbDebug(operation);
+
+ // get the correct pattern and regex
+ fixed_pattern = get_fixed_pattern(ptype, pname);
+ if (fixed_pattern == NULL) {
+ tokendbDebug("parse_and_apply_changes: pattern is NULL. Aborting changes ..");
+ return;
+ }
+
+ regex = (regex_t *) malloc(sizeof(regex_t));
+ memset(regex, 0, sizeof(regex_t));
+
+ if((err_no=regcomp(regex, fixed_pattern, 0))!=0) /* Comple the regex */
+ {
+ // Error in computing the regex
+ size_t length;
+ char *buffer;
+ length = regerror (err_no, regex, NULL, 0);
+ buffer = (char *) PR_Malloc(length);
+ regerror (err_no, regex, buffer, length);
+ tokendbDebug("parse_and_apply_changes: error computing the regex, aborting changes");
+ tokendbDebug(buffer);
+ PR_Free(buffer);
+ regfree(regex);
+ return;
+ }
+ size_t no_sub = regex->re_nsub+1;
+ regmatch_t *result = NULL;
+
+ line = PL_strdup(params);
+ pair = PL_strtok_r(line, "&&", &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip1;
+ }
+ if (pair[i] == '\0') {
+ goto skip1;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+
+ result = NULL;
+ result = (regmatch_t *) PR_Malloc(sizeof(regmatch_t) * no_sub);
+ if (regexec(regex, (char *) &pair[0], no_sub, result, 0)!=0) {
+ tokendbDebug("parse_and_apply_changes: parameter does not match pattern. Dropping edit ..");
+ tokendbDebug(&pair[0]);
+ if (result != NULL) {
+ PR_Free(result);
+ result=NULL;
+ }
+ goto skip1;
+ }
+ if (result != NULL) {
+ PR_Free(result);
+ result=NULL;
+ }
+
+ if (op == 1) { //ADD
+ RA::GetConfigStore()->Add(&pair[0], &pair[i+1]);
+ PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter added");
+ } else if (op == 2) { //DELETE
+ RA::GetConfigStore()->Remove(&pair[0]);
+ PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter deleted");
+ } else if (op == 3) { //MODIFY
+ RA::GetConfigStore()->Add(&pair[0], &pair[i+1]);
+ PR_snprintf(audit_str, 4096, "%s;;%s", &pair[0], &pair[i+1]);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", audit_str, "config parameter modified");
+ }
+ skip1:
+ pair = PL_strtok_r(NULL, "&&", &lasts);
+ }
+ do_strfree(line);
+ do_strfree(fixed_pattern);
+}
+
+static int get_time_limit(char *query)
+{
+ char *val = NULL;
+ int ret;
+
+ val = get_field(query, "timeLimit=", SHORT_LEN);
+ if (val == NULL) {
+ return maxTimeLimit;
+ }
+
+ ret = atoi(val);
+ if ((ret == 0) || (ret > maxTimeLimit)) {
+ return maxTimeLimit;
+ }
+ return ret;
+}
+
+static int get_size_limit(char *query)
+{
+ char *val = NULL;
+ int ret;
+
+ val = get_field(query, "sizeLimit=", SHORT_LEN);
+ if (val == NULL) {
+ return maxSizeLimit;
+ }
+
+ ret = atoi(val);
+ if ((ret == 0) || (ret > maxSizeLimit)) {
+ return maxSizeLimit;
+ }
+ return ret;
+}
+
+/**
+ * generate a simple password of at least specified length
+ * containing upper case, lower case and special characters
+ */
+#define PW_MAX_LEN 1024
+
+static char *generatePassword(int length)
+{
+ char choices[80] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*_-+=':;.,";
+ bool pw_ok = false;
+ int i=0;
+ int upper=0, lower=0, number=0, special=0;
+ char pw[PW_MAX_LEN] = "";
+
+ srand(time(0));
+
+ while (!pw_ok) {
+ int x;
+ x = 0 + int(79.0 * rand()/(RAND_MAX+1.0));
+ pw[i] = choices[x];
+ if (isupper(choices[x])) upper ++;
+ if (islower(choices[x])) lower ++;
+ if (isdigit(choices[x])) number ++;
+ if (! isalpha(choices[x])) special ++;
+
+ if ((i >= length) && (upper >=2) && (lower >=2) && (special >=2) && (number >=2))
+ pw_ok = true;
+ i++;
+ if (i == PW_MAX_LEN) {
+ i=0;
+ upper = 0;
+ lower = 0;
+ special =0;
+ number =0;
+ PR_snprintf(pw, PW_MAX_LEN, "");
+ }
+ }
+
+ return PL_strdup(pw);
+}
+
+
+/**
+ * mod_tokendb_handler handles the protocol between the tokendb and the RA
+ */
+static int
+mod_tokendb_handler( request_rec *rq )
+{
+ int sendPieces = 0;
+ int rc = 0;
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ LDAPMod **mods = NULL;
+ char *injection = NULL;
+ char *mNum = NULL;
+ char *buf = NULL;
+ char *uri = NULL;
+ char *query = NULL;
+ char *cert = NULL;
+ char *base64_cert = NULL;
+ char *userid = NULL;
+ char *error = NULL;
+ char *tid = NULL;
+ char *question = NULL;
+ const char *tokentype = NULL;
+
+
+ /* user fields */
+ char *uid = NULL;
+ char *firstName = NULL;
+ char *lastName = NULL;
+ char *opOperator = NULL;
+ char *opAdmin = NULL;
+ char *opAgent = NULL;
+ char *userCert = NULL;
+
+ /* keep track of which menu we are in - operator or agent */
+ char *topLevel = NULL;
+
+ char **attrs = NULL;
+ char **vals = NULL;
+ struct berval **bvals = NULL;
+ int maxReturns;
+ int q;
+ int i, n, len, nEntries, entryNum;
+ int status = LDAP_SUCCESS;
+ int size, tagOffset, statusNum;
+ char fixed_injection[MAX_INJECTION_SIZE];
+ char pString[512] = "";
+ char oString[512] = "";
+ char pLongString[4096] = "";
+ char configname[512] ="";
+ char filter[512] = "";
+ char msg[512] = "";
+ char question_no[100] ="";
+ char cuid[256] = "";
+ char cuidUserId[100]="";
+ char tokenStatus[100]="";
+ char tokenReason[100]="";
+ int token_ui_state= 0;
+ bool show_token_ui_state = false;
+ char serial[100]="";
+ char userCN[256]="";
+ char tokenType[512]="";
+ apr_table_t *post = NULL; /* used for POST data */
+
+ char *statusString = NULL;
+ char *s1, *s2;
+ char *end;
+ struct berval **attr_values = NULL;
+ char *auth_filter = NULL;
+
+ /* authorization */
+ int is_admin = 0;
+ int is_agent = 0;
+ int is_operator = 0;
+
+ int end_val =0;
+ int start_val = 0;
+
+ /* current operation for audit */
+ char *op = NULL;
+
+ RA::Debug( "mod_tokendb_handler::mod_tokendb_handler",
+ "mod_tokendb_handler::mod_tokendb_handler" );
+
+ RA::Debug( "mod_tokendb::mod_tokendb_handler",
+ "uri '%s'", rq->uri);
+
+ /* XXX: We need to change "tus" to "tokendb" */
+ if (strcmp(rq->handler, "tus") != 0) {
+ RA::Debug( "mod_tokendb::mod_tokendb_handler", "DECLINED uri '%s'", rq->uri);
+ return DECLINED;
+ }
+
+ RA::Debug( "mod_tokendb::mod_tokendb_handler",
+ "uri '%s' DONE", rq->uri);
+
+ tokendbDebug( "tokendb request arrived...serving tokendb\n" );
+
+ injection = fixed_injection;
+
+ ap_set_content_type( rq, "text/html" );
+
+ if( !is_tus_db_initialized() ) {
+ tokendbDebug( "token DB was not initialized \n" );
+
+ if( ( status = tus_db_init( &error ) ) != LDAP_SUCCESS ) {
+ if( error != NULL ) {
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"", error,
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ PR_smprintf_free( error );
+ error = NULL;
+ } else {
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"", "NULL",
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+ }
+
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+
+ return DONE;
+ }
+ } else {
+ tokendbDebug( "token DB was initialized\n" );
+ }
+
+ tokendbDebug( "authentication\n" );
+
+ cert = nss_var_lookup( rq->pool,
+ rq->server,
+ rq->connection,
+ rq,
+ ( char * ) "SSL_CLIENT_CERT" );
+ if( cert == NULL ) {
+ error_out("Authentication Failure", "Failed to authenticate request");
+ RA::Audit(EV_AUTH_FAIL, AUDIT_MSG_AUTH, "null", "null", "Failure", "authentication failure, no cert");
+ do_free(buf);
+ return DONE;
+ }
+
+ tokendbDebug( cert );
+ tokendbDebug( "\n" );
+
+ base64_cert = stripBase64HeaderAndFooter( cert );
+
+ tokendbDebug( base64_cert );
+ tokendbDebug( "\n" );
+
+ userid = tus_authenticate( base64_cert );
+
+ if( userid == NULL ) {
+ error_out("Authentication Failure", "Failed to authenticate request");
+
+ SECStatus rv;
+ SECItem certDER;
+ CERTCertificate *c = NULL;
+
+ rv = ATOB_ConvertAsciiToItem(&certDER, base64_cert);
+ if (rv) {
+ RA::Debug("mod_tokendb_handler::mod_tokendb_handler", "Error converting certificate data to binary");
+ } else {
+ c = CERT_DecodeCertFromPackage((char *)certDER.data, certDER.len);
+ }
+
+ RA::Audit(EV_AUTH_FAIL, AUDIT_MSG_AUTH,
+ (c!= NULL) && (c->subjectName != NULL) ? c->subjectName : "null",
+ "null", "Failure", "authentication failure");
+ do_free(buf);
+
+ if (c != NULL) {
+ CERT_DestroyCertificate(c);
+ }
+
+ return DONE;
+ }
+ do_free(base64_cert);
+
+ // useful to indicate cn of user cert
+ RA::Audit(EV_AUTH_SUCCESS, AUDIT_MSG_AUTH, userid, userid, "Success", "authentication success");
+
+ /* authorization */
+ is_admin = tus_authorize(TOKENDB_ADMINISTRATORS_IDENTIFIER, userid);
+ if (is_admin) {
+ RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Admin", "Success", "assume privileged role");
+ }
+
+ is_agent = tus_authorize(TOKENDB_AGENTS_IDENTIFIER, userid);
+ if (is_agent) {
+ RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Agent", "Success", "assume privileged role");
+ }
+
+ is_operator = tus_authorize(TOKENDB_OPERATORS_IDENTIFIER, userid);
+ if (is_operator) {
+ RA::Audit(EV_ROLE_ASSUME, AUDIT_MSG_ROLE, userid, "Tokendb Operator", "Success", "assume privileged role");
+ }
+
+ if( rq->uri != NULL ) {
+ uri = PL_strdup( rq->uri );
+ }
+
+ if (rq->method_number == M_POST) {
+ status = read_post(rq, &post);
+ if(post && !apr_is_empty_table(post)) {
+ query = PL_strdup( apr_table_get(post, "query"));
+ }
+ } else {
+ /* GET request */
+ if( rq->args != NULL ) {
+ query = PL_strdup( rq->args );
+ }
+ }
+
+ RA::Debug( "mod_tokendb_handler::mod_tokendb_handler",
+ "uri='%s' params='%s'",
+ uri, ( query==NULL?"":query ) );
+
+ if( query == NULL ) {
+ char *itemplate = NULL;
+ tokendbDebug( "authorization for index case\n" );
+ if (is_agent) {
+ itemplate = indexTemplate;
+ } else if (is_operator) {
+ itemplate = indexOperatorTemplate;
+ } else if (is_admin) {
+ itemplate = indexAdminTemplate;
+ } else {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n" );
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( itemplate, injection );
+ itemplate = NULL;
+ } else if( ( PL_strstr( query, "op=index_operator" ) ) ) {
+ tokendbDebug( "authorization for op=index_operator\n" );
+ if (!is_operator) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index_operator", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index_operator", "Success", "Tokendb user authorization");
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexOperatorTemplate, injection );
+ } else if( ( PL_strstr( query, "op=index_admin" ) ) ) {
+ tokendbDebug( "authorization\n" );
+ if (!is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "index_admin", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "index_admin", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n" );
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexAdminTemplate, injection );
+ } else if( ( PL_strstr( query, "op=do_token" ) ) ) {
+ tokendbDebug( "authorization for do_token\n" );
+
+ if( !is_agent ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "do_token", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "do_token", "Success", "Tokendb user authorization");
+
+ /* XXX - chrisho */
+ /* op=do_token */
+ /* question=1|2|... */
+ /* tid=cuid */
+
+ tokendbDebug( "print query\n" );
+ tokendbDebug( query );
+ tokendbDebug( "\n" );
+
+ tid = PL_strstr( query, "tid=" );
+ if( tid != NULL ) {
+ end = PL_strchr( tid, '&' );
+ if( end != NULL ) {
+ i = end - tid - 4;
+ if( i > 0 ) {
+ memcpy( cuid, tid+4, i );
+ }
+ cuid[i] = '\0';
+ } else {
+ PL_strcpy( cuid, tid+4 );
+ }
+ }
+
+ tokendbDebug( "cuid:" );
+ tokendbDebug( cuid );
+ tokendbDebug( "\n" );
+ question = PL_strstr( query, "question=" );
+ q = question[9] - '0';
+
+ PR_snprintf( question_no, 256, "%d", q );
+
+ tokendbDebug( "question_no:" );
+ tokendbDebug( question_no );
+
+ rc = find_tus_db_entry( cuid, 1, &result );
+ if( rc == 0 ) {
+ e = get_first_entry( result );
+ if( e != NULL ) {
+ attr_values = get_attribute_values( e, "tokenUserID" );
+ tokendbDebug( "cuidUserId:" );
+ if (valid_berval(attr_values)) {
+ PL_strcpy( cuidUserId, attr_values[0]->bv_val );
+ tokendbDebug( cuidUserId );
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else
+ tokendbDebug("null");
+
+ attr_values = get_attribute_values( e, "tokenType" );
+ tokendbDebug( "tokenType:" );
+ if (valid_berval(attr_values)) {
+ PL_strcpy( tokenType, attr_values[0]->bv_val );
+ tokendbDebug( tokenType );
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else
+ tokendbDebug("null");
+
+ attr_values = get_attribute_values( e, "tokenStatus" );
+ tokendbDebug( "tokenStatus:" );
+ if (valid_berval(attr_values)) {
+ PL_strcpy( tokenStatus, attr_values[0]->bv_val );
+ tokendbDebug( tokenStatus );
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else
+ tokendbDebug("null");
+
+ attr_values = get_attribute_values( e, "tokenReason" );
+ tokendbDebug( "tokenReason:" );
+ if (valid_berval(attr_values)) {
+ PL_strcpy( tokenReason, attr_values[0]->bv_val );
+ tokendbDebug( tokenReason );
+ free_values(attr_values, 1);
+ attr_values = NULL;
+ } else
+ tokendbDebug("null");
+ }
+ }
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ token_ui_state = get_token_ui_state(tokenStatus, tokenReason);
+
+ /* Is this token physically damaged */
+ if(( q == 1 ) && (transition_allowed(token_ui_state, 1))) {
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked token physically damaged", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ /* get the certificates on this lost token */
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+
+ if( strcmp( attr_status, "revoked" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "destroyed.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "destroyed.revokeCert.reason",
+ attr_tokenType, attr_keyType );
+
+ char *revokeReason = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname,
+ "0" ) );
+
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ statusNum = certEnroll->RevokeCertificate(revokeReason,
+ serial, connid, statusString );
+
+ if (statusNum != 0) { // revocation errors
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoked_on_hold", serial, connid, statusString);
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ }
+ } else {
+ // update certificate status
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked_on_hold" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoked_on_hold", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ }
+ }
+
+ if( attr_cn != NULL ) {
+ PL_strfree( attr_cn );
+ attr_cn = NULL;
+ }
+ do_free(statusString);
+ }
+
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ }
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+
+ }
+
+ /* change the tokenStatus to lost (reason: destroyed). */
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "lost", "destroyed" );
+ if( rc == -1 ) {
+ tokendbDebug( "token is physically damaged. rc = -1\n" );
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed");
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked physically damaged, rc=-1");
+
+ PR_snprintf((char *)msg, 256, "Failed to update token status as physically damaged");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s", JS_START,
+ "var error = \"Failed to create LDAPMod: ",
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "Failed to create LDAPMod" );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ } else if( rc > 0 ) {
+ tokendbDebug( "token is physically damaged. rc > 0\n" );
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed");
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked physically damaged, rc>0");
+
+ PR_snprintf((char *)msg, 256, "Failed to update token status as physically damaged");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"LDAP mod error: ",
+ ldap_err2string( rc ),
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP error: %s",
+ ldap_err2string( rc ) );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;destroyed");
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked physically damaged");
+
+ PR_snprintf((char *)msg, 256, "Token marked as physically damaged");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+
+ /* Is this token permanently lost? */
+ } else if(((q == 2) && (transition_allowed(token_ui_state, 2))) ||
+ ((q == 6) && (transition_allowed(token_ui_state, 6)))) {
+ if (q == 2) {
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked token permanently lost", userid);
+ } else {
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked token terminated", userid);
+ }
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ /* get the certificates on this lost token */
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+
+ if( strcmp( attr_status, "revoked" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "keyCompromise.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "keyCompromise.revokeCert.reason",
+ attr_tokenType, attr_keyType );
+
+ char *revokeReason = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname,
+ "1" ) );
+
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ statusNum = certEnroll->
+ RevokeCertificate( revokeReason,
+ serial,
+ connid,
+ statusString );
+ if (statusNum != 0) { // revocation errors
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoked_on_hold", serial, connid, statusString);
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ }
+ } else {
+ // update certificate status
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked_on_hold" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoked_on_hold", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ }
+ }
+
+ if( attr_cn != NULL ) {
+ PL_strfree( attr_cn );
+ attr_cn = NULL;
+ }
+ do_free(statusString);
+ }
+
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ }
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+ }
+
+ /* revoke all the certs on the token. make http connection to CA */
+
+ /* change the tokenStatus to lost (reason: keyCompromise) */
+ tokendbDebug( "Revoke all the certs on this token "
+ "(reason: keyCompromise)\n" );
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+
+ if (q == 6) { /* terminated */
+ PR_snprintf(pString, 512, "tokenStatus;;terminated+tokenReason;;keyCompromise");
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "terminated", "keyCompromise" );
+ } else {
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;keyCompromise");
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "lost", "keyCompromise" );
+ }
+ if( rc == -1 ) {
+ if (q == 6) { /* terminated*/
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked terminated, rc=-1");
+ PR_snprintf((char *)msg, 256, "Failure in updating token status to terminated");
+ } else {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked permanently lost, rc=-1");
+ PR_snprintf((char *)msg, 256, "Failure in updating token status to permanently lost");
+ }
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s", JS_START,
+ "var error = \"Failed to create LDAPMod: ",
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "Failed to create LDAPMod" );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ } else if( rc > 0 ) {
+ if (q == 6) { /* terminated*/
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked terminated, rc=>0");
+ PR_snprintf((char *)msg, 256, "Failure in updating token status to terminated");
+ } else {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked permanently lost, rc>0");
+ PR_snprintf((char *)msg, 256, "Failure in updating token status to permanently lost");
+ }
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"LDAP mod error: ",
+ ldap_err2string( rc ),
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP error: %s",
+ ldap_err2string( rc ) );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ if (q == 6) { /* terminated*/
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked terminated");
+ PR_snprintf((char *)msg, 256, "Token marked terminated");
+ } else {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked permanently lost");
+ PR_snprintf((char *)msg, 256, "Token marked permanently lost");
+ }
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+
+ /* Is this token temporarily lost? */
+ } else if(( q == 3 ) && (transition_allowed(token_ui_state, 3))) {
+ bool revocation_errors = false;
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked token temporarily lost", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ /* all certs on the token are revoked (onHold) */
+ tokendbDebug( "Revoke all the certs on this token "
+ "(reason: onHold)\n" );
+
+ /* get the certificates on this lost token */
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+ if( strcmp( attr_status, "revoked" ) == 0 ||
+ strcmp( attr_status, "revoked_on_hold" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "onHold.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery.onHold."
+ "revokeCert.reason",
+ attr_tokenType, attr_keyType );
+
+ char *revokeReason = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname,
+ "0" ) );
+
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ statusNum = certEnroll->
+ RevokeCertificate( revokeReason,
+ serial,
+ connid,
+ statusString );
+
+ if (statusNum != 0) { // revocation errors
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Errors in marking certificate on_hold '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoked_on_hold", serial, connid, statusString);
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in revoking certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ }
+ revocation_errors = true;
+ } else {
+ // update certificate status
+ if( strcmp( revokeReason, "6" ) == 0 ) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked_on_hold", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked_on_hold" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoked_on_hold", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ }
+ }
+
+ do_free(statusString);
+ }
+
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ }
+
+ if (result != NULL) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+
+ }
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;onHold");
+ if (revocation_errors) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost failed, failed to revoke certificates");
+
+ PR_snprintf((char *)msg, 256, "Failed to revoke certificates");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ error_out("Errors in revoking certificates.", "Errors in revoking certificates.");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "lost", "onHold" );
+ if( rc == -1 ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost, rc=-1");
+
+ PR_snprintf((char *)msg, 256, "Failed to update token status as temporarily lost");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s", JS_START,
+ "var error = \"Failed to create LDAPMod: ",
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "Failed to create LDAPMod" );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ } else if( rc > 0 ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "token marked temporarily lost, rc>0");
+
+ PR_snprintf((char *)msg, 256, "Failed to update token status as temporarily lost");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s", JS_START,
+ "var error = \"LDAP mod error: ",
+ ldap_err2string( rc ),
+ "\";\n", JS_STOP );
+
+ buf = getData( errorTemplate, injection );
+
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP error: %s",
+ ldap_err2string( rc ) );
+
+ ( void ) ap_rwrite( ( const void * ) buf,
+ PL_strlen( buf ), rq );
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "token marked temporarily lost");
+ PR_snprintf((char *)msg, 256, "Token marked temporarily lost");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+
+ /* Is this temporarily lost token found? */
+ } else if(( q == 4 ) && ( transition_allowed(token_ui_state, 4) )) {
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked lost token found", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ tokendbDebug( "The temporarily lost token is found.\n" );
+
+ // to find out the tokenType on this lost token
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ /* all certs on the token are unrevoked (offHold) */
+ /* get the certificates on this lost token */
+ tokendbDebug( "Offhold all the certificates on "
+ "the temp lost token." );
+
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+ if( strcmp( attr_status, "active" ) == 0 ||
+ strcmp( attr_status, "revoked" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "onHold.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ int statusNum = certEnroll->
+ UnrevokeCertificate( serial,
+ connid,
+ statusString );
+
+ if (statusNum == 0) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as active", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "active" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "unrevoke", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in unrevoking Certificate '%s': %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "unrevoke", serial, connid, statusString);
+ }
+
+ if( attr_cn != NULL ) {
+ PL_strfree( attr_cn );
+ attr_cn = NULL;
+ }
+
+ do_free(statusString);
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ } // end of for loop
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+ }
+
+ update_token_status_reason( cuidUserId, cuid, "active", NULL );
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;active+tokenReason;;null");
+
+ if( rc == -1 ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "lost token marked found, rc=-1");
+ PR_snprintf((char *)msg, 256, "Failed to update lost token status as found");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ error_out("Failed to create LDAPMod: ", "Failed to create LDAPMod");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ } else if( rc > 0 ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pString, "lost token marked found, rc>0");
+ PR_snprintf((char *)msg, 256, "Failed to update lost token status as found");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure",
+ msg, cuidUserId, tokenType);
+
+ ldap_error_out("LDAP mod error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "lost token marked found");
+ PR_snprintf((char *)msg, 256, "Lost token marked found");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+
+ /* Does this temporarily lost token become permanently lost? */
+ } else if ( (q == 5) && (transition_allowed(token_ui_state, 5)) ) {
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' marked lost token permanently lost", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated",
+ msg, cuidUserId, tokenType);
+
+ tokendbDebug( "Change the revocation reason from onHold "
+ "to keyCompromise\n" );
+
+ // to find out the tokenType on this lost token
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ /* revoke all the certs on this token (reason: keyCompromise) */
+ tokendbDebug( "Revoke all the certs on this token "
+ "(reason: keyCompromise)\n" );
+
+ /* get the certificates on this lost token */
+ PR_snprintf( ( char * ) filter, 256,
+ "(&(tokenID=%s)(tokenUserID=%s))",
+ cuid, cuidUserId );
+
+ rc = find_tus_certificate_entries_by_order_no_vlv( filter,
+ &result, 1 );
+ if( rc == 0 ) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for( e = get_first_entry(result);
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *attr_status = get_cert_status( e );
+ if( strcmp( attr_status, "revoked" ) == 0 ) {
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+ continue;
+ }
+
+ char *attr_serial= get_cert_serial( e );
+ char *attr_tokenType = get_cert_tokenType( e );
+ char *attr_keyType = get_cert_type( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "keyCompromise.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, true );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "keyCompromise.revokeCert.reason",
+ attr_tokenType, attr_keyType );
+
+ char *revokeReason = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname,
+ "1" ) );
+
+ if( revokeCert ) {
+ char *attr_cn = get_cert_cn( e );
+
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ ( RA::GetConfigStore()->
+ GetConfigAsString( configname ) );
+
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ int statusNum = 0;
+ if(( strcmp( attr_status, "revoked_on_hold" ) == 0 ) && (strcmp(revokeReason, "6" ) != 0)) {
+ statusNum = certEnroll->
+ UnrevokeCertificate( serial,
+ connid,
+ statusString );
+ if (statusNum == 0) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as active", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "initiated", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "active" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "unrevoke", serial, connid, "");
+
+ do_free(statusString);
+ statusNum = certEnroll->
+ RevokeCertificate( revokeReason,
+ serial,
+ connid,
+ statusString );
+ if (statusNum == 0) {
+ PR_snprintf((char *)msg, 256, "Certificate '%s' is marked as revoked", attr_cn);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success", msg, cuidUserId, attr_tokenType);
+ update_cert_status( attr_cn, "revoked" );
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in revoking Certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ }
+ } else {
+ PR_snprintf((char *)msg, 256, "Errors in unrevoking Certificate '%s' : %s", attr_cn, statusString);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "failure", msg, cuidUserId, attr_tokenType);
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "unrevoke", serial, connid, statusString);
+ }
+
+ do_free(statusString);
+ }
+
+ if( attr_cn != NULL ) {
+ PL_strfree( attr_cn );
+ attr_cn = NULL;
+ }
+ }
+
+ if( attr_serial != NULL ) {
+ PL_strfree( attr_serial );
+ attr_serial = NULL;
+ }
+
+ if( attr_tokenType != NULL ) {
+ PL_strfree( attr_tokenType );
+ attr_tokenType = NULL;
+ }
+
+ if( attr_keyType != NULL ) {
+ PL_strfree( attr_keyType );
+ attr_keyType = NULL;
+ }
+ } // end of the for loop
+
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+ }
+
+ rc = update_token_status_reason( cuidUserId, cuid,
+ "lost", "keyCompromise" );
+
+ PR_snprintf(oString, 512, "token_id;;%s", cuid);
+ PR_snprintf(pString, 512, "tokenStatus;;lost+tokenReason;;keyCompromise");
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pString, "lost token marked permanently lost");
+
+ PR_snprintf((char *)msg, 256, "Lost token marked permanently lost");
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "do_token", "success",
+ msg, cuidUserId, tokenType);
+ } else {
+ // invalid operation or transition
+ error_out("Transition or operation not allowed", "Transition or operation not allowed");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ tokendbDebug( "do_token: rc = 0\n" );
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%d%s%s%s%s%s%s%s", JS_START,
+ "var rc = \"", rc, "\";\n",
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+
+ add_allowed_token_transitions(token_ui_state, injection);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( doTokenTemplate, injection );
+/* currently not used - alee
+ } else if( ( PL_strstr( query, "op=revoke" ) ) ) {
+ tokendbDebug("authorization\n");
+
+ if( ! is_agent ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "revoke", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "revoke", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( revokeTemplate, injection );
+*/
+ } else if( ( PL_strstr( query, "op=search_activity_admin" ) ) ) {
+ tokendbDebug( "authorization\n" );
+
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_activity_admin", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_activity_admin", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( searchActivityAdminTemplate, injection );
+ } else if( ( PL_strstr( query, "op=search_activity" ) ) ) {
+ tokendbDebug( "authorization\n" );
+
+ if ((! is_agent) && (! is_operator)) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_activity", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_activity", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+
+ topLevel = get_field(query, "top=", SHORT_LEN);
+ if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) {
+ PL_strcat(injection, "var topLevel = \"operator\";\n");
+ }
+ do_free(topLevel);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( searchActivityTemplate, injection );
+ } else if( ( PL_strstr( query, "op=search_admin" ) ) ||
+ ( PL_strstr( query, "op=search_users" ) )) {
+ tokendbDebug( "authorization\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_admin,search_users", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_admin,search_users", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ if ( PL_strstr( query, "op=search_admin" ) ) {
+ buf = getData( searchAdminTemplate, injection );
+ } else if ( PL_strstr( query, "op=search_users" ) ) {
+ buf = getData( searchUserTemplate, injection );
+ }
+ } else if ( PL_strstr( query, "op=search_certificate" ) ) {
+ tokendbDebug( "authorization\n" );
+ if ((! is_agent) && (! is_operator)) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search_certificate", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search_certificate", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n");
+
+ topLevel = get_field(query, "top=", SHORT_LEN);
+ if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) {
+ PL_strcat(injection, "var topLevel = \"operator\";\n");
+ }
+ do_free(topLevel);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( searchCertificateTemplate, injection );
+ } else if( ( PL_strstr( query, "op=search" ) ) ) {
+ tokendbDebug( "authorization for op=search\n" );
+ if ((! is_agent) && (! is_operator)) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "search", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "search", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n");
+
+ topLevel = get_field(query, "top=", SHORT_LEN);
+ if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) {
+ PL_strcat(injection, "var topLevel = \"operator\";\n");
+ }
+ do_free(topLevel);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( searchTemplate, injection );
+ } else if( ( PL_strstr( query, "op=new" ) ) ) {
+ tokendbDebug( "authorization\n" );
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "new", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "new", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n" );
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( newTemplate,injection );
+ } else if ( ( PL_strstr( query, "op=add_user" ) ) ) {
+ tokendbDebug( "authorization for add_user\n" );
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_user", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_user", "Success", "Tokendb user authorization");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid,
+ "\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( newUserTemplate,injection );
+
+ } else if ( ( PL_strstr( query, "op=confirm_delete_config" ) ) ) {
+ tokendbDebug( "authorization for confirm_delete_config\n" );
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "confirm_delete_config", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "confirm_delete_config", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *ptimestamp = NULL;
+ char *pvalues = NULL;
+ char *large_injection = NULL;
+ char *pstate = NULL;
+ char *disp_conf_type = NULL;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ pstate = get_post_field(post, "pstate", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ pvalues = get_post_field_s(post, "pvalues");
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ large_injection = (char *) PR_Malloc(PL_strlen(pvalues) + MAX_INJECTION_SIZE);
+ PR_snprintf( large_injection, PL_strlen(pvalues) + MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_state = \"", pstate, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n",
+ "var conf_values= \"", pvalues, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection);
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( confirmDeleteConfigTemplate, large_injection );
+
+ do_free(ptype);
+ do_free(pname);
+ do_free(ptimestamp);
+ do_free(pvalues);
+ do_free(pstate);
+ do_free(large_injection);
+ } else if( ( PL_strstr( query, "op=delete_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=delete_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "delete_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "delete_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *ptimestamp = NULL;
+
+ char *key_values = NULL;
+ char *new_value = NULL;
+ char *conf_list = NULL;
+ ConfigStore *store = NULL;
+ int return_done = 0;
+ int status=0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL) || (PL_strlen(pname)==0) || (PL_strlen(ptype)==0)) {
+ error_out("Invalid Invocation: Parameter type or name is NULL or empty", "Parameter type or name is NULL or empty");
+ return_done = 1;
+ goto delete_config_parameter_cleanup;
+ }
+
+ if (!config_param_exists(ptype, pname)) {
+ error_out("Parameter does not exist", "Parameter does not exist");
+ return_done = 1;
+ goto delete_config_parameter_cleanup;
+ }
+
+ status = set_config_state_timestamp(ptype, pname, ptimestamp, "Writing", "Admin", false, userid);
+ if (status != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto delete_config_parameter_cleanup;
+ }
+
+ store = get_pattern_substore(ptype, pname);
+
+ key_values = (char *) store->GetOrderedList();
+ if (PL_strlen(key_values) > 0) parse_and_apply_changes(userid, ptype, pname, "DELETE", key_values);
+
+ // remove from the list for that config type
+ PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype );
+ conf_list = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+ new_value = RA::remove_from_comma_list((const char*) pname, (char *)conf_list);
+ RA::GetConfigStore()->Add(configname, new_value);
+
+ // remove state and timestamp variables
+ remove_config_state_timestamp(ptype, pname);
+
+ tokendbDebug("Committing delete ..");
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(true, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+
+ PR_snprintf(oString, 512, "%s", pname);
+ PR_snprintf(pLongString, 4096, "%s;;%s", configname, new_value);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, pLongString, "config item deleted");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var flash = \"Configuration changes have been saved.\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexTemplate, injection );
+ delete_config_parameter_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_free(key_values);
+ do_free(new_value);
+ do_free(ptimestamp);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ } else if( ( PL_strstr( query, "op=add_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=add_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+
+ ConfigStore *store = NULL;
+ char *pattern = NULL;
+ char *disp_conf_type = NULL;
+ int return_done =0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL) || (PL_strlen(pname)==0) || (PL_strlen(ptype)==0)) {
+ error_out("Invalid Invocation: Parameter type or name is NULL or empty", "Parameter type or name is NULL or empty");
+ return_done = 1;
+ goto add_config_parameter_cleanup;
+ }
+
+ if (config_param_exists(ptype, pname)) {
+ error_out("Parameter already exists. Use edit instead.", "Parameter already exists");
+ return_done = 1;
+ goto add_config_parameter_cleanup;
+ }
+
+ /* extra check (just in case) */
+ store = get_pattern_substore(ptype, pname);
+
+ if ((store != NULL) && (store->Size() != 0)) {
+ error_out("Config entries already exist for this parameter. This is an error. Manually delete them first.", "Setup Error");
+ return_done = 1;
+ goto add_config_parameter_cleanup;
+ }
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype );
+ pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_pattern = \"", pattern, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed?
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( addConfigTemplate, injection );
+ add_config_parameter_cleanup:
+ do_free(ptype);
+ do_free(pname);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=agent_change_config_state" ) ) ) {
+ tokendbDebug( "authorization for op=agent_change_config_state\n" );
+ if (! is_agent) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_change_config_state", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_change_config_state", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *ptimestamp = NULL;
+ char *choice = NULL;
+
+ char pstate[128]="";
+ int return_done =0;
+ int set_status = 0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ choice = get_post_field(post, "choice", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL) || (ptimestamp == NULL) || (choice == NULL)) {
+ error_out("Invalid Invocation: A required parameter is NULL", "Invalid Invocation: A required parameter is NULL");
+ return_done=1;
+ goto agent_change_config_state_cleanup;
+ }
+
+ // check if agent has permission to see this config parameter
+ if (!agent_must_approve(ptype)) {
+ error_out("Invalid Invocation: Agent is not permitted to change the state of this configuration item",
+ "Invalid Invocation: Agent is not permitted to change the state of this configuration item");
+ return_done=1;
+ goto agent_change_config_state_cleanup;
+ }
+
+ if ((PL_strcmp(choice, "Disable") == 0) || (PL_strcmp(choice, "Reject") == 0)) {
+ PR_snprintf(pstate, 128, "Disabled");
+ } else {
+ PR_snprintf(pstate, 128, "Enabled");
+ }
+
+ set_status = set_config_state_timestamp(ptype, pname, ptimestamp, pstate, "Agent", false, userid);
+
+ if (set_status != 0) {
+ error_out("The data you are viewing has been changed by an administrator and is out of date. Please reload the data and try again.",
+ "Data Out of Date");
+ return_done=1;
+ goto agent_change_config_state_cleanup;
+ }
+
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(false, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var flash = \"Configuration changes have been saved.\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexTemplate, injection );
+ agent_change_config_state_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_strfree(ptimestamp);
+ do_strfree(choice);
+
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ } else if( ( PL_strstr( query, "op=agent_view_config" ) ) ) {
+ tokendbDebug( "authorization for op=agent_view_config\n" );
+ if (! is_agent) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_view_config", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_view_config", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *pstate = NULL;
+ char *ptimestamp = NULL;
+ char *disp_conf_type = NULL;
+ int return_done = 0;
+
+ char *key_values = NULL;
+ char *large_injection = NULL;
+ char *escaped = NULL;
+ ConfigStore *store = NULL;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL)) {
+ error_out("Invalid Invocation: Parameter type or name is NULL", "Invalid Invocation: Parameter type or name is NULL");
+ return_done =1;
+ goto agent_view_config_cleanup;
+ }
+
+ // check if agent has permission to see this config parameter
+ if (! agent_must_approve(ptype)) {
+ error_out("Invalid Invocation: Agent is not permitted to view this configuration item",
+ "Invalid Invocation: Agent is not permitted to view this configuration item");
+ return_done =1;
+ goto agent_view_config_cleanup;
+ }
+
+ get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp);
+
+ store = get_pattern_substore(ptype, pname);
+
+ if (store == NULL) {
+ error_out("Setup Error: Pattern Substore is NULL", "Pattern Substore is NULL");
+ return_done =1;
+ goto agent_view_config_cleanup;
+ }
+
+ key_values = (char *) store->GetOrderedList();
+ escaped = escapeSpecialChars(key_values);
+ tokendbDebug( "got ordered list");
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ large_injection = (char *) PR_Malloc(PL_strlen(key_values) + MAX_INJECTION_SIZE);
+ PR_snprintf( large_injection, PL_strlen(key_values) + MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_state = \"", pstate, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var conf_values= \"", escaped, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed?
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( agentViewConfigTemplate, large_injection );
+ agent_view_config_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_free(pstate);
+ do_free(ptimestamp);
+ do_free(key_values);
+ do_free(large_injection);
+ do_strfree(escaped);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+
+ if (return_done != 0 ) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=edit_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=edit_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "edit_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "edit_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+
+ char *pstate = NULL;
+ char *ptimestamp = NULL;
+ char *key_values = NULL;
+ char *escaped = NULL;
+ ConfigStore *store = NULL;
+ char *large_injection = NULL;
+ char *pattern = NULL;
+ char *disp_conf_type = NULL;
+ int return_done = 0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL)) {
+ error_out("Invalid Invocation: Parameter type or name is NULL", "Invalid Invocation: Parameter type or name is NULL");
+ return_done =1;
+ goto edit_config_parameter_cleanup;
+ }
+
+ get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp);
+ tokendbDebug(pstate);
+ tokendbDebug(ptimestamp);
+
+ store = get_pattern_substore(ptype, pname);
+
+ if (store == NULL) {
+ error_out("Setup Error", "Pattern Substore is NULL");
+ return_done =1;
+ goto edit_config_parameter_cleanup;
+ }
+
+ key_values = (char *) store->GetOrderedList();
+ //escaped = escapeSpecialChars(key_values);
+ escaped = escapeString(key_values);
+ tokendbDebug( "got ordered list");
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype );
+ pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ large_injection = (char *) PR_Malloc(PL_strlen(key_values) + MAX_INJECTION_SIZE);
+ PR_snprintf( large_injection, PL_strlen(key_values) + MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_state = \"", pstate, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n",
+ "var conf_pattern = \"", pattern, "\";\n",
+ "var conf_values= \"", escaped, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed?
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( editConfigTemplate, large_injection );
+ edit_config_parameter_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_strfree(ptimestamp);
+ do_strfree(pstate);
+ do_free(large_injection);
+ do_free(key_values);
+ do_strfree(escaped);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=return_to_edit_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=return_to_edit_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "return_to_edit_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "return_to_edit_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *pstate = NULL;
+ char *ptimestamp = NULL;
+ char *pvalues = NULL;
+
+ char *large_injection = NULL;
+ char *pattern = NULL;
+ char *disp_conf_type = NULL;
+ int return_done = 0;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ pstate = get_post_field(post, "pstate", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ pvalues = get_post_field_s(post, "pvalues");
+
+ if ((ptype == NULL) || (pname == NULL) || (pstate == NULL) || (ptimestamp == NULL) || (pvalues == NULL)) {
+ error_out("Invalid Invocation: A required parameter is missing", "Invalid Invocation: A required parameter is missing");
+ return_done =1;
+ goto return_to_edit_config_parameter_cleanup;
+ }
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.pattern", ptype );
+ pattern = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+
+ large_injection = (char *) PR_Malloc(PL_strlen(pvalues) + MAX_INJECTION_SIZE);
+ PR_snprintf( large_injection, PL_strlen(pvalues) + MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_state = \"", pstate, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var agent_must_approve = \"", agent_must_approve(ptype)? "true": "false", "\";\n",
+ "var conf_pattern = \"", pattern, "\";\n",
+ "var conf_values= \"", pvalues, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed?
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( editConfigTemplate, large_injection );
+ return_to_edit_config_parameter_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_free(ptimestamp);
+ do_free(pstate);
+ do_free(pvalues);
+ do_free(large_injection);
+
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=confirm_config_changes" ) ) ) {
+ tokendbDebug( "authorization for op=confirm_config_changes\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "confirm_config_changes", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "confirm_config_changes", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *pvalues = NULL;
+ char *ptimestamp = NULL;
+ char *choice = NULL;
+
+ char *cur_ts = NULL;
+ char *cur_state = NULL;
+ char *changed_str = NULL;
+ char *added_str = NULL;
+ char *deleted_str = NULL;
+ char *escaped_deleted_str = NULL;
+ char *escaped_added_str = NULL;
+ char *escaped_changed_str = NULL;
+ char *escaped_pvalues = NULL;
+ char *disp_conf_type = NULL;
+ int return_done=0;
+ char flash[512]="";
+
+ char *pair = NULL;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+ char *value = NULL;
+ ConfigStore *store = NULL;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ escaped_pvalues = get_post_field_s(post, "pvalues");
+ choice = get_post_field(post, "choice", SHORT_LEN);
+
+ if ((ptype == NULL) || (pname == NULL) || (escaped_pvalues == NULL) || (ptimestamp == NULL)) {
+ error_out("Invalid Invocation: A required parameter is NULL", "A required parameter is NULL");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+
+ tokendbDebug(ptype);
+ tokendbDebug(pname);
+
+ if (PL_strlen(escaped_pvalues) == 0) {
+ error_out("Empty Data not allowed. Use Delete Parameter instead", "Empty Data");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+
+ get_config_state_timestamp(ptype, pname, &cur_state, &cur_ts);
+ if (PL_strcmp(cur_ts, ptimestamp) != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+
+
+ store = get_pattern_substore(ptype, pname);
+ if (store == NULL) {
+ error_out("Setup Error", "Pattern Substore is NULL");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+
+ // parse the pvalues string of form foo=bar&&foo2=baz&& ...
+ pvalues = unescapeString(escaped_pvalues);
+ changed_str = (char*) PR_Malloc(PL_strlen(pvalues));
+ added_str = (char*) PR_Malloc(PL_strlen(pvalues));
+
+ PR_snprintf(changed_str, PL_strlen(pvalues),"");
+ PR_snprintf(added_str, PL_strlen(pvalues), "");
+
+ line = PL_strdup(pvalues);
+ pair = PL_strtok_r(line, "&&", &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip;
+ }
+ if (pair[i] == '\0') {
+ goto skip;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+ if ((value= (char *) store->GetConfigAsString(&pair[0]))) { // key exists
+ if (PL_strcmp(value, &pair[i+1]) != 0) {
+ // value has changed
+ PR_snprintf(changed_str, PL_strlen(pvalues), "%s%s%s=%s", changed_str,
+ (PL_strlen(changed_str) != 0) ? "&&" : "",
+ &pair[0], &pair[i+1]);
+ }
+ store->Remove(&pair[0]);
+ } else { // new key
+ PR_snprintf(added_str, PL_strlen(pvalues), "%s%s%s=%s", added_str,
+ (PL_strlen(added_str) != 0) ? "&&" : "",
+ &pair[0], &pair[i+1]);
+ }
+ skip:
+ pair = PL_strtok_r(NULL, "&&", &lasts);
+ }
+
+ // remaining entries have been deleted
+ deleted_str = (char *) store->GetOrderedList();
+
+ //escape special characters
+ escaped_deleted_str = escapeString(deleted_str);
+ escaped_added_str = escapeString(added_str);
+ escaped_changed_str = escapeString(changed_str);
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", ptype );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ if ((PL_strlen(escaped_added_str) + PL_strlen(escaped_changed_str) + PL_strlen(escaped_deleted_str))!=0) {
+ int injection_size = PL_strlen(escaped_deleted_str) + PL_strlen(escaped_pvalues) + PL_strlen(escaped_added_str) +
+ PL_strlen(escaped_changed_str) + MAX_INJECTION_SIZE;
+ char * large_injection = (char *) PR_Malloc(injection_size);
+
+ PR_snprintf( large_injection, injection_size,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", ptype, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_name = \"", pname, "\";\n",
+ "var conf_tstamp = \"", ptimestamp, "\";\n",
+ "var conf_state = \"", cur_state, "\";\n",
+ "var conf_values = \"", escaped_pvalues, "\";\n",
+ "var added_str= \"", escaped_added_str, "\";\n",
+ "var changed_str= \"", escaped_changed_str, "\";\n",
+ "var conf_approval_requested = \"", (PL_strcmp(choice, "Save") == 0) ? "FALSE" : "TRUE", "\";\n",
+ "var deleted_str= \"", escaped_deleted_str, "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, large_injection); //needed?
+ PL_strcat(large_injection, JS_STOP);
+
+ buf = getData( confirmConfigChangesTemplate, large_injection );
+
+ do_free(large_injection);
+
+ } else {
+ // no changes need to be saved
+
+ if (PL_strcmp(choice, "Save") != 0) {
+ int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Pending_Approval", "Admin", false, userid);
+ if (status != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto confirm_config_changes_cleanup;
+ }
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(false, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+
+ PR_snprintf(flash, 512, "Configuration Parameters have been submitted for Agent Approval");
+ } else {
+ PR_snprintf(flash, 512, "The data displayed is up-to-date. No changes need to be saved.");
+ }
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var flash = \"", flash , "\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+ buf = getData( indexTemplate, injection );
+ }
+
+ confirm_config_changes_cleanup:
+ do_strfree(cur_state);
+ do_strfree(cur_ts);
+ do_free(changed_str);
+ do_free(added_str);
+ do_free(deleted_str);
+ do_strfree(escaped_deleted_str);
+ do_strfree(escaped_added_str);
+ do_strfree(escaped_changed_str);
+ do_strfree(escaped_pvalues);
+ do_free(ptype);
+ do_free(pname);
+ do_free(pvalues);
+ do_free(ptimestamp);
+ do_free(choice);
+ do_strfree(line);
+
+ if (store != NULL) {
+ delete store;
+ store = NULL;
+ }
+ if (return_done != 0) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ } else if( ( PL_strstr( query, "op=save_config_changes" ) ) ) {
+ tokendbDebug( "authorization for op=save_config_changes\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save_config_changes", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save_config_parameter", "Success", "Tokendb user authorization");
+
+ char *ptype = NULL;
+ char *pname = NULL;
+ char *ptimestamp = NULL;
+ char *escaped_added_str = NULL;
+ char *escaped_deleted_str = NULL;
+ char *escaped_changed_str = NULL;
+ char *new_config = NULL;
+ char *approval_requested = NULL;
+ char *pstate = NULL;
+ char flash[256] = "";
+ int return_done = 0;
+ bool new_config_bool = false;
+
+ ptype = get_post_field(post, "ptype", SHORT_LEN);
+ pname = get_post_field(post, "pname", SHORT_LEN);
+ ptimestamp = get_post_field(post, "ptimestamp", SHORT_LEN);
+ escaped_added_str = get_post_field_s(post, "added_params");
+ escaped_deleted_str = get_post_field_s(post, "deleted_params");
+ escaped_changed_str = get_post_field_s(post, "changed_params");
+ new_config = get_post_field(post, "new_config", SHORT_LEN);
+ approval_requested = get_post_field(post, "approval_requested", SHORT_LEN);
+ new_config_bool = (PL_strcmp(new_config, "true") == 0) ? true : false;
+
+ tokendbDebug(ptype);
+ tokendbDebug(pname);
+ tokendbDebug(new_config);
+ tokendbDebug(ptimestamp);
+ tokendbDebug(approval_requested);
+
+ char *added_str = unescapeString(escaped_added_str);
+ char *deleted_str = unescapeString(escaped_deleted_str);
+ char *changed_str = unescapeString(escaped_changed_str);
+
+ tokendbDebug(added_str);
+ tokendbDebug(deleted_str);
+ tokendbDebug(changed_str);
+
+ if ((ptype == NULL) || (pname == NULL)) {
+ error_out("Invalid Invocation: Parameter type, name or values is NULL", "Parameter type, name or values is NULL");
+ return_done = 1;
+ goto save_config_changes_cleanup;
+ }
+
+ if (set_config_state_timestamp(ptype, pname, ptimestamp, "Writing", "Admin", new_config_bool, userid) != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto save_config_changes_cleanup;
+ }
+
+ if (new_config) {
+ do_free(ptimestamp);
+ get_config_state_timestamp(ptype, pname, &pstate, &ptimestamp);
+ }
+
+ if (PL_strlen(added_str) != 0) parse_and_apply_changes(userid, ptype, pname, "ADD", added_str);
+ if (PL_strlen(deleted_str) != 0) parse_and_apply_changes(userid, ptype, pname, "DELETE", deleted_str);
+ if (PL_strlen(changed_str) != 0) parse_and_apply_changes(userid, ptype, pname, "MODIFY", changed_str);
+
+ if (PL_strcmp(new_config, "true") ==0) {
+ // add to the list for that config type
+ PR_snprintf( ( char * ) configname, 256, "target.%s.list", ptype );
+ const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname );
+ char value[4096] = "";
+ PR_snprintf(value, 4096, "%s%s%s", conf_list, (PL_strlen(conf_list) > 0) ? "," : "", pname);
+ RA::GetConfigStore()->Add(configname, value);
+
+ PR_snprintf(oString, 512, "%s", pname);
+ PR_snprintf(pLongString, 4096, "%s;;%s", configname, value);
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, pLongString, "config item added");
+ }
+
+ if (PL_strcmp(approval_requested, "TRUE") == 0) {
+ int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Pending_Approval", "Admin", false, userid);
+ if (status != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto save_config_changes_cleanup;
+ }
+ PR_snprintf(flash, 256, "Configuration Parameters have been saved and submitted for approval");
+ } else {
+ int status = set_config_state_timestamp(ptype, pname, ptimestamp, "Disabled", "Admin", false, userid);
+ if (status != 0) {
+ error_out("The data you are viewing has changed. Please reload the data and try your edits again.", "Data Out of Date");
+ return_done=1;
+ goto save_config_changes_cleanup;
+ }
+ PR_snprintf(flash, 256, "Configuration Parameters have been saved");
+ }
+
+ if ((PL_strlen(added_str) != 0) || (PL_strlen(deleted_str) != 0) || (PL_strlen(changed_str) != 0)) {
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(true, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+
+ RA::Audit(EV_CONFIG, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", "", "config changes committed to filesystem");
+ } else {
+ // commit state changes
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(false, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+ }
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var flash = \"" , flash, "\";\n",
+ "var agent_target_list = \"",
+ RA::GetConfigStore()->GetConfigAsString("target.agent_approve.list", ""), "\";\n",
+ "var target_list = \"", RA::GetConfigStore()->GetConfigAsString("target.configure.list", ""), "\";\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( indexTemplate, injection );
+ save_config_changes_cleanup:
+ do_free(ptype);
+ do_free(pname);
+ do_free(added_str);
+ do_free(deleted_str);
+ do_free(changed_str);
+ do_free(escaped_added_str);
+ do_free(escaped_deleted_str);
+ do_free(escaped_changed_str);
+ do_free(new_config);
+ do_free(ptimestamp);
+ do_free(pstate);
+ do_free(approval_requested);
+ if (return_done == 1) {
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ } else if( ( PL_strstr( query, "op=view_admin" ) ) ||
+ ( PL_strstr( query, "op=view_certificate" ) ) ||
+ ( PL_strstr( query, "op=view_activity_admin" ) ) ||
+ ( PL_strstr( query, "op=view_activity" ) ) ||
+ ( PL_strstr( query, "op=view_users" ) ) ||
+ ( PL_strstr( query, "op=view" ) ) ||
+ ( PL_strstr( query, "op=edit_user" ) ) ||
+ ( PL_strstr( query, "op=edit" ) ) ||
+ ( PL_strstr( query, "op=show_certificate" ) ) ||
+ ( PL_strstr( query, "op=show" ) ) ||
+ ( PL_strstr( query, "op=do_confirm_token" ) ) ||
+ ( PL_strstr( query, "op=user_delete_confirm"))||
+ ( PL_strstr( query, "op=confirm" ) ) ) {
+
+ op = get_field(query, "op=", SHORT_LEN);
+
+ if( ( PL_strstr( query, "op=confirm" ) ) ||
+ ( PL_strstr( query, "op=view_admin" ) ) ||
+ ( PL_strstr( query, "op=view_activity_admin" ) ) ||
+ ( PL_strstr( query, "op=show_admin" ) ) ||
+ ( PL_strstr( query, "op=view_users") ) ||
+ ( PL_strstr( query, "op=edit_user") ) ||
+ ( PL_strstr( query, "op=user_delete_confirm") ) ) {
+ tokendbDebug( "authorization for admin ops\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization");
+ } else if ((PL_strstr(query, "op=edit")) ||
+ (PL_strstr(query, "do_confirm_token"))) {
+ tokendbDebug( "authorization for op=edit and op=do_confirm_token\n" );
+
+ if (! is_agent ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization");
+ } else if (PL_strstr(query, "op=view_activity")) {
+ tokendbDebug( "authorization for view_activity\n" );
+
+ /* check removed -- all roles permitted
+ if ( (! is_agent) && (! is_operator) && (! is_admin)) {
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DECLINED;
+ } */
+ } else {
+ tokendbDebug( "authorization\n" );
+
+ if ((! is_agent) && (!is_operator)) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, op, "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, op, "Success", "Tokendb user authorization");
+ }
+
+ do_free(op);
+
+ if ((PL_strstr( query, "op=view_activity_admin")) ||
+ (PL_strstr( query, "op=view_activity" ) )) {
+ getActivityFilter( filter, query );
+ } else if( PL_strstr( query, "op=view_certificate" ) ) {
+ getCertificateFilter( filter, query );
+ } else if( PL_strstr( query, "op=show_certificate" ) ) {
+ getCertificateFilter( filter, query );
+ } else if ((PL_strstr( query, "op=view_users" ) ) ||
+ (PL_strstr( query, "op=user_delete_confirm")) ||
+ (PL_strstr( query, "op=edit_user" ) )) {
+ getUserFilter( filter, query );
+ } else {
+ getFilter( filter, query );
+ }
+
+ auth_filter = get_authorized_profiles(userid, is_admin);
+
+ tokendbDebug("auth_filter");
+ tokendbDebug(auth_filter);
+
+ char *complete_filter = add_profile_filter(filter, auth_filter);
+ do_free(auth_filter);
+
+ int time_limit = get_time_limit(query);
+ int size_limit = get_size_limit(query);
+
+ tokendbDebug( "looking for filter:" );
+ tokendbDebug( complete_filter );
+ tokendbDebug( filter );
+ tokendbDebug( "\n" );
+
+ /* retrieve maxCount */
+ s1 = PL_strstr( query, "maxCount=" );
+ if( s1 == NULL ) {
+ maxReturns = 100;
+ } else {
+ s2 = PL_strchr( ( const char * ) s1, '&' );
+ if( s2 == NULL ) {
+ maxReturns = atoi( s1+9 );
+ } else {
+ *s2 = '\0';
+ maxReturns = atoi( s1+9 );
+ *s2 = '&';
+ }
+ }
+
+ if (( PL_strstr( query, "op=view_activity_admin_all" )) ||
+ ( PL_strstr( query, "op=view_activity_all") )) {
+ // TODO: error check to confirm that search filter is non-empty
+ status = find_tus_activity_entries_no_vlv( complete_filter, &result, 1 );
+ } else if (( PL_strstr( query, "op=view_activity_admin" )) ||
+ ( PL_strstr( query, "op=view_activity" ) )) {
+ if (PL_strcmp(complete_filter, "(&(tokenID=*)(tokenUserID=*))") == 0) {
+ tokendbDebug("activity vlv search");
+ status = find_tus_activity_entries(complete_filter, maxReturns, &result);
+ } else {
+ status = find_tus_activity_entries_pcontrol_1( complete_filter, maxReturns, time_limit, size_limit, &result);
+ }
+ } else if(( PL_strstr( query, "op=view_certificate_all" ) ) ||
+ ( PL_strstr( query, "op=show_certificate") )) {
+
+ // TODO: error check to confirm that search filter is non-empty
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP filter: %s", complete_filter);
+
+ status = find_tus_certificate_entries_by_order_no_vlv( complete_filter,
+ &result,
+ 0 );
+ } else if( PL_strstr( query, "op=view_certificate" )) {
+ ap_log_error( ( const char * ) "tus", __LINE__,
+ APLOG_ERR, 0, rq->server,
+ ( const char * ) "LDAP filter: %s", complete_filter);
+
+ status = find_tus_certificate_entries_by_order( complete_filter,
+ maxReturns,
+ &result,
+ 0 );
+ } else if( PL_strstr( query, "op=show_admin" ) ||
+ PL_strstr( query, "op=show" ) ||
+ PL_strstr( query, "op=confirm" ) ||
+ PL_strstr( query, "op=do_confirm_token" ) ) {
+ status = find_tus_token_entries_no_vlv( complete_filter, &result, 0 );
+ } else if ((PL_strstr (query, "op=view_users" )) ||
+ (PL_strstr (query, "op=user_delete_confirm")) ||
+ (PL_strstr (query, "op=edit_user" ))) {
+ status = find_tus_user_entries_no_vlv( filter, &result, 0);
+ } else {
+ if (PL_strcmp(complete_filter, "(&(cn=*)(tokenUserID=*))") == 0) {
+ tokendbDebug("token vlv search");
+ status = find_tus_db_entries(complete_filter, maxReturns, &result);
+ } else {
+ status = find_tus_db_entries_pcontrol_1( complete_filter, maxReturns, time_limit, size_limit, &result );
+ }
+ }
+
+ if( status != LDAP_SUCCESS ) {
+ ldap_error_out("LDAP search error: ", "LDAP search error: %s");
+ do_free(complete_filter);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ do_free(complete_filter);
+ nEntries = get_number_of_entries( result );
+ entryNum = 0;
+ size = 0;
+
+ PL_strcpy( injection, JS_START );
+ PL_strcat( injection, "var userid = \"" );
+ PL_strcat( injection, userid );
+ PL_strcat( injection, "\";\n" );
+ PL_strcat( injection, "var uriBase = \"" );
+ PL_strcat( injection, uri );
+ PL_strcat( injection, "\";\n" );
+
+ if( nEntries > 1 ) {
+ if( sendInPieces && PL_strstr( query, "op=view_activity_admin" ) ) {
+ buf = getTemplateFile( searchActivityAdminResultTemplate,
+ &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ } else if( sendInPieces && PL_strstr( query, "op=view_activity" ) ) {
+ buf = getTemplateFile( searchActivityResultTemplate,
+ &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ } else if( sendInPieces &&
+ PL_strstr( query, "op=view_certificate" ) ) {
+ buf = getTemplateFile( searchCertificateResultTemplate,
+ &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ } else if (sendInPieces && PL_strstr( query, "op=view_users" )) {
+ buf = getTemplateFile( searchUserResultTemplate, &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ } else if( sendInPieces && PL_strstr( query, "op=view" ) ) {
+ buf = getTemplateFile( searchResultTemplate, &tagOffset );
+ if( buf != NULL && tagOffset >= 0 ) {
+ ( void ) ap_rwrite( ( const void * ) buf, tagOffset, rq );
+ sendPieces = 1;
+ }
+ }
+
+ PL_strcat( injection, "var total = \"" );
+
+ len = PL_strlen( injection );
+
+ PR_snprintf( &injection[len], ( MAX_INJECTION_SIZE-len ),
+ "%d", nEntries );
+
+ PL_strcat( injection, "\";\n" );
+ } else {
+ if( ( vals = get_token_states() ) != NULL ) {
+ PL_strcat( injection, "var tokenStates = \"" );
+ for( i = 0; vals[i] != NULL; i++ ) {
+ if( i > 0 ) {
+ PL_strcat( injection, "," );
+ }
+
+ PL_strcat( injection, vals[i] );
+ }
+
+ if( i > 0 ) {
+ PL_strcat( injection, "\";\n" );
+ } else {
+ PL_strcat( injection, "null;\n" );
+ }
+ }
+ }
+
+ PL_strcat( injection, "var results = new Array();\n" );
+ PL_strcat( injection, "var item = 0;\n" );
+
+ if( PL_strstr( query, "op=do_confirm_token" ) ) {
+ question = PL_strstr( query, "question=" );
+
+ q = question[9] - '0';
+
+ PR_snprintf( question_no, 256, "%d", q );
+
+ PL_strcat( injection, "var question = \"" );
+ PL_strcat( injection, question_no );
+ PL_strcat( injection, "\";\n" );
+ }
+
+ if (PL_strstr( query, "op=do_confirm_token" ) ||
+ PL_strstr( query, "op=show" )) {
+ show_token_ui_state = true;
+ }
+
+ /* get attributes to be displayed to the user */
+ if (( PL_strstr( query, "op=view_activity_admin" ) ) ||
+ ( PL_strstr( query, "op=view_activity" ) )) {
+ attrs = get_activity_attributes();
+ } else if( PL_strstr( query, "op=view_certificate" ) ) {
+ attrs = get_certificate_attributes();
+ } else if( PL_strstr( query, "op=show_certificate" ) ) {
+ attrs = get_certificate_attributes();
+ } else if ((PL_strstr( query, "op=user_delete_confirm")) ||
+ (PL_strstr( query, "op=edit_user") ) ) {
+ attrs = get_user_attributes();
+ } else if (PL_strstr( query, "op=view_users") ) {
+ attrs = get_view_user_attributes();
+ } else {
+ attrs = get_token_attributes();
+ }
+
+ /* start_val used in paging of profiles on the edit_user page */
+ if (PL_strstr( query, "op=edit_user") ) {
+ char *start_val_str = get_field(query, "start_val=", SHORT_LEN);
+ if (start_val_str != NULL) {
+ start_val = atoi(start_val_str);
+ do_free(start_val_str);
+ } else {
+ start_val = 0;
+ }
+ end_val = start_val + NUM_PROFILES_TO_DISPLAY;
+ }
+
+ /* flash used to display edit result upon redirection back to the edit_user page */
+ if (PL_strstr(query, "op=edit_user") ) {
+ char *flash = get_field(query, "flash=", SHORT_LEN);
+ if (flash != NULL) {
+ PL_strcat(injection, "var flash = \"");
+ PL_strcat(injection, flash);
+ PL_strcat(injection, "\";\n");
+ do_free(flash);
+ }
+ PR_snprintf(msg, 256, "var num_profiles_to_display = %d ;\n", NUM_PROFILES_TO_DISPLAY);
+ PL_strcat(injection, msg);
+ }
+
+ int injection_size = MAX_INJECTION_SIZE;
+ /* start_entry_val is used for pagination of entries on all other pages */
+ int start_entry_val;
+ int end_entry_val;
+ int first_pass = 1;
+ int one_time = 1;
+ char *start_entry_val_str = get_field(query, "start_entry_val=", SHORT_LEN);
+ if (start_entry_val_str != NULL) {
+ start_entry_val = atoi(start_entry_val_str);
+ do_free(start_entry_val_str);
+ } else {
+ start_entry_val = 1;
+ }
+ end_entry_val = start_entry_val + NUM_ENTRIES_PER_PAGE;
+
+ if( (maxReturns > 0) && (maxReturns < nEntries)) {
+ PR_snprintf(msg, 256, "var limited = %d ;\n", maxReturns);
+ PL_strcat( injection, msg);
+ }
+
+ for( e = get_first_entry( result );
+ ( maxReturns > 0 ) && ( e != NULL );
+ e = get_next_entry( e ) ) {
+ maxReturns--;
+ entryNum++;
+
+ if ((entryNum < start_entry_val) || (entryNum >= end_entry_val)) {
+ if (one_time == 1) {
+ PL_strcat(injection, "var my_query = \"");
+ PL_strcat(injection, query);
+ PL_strcat(injection, "\";\n");
+ one_time =0;
+ }
+ // skip values not within the page range
+ if (entryNum == end_entry_val) {
+ PL_strcat( injection, "var has_more_entries = 1;\n");
+ break;
+ }
+ continue;
+ }
+
+ PL_strcat( injection, "var o = new Object();\n" );
+
+ for( n = 0; attrs[n] != NULL; n++ ) {
+ /* Get the values of the attribute. */
+ if( ( bvals = get_attribute_values( e, attrs[n] ) ) != NULL ) {
+ int v_start =0;
+ int v_end = MAX_INJECTION_SIZE;
+ PL_strcat( injection, "o." );
+ PL_strcat( injection, attrs[n] );
+ PL_strcat( injection, " = " );
+
+ if (PL_strstr(attrs[n], PROFILE_ID)) {
+ v_start = start_val;
+ v_end = end_val;
+ }
+
+ for( i = v_start; (bvals[i] != NULL) && (i < v_end); i++ ) {
+ if( i > start_val ) {
+ PL_strcat( injection, "#" );
+ } else {
+ PL_strcat( injection, "\"" );
+ }
+
+ // make sure to escape any special characters
+ if (bvals[i]->bv_val != NULL) {
+ char *escaped = escapeSpecialChars(bvals[i]->bv_val);
+ PL_strcat( injection, escaped );
+ if (escaped != NULL) {
+ PL_strfree(escaped);
+ }
+ }
+ }
+
+ if( i > v_start ) {
+ PL_strcat( injection, "\";\n" );
+ } else {
+ PL_strcat( injection, "null;\n" );
+ }
+
+ if ((PL_strcmp(attrs[n], TOKEN_STATUS)==0) && show_token_ui_state && valid_berval(bvals)) {
+ PL_strncpy( tokenStatus, bvals[0]->bv_val, 100 );
+ }
+
+ if ((PL_strcmp(attrs[n], TOKEN_REASON)==0) && show_token_ui_state && valid_berval(bvals)) {
+ PL_strncpy( tokenReason, bvals[0]->bv_val, 100 );
+ }
+
+ if (PL_strstr(attrs[n], PROFILE_ID)) {
+ if (bvals[i] != NULL) {
+ PL_strcat( injection, "var has_more_profile_vals = \"true\";\n");
+ } else {
+ PL_strcat( injection, "var has_more_profile_vals = \"false\";\n");
+ }
+ PR_snprintf(msg, 256, "var start_val = %d ;\n var end_val = %d ;\n",
+ start_val, i);
+ PL_strcat( injection, msg);
+ }
+
+ /* Free the attribute values from memory when done. */
+ if( bvals != NULL ) {
+ free_values( bvals, 1 );
+ bvals = NULL;
+ }
+ }
+ }
+
+ PL_strcat( injection, "results[item++] = o;\n" );
+
+ if (check_injection_size(&injection, &injection_size, fixed_injection) != 0) {
+ // failed to allocate more space to injection, truncating output
+ break;
+ }
+
+ if( first_pass == 1 && nEntries > 1 && sendPieces == 0 ) {
+ first_pass=0;
+
+ PR_snprintf(msg, 256, "var start_entry_val = %d ; \nvar num_entries_per_page= %d ; \n",
+ start_entry_val, NUM_ENTRIES_PER_PAGE);
+ PL_strcat( injection, msg);
+ }
+
+ if( sendPieces ) {
+ ( void ) ap_rwrite( ( const void * ) injection,
+ PL_strlen( injection ), rq );
+ injection[0] = '\0';
+ }
+
+ }
+
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+
+ /* populate the user roles */
+ if ((PL_strstr( query, "op=edit_user")) ||
+ (PL_strstr( query, "op=user_delete_confirm"))) {
+
+ uid = get_field(query, "uid=", SHORT_LEN);
+ bool officer = false;
+ bool agent = false;
+ bool admin = false;
+ status = find_tus_user_role_entries( uid, &result );
+ for (e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *dn = NULL;
+ dn = get_dn(e);
+ if (PL_strstr(dn, "Operators"))
+ officer=true;
+ if (PL_strstr(dn, "Agents"))
+ agent = true;
+ if (PL_strstr(dn, "Administrators"))
+ admin = true;
+ if (dn != NULL) {
+ PL_strfree(dn);
+ dn=NULL;
+ }
+ }
+ if (officer) {
+ PL_strcat( injection, "var operator = \"CHECKED\"\n");
+ } else {
+ PL_strcat( injection, "var operator = \"\"\n");
+ }
+ if (agent) {
+ PL_strcat( injection, "var agent = \"CHECKED\"\n");
+ } else {
+ PL_strcat( injection, "var agent = \"\"\n");
+ }
+ if (admin) {
+ PL_strcat( injection, "var admin = \"CHECKED\"\n");
+ } else {
+ PL_strcat( injection, "var admin = \"\"\n");
+ }
+
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ do_free(uid);
+ }
+
+ /* populate the profile checkbox */
+ /* for sanity, we limit the number of entries displayed as well as the max number of characters transferred */
+ if (PL_strstr( query, "op=edit_user")) {
+ if (profileList != NULL) {
+ int n_profiles = 0;
+ int l_profiles = 0;
+ bool more_profiles = false;
+
+ char *pList = PL_strdup(profileList);
+ char *sresult = NULL;
+
+ PL_strcat( injection, "var profile_list = new Array(");
+ sresult = strtok(pList, ",");
+ n_profiles++;
+ while (sresult != NULL) {
+ n_profiles++;
+ l_profiles += PL_strlen(sresult);
+ if ((n_profiles > NUM_PROFILES_TO_DISPLAY) || (l_profiles > MAX_LEN_PROFILES_TO_DISPLAY)) {
+ PL_strcat(injection, "\"Other Profiles\",");
+ more_profiles = true;
+ break;
+ }
+
+ PL_strcat(injection, "\"");
+ PL_strcat(injection, sresult);
+ PL_strcat(injection, "\",");
+ sresult = strtok(NULL, ",");
+ }
+ do_free(pList);
+ PL_strcat(injection, "\"All Profiles\")\n");
+ if (more_profiles) {
+ PL_strcat(injection, "var more_profiles=\"true\";\n");
+ } else {
+ PL_strcat(injection, "var more_profiles=\"false\";\n");
+ }
+ }
+ }
+ topLevel = get_field(query, "top=", SHORT_LEN);
+ if ((topLevel != NULL) && (PL_strstr(topLevel, "operator"))) {
+ PL_strcat(injection, "var topLevel = \"operator\";\n");
+ }
+ do_free(topLevel);
+
+ /* populate the authorized token transitions */
+ if (show_token_ui_state) {
+ token_ui_state = get_token_ui_state(tokenStatus, tokenReason);
+ add_allowed_token_transitions(token_ui_state, injection);
+ }
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat( injection, JS_STOP );
+
+ if( sendPieces ) {
+ ( void ) ap_rwrite( ( const void * ) injection,
+ PL_strlen( injection ), rq );
+
+ mNum = buf + tagOffset + PL_strlen( CMS_TEMPLATE_TAG );
+
+ ( void ) ap_rwrite( ( const void * ) mNum,
+ PL_strlen( mNum ), rq );
+
+ mNum = NULL;
+
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ } else {
+ if( PL_strstr( query, "op=view_activity_admin" ) ) {
+ buf = getData( searchActivityAdminResultTemplate, injection );
+ } else if( PL_strstr( query, "op=view_activity" ) ) {
+ buf = getData( searchActivityResultTemplate, injection );
+ } else if( PL_strstr( query, "op=view_certificate" ) ) {
+ buf = getData( searchCertificateResultTemplate, injection );
+ } else if( PL_strstr( query, "op=show_admin" ) ) {
+ buf = getData( showAdminTemplate, injection );
+ } else if( PL_strstr( query, "op=view_admin" ) ) {
+ buf = getData( searchAdminResultTemplate, injection );
+ } else if (PL_strstr( query, "op=view_users") ) {
+ buf = getData( searchUserResultTemplate, injection);
+ } else if( PL_strstr( query, "op=view" ) ) {
+ buf = getData( searchResultTemplate, injection );
+ } else if (PL_strstr( query, "op=edit_user") ) {
+ buf = getData( editUserTemplate, injection);
+ } else if( PL_strstr( query, "op=edit" ) ) {
+ buf = getData( editTemplate, injection );
+ } else if( PL_strstr( query, "op=show_certificate" ) ) {
+ buf = getData( showCertTemplate, injection );
+ } else if( PL_strstr( query, "op=do_confirm_token" ) ) {
+ buf = getData( doTokenConfirmTemplate, injection );
+ } else if( PL_strstr( query, "op=show" ) ) {
+ buf = getData( showTemplate, injection );
+ } else if( PL_strstr( query, "op=confirm" ) ) {
+ buf = getData( deleteTemplate, injection );
+ } else if ( PL_strstr( query, "op=user_delete_confirm" ) ) {
+ buf = getData( userDeleteTemplate, injection );
+ }
+
+ }
+
+ if( injection != fixed_injection ) {
+ if( injection != NULL ) {
+ PR_Free( injection );
+ injection = NULL;
+ }
+
+ injection = fixed_injection;
+ }
+ } else if ( PL_strstr( query, "op=add_profile_user" )) {
+ tokendbDebug("authorization for op=add_profile_user");
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add_profile_user", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add_profile_user", "Success", "Tokendb user authorization");
+ uid = get_post_field(post, "uid", SHORT_LEN);
+ char *profile = get_post_field(post, "profile_0", SHORT_LEN);
+ char *other_profile = get_post_field(post, "other_profile", SHORT_LEN);
+ if ((profile != NULL) && (uid != NULL)) {
+ if (PL_strstr(profile, "Other Profiles")) {
+ if ((other_profile != NULL) && (match_profile(other_profile))) {
+ do_free(profile);
+ profile = PL_strdup(other_profile);
+ } else {
+ error_out("Invalid Profile to be added", "Invalid Profile to be added");
+ do_free(profile);
+ do_free(other_profile);
+ do_free(uid);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return OK;
+ }
+ }
+ if (PL_strstr(profile, ALL_PROFILES)) {
+ status = delete_all_profiles_from_user(userid, uid);
+ }
+
+ PR_snprintf(oString, 512, "userid;;%s", uid);
+ PR_snprintf(pString, 512, "profile;;%s", profile);
+
+ status = add_profile_to_user(userid, uid, profile);
+ if ((status != LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, pString, "failure adding profile to user");
+ PR_snprintf(msg, 512, "LDAP Error in adding profile %s to user %s",
+ profile, uid);
+ post_ldap_error(msg);
+ }
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "profile added to user");
+ }
+ do_free(other_profile);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ PR_snprintf((char *)msg, 512,
+ "'%s' has added profile %s to user %s", userid, profile, uid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "add_profile", "success", msg, uid, NO_TOKEN_TYPE);
+
+ PR_snprintf(oString, 512, "userid;;%s", uid);
+ PR_snprintf(pString, 512, "profile;;%s", profile);
+
+ PR_snprintf(injection, MAX_INJECTION_SIZE,
+ "/tus/tus?op=edit_user&uid=%s&flash=Profile+%s+has+been+added+to+the+user+record",
+ uid, profile);
+ do_free(profile);
+ do_free(uid);
+ rq->method = apr_pstrdup(rq->pool, "GET");
+ rq->method_number = M_GET;
+
+ ap_internal_redirect_handler(injection, rq);
+ return OK;
+ } else if ( PL_strstr( query, "op=save_user" )) {
+ tokendbDebug( "authorization for op=save_user\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save_user", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save_user", "Success", "Tokendb user authorization");
+ // first save user details
+ uid = get_post_field(post, "uid", SHORT_LEN);
+ firstName = get_post_field(post, "firstName", SHORT_LEN);
+ lastName = get_post_field(post, "lastName", SHORT_LEN);
+ userCert = get_encoded_post_field(post, "userCert", HUGE_STRING_LEN);
+ opOperator = get_post_field(post, "opOperator", SHORT_LEN);
+ opAgent = get_post_field(post, "opAgent", SHORT_LEN);
+ opAdmin = get_post_field(post, "opAdmin", SHORT_LEN);
+
+ // construct audit log message
+ PR_snprintf(oString, 512, "userid;;%s", uid);
+ PR_snprintf(pLongString, 4096, "");
+ PR_snprintf(filter, 512, "uid=%s", uid);
+ status = find_tus_user_entries_no_vlv( filter, &result, 0);
+ e = get_first_entry( result );
+ if( e != NULL ) {
+ audit_attribute_change(e, "givenName", firstName, pLongString);
+ audit_attribute_change(e, "sn", lastName, pLongString);
+ }
+
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+
+ // now check cert
+ char *test_user = tus_authenticate(userCert);
+ if ((test_user != NULL) && (strcmp(test_user, uid) == 0)) {
+ // cert did not change
+ } else {
+ if (strlen(pLongString) > 0) PL_strcat(pLongString, "+");
+ PR_snprintf(pLongString, 4096, "%suserCertificate;;%s", pLongString, userCert);
+ }
+
+ PR_snprintf((char *)userCN, 256,
+ "%s%s%s", ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""),
+ ((firstName != NULL && PL_strlen(firstName) > 0)? " ": ""), lastName);
+
+ status = update_user_db_entry(userid, uid, lastName, firstName, userCN, userCert);
+
+ do_free(firstName);
+ do_free(lastName);
+ do_free(userCert);
+
+ if( status != LDAP_SUCCESS ) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pLongString, "user record failed to be updated");
+ ldap_error_out("LDAP modify error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ do_free(uid);
+ do_free(opOperator);
+ do_free(opAgent);
+ do_free(opAdmin);
+
+ return DONE;
+ }
+ if (strlen(pLongString) > 0)
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pLongString, "user record updated");
+
+ bool has_role = tus_authorize(TOKENDB_OPERATORS_IDENTIFIER, uid);
+ PR_snprintf(pString, 512, "role;;operator");
+ if ((opOperator != NULL) && (PL_strstr(opOperator, OPERATOR))) {
+ if (!has_role) {
+ status = add_user_to_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ }
+ } else if (has_role) {
+ status = delete_user_from_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ has_role = tus_authorize(TOKENDB_AGENTS_IDENTIFIER, uid);
+ PR_snprintf(pString, 512, "role;;agent");
+ if ((opAgent != NULL) && (PL_strstr(opAgent, AGENT))) {
+ if (!has_role) {
+ status = add_user_to_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, AGENT);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ }
+ } else if (has_role) {
+ status = delete_user_from_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ has_role = tus_authorize(TOKENDB_ADMINISTRATORS_IDENTIFIER, uid);
+ PR_snprintf(pString, 512, "role;;administrator");
+ if ((opAdmin != NULL) && (PL_strstr(opAdmin, ADMINISTRATOR))) {
+ if (!has_role) {
+ status = add_user_to_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ }
+ } else if (has_role) {
+ status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ do_free(opOperator);
+ do_free(opAgent);
+ do_free(opAdmin);
+
+ // save profile details
+ char *nProfileStr = get_post_field(post, "nProfiles", SHORT_LEN);
+ int nProfiles = atoi (nProfileStr);
+ do_free(nProfileStr);
+
+ for (int i=0; i< nProfiles; i++) {
+ char p_name[256];
+ char p_delete[256];
+ PR_snprintf(p_name, 256, "profile_%d", i);
+ PR_snprintf(p_delete, 256, "delete_%d", i);
+ char *profile = get_post_field(post, p_name, SHORT_LEN);
+ char *p_del = get_post_field(post, p_delete, SHORT_LEN);
+
+ if ((profile != NULL) && (p_del != NULL) && (PL_strstr(p_del, "delete"))) {
+ PR_snprintf(pString, 512, "profile_id;;%s", profile);
+ status = delete_profile_from_user(userid, uid, profile);
+ if ((status != LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "error deleting profile from user");
+ PR_snprintf(msg, 512, "LDAP Error in deleting profile %s from user %s",
+ profile, uid);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "profile deleted from user");
+ }
+ }
+ do_free(profile);
+ do_free(p_del);
+ }
+
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ PR_snprintf((char *)msg, 512,
+ "'%s' has modified user %s", userid, uid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_user", "success", msg, uid, NO_TOKEN_TYPE);
+
+ PR_snprintf(injection, MAX_INJECTION_SIZE,
+ "/tus/tus?op=edit_user&uid=%s&flash=User+record+%s+has+been+updated",
+ uid, uid);
+ do_free(uid);
+ rq->method = apr_pstrdup(rq->pool, "GET");
+ rq->method_number = M_GET;
+
+ ap_internal_redirect_handler(injection, rq);
+ return OK;
+ } else if( PL_strstr( query, "op=save" ) ) {
+ tokendbDebug( "authorization\n" );
+
+ if( ! is_agent ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "save", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "save", "Success", "Tokendb user authorization");
+
+ getCN( filter, query );
+ mNum = parse_modification_number( query );
+ mods = getModifications( query );
+
+ if( mNum != NULL ) {
+ status = check_and_modify_tus_db_entry( userid, filter,
+ mNum, mods );
+
+ PL_strfree( mNum );
+
+ mNum = NULL;
+ } else {
+ status = modify_tus_db_entry( userid, filter, mods );
+ }
+
+ int cc;
+ PR_snprintf(oString, 512, "token_id;;%s", filter);
+ PR_snprintf(pLongString, 4096, "");
+ int first_item = 1;
+ for (cc = 0; mods[cc] != NULL; cc++) {
+ if (! first_item) PL_strcat(pLongString, "+");
+ if (mods[cc]->mod_type != NULL) {
+ PL_strcat(pLongString, mods[cc]->mod_type);
+ PL_strcat(pLongString, ";;");
+ PL_strcat(pLongString, *mods[cc]->mod_values);
+ first_item =0;
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ if( status != LDAP_SUCCESS ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Failure", oString, pLongString, "failed to modify token record");
+ ldap_error_out("LDAP modify error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Agent", "Success", oString, pLongString, "token record modified");
+ PR_snprintf((char *)msg, 256, "Token record modified by %s", userid);
+ RA::tdb_activity(rq->connection->remote_ip, cuid, "save", "success",
+ msg, cuidUserId, tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", filter, "\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( editResultTemplate, injection );
+
+ } else if ( PL_strstr( query, "op=do_delete_user" ) ) {
+ tokendbDebug( "authorization for do_delete_user\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "do_delete_user", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "do_delete_user", "Success", "Tokendb user authorization");
+
+ uid = get_post_field(post, "uid", SHORT_LEN);
+
+ if (uid == NULL) {
+ error_out("Error in delete user. userid is null", "Error in delete user. userid is null");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ bool officer = false;
+ bool agent = false;
+ bool admin = false;
+ status = find_tus_user_role_entries( uid, &result );
+ for (e = get_first_entry( result );
+ e != NULL;
+ e = get_next_entry( e ) ) {
+ char *dn = NULL;
+ dn = get_dn(e);
+ if (PL_strstr(dn, "Operators"))
+ officer=true;
+ if (PL_strstr(dn, "Agents"))
+ agent = true;
+ if (PL_strstr(dn, "Administrators"))
+ admin = true;
+ if (dn != NULL) {
+ PL_strfree(dn);
+ dn=NULL;
+ }
+ }
+
+ if (result != NULL) {
+ free_results( result );
+ result = NULL;
+ }
+
+ if (officer) {
+ status = delete_user_from_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ }
+ }
+
+ if (agent) {
+ status = delete_user_from_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT);
+ post_ldap_error(msg);
+ }
+ }
+
+ if (admin) {
+ status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ }
+ }
+
+ status = delete_user_db_entry(userid, uid);
+
+ if ((status != LDAP_SUCCESS) && (status != LDAP_NO_SUCH_OBJECT)) {
+ PR_snprintf(oString, 512, "uid;;%s", uid);
+ PR_snprintf(pString, 512, "status;;%d", status);
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "error in deleting user");
+
+ PR_snprintf(msg, 512, "Error deleting user %s", uid);
+ ldap_error_out(msg, msg);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ do_free(uid);
+
+ return DONE;
+ }
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' has deleted user %s", userid, uid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "delete_user", "success", msg, uid, NO_TOKEN_TYPE);
+ PR_snprintf(oString, 512, "uid;;%s", uid);
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, "", "tokendb user deleted");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", uid, "\";\n",
+ "var deleteType = \"user\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ do_free(uid);
+
+ buf = getData( deleteResultTemplate, injection );
+ } else if ( PL_strstr( query, "op=addUser" ) ) {
+ tokendbDebug( "authorization for addUser\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "addUser", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "addUser", "Success", "Tokendb user authorization");
+
+ uid = get_post_field(post, "userid", SHORT_LEN);
+ firstName = get_post_field(post, "firstName", SHORT_LEN);
+ lastName = get_post_field(post, "lastName", SHORT_LEN);
+ opOperator = get_post_field(post, "opOperator", SHORT_LEN);
+ opAdmin = get_post_field(post, "opAdmin", SHORT_LEN);
+ opAgent = get_post_field(post, "opAgent", SHORT_LEN);
+ userCert = get_encoded_post_field(post, "cert", HUGE_STRING_LEN);
+
+ if ((PL_strlen(uid) == 0) || (PL_strlen(lastName) == 0)) {
+ error_out("Bad input to op=addUser", "Bad input to op=addUser");
+ do_free(uid);
+ do_free(firstName);
+ do_free(lastName);
+ do_free(opOperator);
+ do_free(opAdmin);
+ do_free(opAgent);
+ do_free(userCert);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return OK;
+ }
+ PR_snprintf((char *)userCN, 256,
+ "%s%s%s", ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""),
+ ((firstName != NULL && PL_strlen(firstName) > 0)? " ": ""), lastName);
+
+ PR_snprintf(oString, 512, "uid;;%s", uid);
+ PR_snprintf(pString, 512, "givenName;;%s+sn;;%s",
+ ((firstName != NULL && PL_strlen(firstName) > 0)? firstName: ""), lastName);
+
+ /* to meet STIG requirements, every user in ldap must have a password, even if that password is never used */
+ char *pwd = generatePassword(pwLength);
+ status = add_user_db_entry(userid, uid, pwd, lastName, firstName, userCN, userCert);
+ do_free(pwd);
+
+ if (status != LDAP_SUCCESS) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, pString, "failure in adding tokendb user");
+ PR_snprintf((char *)msg, 512, "LDAP Error in adding new user %s", uid);
+ ldap_error_out(msg, msg);
+ do_free(uid);
+ do_free(firstName);
+ do_free(lastName);
+ do_free(opOperator);
+ do_free(opAdmin);
+ do_free(opAgent);
+ do_free(userCert);
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return OK;
+ }
+
+ PR_snprintf((char *)msg, 512,
+ "'%s' has created new user %s", userid, uid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "add_user", "success", msg, uid, NO_TOKEN_TYPE);
+
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "tokendb user added");
+
+ PR_snprintf(pString, 512, "role;;operator");
+ if ((opOperator != NULL) && (PL_strstr(opOperator, OPERATOR))) {
+ status = add_user_to_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ } else {
+ status = delete_user_from_role_db_entry(userid, uid, OPERATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, OPERATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+
+ }
+
+ PR_snprintf(pString, 512, "role;;agent");
+ if ((opAgent != NULL) && (PL_strstr(opAgent, AGENT))) {
+ status = add_user_to_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, AGENT);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ } else {
+ status = delete_user_from_role_db_entry(userid, uid, AGENT);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, AGENT);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ PR_snprintf(pString, 512, "role;;admin");
+ if ((opAdmin != NULL) && (PL_strstr(opAdmin, ADMINISTRATOR))) {
+ status = add_user_to_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_TYPE_OR_VALUE_EXISTS)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error adding user to role");
+ PR_snprintf(msg, 512, "Error adding user %s to role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user added to role");
+ }
+ } else {
+ status = delete_user_from_role_db_entry(userid, uid, ADMINISTRATOR);
+ if ((status!= LDAP_SUCCESS) && (status != LDAP_NO_SUCH_ATTRIBUTE)) {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "failure", oString, pString, "Error deleting user from role");
+ PR_snprintf(msg, 512, "Error deleting user %s from role %s", uid, ADMINISTRATOR);
+ post_ldap_error(msg);
+ } else {
+ RA::Audit(EV_CONFIG_ROLE, AUDIT_MSG_CONFIG, userid, "Admin", "success", oString, pString, "user deleted from role");
+ }
+ }
+
+ do_free(firstName);
+ do_free(lastName);
+ do_free(opOperator);
+ do_free(opAdmin);
+ do_free(opAgent);
+ do_free(userCert);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", uid, "\";\n",
+ "var addType = \"user\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ do_free(uid);
+
+ buf = getData( addResultTemplate, injection );
+
+ } else if( PL_strstr( query, "op=add" ) ) {
+ tokendbDebug( "authorization for op=add\n" );
+ RA_Status token_type_status;
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "add", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "add", "Success", "Tokendb user authorization");
+
+ getCN( filter, query );
+
+ if (m_processor.GetTokenType(OP_PREFIX, 0, 0, filter, (const char*) NULL, (NameValueSet*) NULL,
+ token_type_status, tokentype)) {
+ PL_strcpy(tokenType, tokentype);
+ } else {
+ PL_strcpy(tokenType, NO_TOKEN_TYPE);
+ }
+
+ if( strcmp( filter, "" ) == 0 ) {
+ error_out("No Token ID Found", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ status = add_default_tus_db_entry( NULL, userid,
+ filter, "uninitialized",
+ NULL, NULL, tokenType );
+
+ PR_snprintf(oString, 512, "token_id;;%s", filter);
+ if( status != LDAP_SUCCESS ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, "", "failed to add token record");
+ ldap_error_out("LDAP add error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, "", "token record added");
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' has created new token", userid);
+ RA::tdb_activity(rq->connection->remote_ip, filter, "add", "token", msg, "success", tokenType);
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", filter, "\";\n",
+ "var addType = \"token\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+
+ buf = getData( addResultTemplate, injection );
+ } else if( PL_strstr( query, "op=delete" ) ) {
+ RA_Status token_type_status;
+ tokendbDebug( "authorization for op=delete\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "delete", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "delete", "Success", "Tokendb user authorization");
+
+ getCN( filter, query );
+
+ if (m_processor.GetTokenType(OP_PREFIX, 0, 0, filter, (const char*) NULL, (NameValueSet*) NULL,
+ token_type_status, tokentype)) {
+ PL_strcpy(tokenType, tokentype);
+ } else {
+ PL_strcpy(tokenType, NO_TOKEN_TYPE);
+ }
+
+
+ PR_snprintf((char *)msg, 256,
+ "'%s' has deleted token", userid);
+ RA::tdb_activity(rq->connection->remote_ip, filter, "delete", "token", msg, "", tokenType);
+
+ PR_snprintf(oString, 512, "token_id;;%s", filter);
+ status = delete_tus_db_entry( userid, filter );
+
+ if( status != LDAP_SUCCESS ) {
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Failure", oString, "", "failure in deleting token record");
+ ldap_error_out("LDAP delete error: ", "LDAP error: %s");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+
+ RA::Audit(EV_CONFIG_TOKEN, AUDIT_MSG_CONFIG, userid, "Admin", "Success", oString, "", "token record deleted");
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var tid = \"", filter, "\";\n",
+ "var deleteType = \"token\";\n");
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( deleteResultTemplate, injection );
+ } else if ( PL_strstr( query, "op=audit_admin") ) {
+ tokendbDebug( "authorization for op=audit_admin\n" );
+
+ if (!is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "audit_admin", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "audit_admin", "Success", "Tokendb user authorization");
+
+ PR_snprintf (injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%d%s%s%d%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var signedAuditEnable = \"", RA::m_audit_enabled ? "true": "false", "\";\n",
+ "var logSigningEnable = \"", RA::m_audit_signed ? "true" : "false", "\";\n",
+ "var signedAuditLogInterval = \"", RA::m_flush_interval, "\";\n",
+ "var signedAuditLogBufferSize = \"", RA::m_buffer_size, "\";\n",
+ "var signedAuditSelectedEvents = \"", RA::m_signedAuditSelectedEvents, "\";\n",
+ "var signedAuditSelectableEvents = \"", RA::m_signedAuditSelectableEvents, "\";\n",
+ "var signedAuditNonSelectableEvents = \"", RA::m_signedAuditNonSelectableEvents, "\";\n");
+
+ RA::Debug( "mod_tokendb::mod_tokendb_handler",
+ "signedAudit: %s %s %d %d %s %s %s",
+ RA::m_audit_enabled ? "true": "false",
+ RA::m_audit_signed ? "true": "false",
+ RA::m_flush_interval,
+ RA::m_buffer_size,
+ RA::m_signedAuditSelectedEvents,
+ RA::m_signedAuditSelectableEvents,
+ RA::m_signedAuditNonSelectableEvents);
+
+ char *flash = get_field(query, "flash=", SHORT_LEN);
+ if (flash != NULL) {
+ PL_strcat(injection, "var flash = \"");
+ PL_strcat(injection, flash);
+ PL_strcat(injection, "\";\n");
+ do_free(flash);
+ }
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+ buf = getData(auditAdminTemplate, injection);
+ } else if (PL_strstr( query, "op=update_audit_admin") ) {
+ tokendbDebug( "authorization for op=audit_admin\n" );
+
+ if (!is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "update_audit_admin", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "update_audit_admin", "Success", "Tokendb user authorization");
+
+ int need_update=0;
+
+ bool o_signing = RA::m_audit_signed;
+ bool n_signing = o_signing;
+ char *logSigning = get_post_field(post, "logSigningEnable", SHORT_LEN);
+ if (logSigning != NULL) {
+ n_signing = (PL_strcmp(logSigning, "true") == 0)? true: false;
+ }
+ do_free(logSigning);
+
+ bool o_enable = RA::m_audit_enabled;
+ bool n_enable = o_enable;
+ char *auditEnable = get_post_field(post, "auditEnable", SHORT_LEN);
+ if (auditEnable != NULL) {
+ n_enable = (PL_strcmp(auditEnable, "true") == 0)? true: false;
+ }
+ do_free(auditEnable);
+
+ if ((o_signing == n_signing) && (o_enable == n_enable)) {
+ // nothing changed, continue
+ } else {
+ if (o_signing != n_signing) {
+ PR_snprintf(pString, 512, "logging.audit.logSigning;;%s", (n_signing)? "true":"false");
+ if (o_enable != n_enable) {
+ PL_strcat(pString, "+logging.audit.enable;;");
+ PL_strcat(pString, (n_enable)? "true" : "false");
+ }
+ } else {
+ PR_snprintf(pString, 512, "logging.audit.enable;;%s", (n_enable)? "true":"false");
+ }
+
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "attempting to modify audit log configuration");
+
+ if (n_enable) { // be sure to log audit log startup messages,if any
+ RA::enable_audit_logging(n_enable);
+ }
+
+ RA::setup_audit_log(n_signing, n_signing != o_signing);
+
+ if (n_enable && !o_enable) {
+ RA::Audit(EV_AUDIT_LOG_STARTUP, AUDIT_MSG_FORMAT, "System", "Success",
+ "audit function startup");
+ } else if (!n_enable && o_enable) {
+ RA::Audit(EV_AUDIT_LOG_SHUTDOWN, AUDIT_MSG_FORMAT, "System", "Success",
+ "audit function shutdown");
+ }
+ RA::FlushAuditLogBuffer();
+
+ // sleep to ensure all logs written
+ PR_Sleep(PR_SecondsToInterval(1));
+
+ if (!n_enable) { // turn off logging after all logs written
+ RA::enable_audit_logging(n_enable);
+ }
+ need_update = 1;
+
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log config modified");
+ PR_snprintf((char *)msg, 512, "'%s' has modified audit log config: %s", userid, pString);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE);
+ }
+
+ char *logSigningInterval_str = get_post_field(post, "logSigningInterval", SHORT_LEN);
+ int logSigningInterval = atoi(logSigningInterval_str);
+ do_free(logSigningInterval_str);
+
+ if ((logSigningInterval>=0) &&(logSigningInterval != RA::m_flush_interval)) {
+ RA::SetFlushInterval(logSigningInterval);
+ PR_snprintf((char *)msg, 512, "'%s' has modified the audit log signing interval to %d seconds", userid, logSigningInterval);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE);
+
+ PR_snprintf(pString, 512, "logging.audit.flush.interval;;%d", logSigningInterval);
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log configuration modified");
+ }
+
+ char *logSigningBufferSize_str = get_post_field(post, "logSigningBufferSize", SHORT_LEN);
+ int logSigningBufferSize = atoi(logSigningBufferSize_str);
+ do_free(logSigningBufferSize_str);
+
+ if ((logSigningBufferSize >= 512) && (logSigningBufferSize != (int) RA::m_buffer_size)) {
+ RA::SetBufferSize(logSigningBufferSize);
+ PR_snprintf((char *)msg, 512, "'%s' has modified the audit log signing buffer size to %d bytes", userid, logSigningBufferSize);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE);
+
+ PR_snprintf(pString, 512, "logging.audit.buffer.size;;%d", logSigningBufferSize);
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pString, "audit log configuration modified");
+ }
+
+ char *nEvents_str = get_post_field(post, "nEvents", SHORT_LEN);
+ int nEvents = atoi(nEvents_str);
+ do_free(nEvents_str);
+
+ char new_selected[MAX_INJECTION_SIZE];
+
+ int first_match = 1;
+ for (int i=0; i< nEvents; i++) {
+ char e_name[256];
+ PR_snprintf(e_name, 256, "event_%d", i);
+ char *event = get_post_field(post, e_name, SHORT_LEN);
+ if ((event != NULL) && RA::IsValidEvent(event)) {
+ if (first_match != 1) {
+ PL_strcat(new_selected, ",");
+ }
+ first_match = 0;
+ PL_strcat(new_selected, event);
+ }
+ do_free(event);
+ }
+
+ if (PL_strcmp(new_selected, RA::m_signedAuditSelectedEvents) != 0) {
+ need_update = 1;
+ RA::update_signed_audit_selected_events(new_selected);
+
+ PR_snprintf((char *)msg, 512,
+ "'%s' has modified audit signing configuration", userid);
+ RA::tdb_activity(rq->connection->remote_ip, "", "modify_audit_signing", "success", msg, userid, NO_TOKEN_TYPE);
+
+ PR_snprintf(pLongString, 4096, "logging.audit.selected.events;;%s", new_selected);
+ RA::Audit(EV_CONFIG_AUDIT, AUDIT_MSG_CONFIG, userid, "Admin", "Success", "", pLongString, "audit log configuration modified");
+
+ }
+
+ if (need_update == 1) {
+ tokendbDebug("Updating signed audit events in CS.cfg");
+ char error_msg[512];
+ status = RA::GetConfigStore()->Commit(true, error_msg, 512);
+ if (status != 0) {
+ tokendbDebug(error_msg);
+ }
+ }
+
+ PR_snprintf(injection, MAX_INJECTION_SIZE,
+ "/tus/tus?op=audit_admin&flash=Signed+Audit+configuration+has+been+updated");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+
+ rq->method = apr_pstrdup(rq->pool, "GET");
+ rq->method_number = M_GET;
+
+ ap_internal_redirect_handler(injection, rq);
+ return OK;
+ } else if ( PL_strstr( query, "op=self_test") ) {
+ tokendbDebug( "authorization for op=self_test\n" );
+
+ if (!is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "self_test", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_free(uri);
+ do_free(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "self_test", "Success", "Tokendb user authorization");
+
+ PR_snprintf (injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%d%s%s%d%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var enabled = ", SelfTest::isOnDemandEnabled(), ";\n",
+ "var critical = ", SelfTest::isOnDemandCritical(), ";\n");
+
+ if (SelfTest::nTests > 0)
+ PL_strcat(injection, "var test_list = [");
+ for (int i = 0; i < SelfTest::nTests; i++) {
+ RA::Debug( "mod_tokendb::mod_tokendb_handler", "test name: %s", SelfTest::TEST_NAMES[i]);
+ if (i > 0)
+ PL_strcat(injection, ", ");
+ PL_strcat(injection, "\"");
+ PL_strcat(injection, SelfTest::TEST_NAMES[i]);
+ PL_strcat(injection, "\"");
+ }
+ if (SelfTest::nTests > 0)
+ PL_strcat(injection, "];\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+ buf = getData(selfTestTemplate, injection);
+ } else if ( PL_strstr( query, "op=run_self_test" ) ) {
+ tokendbDebug( "authorization for run_self_test\n" );
+
+ if( ! is_admin ) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "run_self_test", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_free(uri);
+ do_free(query);
+
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "run_self_test", "Success", "Tokendb user authorization");
+
+ rc = SelfTest::runOnDemandSelfTests();
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%d%s%s%d%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var enabled = ", SelfTest::isOnDemandEnabled(), ";\n",
+ "var result = \"", rc, "\";\n");
+
+ if (SelfTest::nTests > 0)
+ PL_strcat(injection, "var test_list = [");
+ for (int i = 0; i < SelfTest::nTests; i++) {
+ RA::Debug( "mod_tokendb::mod_tokendb_handler", "test name: %s", SelfTest::TEST_NAMES[i]);
+ if (i > 0)
+ PL_strcat(injection, ", ");
+ PL_strcat(injection, "\"");
+ PL_strcat(injection, SelfTest::TEST_NAMES[i]);
+ PL_strcat(injection, "\"");
+ }
+ if (SelfTest::nTests > 0)
+ PL_strcat(injection, "];\n");
+
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection);
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( selfTestResultsTemplate, injection );
+ } else if( ( PL_strstr( query, "op=agent_select_config" ) ) ) {
+ tokendbDebug( "authorization for op=agent_select_config\n" );
+ if (! is_agent) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "agent_select_config", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "agent_select_config", "Success", "Tokendb user authorization");
+
+ char *conf_type = NULL;
+ char *disp_conf_type = NULL;
+ conf_type = get_field(query, "type=", SHORT_LEN);
+
+ if (conf_type == NULL) {
+ error_out("Invalid Invocation: Type is NULL", "Type is NULL");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ do_free(conf_type);
+ return DONE;
+ }
+
+ // check if agent has permission to see this config parameter
+ if (! agent_must_approve(conf_type)) {
+ error_out("Invalid Invocation: Agent is not permitted to view this configuration item", "Agent is not permitted to view this configuration item");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.list", conf_type );
+ const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", conf_type );
+ disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", conf_type, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_list = \"", (conf_list != NULL)? conf_list : "", "\";\n");
+
+ do_free(conf_type);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed?
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( agentSelectConfigTemplate, injection );
+ } else if( ( PL_strstr( query, "op=select_config_parameter" ) ) ) {
+ tokendbDebug( "authorization for op=select_config_parameter\n" );
+ if (! is_admin) {
+ RA::Audit(EV_AUTHZ_FAIL, AUDIT_MSG_AUTHZ, userid, "select_config_parameter", "Failure", "Tokendb user authorization");
+ error_out("Authorization Failure", "Failed to authorize request");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+ RA::Audit(EV_AUTHZ_SUCCESS, AUDIT_MSG_AUTHZ, userid, "select_config_parameter", "Success", "Tokendb user authorization");
+
+ char *conf_type = NULL;
+ conf_type = get_field(query, "type=", SHORT_LEN);
+
+ if (conf_type == NULL) {
+ error_out("Invalid Invocation: Type is NULL", "Type is NULL");
+ do_free(buf);
+ do_strfree(uri);
+ do_strfree(query);
+ return DONE;
+ }
+
+ PR_snprintf( ( char * ) configname, 256,
+ "target.%s.list", conf_type );
+ const char *conf_list = RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( ( char * ) configname, 256, "target.%s.displayname", conf_type );
+ const char *disp_conf_type = (char *) RA::GetConfigStore()->GetConfigAsString( configname );
+
+ PR_snprintf( injection, MAX_INJECTION_SIZE,
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", JS_START,
+ "var uriBase = \"", uri, "\";\n",
+ "var userid = \"", userid, "\";\n",
+ "var conf_type = \"", conf_type, "\";\n",
+ "var disp_conf_type = \"", disp_conf_type, "\";\n",
+ "var conf_list = \"", (conf_list != NULL)? conf_list : "", "\";\n");
+
+ do_free(conf_type);
+ // do_free(conf_list);
+ add_authorization_data(userid, is_admin, is_operator, is_agent, injection); //needed?
+ PL_strcat(injection, JS_STOP);
+
+ buf = getData( selectConfigTemplate, injection );
+ }
+
+ if( buf != NULL ) {
+ len = PL_strlen( buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, len, rq );
+
+ do_free(buf);
+ }
+ do_free(userid);
+ do_strfree(uri);
+ do_strfree(query);
+
+ return OK;
+}
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Command Phase
+** _________________________________________________________________
+*/
+
+static const char *mod_tokendb_get_config_path_file( cmd_parms *cmd,
+ void *mconfig,
+ const char *tokendbconf )
+{
+ if( cmd->path ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, 0, NULL,
+ "The %s config param cannot be specified "
+ "in a Directory section.",
+ cmd->directive->directive );
+ } else {
+ mod_tokendb_server_configuration *sc = NULL;
+
+ /* Retrieve the Tokendb module. */
+ sc = ( ( mod_tokendb_server_configuration * )
+ ap_get_module_config( cmd->server->module_config,
+ &MOD_TOKENDB_CONFIG_KEY ) );
+
+ /* Initialize the "Tokendb Configuration File" */
+ /* member of mod_tokendb_server_configuration. */
+ sc->Tokendb_Configuration_File = apr_pstrdup( cmd->pool, tokendbconf );
+ }
+
+ return NULL;
+}
+
+
+static const command_rec mod_tokendb_config_cmds[] = {
+ AP_INIT_TAKE1( MOD_TOKENDB_CONFIGURATION_FILE_PARAMETER,
+ ( const char*(*)() ) mod_tokendb_get_config_path_file,
+ NULL,
+ RSRC_CONF,
+ MOD_TOKENDB_CONFIGURATION_FILE_USAGE ),
+ { NULL }
+};
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Server Configuration Creation Phase
+** _________________________________________________________________
+*/
+
+/**
+ * Create Tokendb module server configuration
+ */
+static void *
+mod_tokendb_config_server_create( apr_pool_t *p, server_rec *sv )
+{
+ /* Initialize all APR library routines. */
+ apr_initialize();
+
+ /* Create a memory pool for this server. */
+ mod_tokendb_server_configuration *sc = ( mod_tokendb_server_configuration * )
+ apr_pcalloc( p,
+ ( apr_size_t )
+ sizeof( *sc ) );
+
+ /* Initialize all members of mod_tokendb_server_configuration. */
+ sc->Tokendb_Configuration_File = NULL;
+ sc->enabled = MOD_TOKENDB_FALSE;
+
+ return sc;
+}
+
+
+
+/* _________________________________________________________________
+**
+** Tokendb Module Registration Phase
+** _________________________________________________________________
+*/
+
+static void
+mod_tokendb_register_hooks( apr_pool_t *p )
+{
+ static const char *const mod_tokendb_preloaded_modules[] = { "mod_nss.c",
+ "mod_tps.cpp",
+ NULL };
+ static const char *const mod_tokendb_postloaded_modules[] = { NULL };
+
+ ap_hook_post_config( mod_tokendb_initialize,
+ mod_tokendb_preloaded_modules,
+ mod_tokendb_postloaded_modules,
+ APR_HOOK_MIDDLE );
+
+ ap_hook_handler( mod_tokendb_handler,
+ mod_tokendb_preloaded_modules,
+ mod_tokendb_postloaded_modules,
+ APR_HOOK_MIDDLE );
+}
+
+
+module TOKENDB_PUBLIC MOD_TOKENDB_CONFIG_KEY = {
+ STANDARD20_MODULE_STUFF,
+ NULL, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ mod_tokendb_config_server_create, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ mod_tokendb_config_cmds, /* table of configuration directives */
+ mod_tokendb_register_hooks /* register hooks */
+};
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/base/tps/src/modules/tps/AP_Context.cpp b/base/tps/src/modules/tps/AP_Context.cpp
new file mode 100644
index 000000000..cde314254
--- /dev/null
+++ b/base/tps/src/modules/tps/AP_Context.cpp
@@ -0,0 +1,83 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "httpd/httpd.h"
+#include "httpd/http_log.h"
+#include "nspr.h"
+
+#include "modules/tps/AP_Context.h"
+
+#define MAX_LOG_MSG_SIZE 4096
+
+
+AP_Context::AP_Context( server_rec *sv )
+{
+ m_sv = sv;
+}
+
+
+AP_Context::~AP_Context()
+{
+ /* no clean up */
+}
+
+
+void AP_Context::LogError( const char *func, int line, const char *fmt, ... )
+{
+ char buf[MAX_LOG_MSG_SIZE];
+
+ va_list argp;
+ va_start( argp, fmt );
+ PR_vsnprintf( buf, MAX_LOG_MSG_SIZE, fmt, argp );
+ va_end( argp );
+
+ ap_log_error( func, line, APLOG_ERR, 0, m_sv, buf );
+}
+
+
+void AP_Context::LogInfo( const char *func, int line, const char *fmt, ... )
+{
+ char buf[MAX_LOG_MSG_SIZE];
+
+ va_list argp;
+ va_start( argp, fmt );
+ PR_vsnprintf( buf, MAX_LOG_MSG_SIZE, fmt, argp );
+ va_end( argp );
+
+ ap_log_error( func, line, APLOG_INFO, 0, m_sv, buf );
+}
+
+
+void AP_Context::InitializationError( const char *func, int line )
+{
+ ap_log_error( func, line, APLOG_INFO, 0, m_sv,
+ "The nss module must be initialized "
+ "prior to calling the tps module." );
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/base/tps/src/modules/tps/AP_Session.cpp b/base/tps/src/modules/tps/AP_Session.cpp
new file mode 100644
index 000000000..36f455355
--- /dev/null
+++ b/base/tps/src/modules/tps/AP_Session.cpp
@@ -0,0 +1,1169 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "nspr.h"
+#include "httpd/httpd.h"
+#include "httpd/http_protocol.h"
+
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "main/RA_Msg.h"
+#include "main/RA_pblock.h"
+#include "main/RA_Session.h"
+#include "msg/RA_Begin_Op_Msg.h"
+#include "msg/RA_Login_Response_Msg.h"
+#include "msg/RA_Extended_Login_Response_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_ASQ_Response_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "msg/RA_Login_Request_Msg.h"
+#include "msg/RA_Extended_Login_Request_Msg.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_ASQ_Request_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_End_Op_Msg.h"
+#include "msg/RA_Status_Update_Request_Msg.h"
+#include "msg/RA_Status_Update_Response_Msg.h"
+#include "modules/tps/AP_Session.h"
+#include "main/Memory.h"
+#include "apr_strings.h"
+
+/**
+ * http parameters used in the protocol
+ */
+#define PARAM_MSG_TYPE "msg_type"
+#define PARAM_OPERATION "operation"
+#define PARAM_INVALID_PW "invalid_pw"
+#define PARAM_BLOCKED "blocked"
+#define PARAM_SCREEN_NAME "screen_name"
+#define PARAM_PASSWORD "password"
+#define PARAM_PIN_REQUIRED "pin_required"
+#define PARAM_NEXT_VALUE "next_value"
+#define PARAM_VALUE "value"
+#define PARAM_PIN "pin"
+#define PARAM_QUESTION "question"
+#define PARAM_ANSWER "answer"
+#define PARAM_MINIMUM_LENGTH "minimum_length"
+#define PARAM_MAXIMUM_LENGTH "maximum_length"
+#define PARAM_NEW_PIN "new_pin"
+#define PARAM_PDU_SIZE "pdu_size"
+#define PARAM_PDU_DATA "pdu_data"
+#define PARAM_RESULT "result"
+#define PARAM_MESSAGE "message"
+#define PARAM_STATUS "current_state"
+#define PARAM_INFO "next_task_name"
+#define PARAM_EXTENSIONS "extensions"
+
+#define MAX_RA_MSG_SIZE 4096
+#define MAX_LOG_MSG_SIZE 4096
+
+// maximum number of digits for message length
+#define MAX_LEN_DIGITS 4
+
+
+static int contains_sensitive_keywords(char *msg)
+{
+ if (strstr(msg, "password" ) != NULL ) {
+ return 1;
+ }
+ if (strstr(msg, "PASSWORD" ) != NULL ) {
+ return 1;
+ }
+ if (strstr(msg, "new_pin" ) != NULL ) {
+ return 1;
+ }
+ return 0;
+}
+
+
+/**
+ * AP_Session represents an active connection between the
+ * Registration authority and the token client.
+ *
+ * Note that AP_Session encapsulates all the glue logic
+ * between Apache and the RA. If we need to go to anther platform
+ * (i.e. NPE, NES, or other web servers) later, we just need
+ * to implement a new Session implementation.
+ */
+AP_Session::AP_Session( request_rec *rq )
+{
+ m_rq = rq;
+ /* REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me */
+ ap_setup_client_block( rq, REQUEST_CHUNKED_DECHUNK);
+}
+
+
+AP_Session::~AP_Session()
+{
+ /* no clean up */
+}
+
+
+char *AP_Session::GetRemoteIP()
+{
+ return ( m_rq->connection->remote_ip );
+}
+
+
+/**
+ * reads from network "s=xx" where xx is the length of the message
+ * that follows. The length is returned as int.
+ * @return length in int
+ */
+static int GetMsgLen( request_rec *rq )
+{
+ int len=0;
+ char msg_len[MAX_LEN_DIGITS]; // msg_len can't take more than 4 digits
+ char *p_msg_len = msg_len;
+ int sum = 0;
+
+ /* read msg size */
+ len = ( int ) ap_get_client_block( rq, p_msg_len,
+ ( apr_size_t ) 1 ); /* s */
+ if( len != 1 ) {
+ RA::Error( "AP_Session::GetMsgLen",
+ "ap_get_client_block returned error: %d", len );
+
+ return 0;
+ }
+
+ len = ( int ) ap_get_client_block( rq, p_msg_len,
+ ( apr_size_t ) 1 ); /* = */
+
+ if( len != 1 ) {
+ RA::Error( "AP_Session::GetMsgLen",
+ "ap_get_client_block returned error: %d", len );
+
+ return 0;
+ }
+
+ while( 1 ) {
+ if( sum > ( MAX_LEN_DIGITS -1 ) ) {
+ /* the length is too large */
+ RA::Error( "AP_Session::ReadMsg", "Message Size is too large." );
+ return -1;
+ }
+
+ len = ( int ) ap_get_client_block( rq, p_msg_len, ( apr_size_t ) 1 );
+
+ if( len != 1 ) {
+ break;
+ }
+
+ if( len != 0 ) {
+ if( *p_msg_len == '&' ) {
+ break;
+ }
+
+ p_msg_len++;
+ sum++;
+ }
+ }
+
+ *p_msg_len = '\0';
+
+ return atoi( msg_len );
+}
+
+static int GetMsg( request_rec *rq, char *buf, int size )
+{
+ int len;
+ int sum = 0;
+ char *p_msg = buf;
+
+ while( 1 ) {
+ len = ( int ) ap_get_client_block( rq, p_msg, ( apr_size_t ) 1 );
+ if( len != 1 ) {
+ return -1;
+ }
+ p_msg += len;
+ sum += len;
+ buf[sum] = '\0';
+ if( sum == size ) {
+ break;
+ }
+ }
+
+ buf[sum] = '\0';
+
+ return sum;
+}
+
+char *stripEmptyArgs( char *data )
+{
+ char *n_data = ( char * ) PR_Malloc( strlen( data ) + 2 );
+ n_data[0] = '\0';
+ int nv_count = 0;
+
+ if( data != NULL && strlen( data ) > 0 ) {
+ char *lasts = NULL;
+ char *tok = PL_strtok_r( data, " ", &lasts );
+
+ while( tok != NULL ) {
+ if( tok[strlen( tok )-1] != '=' ) {
+ n_data = strcat( n_data, tok );
+ n_data = strcat( n_data, " " );
+ nv_count++;
+ }
+
+ tok = PL_strtok_r( NULL, " ", &lasts );
+ }
+ int len = strlen( n_data );
+ n_data[len-1] = '\0';
+ }
+
+ if( ( nv_count > MAX_NVS ) || ( n_data[0] == '\0' ) ) {
+ PR_Free( n_data );
+ n_data = NULL;
+ }
+
+ return n_data;
+}
+
+
+int pblock_str2pblock( char *n_data, apr_array_header_t *tm_pblock , request_rec *rec)
+{
+ int element = 0;
+
+ if( n_data != NULL && strlen( n_data ) > 0 ) {
+ char *lasts = NULL;
+ char *tok = PL_strtok_r( n_data, " ", &lasts );
+
+ /* store each name/value pair in the string into the pblock array */
+ while( tok != NULL ) {
+ char name[4096];
+ char value[4096];
+
+ for( int i = 0; i < ( int ) strlen( tok ); i++ ) {
+ if( tok[i] != '=' ) {
+ /* extract and add to the name portion */
+ name[i] = tok[i];
+ } else {
+ /* null terminate the name portion */
+ name[i] = '\0';
+ /* extract the entire value portion */
+ strcpy( value, &tok[i+1] );
+ break;
+ }
+ }
+
+ /* store the name/value pair as an entry in the pblock array */
+ ( ( apr_table_entry_t * ) tm_pblock->elts )[element].key =
+ apr_pstrdup(rec->pool, name);
+ ( ( apr_table_entry_t * ) tm_pblock->elts )[element].val =
+ apr_pstrdup(rec->pool, value);
+
+ /* increment the entry to the pblock array */
+ element++;
+
+ /* get the next name/value pair from the string */
+ tok = PL_strtok_r( NULL, " ", &lasts );
+ }
+ }
+
+ return element;
+}
+
+
+/**
+ * Parses the data and creates an RA_pblock to store name/value pairs
+ * @param data null-terminated string containing a string with format:
+ * n1=v1&n2=v2&n3=v3&...
+ * @return
+ * pointer to RA_pblock if success
+ * NULL if failure;
+ */
+RA_pblock *AP_Session::create_pblock( char *data )
+{
+ if( ( data == NULL ) || ( data[0] == '\0' ) ) {
+ RA::Error( "AP_Session::create_pblock",
+ "data is NULL" );
+ return NULL;
+ }
+
+ if(contains_sensitive_keywords(data)) {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "Data '(sensitive)'");
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "Data '%s'", data);
+ }
+
+ //
+ // The data contains a set of name value pairs separated by an '&'
+ // (i. e. - n1=v1&n2=v2...). Replace each '&' with a ' '.
+ //
+ // Note that since the values are expected to have been url-encoded,
+ // they must be url-decoded within the subclass method.
+ //
+ int i, j;
+ int len = strlen( data );
+
+ for( i = 0; i < len; i++ ) {
+ // need to check if data[i] is a valid url-encoded char...later
+ if( data[i] == '&' ) {
+ data[i] = ' ';
+ }
+ }
+
+ apr_array_header_t *tm_pblock = apr_array_make( m_rq->pool,
+ MAX_NVS,
+ sizeof( apr_table_entry_t )
+ );
+
+ if( tm_pblock == NULL ) {
+ RA::Error( "AP_Session::create_pblock",
+ "apr_array_make returns NULL" );
+ return NULL;
+ }
+
+ //
+ // The data is in the format of "name=v1 name=v2 name=v3". If the data
+ // has content like "name=v1 name= name=v3", the pblock_str2pblock will
+ // return (-1). This is because pblock_str2pblock does not know how to
+ // handle the case of an empty value. Therefore, before we invoke
+ // pblock_str2pblock, we make sure to remove any input data which
+ // contains an empty value.
+ //
+ char *n_data = stripEmptyArgs( data );
+ if( n_data == NULL ) {
+ RA::Error( "AP_Session::create_pblock",
+ "stripEmptyArgs was either empty or "
+ "contained more than %d name/value pairs!",
+ MAX_NVS );
+ return NULL;
+ }
+
+ int tm_nargs = pblock_str2pblock( n_data, tm_pblock , m_rq);
+ apr_table_entry_t *pe = NULL;
+
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "Found Arguments=%d, nalloc=%d",
+ tm_nargs,
+ tm_pblock->nalloc );
+
+ // url decode all values and place into Buffer_nv's
+ Buffer_nv *tm_nvs[MAX_NVS];
+
+ for( i = 0, j = 0; i < tm_nargs; i++, j++ ) {
+ tm_nvs[j] = NULL;
+
+ pe = ( apr_table_entry_t * ) tm_pblock->elts;
+
+ if( pe == NULL ) {
+ continue;
+ }
+
+ if( ( pe[i].key == NULL ) ||
+ ( ( PR_CompareStrings( pe[i].key, "" ) == 1 ) ) ||
+ ( pe[i].val == NULL ) ||
+ ( ( PR_CompareStrings( pe[i].val, "" ) == 1 ) ) ) {
+ RA::Debug( LL_ALL_DATA_IN_PDU,
+ "AP_Session::create_pblock",
+ "name/value pair contains NULL...skip" );
+ continue;
+ }
+
+ if(contains_sensitive_keywords(pe[i].key)) {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "entry name=%s, value=<...do not print...>",
+ pe[i].key );
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "entry name=%s, value=%s",
+ pe[i].key,
+ pe[i].val );
+ }
+
+ Buffer *decoded = NULL;
+
+ decoded = Util::URLDecode( pe[i].val );
+
+ tm_nvs[j] = ( struct Buffer_nv * )
+ PR_Malloc( sizeof( struct Buffer_nv ) );
+
+ if( tm_nvs[j] != NULL ) {
+ tm_nvs[j]->name = PL_strdup( pe[i].key );
+ tm_nvs[j]->value_s = PL_strdup( pe[i].val );
+ tm_nvs[j]->value = decoded;
+ } else {
+ RA::Debug( LL_PER_PDU,
+ "AP_Session::create_pblock",
+ "tm_nvs[%d] is NULL",
+ j );
+ }
+ } // for
+
+ RA_pblock *ra_pb = new RA_pblock( tm_nargs, tm_nvs );
+
+ if( n_data != NULL ) {
+ PR_Free( n_data );
+ n_data = NULL;
+ }
+
+ if( ra_pb == NULL ) {
+ RA::Error( "AP_Session::create_pblock",
+ "RA_pblock is NULL" );
+ return NULL;
+ }
+
+ return ra_pb;
+}
+
+RA_Msg *AP_Session::ReadMsg()
+{
+ int len;
+ int msg_len = 0;
+ char msg[MAX_RA_MSG_SIZE];
+ char *msg_type = NULL;
+ int i_msg_type;
+ Buffer *msg_type_b = NULL;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "========== ReadMsg Begins =======" );
+
+ msg_len = GetMsgLen( m_rq );
+
+ if( ( msg_len <= 0 ) || ( msg_len > MAX_RA_MSG_SIZE ) ) {
+ RA::Error( "AP_Session::ReadMsg",
+ "Message Size not in range. size =%d. Operation may have been cancelled.", msg_len );
+ return NULL;
+ }
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg", "msg_len=%d", msg_len );
+
+ len = GetMsg( m_rq, msg, msg_len );
+
+ if( len != msg_len ) {
+ RA::Error( "AP_Session::ReadMsg",
+ "Message Size Mismatch. Expected '%d' Received '%d'",
+ msg_len, len );
+ return NULL;
+ }
+
+ if(!contains_sensitive_keywords(msg)) {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Received len='%d' msg='%s'", len, msg );
+ } else {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Received len='%d' msg='<Password or new pin>'", len );
+ }
+
+ RA_Msg *ret_msg = NULL;
+
+ // format into array of name/value pair with value Buffer's
+ RA_pblock *ra_pb = ( RA_pblock * ) create_pblock( msg );
+
+ if( ra_pb == NULL ) {
+ goto loser;
+ }
+
+ // msg_type_b will be freed by destructor of RA_pblock
+ msg_type_b = ra_pb->find_val( PARAM_MSG_TYPE );
+ if( msg_type_b == NULL ) {
+ goto loser;
+ }
+
+ // msg_type should be freed when done using
+ msg_type = msg_type_b->string();
+
+ if( msg_type == NULL ) {
+ RA::Error( "AP_Session::ReadMsg",
+ "Parameter Not Found %s", PARAM_MSG_TYPE );
+ goto loser;
+ }
+
+ i_msg_type = atoi( msg_type );
+
+ switch( i_msg_type )
+ {
+ case MSG_BEGIN_OP: /* BEGIN_OP */
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "BEGIN_OP", msg_type );
+
+ Buffer *opB = ra_pb->find_val( PARAM_OPERATION );
+
+ if( opB == NULL ) {
+ goto loser;
+ }
+
+ RA::DebugBuffer( "AP_Session::ReadMsg", "content=", opB );
+
+ char *op_c = opB->string();
+
+ if( op_c == NULL ) {
+ goto loser;
+ }
+
+ int i_op = atoi( op_c );
+
+ if( op_c != NULL ) {
+ PR_Free( op_c );
+ op_c = NULL;
+ }
+
+ NameValueSet *exts = NULL;
+
+ Buffer *opE = ra_pb->find_val( PARAM_EXTENSIONS ); // optional
+
+ if( opE != NULL ) {
+ char *op_e = opE->string();
+ if( op_e == NULL ) {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "No extensions" );
+ } else {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Extensions %s", op_e );
+ exts = NameValueSet::Parse( op_e, "&" );
+ if( op_e != NULL ) {
+ PR_Free( op_e );
+ op_e = NULL;
+ }
+ }
+ }
+
+ switch( i_op )
+ {
+ case OP_ENROLL:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=ENROLL" );
+ ret_msg = new RA_Begin_Op_Msg( OP_ENROLL, exts );
+ break;
+ }
+ case OP_UNBLOCK:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=UNBLOCK" );
+ ret_msg = new RA_Begin_Op_Msg( OP_UNBLOCK, exts );
+ break;
+ }
+ case OP_RESET_PIN:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=RESET_PIN" );
+ ret_msg = new RA_Begin_Op_Msg( OP_RESET_PIN, exts );
+ break;
+ }
+ case OP_RENEW:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=RENEW" );
+ ret_msg = new RA_Begin_Op_Msg( OP_RENEW, exts );
+ break;
+ }
+ case OP_FORMAT:
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "begin_op_msg msg_type=FORMAT" );
+ ret_msg = new RA_Begin_Op_Msg( OP_FORMAT, exts );
+ break;
+ }
+ default:
+ {
+ break;
+ /* error */
+ }
+ } // switch( i_op )
+
+ break;
+ }
+ case MSG_EXTENDED_LOGIN_RESPONSE: /* LOGIN_RESPONSE */
+ {
+ char *name = NULL;
+ Buffer* value = NULL;
+ char *bufferStr = NULL;
+ AuthParams *params = new AuthParams();
+ int i;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "EXTENDED_LOGIN_RESPONSE", msg_type );
+
+ i = ra_pb->get_num_of_names();
+
+ for( i = 0; i < ra_pb->get_num_of_names(); i++ ) {
+ name = ra_pb->get_name( i );
+ if( name != NULL ) {
+ value = ra_pb->find_val( ( const char * ) name );
+ bufferStr = value->string();
+ if( value != NULL ) {
+ params->Add( name, bufferStr );
+ }
+ if (bufferStr != NULL) {
+ PR_Free(bufferStr);
+ bufferStr = NULL;
+ }
+ }
+ }
+
+ ret_msg = new RA_Extended_Login_Response_Msg( params );
+
+ break;
+ }
+ case MSG_LOGIN_RESPONSE: /* LOGIN_RESPONSE */
+ {
+ char *uid = NULL, *password = NULL;
+ Buffer *uid_b, *pwd_b = NULL;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "LOGIN_RESPONSE", msg_type );
+
+ uid_b = ra_pb->find_val( PARAM_SCREEN_NAME );
+
+ if( uid_b == NULL ) {
+ goto aloser;
+ }
+
+ uid = uid_b->string();
+
+ if( uid == NULL ) {
+ goto aloser;
+ }
+
+ pwd_b = ra_pb->find_val( PARAM_PASSWORD );
+
+ if( pwd_b == NULL ) {
+ goto aloser;
+ }
+
+ password = pwd_b->string();
+
+ if( password == NULL ) {
+ goto aloser;
+ }
+
+ ret_msg = new RA_Login_Response_Msg( uid, password );
+
+ aloser:
+ if( uid != NULL ) {
+ PR_Free( uid );
+ uid = NULL;
+ }
+
+ if( password != NULL ) {
+ PR_Free( password );
+ password = NULL;
+ }
+
+ goto loser;
+
+ break;
+ }
+ case MSG_STATUS_UPDATE_RESPONSE: /* SECUREID_RESPONSE */
+ {
+ char *value = NULL;
+ Buffer *value_b;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "STATUS_UPDATE_RESPONSE", msg_type );
+
+ value_b = ra_pb->find_val( PARAM_STATUS );
+
+ if( value_b == NULL ) {
+ goto zloser;
+ }
+
+ value = value_b->string();
+
+ if( value == NULL ) {
+ goto zloser;
+ }
+
+ ret_msg = new RA_Status_Update_Response_Msg( atoi( value ) );
+
+ zloser:
+ if( value != NULL ) {
+ PR_Free( value );
+ value = NULL;
+ }
+
+ goto loser;
+
+ break;
+ }
+ case MSG_SECUREID_RESPONSE: /* SECUREID_RESPONSE */
+ {
+ char *value = NULL, *pin = NULL;
+ Buffer *value_b = NULL, *pin_b = NULL;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "SECUREID_RESPONSE", msg_type );
+
+ value_b = ra_pb->find_val( PARAM_VALUE );
+
+ if( value_b == NULL ) {
+ goto bloser;
+ }
+
+ value = value_b->string();
+
+ if( value == NULL ) {
+ goto bloser;
+ }
+
+ pin_b = ra_pb->find_val( PARAM_PIN );
+
+ if( pin_b == NULL ) {
+ goto bloser;
+ }
+
+ pin = pin_b->string();
+
+ if( pin == NULL ) {
+ pin_b->zeroize();
+ goto bloser;
+ }
+
+ ret_msg = new RA_SecureId_Response_Msg( value, pin );
+
+ if( pin != NULL ) {
+ // zeroize memory before releasing
+ unsigned int i = 0;
+ for( i = 0; i < strlen( pin ); i++ ) {
+ pin[i] = '\0';
+ }
+ if( pin != NULL ) {
+ PR_Free( pin );
+ pin = NULL;
+ }
+ }
+
+ pin_b->zeroize();
+
+ bloser:
+ if( value != NULL ) {
+ PR_Free( value );
+ value = NULL;
+ }
+
+ if( pin != NULL ) {
+ PR_Free( pin );
+ pin = NULL;
+ }
+
+ goto loser;
+
+ break;
+ }
+ case MSG_ASQ_RESPONSE: /* ASQ_RESPONSE */
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "ASQ_RESPONSE", msg_type );
+
+ Buffer *ans_b = ra_pb->find_val( PARAM_ANSWER );
+
+ if( ans_b == NULL ) {
+ goto loser;
+ }
+
+ char *answer = ans_b->string();
+
+ if( answer == NULL ) {
+ goto loser;
+ }
+
+ ret_msg = new RA_ASQ_Response_Msg( answer );
+
+ if( answer != NULL ) {
+ PR_Free( answer );
+ answer = NULL;
+ }
+
+ break;
+ }
+ case MSG_TOKEN_PDU_RESPONSE: /* TOKEN_PDU_RESPONSE */
+ {
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "TOKEN_PDU_RESPONSE", msg_type );
+
+ unsigned int pdu_size =0;
+
+ Buffer *pdu_size_b = ra_pb->find_val( PARAM_PDU_SIZE );
+
+ if( pdu_size_b == NULL ) {
+ goto loser;
+ }
+
+ char *p = pdu_size_b->string();
+
+ pdu_size = atoi( p );
+
+ if( p != NULL ) {
+ PR_Free( p );
+ p = NULL;
+ }
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%d", PARAM_PDU_SIZE, pdu_size );
+
+ if( pdu_size > 261 ) {
+ RA::Error( LL_PER_PDU, "AP_Session::ReadMsg",
+ "%s exceeds limit", PARAM_PDU_SIZE );
+ goto loser;
+ }
+
+ Buffer *decoded_pdu = ra_pb->find_val( PARAM_PDU_DATA );
+
+ if( decoded_pdu == NULL ) {
+ goto loser;
+ }
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "decoded_pdu size= %d", decoded_pdu->size() );
+
+ if( pdu_size != decoded_pdu->size() ) {
+ goto loser;
+ }
+
+ RA::DebugBuffer( "AP_Session::ReadMsg",
+ "decoded pdu = ", decoded_pdu );
+
+ APDU_Response *response = new APDU_Response( *decoded_pdu );
+
+ ret_msg = new RA_Token_PDU_Response_Msg( response );
+
+ break;
+ }
+ case MSG_NEW_PIN_RESPONSE: /* NEW_PIN_RESPONSE */
+ {
+ char *new_pin = NULL;
+ Buffer *new_pin_b = NULL;
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "Found %s=%s (%s)", PARAM_MSG_TYPE,
+ "NEW_PIN_RESPONSE", msg_type );
+
+ new_pin_b = ra_pb->find_val( PARAM_NEW_PIN );
+
+ if( new_pin_b == NULL ) {
+ goto loser;
+ }
+
+ new_pin = new_pin_b->string();
+
+ if( new_pin == NULL ) {
+ new_pin_b->zeroize();
+ goto loser;
+ }
+
+ ret_msg = new RA_New_Pin_Response_Msg( new_pin );
+
+ if( new_pin != NULL ) {
+ // zeroize memory before releasing
+ unsigned int i = 0;
+
+ for( i = 0; i< strlen( new_pin ); i++ ) {
+ new_pin[i] = '\0';
+ }
+
+ if( new_pin != NULL ) {
+ PR_Free( new_pin );
+ new_pin = NULL;
+ }
+ }
+
+ new_pin_b->zeroize();
+
+ break;
+ }
+ default:
+ {
+ RA::Error( "AP_Session::ReadMsg", "Found %s=%s",
+ PARAM_MSG_TYPE, "UNDEFINED" );
+ /* error */
+ break;
+ }
+ } // switch( i_msg_type )
+
+loser:
+ if( msg_type != NULL ) {
+ PR_Free( msg_type );
+ msg_type = NULL;
+ }
+
+ if( ra_pb != NULL ) {
+ delete ra_pb;
+ ra_pb = NULL;
+ }
+
+ RA::Debug( LL_PER_PDU, "AP_Session::ReadMsg",
+ "========= ReadMsg Ends =========" );
+
+ return ret_msg;
+}
+
+static void CreateChunk( char *msgbuf, char *buf, int buflen )
+{
+ int len;
+
+ len = strlen( msgbuf );
+ sprintf( buf, "s=%d&%s", len, msgbuf );
+}
+
+void AP_Session::WriteMsg( RA_Msg *msg )
+{
+ char msgbuf[MAX_RA_MSG_SIZE];
+ char buf[MAX_RA_MSG_SIZE];
+
+ switch( msg->GetType() )
+ {
+ case MSG_EXTENDED_LOGIN_REQUEST:
+ {
+ RA_Extended_Login_Request_Msg *login_request_msg =
+ ( RA_Extended_Login_Request_Msg * ) msg;
+ int invalid_password = login_request_msg->IsInvalidPassword();
+ int is_blocked = login_request_msg->IsBlocked();
+
+ char *title = Util::URLEncode( login_request_msg->GetTitle() );
+ char *desc = Util::URLEncode( login_request_msg->GetDescription() );
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d&%s=%s&%s=%s",
+ PARAM_MSG_TYPE, MSG_EXTENDED_LOGIN_REQUEST,
+ "invalid_login", invalid_password,
+ PARAM_BLOCKED, is_blocked,
+ "title", title,
+ "description", desc);
+ if (title != NULL) {
+ PR_Free(title);
+ title = NULL;
+ }
+
+ if (desc != NULL) {
+ PR_Free(desc);
+ desc = NULL;
+ }
+
+ for( int i = 0; i < login_request_msg->GetLen(); i++ ) {
+ char *p = login_request_msg->GetParam( i );
+ char *encp = Util::URLEncode1( p );
+ sprintf( msgbuf, "%s&required_parameter%d=%s",
+ msgbuf, i, encp );
+ if (encp != NULL) {
+ PR_Free(encp);
+ encp = NULL;
+ }
+ }
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+ break;
+ }
+ case MSG_LOGIN_REQUEST:
+ {
+ RA_Login_Request_Msg *login_request_msg =
+ ( RA_Login_Request_Msg * ) msg;
+ int invalid_password = login_request_msg->IsInvalidPassword();
+ int is_blocked = login_request_msg->IsBlocked();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d",
+ PARAM_MSG_TYPE, MSG_LOGIN_REQUEST,
+ PARAM_INVALID_PW, invalid_password,
+ PARAM_BLOCKED, is_blocked );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_END_OP:
+ {
+ RA_End_Op_Msg *end_op = ( RA_End_Op_Msg * ) msg;
+ int result = end_op->GetResult();
+ int local_msg = end_op->GetMsg();
+ int op = end_op->GetOpType();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d&%s=%d\r\n0\r\n",
+ PARAM_MSG_TYPE, MSG_END_OP,
+ PARAM_OPERATION, op,
+ PARAM_RESULT, result,
+ PARAM_MESSAGE, local_msg );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_STATUS_UPDATE_REQUEST:
+ {
+ RA_Status_Update_Request_Msg *status_update_request_msg =
+ ( RA_Status_Update_Request_Msg * ) msg;
+ int status = status_update_request_msg->GetStatus();
+ char *info = status_update_request_msg->GetInfo();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%s",
+ PARAM_MSG_TYPE, MSG_STATUS_UPDATE_REQUEST,
+ PARAM_STATUS, status,
+ PARAM_INFO, info );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_SECUREID_REQUEST:
+ {
+ RA_SecureId_Request_Msg *secureid_request_msg =
+ ( RA_SecureId_Request_Msg * ) msg;
+ int is_pin_required = secureid_request_msg->IsPinRequired();
+ int is_next_value = secureid_request_msg->IsNextValue();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d",
+ PARAM_MSG_TYPE, MSG_SECUREID_REQUEST,
+ PARAM_PIN_REQUIRED, is_pin_required,
+ PARAM_NEXT_VALUE, is_next_value );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_ASQ_REQUEST:
+ {
+ RA_ASQ_Request_Msg *asq_request_msg = ( RA_ASQ_Request_Msg * ) msg;
+ char *question = asq_request_msg->GetQuestion();
+
+ sprintf( msgbuf, "%s=%d&%s=%s",
+ PARAM_MSG_TYPE, MSG_ASQ_REQUEST,
+ PARAM_QUESTION, question );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_NEW_PIN_REQUEST:
+ {
+ RA_New_Pin_Request_Msg *new_pin_request_msg =
+ ( RA_New_Pin_Request_Msg * ) msg;
+ int min = new_pin_request_msg->GetMinLen();
+ int max = new_pin_request_msg->GetMaxLen();
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%d",
+ PARAM_MSG_TYPE, MSG_NEW_PIN_REQUEST,
+ PARAM_MINIMUM_LENGTH, min,
+ PARAM_MAXIMUM_LENGTH, max );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ case MSG_TOKEN_PDU_REQUEST:
+ {
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg =
+ ( RA_Token_PDU_Request_Msg * ) msg;
+ APDU *apdu = token_pdu_request_msg->GetAPDU();
+ Buffer encoding;
+
+ apdu->GetEncoding( encoding );
+
+ int pdu_len = encoding.size();
+
+ RA::Debug( LL_PER_CONNECTION, "AP_Session::WriteMsg",
+ "pdu_len='%d'", pdu_len );
+
+ Buffer pdu = encoding;
+ char *pdu_encoded = NULL;
+
+ if( RA::GetConfigStore()->GetConfigAsBool( "pdu_encoding.hex_mode",
+ 1 ) ) {
+ // pdu will be encoded in Hex mode which is easier to read
+ pdu_encoded = Util::URLEncodeInHex( pdu );
+ } else {
+ pdu_encoded = Util::URLEncode( pdu );
+ }
+
+ sprintf( msgbuf, "%s=%d&%s=%d&%s=%s",
+ PARAM_MSG_TYPE, MSG_TOKEN_PDU_REQUEST,
+ PARAM_PDU_SIZE, pdu_len,
+ PARAM_PDU_DATA, pdu_encoded );
+
+ CreateChunk( msgbuf, buf, MAX_RA_MSG_SIZE );
+
+ if( pdu_encoded != NULL ) {
+ PR_Free( pdu_encoded );
+ pdu_encoded = NULL;
+ }
+
+ RA::Debug( "AP_Session::WriteMsg", "Sent '%s'", buf );
+
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), m_rq );
+
+ break;
+ }
+ default:
+ {
+ break;
+ /* error */
+ }
+ } // switch( msg->GetType() )
+
+ ap_rflush(m_rq);
+
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/base/tps/src/modules/tps/CMakeLists.txt b/base/tps/src/modules/tps/CMakeLists.txt
new file mode 100644
index 000000000..275d8b30a
--- /dev/null
+++ b/base/tps/src/modules/tps/CMakeLists.txt
@@ -0,0 +1,52 @@
+project(tps_module CXX)
+
+set(TPS_PRIVATE_INCLUDE_DIRS
+ ${TPS_INCLUDE_DIR}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${APR_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(TPS_MODULE
+ tps_module
+ CACHE INTERNAL "tps apache module"
+)
+
+set(TPS_LINK_LIBRARIES
+ ${TPS_SHARED_LIBRARY}
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${APR_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+ ${TOKENDB_SHARED_LIBRARY}
+ ${TPS_SHARED_LIBRARY}
+)
+
+set(tps_module_SRCS
+ AP_Context.cpp
+ AP_Session.cpp
+ mod_tps.cpp
+)
+
+include_directories(${TPS_PRIVATE_INCLUDE_DIRS})
+
+add_library(${TPS_MODULE} MODULE ${tps_module_SRCS})
+target_link_libraries(${TPS_MODULE} ${TPS_LINK_LIBRARIES})
+
+set_target_properties(${TPS_MODULE}
+ PROPERTIES
+ OUTPUT_NAME
+ mod_tps
+ PREFIX ""
+)
+
+install(
+ TARGETS
+ ${TPS_MODULE}
+ DESTINATION
+ ${LIB_INSTALL_DIR}/httpd/modules
+)
diff --git a/base/tps/src/modules/tps/mod_tps.cpp b/base/tps/src/modules/tps/mod_tps.cpp
new file mode 100644
index 000000000..dc6cc95f9
--- /dev/null
+++ b/base/tps/src/modules/tps/mod_tps.cpp
@@ -0,0 +1,732 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Headers
+** _________________________________________________________________
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include "nspr.h"
+
+#include "httpd/httpd.h"
+#include "httpd/http_config.h"
+#include "httpd/http_log.h"
+#include "httpd/http_protocol.h"
+#include "httpd/http_main.h"
+
+#include "apr_strings.h"
+
+#include "engine/RA.h"
+#include "main/Memory.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "modules/tps/AP_Context.h"
+#include "modules/tps/AP_Session.h"
+#include "msg/RA_Begin_Op_Msg.h"
+#include "msg/RA_End_Op_Msg.h"
+#include "processor/RA_Enroll_Processor.h"
+#include "processor/RA_Format_Processor.h"
+#include "processor/RA_Pin_Reset_Processor.h"
+#include "processor/RA_Renew_Processor.h"
+#include "processor/RA_Unblock_Processor.h"
+#include "ssl.h"
+
+#define MOD_TPS_KEY_NAME "mod_tps"
+
+/* _________________________________________________________________
+**
+** TPS Module Request Data
+** _________________________________________________________________
+*/
+
+/**
+ * Processors for different operations.
+ */
+static RA_Enroll_Processor m_enroll_processor;
+static RA_Unblock_Processor m_unblock_processor;
+static RA_Pin_Reset_Processor m_pin_reset_processor;
+static RA_Renew_Processor m_renew_processor;
+static RA_Format_Processor m_format_processor;
+
+
+/* _________________________________________________________________
+**
+** TPS Module Command Data
+** _________________________________________________________________
+*/
+
+static const char MOD_TPS_CONFIGURATION_FILE_PARAMETER[] = "TPSConfigPathFile";
+
+static const char MOD_TPS_CONFIGURATION_FILE_USAGE[] =
+"TPS Configuration Filename prefixed by a complete path, or\n"
+"a path that is relative to the Apache server root.";
+
+/* per-process config structure */
+typedef struct {
+ int nInitCount;
+ int nSignedAuditInitCount;
+} mod_tps_global_config;
+
+
+/* _________________________________________________________________
+**
+** TPS Module Server Configuration Creation Data
+** _________________________________________________________________
+*/
+
+typedef struct {
+ char *TPS_Configuration_File;
+ AP_Context *context;
+ mod_tps_global_config *gconfig; /* pointer to per-process config */
+} mod_tps_server_configuration;
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Registration Data
+** _________________________________________________________________
+*/
+
+#define MOD_TPS_CONFIG_KEY tps_module
+
+static const char MOD_TPS_CONFIG_KEY_NAME[] = "tps_module";
+
+extern module TPS_PUBLIC MOD_TPS_CONFIG_KEY;
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Helper Functions
+** _________________________________________________________________
+*/
+
+mod_tps_global_config *mod_tps_config_global_create(server_rec *s)
+{
+ apr_pool_t *pool = s->process->pool;
+ mod_tps_global_config *globalc = NULL;
+ void *vglobalc = NULL;
+
+ apr_pool_userdata_get(&vglobalc, MOD_TPS_KEY_NAME, pool);
+ if (vglobalc) {
+ return (mod_tps_global_config *) vglobalc; /* reused for lifetime of the server */
+ }
+
+ /*
+ * allocate an own subpool which survives server restarts
+ */
+ globalc = (mod_tps_global_config *)apr_palloc(pool, sizeof(*globalc));
+
+ /*
+ * initialize per-module configuration
+ */
+ globalc->nInitCount = 0;
+ globalc->nSignedAuditInitCount = 0;
+
+ apr_pool_userdata_set(globalc, MOD_TPS_KEY_NAME,
+ apr_pool_cleanup_null,
+ pool);
+
+ return globalc;
+}
+
+/**
+ * Terminate Apache
+ */
+void tps_die( void )
+{
+ /*
+ * This is used for fatal errors and here
+ * it is common module practice to really
+ * exit from the complete program.
+ */
+ exit( 1 );
+}
+
+
+/**
+ * Creates an RA_Session from the RA framework.
+ *
+ * Centralize the allocation of the session object here so that
+ * we can provide our own session management here in the future.
+ */
+static RA_Session *
+mod_tps_create_session( request_rec *rq )
+{
+ return new AP_Session( rq );
+} /* mod_tps_create_session */
+
+
+/**
+ * Returns RA_Session to the RA framework.
+ */
+static void
+mod_tps_destroy_session( RA_Session *session )
+{
+ if( session != NULL ) {
+ delete session;
+ session = NULL;
+ }
+} /* mod_tps_destroy_session */
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Request Phase
+** _________________________________________________________________
+*/
+
+/**
+ * Terminate the TPS module
+ */
+static apr_status_t
+mod_tps_terminate( void *data )
+{
+ /* This routine is ONLY called when this server's */
+ /* pool has been cleared or destroyed. */
+
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_terminate",
+ "The TPS module has been terminated!" );
+
+ /* Free TPS resources. */
+ RA::Shutdown();
+
+ /* Since all members of mod_tps_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+#ifdef MEM_PROFILING
+ /* If memory profiling is enabled, turn off memory profiling. */
+ MEM_shutdown();
+#endif
+
+ SSL_ClearSessionCache();
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ /* Allow the NSS Module to perform this task. */
+ /* apr_terminate(); */
+
+
+ /* Terminate the entire Apache server */
+ /* NOTE: Allow the NSS Module to perform this task. */
+ /* tps_die(); */
+
+ return OK;
+}
+
+static apr_status_t
+mod_tps_child_terminate (void *data)
+{
+ RA::Debug("mod_tps::mod_tps_child_terminate",
+ "The TPS module has been terminated!" );
+
+ /* Free TPS resources. */
+ RA::Child_Shutdown();
+
+ return OK;
+}
+
+static int
+mod_tps_initialize( apr_pool_t *p,
+ apr_pool_t *plog,
+ apr_pool_t *ptemp,
+ server_rec *sv )
+{
+ mod_tps_server_configuration *sc = NULL;
+ char *cfg_path_file = NULL;
+ int status;
+
+ /* Retrieve the TPS module. */
+ sc = ( ( mod_tps_server_configuration * )
+ ap_get_module_config( sv->module_config,
+ &MOD_TPS_CONFIG_KEY ) );
+
+ /* Check to see if the TPS module has been loaded. */
+ if( sc->context != NULL ) {
+ return OK;
+ }
+
+ sc->gconfig->nInitCount++;
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, sv,
+ "Entering mod_tps_initialize - init count is [%d]",
+ sc->gconfig->nInitCount);
+
+ /* Load the TPS module. */
+
+#ifdef MEM_PROFILING
+ /* If memory profiling is enabled, turn on memory profiling. */
+ MEM_init( MEM_AUDIT_FILE, MEM_DUMP_FILE );
+#endif
+
+ /* Retrieve the path to where the configuration files are located, */
+ /* and insure that the TPS module configuration file is located here. */
+ if( sc->TPS_Configuration_File != NULL ) {
+ /* provide TPS Config File from <apache_server_root>/conf/httpd.conf */
+ if( sc->TPS_Configuration_File[0] == '/' ) {
+ /* Complete path to TPS Config File is denoted */
+ cfg_path_file = apr_psprintf( p,
+ "%s",
+ ( char * )
+ sc->TPS_Configuration_File );
+ } else {
+ /* TPS Config File is located relative to the Apache server root */
+ cfg_path_file = apr_psprintf( p,
+ "%s/%s",
+ ( char * ) ap_server_root,
+ ( char * )
+ sc->TPS_Configuration_File );
+ }
+ } else {
+ /* Log information regarding this failure. */
+ ap_log_error( "mod_tps_initialize",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tps module was installed incorrectly since the "
+ "parameter named '%s' is missing from the Apache "
+ "Configuration file!",
+ ( char * ) MOD_TPS_CONFIGURATION_FILE_PARAMETER );
+
+ /* Display information on the screen regarding this failure. */
+ printf( "\nUnable to start Apache:\n"
+ " The tps module is missing the required parameter named\n"
+ " '%s' in the Apache Configuration file!\n",
+ ( char * ) MOD_TPS_CONFIGURATION_FILE_PARAMETER );
+
+ goto loser;
+ }
+
+ /* Initialize the "server" member of mod_tps_server_configuration. */
+ sc->context = new AP_Context( sv );
+
+ status = RA::Initialize( cfg_path_file, sc->context );
+ if( status != RA_INITIALIZATION_SUCCESS ) {
+ /* Log information regarding this failure. */
+ ap_log_error( "mod_tps_initialize",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tps module was installed incorrectly "
+ "since the file named '%s' does not exist!",
+ cfg_path_file );
+
+ /* Display information on the screen regarding this failure. */
+ printf( "\nUnable to start Apache:\n"
+ " The tps module configuration file called\n"
+ " '%s' does not exist!\n",
+ cfg_path_file );
+
+ /* Since all members of mod_tps_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+ goto loser;
+ }
+
+ if (sc->gconfig->nInitCount < 2 ) {
+ sc->gconfig->nSignedAuditInitCount++;
+ status = RA::InitializeInChild( sc->context,
+ sc->gconfig->nSignedAuditInitCount);
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, sv,
+ "mod_tps_initialize - pid is [%d] - post config already done once -"
+ " additional config will be done in init_child",
+ getpid());
+ status = RA_INITIALIZATION_SUCCESS;
+ }
+
+ if (status != RA_INITIALIZATION_SUCCESS ) {
+ ap_log_error( "mod_tps_initialize",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tps module failed to do the initializeInChild tasks. ");
+ printf( "\nUnable to start Apache:\n"
+ " The tps module failed to do the initializeInChild tasks. ");
+ goto loser;
+ }
+
+ /* Register a server termination routine. */
+ apr_pool_cleanup_register( p,
+ sv,
+ mod_tps_terminate,
+ apr_pool_cleanup_null );
+
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_initialize",
+ "The TPS module has been successfully loaded!" );
+
+ return OK;
+
+loser:
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_initialize",
+ "Failed loading the TPS module!" );
+
+ if( sc->context != NULL ) {
+ /* Free TPS resources. */
+ RA::Shutdown();
+
+ /* Since all members of mod_tps_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+ }
+
+#ifdef MEM_PROFILING
+ /* If memory profiling is enabled, turn off memory profiling. */
+ MEM_shutdown();
+#endif
+
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ apr_terminate();
+
+ /* Terminate the entire Apache server */
+ tps_die();
+
+ return DECLINED;
+}
+
+/**
+ * mod_tps_handler handles the protocol between the token client
+ * and the RA (Session)
+ */
+static int
+mod_tps_handler( request_rec *rq )
+{
+ char buf[1024];
+ int ret_code = DECLINED;
+ int status = DECLINED;
+ RA_Session *session = NULL;
+ RA_Begin_Op_Msg *begin_op_msg = NULL;
+ NameValueSet *extensions = NULL;
+ const char *tenc = apr_table_get(rq->headers_in, "Transfer-Encoding");
+
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_handler",
+ "mod_tps::mod_tps_handler" );
+
+ RA::Debug( "mod_tps::mod_tps_handler",
+ "uri '%s'", rq->uri);
+
+ /* XXX: We need to change "nk_service" to "tps",
+ and need to update ESC. */
+ if (strcmp(rq->handler,"nk_service") != 0) {
+ RA::Debug( "mod_tps::mod_tps_handler",
+ "DECLINED uri '%s'", rq->uri);
+ return DECLINED;
+ }
+
+ RA::Debug( "mod_tps::mod_tps_handler",
+ "uri '%s' DONE", rq->uri);
+
+ /*
+ * check to see if the http request contains
+ * "transfer-encoding: chunked"
+ */
+ /* XXX: rq->chunked not set to true even in the chunked mode */
+ if(!tenc || PL_strcasecmp(tenc, "chunked") != 0) {
+ /* print the following when browser accesses directly */
+ strcpy( buf, "<HTML>Registration Authority</HTML>" );
+
+ /* write out the data */
+ ( void ) ap_rwrite( ( const void * ) buf, strlen( buf ), rq );
+
+ ret_code = OK;
+
+ return ret_code;
+ }
+
+ /* request contains chunked encoding */
+ session = mod_tps_create_session( rq );
+
+ /* read in the data present on the connection */
+ begin_op_msg = ( RA_Begin_Op_Msg * ) session->ReadMsg();
+ if( begin_op_msg == NULL ) {
+ /* Log TPS module error information. */
+ RA::Error( "mod_tps::mod_tps_handler",
+ "no begin op found" );
+ goto loser;
+ }
+
+ /* retrieve the extensions */
+ extensions = begin_op_msg->GetExtensions();
+
+ /* perform the appropriate processing based upon the type of operation */
+ if( begin_op_msg->GetOpType() == OP_ENROLL ) {
+ status = m_enroll_processor.Process( session, extensions );
+ } else if( begin_op_msg->GetOpType() == OP_UNBLOCK ) {
+ status = m_unblock_processor.Process( session, extensions );
+ } else if( begin_op_msg->GetOpType() == OP_RESET_PIN ) {
+ status = m_pin_reset_processor.Process( session, extensions );
+ } else if( begin_op_msg->GetOpType() == OP_RENEW ) {
+ status = m_renew_processor.Process( session, extensions );
+ } else if( begin_op_msg->GetOpType() == OP_FORMAT ) {
+ status = m_format_processor.Process( session, extensions );
+ } else {
+ /* Log TPS module error information. */
+ RA::Error( "mod_tps::mod_tps_handler",
+ "unknown operation requested (op='%d')",
+ begin_op_msg->GetOpType() );
+ goto loser;
+ } /* if */
+
+ ret_code = OK;
+
+loser:
+ /* determine the results of the operation and report it */
+ if( begin_op_msg != NULL ) {
+ int result;
+
+ if( status == 0 ) {
+ result = RESULT_GOOD;
+ } else {
+ result = RESULT_ERROR;
+ }
+
+ RA_End_Op_Msg *end_op = new RA_End_Op_Msg( begin_op_msg->GetOpType(),
+ result,
+ status );
+
+ session->WriteMsg( end_op );
+
+ if( end_op != NULL ) {
+ delete end_op;
+ end_op = NULL;
+ }
+ }
+
+ /* remove any operational messages */
+ if( begin_op_msg != NULL ) {
+ delete begin_op_msg;
+ begin_op_msg = NULL;
+ }
+
+ /* remove any sessions */
+ if( session != NULL ) {
+ mod_tps_destroy_session( session );
+ session = NULL;
+ }
+
+ return ret_code;
+} /* mod_tps_handler */
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Command Phase
+** _________________________________________________________________
+*/
+
+static const char *mod_tps_get_config_path_file( cmd_parms *cmd,
+ void *mconfig,
+ const char *tpsconf )
+{
+ if( cmd->path ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, 0, NULL,
+ "The %s config param cannot be specified "
+ "in a Directory section.",
+ cmd->directive->directive );
+ } else {
+ mod_tps_server_configuration *sc = NULL;
+
+ /* Retrieve the TPS module. */
+ sc = ( ( mod_tps_server_configuration * )
+ ap_get_module_config( cmd->server->module_config,
+ &MOD_TPS_CONFIG_KEY ) );
+
+ /* Initialize the "TPS Configuration File" */
+ /* member of mod_tps_server_configuration. */
+ sc->TPS_Configuration_File = apr_pstrdup( cmd->pool, tpsconf );
+ }
+
+ return NULL;
+}
+
+
+static const command_rec mod_tps_config_cmds[] = {
+ AP_INIT_TAKE1( MOD_TPS_CONFIGURATION_FILE_PARAMETER,
+ ( const char*(*)() ) mod_tps_get_config_path_file,
+ NULL,
+ RSRC_CONF,
+ MOD_TPS_CONFIGURATION_FILE_USAGE ),
+ { NULL }
+};
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Server Configuration Creation Phase
+** _________________________________________________________________
+*/
+
+/**
+ * Create TPS module server configuration
+ */
+static void *
+mod_tps_config_server_create( apr_pool_t *p, server_rec *sv )
+{
+ /* Initialize all APR library routines. */
+ apr_initialize();
+
+ /* Create a memory pool for this server. */
+ mod_tps_server_configuration *sc = ( mod_tps_server_configuration * )
+ apr_pcalloc( p,
+ ( apr_size_t )
+ sizeof( *sc ) );
+
+ /* Initialize all members of mod_tps_server_configuration. */
+ sc->TPS_Configuration_File = NULL;
+ sc->context = NULL;
+ sc->gconfig = mod_tps_config_global_create(sv);
+
+ return sc;
+}
+
+static void mod_tps_init_child(apr_pool_t *p, server_rec *sv)
+{
+ int status = -1;
+ mod_tps_server_configuration *srv_cfg = NULL;
+ srv_cfg = ( ( mod_tps_server_configuration * )
+ ap_get_module_config(sv->module_config, &MOD_TPS_CONFIG_KEY));
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0 /* status */, NULL,
+ "Entering mod_tps_init_child pid [%d] init count is [%d]",
+ getpid(), srv_cfg->gconfig->nInitCount);
+
+ srv_cfg = ( ( mod_tps_server_configuration * )
+ ap_get_module_config(sv->module_config, &MOD_TPS_CONFIG_KEY));
+
+ if (srv_cfg->gconfig->nInitCount > 1) {
+ srv_cfg->gconfig->nSignedAuditInitCount++;
+ status = RA::InitializeInChild(srv_cfg->context,
+ srv_cfg->gconfig->nSignedAuditInitCount);
+
+
+ if (status != RA_INITIALIZATION_SUCCESS) {
+ /* Need to shut down, the child was not initialized properly. */
+ ap_log_error( "mod_tps_init_child",
+ __LINE__, APLOG_ERR, 0, sv,
+ "The tps module failed to do the initializeInChild tasks. ");
+ printf( "\nUnable to start Apache:\n"
+ " The tps module failed to do the initializeInChild tasks. ");
+ goto loser;
+ }
+
+ /* Register a server termination routine. */
+ apr_pool_cleanup_register( p,
+ sv,
+ mod_tps_child_terminate,
+ apr_pool_cleanup_null );
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, sv,
+ "mod_tps_init_child - pid is [%d] - config should be done in regular post config",
+ getpid());
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0 /* status */, NULL,
+ "Leaving mod_tps_init_child");
+ return;
+loser:
+ /* Log TPS module debug information. */
+ RA::Debug( "mod_tps::mod_tps_initialize",
+ "Failed loading the TPS module!" );
+
+ /* Free TPS resources. */
+ /* If we are here, the parent should be up. */
+ RA::Shutdown();
+
+ /* Since all members of mod_tps_server_configuration are allocated */
+ /* from a pool, there is no need to unset any of these members. */
+
+#ifdef MEM_PROFILING
+ /* If memory profiling is enabled, turn off memory profiling. */
+ MEM_shutdown();
+#endif
+
+ /* Shutdown all APR library routines. */
+ /* NOTE: This automatically destroys all memory pools. */
+ apr_terminate();
+
+ /* Terminate the entire Apache server */
+ _exit(APEXIT_CHILDFATAL);
+
+ return;
+
+}
+
+
+
+/* _________________________________________________________________
+**
+** TPS Module Registration Phase
+** _________________________________________________________________
+*/
+
+static void
+mod_tps_register_hooks( apr_pool_t *p )
+{
+ static const char *const mod_tps_preloaded_modules[] = { "mod_nss.c",
+ NULL };
+ static const char *const mod_tps_postloaded_modules[] = { NULL };
+
+ ap_hook_post_config( mod_tps_initialize,
+ mod_tps_preloaded_modules,
+ mod_tps_postloaded_modules,
+ APR_HOOK_MIDDLE );
+
+ ap_hook_child_init(mod_tps_init_child, NULL,NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_handler( mod_tps_handler,
+ mod_tps_preloaded_modules,
+ mod_tps_postloaded_modules,
+ APR_HOOK_MIDDLE );
+}
+
+
+module TPS_PUBLIC MOD_TPS_CONFIG_KEY = {
+ STANDARD20_MODULE_STUFF,
+ NULL, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ mod_tps_config_server_create, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ mod_tps_config_cmds, /* table of configuration directives */
+ mod_tps_register_hooks /* register hooks */
+};
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/base/tps/src/msg/RA_ASQ_Request_Msg.cpp b/base/tps/src/msg/RA_ASQ_Request_Msg.cpp
new file mode 100644
index 000000000..112c42152
--- /dev/null
+++ b/base/tps/src/msg/RA_ASQ_Request_Msg.cpp
@@ -0,0 +1,70 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "main/Base.h"
+#include "msg/RA_ASQ_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs A Security Question (ASQ) request message.
+ */
+TPS_PUBLIC RA_ASQ_Request_Msg::RA_ASQ_Request_Msg (char *question)
+{
+ if (question == NULL)
+ m_question = NULL;
+ else
+ m_question = PL_strdup(question);
+}
+
+
+/**
+ * Destructs a ASQ request message.
+ */
+TPS_PUBLIC RA_ASQ_Request_Msg::~RA_ASQ_Request_Msg ()
+{
+ if( m_question != NULL ) {
+ PL_strfree( m_question );
+ m_question = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_ASQ_Request_Msg::GetType ()
+{
+ return MSG_ASQ_REQUEST;
+}
+
+/**
+ * Retrieves the security question for
+ * the end user.
+ */
+TPS_PUBLIC char *RA_ASQ_Request_Msg::GetQuestion()
+{
+ return m_question;
+}
diff --git a/base/tps/src/msg/RA_ASQ_Response_Msg.cpp b/base/tps/src/msg/RA_ASQ_Response_Msg.cpp
new file mode 100644
index 000000000..5e480c1f1
--- /dev/null
+++ b/base/tps/src/msg/RA_ASQ_Response_Msg.cpp
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "msg/RA_ASQ_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs A Security Question (ASQ) response.
+ */
+TPS_PUBLIC RA_ASQ_Response_Msg::RA_ASQ_Response_Msg (char *answer)
+{
+ if (answer == NULL)
+ m_answer = NULL;
+ else
+ m_answer = PL_strdup(answer);
+}
+
+/**
+ * Destructs a ASQ response.
+ */
+TPS_PUBLIC RA_ASQ_Response_Msg::~RA_ASQ_Response_Msg ()
+{
+ if( m_answer != NULL ) {
+ PL_strfree( m_answer );
+ m_answer = NULL;
+ }
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_ASQ_Response_Msg::GetType ()
+{
+ return MSG_ASQ_RESPONSE;
+}
+
+/**
+ * Retrieves the answer to the security question
+ * from the end user.
+ */
+TPS_PUBLIC char *RA_ASQ_Response_Msg::GetAnswer()
+{
+ return m_answer;
+}
diff --git a/base/tps/src/msg/RA_Begin_Op_Msg.cpp b/base/tps/src/msg/RA_Begin_Op_Msg.cpp
new file mode 100644
index 000000000..44d568bd9
--- /dev/null
+++ b/base/tps/src/msg/RA_Begin_Op_Msg.cpp
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "msg/RA_Begin_Op_Msg.h"
+#include "main/Memory.h"
+#include "main/NameValueSet.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a begin op message. Each operation
+ * transaction (i.e. enrollment, reset pin)
+ * starts with a Begin Op message.
+ */
+TPS_PUBLIC RA_Begin_Op_Msg::RA_Begin_Op_Msg (RA_Op_Type op, NameValueSet *exts)
+{
+ m_op = op;
+ m_exts = exts;
+}
+
+/**
+ * Destructs a begin op message.
+ */
+TPS_PUBLIC RA_Begin_Op_Msg::~RA_Begin_Op_Msg ()
+{
+ if( m_exts != NULL ) {
+ delete m_exts;
+ m_exts = NULL;
+ }
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Begin_Op_Msg::GetType ()
+{
+ return MSG_BEGIN_OP;
+}
+
+TPS_PUBLIC NameValueSet *RA_Begin_Op_Msg::GetExtensions()
+{
+ return m_exts;
+}
+
+/**
+ * Retrieves operation type.
+ */
+TPS_PUBLIC RA_Op_Type RA_Begin_Op_Msg::GetOpType()
+{
+ return m_op;
+}
diff --git a/base/tps/src/msg/RA_End_Op_Msg.cpp b/base/tps/src/msg/RA_End_Op_Msg.cpp
new file mode 100644
index 000000000..232122d49
--- /dev/null
+++ b/base/tps/src/msg/RA_End_Op_Msg.cpp
@@ -0,0 +1,73 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "msg/RA_End_Op_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a begin op message. Each operation
+ * transaction (i.e. enrollment, reset pin)
+ * starts with a Begin Op message.
+ */
+TPS_PUBLIC RA_End_Op_Msg::RA_End_Op_Msg (RA_Op_Type op, int result, int msg)
+{
+ m_op = op;
+ m_result = result;
+ m_msg = msg;
+}
+
+/**
+ * Destructs a begin op message.
+ */
+TPS_PUBLIC RA_End_Op_Msg::~RA_End_Op_Msg ()
+{
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_End_Op_Msg::GetType ()
+{
+ return MSG_END_OP;
+}
+
+/**
+ * Retrieves operation type.
+ */
+TPS_PUBLIC RA_Op_Type RA_End_Op_Msg::GetOpType()
+{
+ return m_op;
+}
+
+TPS_PUBLIC int RA_End_Op_Msg::GetResult()
+{
+ return m_result;
+}
+
+TPS_PUBLIC int RA_End_Op_Msg::GetMsg()
+{
+ return m_msg;
+}
diff --git a/base/tps/src/msg/RA_Extended_Login_Request_Msg.cpp b/base/tps/src/msg/RA_Extended_Login_Request_Msg.cpp
new file mode 100644
index 000000000..9da2f6d8f
--- /dev/null
+++ b/base/tps/src/msg/RA_Extended_Login_Request_Msg.cpp
@@ -0,0 +1,114 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#include "plstr.h"
+#include "main/Base.h"
+#include "msg/RA_Extended_Login_Request_Msg.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a login request message that requests
+ * user id and password from the end user.
+ */
+TPS_PUBLIC RA_Extended_Login_Request_Msg::RA_Extended_Login_Request_Msg (int invalid_pw, int blocked, char **parameters, int len, char *title, char *description)
+{
+ m_invalid_pw = invalid_pw;
+ m_blocked = blocked;
+ m_title = PL_strdup(title);
+ m_description = PL_strdup(description);
+ if (parameters != NULL) {
+ if (len > 0) {
+ m_parameters = (char **) PR_Malloc (len);
+ for (int i = 0; i < len; i++) {
+ m_parameters[i] = PL_strdup(parameters[i]);
+ }
+ } else {
+ m_parameters = NULL;
+ }
+ }
+ m_len = len;
+}
+
+/**
+ * Destructs a login request message.
+ */
+TPS_PUBLIC RA_Extended_Login_Request_Msg::~RA_Extended_Login_Request_Msg ()
+{
+ for (int i = 0; i < m_len; i++) {
+ PL_strfree(m_parameters[i]);
+ }
+ if (m_parameters != NULL) {
+ PR_Free(m_parameters);
+ }
+}
+
+TPS_PUBLIC int RA_Extended_Login_Request_Msg::GetLen ()
+{
+ return m_len;
+}
+
+TPS_PUBLIC char *RA_Extended_Login_Request_Msg::GetTitle()
+{
+ return m_title;
+}
+
+TPS_PUBLIC char *RA_Extended_Login_Request_Msg::GetDescription()
+{
+ return m_description;
+}
+
+TPS_PUBLIC char *RA_Extended_Login_Request_Msg::GetParam (int i)
+{
+ return m_parameters[i];
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Extended_Login_Request_Msg::GetType ()
+{
+ return MSG_EXTENDED_LOGIN_REQUEST;
+}
+
+/**
+ * Is the password invalid in the previous login
+ * request.
+ */
+TPS_PUBLIC int RA_Extended_Login_Request_Msg::IsInvalidPassword()
+{
+ return m_invalid_pw;
+}
+
+/**
+ * Should the client block due to the previous
+ * invalid login.
+ */
+TPS_PUBLIC int RA_Extended_Login_Request_Msg::IsBlocked()
+{
+ return m_blocked;
+}
diff --git a/base/tps/src/msg/RA_Extended_Login_Response_Msg.cpp b/base/tps/src/msg/RA_Extended_Login_Response_Msg.cpp
new file mode 100644
index 000000000..f1d66b558
--- /dev/null
+++ b/base/tps/src/msg/RA_Extended_Login_Response_Msg.cpp
@@ -0,0 +1,65 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "msg/RA_Extended_Login_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a login response message.
+ */
+TPS_PUBLIC RA_Extended_Login_Response_Msg::RA_Extended_Login_Response_Msg (AuthParams *params)
+{
+ m_params = params;
+}
+
+/**
+ * Destructs a login response message.
+ */
+TPS_PUBLIC RA_Extended_Login_Response_Msg::~RA_Extended_Login_Response_Msg ()
+{
+ if( m_params != NULL ) {
+ delete m_params;
+ m_params = NULL;
+ }
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Extended_Login_Response_Msg::GetType ()
+{
+ return MSG_EXTENDED_LOGIN_RESPONSE;
+}
+
+/**
+ * Retrieves null-pointer terminated
+ * user ID given by the end user.
+ */
+TPS_PUBLIC AuthParams *RA_Extended_Login_Response_Msg::GetAuthParams()
+{
+ return m_params;
+}
diff --git a/base/tps/src/msg/RA_Login_Request_Msg.cpp b/base/tps/src/msg/RA_Login_Request_Msg.cpp
new file mode 100644
index 000000000..7bad331d7
--- /dev/null
+++ b/base/tps/src/msg/RA_Login_Request_Msg.cpp
@@ -0,0 +1,71 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "msg/RA_Login_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a login request message that requests
+ * user id and password from the end user.
+ */
+TPS_PUBLIC RA_Login_Request_Msg::RA_Login_Request_Msg (int invalid_pw, int blocked)
+{
+ m_invalid_pw = invalid_pw;
+ m_blocked = blocked;
+}
+
+/**
+ * Destructs a login request message.
+ */
+TPS_PUBLIC RA_Login_Request_Msg::~RA_Login_Request_Msg ()
+{
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Login_Request_Msg::GetType ()
+{
+ return MSG_LOGIN_REQUEST;
+}
+
+/**
+ * Is the password invalid in the previous login
+ * request.
+ */
+TPS_PUBLIC int RA_Login_Request_Msg::IsInvalidPassword()
+{
+ return m_invalid_pw;
+}
+
+/**
+ * Should the client block due to the previous
+ * invalid login.
+ */
+TPS_PUBLIC int RA_Login_Request_Msg::IsBlocked()
+{
+ return m_blocked;
+}
diff --git a/base/tps/src/msg/RA_Login_Response_Msg.cpp b/base/tps/src/msg/RA_Login_Response_Msg.cpp
new file mode 100644
index 000000000..67d796e6e
--- /dev/null
+++ b/base/tps/src/msg/RA_Login_Response_Msg.cpp
@@ -0,0 +1,85 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "msg/RA_Login_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a login response message.
+ */
+TPS_PUBLIC RA_Login_Response_Msg::RA_Login_Response_Msg (char *uid, char *password)
+{
+ if (uid == NULL)
+ m_uid = NULL;
+ else
+ m_uid = PL_strdup(uid);
+ if (password == NULL)
+ m_password = NULL;
+ else
+ m_password = PL_strdup(password);
+}
+
+/**
+ * Destructs a login response message.
+ */
+TPS_PUBLIC RA_Login_Response_Msg::~RA_Login_Response_Msg ()
+{
+ if( m_uid != NULL ) {
+ PL_strfree( m_uid );
+ m_uid = NULL;
+ }
+ if( m_password != NULL ) {
+ PL_strfree( m_password );
+ m_password = NULL;
+ }
+}
+
+/**
+ * Retrieves message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Login_Response_Msg::GetType ()
+{
+ return MSG_LOGIN_RESPONSE;
+}
+
+/**
+ * Retrieves null-pointer terminated
+ * user ID given by the end user.
+ */
+TPS_PUBLIC char *RA_Login_Response_Msg::GetUID()
+{
+ return m_uid;
+}
+
+/**
+ * Retrieves null-pointer terminated password
+ * given by the end user.
+ */
+TPS_PUBLIC char *RA_Login_Response_Msg::GetPassword()
+{
+ return m_password;
+}
diff --git a/base/tps/src/msg/RA_New_Pin_Request_Msg.cpp b/base/tps/src/msg/RA_New_Pin_Request_Msg.cpp
new file mode 100644
index 000000000..71889359e
--- /dev/null
+++ b/base/tps/src/msg/RA_New_Pin_Request_Msg.cpp
@@ -0,0 +1,70 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a new pin request for the token.
+ */
+TPS_PUBLIC RA_New_Pin_Request_Msg::RA_New_Pin_Request_Msg (int min_len, int max_len)
+{
+ m_min_len = min_len;
+ m_max_len = max_len;
+}
+
+
+/**
+ * Destructs a new pin request.
+ */
+TPS_PUBLIC RA_New_Pin_Request_Msg::~RA_New_Pin_Request_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_New_Pin_Request_Msg::GetType ()
+{
+ return MSG_NEW_PIN_REQUEST;
+}
+
+/**
+ * Retrieves the minimium length required for the new password.
+ */
+TPS_PUBLIC int RA_New_Pin_Request_Msg::GetMinLen()
+{
+ return m_min_len;
+}
+
+
+/**
+ * Retrieves the maximium length required for the new password.
+ */
+TPS_PUBLIC int RA_New_Pin_Request_Msg::GetMaxLen()
+{
+ return m_max_len;
+}
diff --git a/base/tps/src/msg/RA_New_Pin_Response_Msg.cpp b/base/tps/src/msg/RA_New_Pin_Response_Msg.cpp
new file mode 100644
index 000000000..69b63f934
--- /dev/null
+++ b/base/tps/src/msg/RA_New_Pin_Response_Msg.cpp
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a new pin response.
+ */
+TPS_PUBLIC RA_New_Pin_Response_Msg::RA_New_Pin_Response_Msg (char *new_pin)
+{
+ if (new_pin == NULL)
+ m_new_pin = NULL;
+ else
+ m_new_pin = PL_strdup(new_pin);
+}
+
+/**
+ * Destructs a new pin response.
+ */
+TPS_PUBLIC RA_New_Pin_Response_Msg::~RA_New_Pin_Response_Msg ()
+{
+ if( m_new_pin != NULL ) {
+ PL_strfree( m_new_pin );
+ m_new_pin = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_New_Pin_Response_Msg::GetType ()
+{
+ return MSG_NEW_PIN_RESPONSE;
+}
+
+/**
+ * Retrieves the null-pointer terminated new pin
+ * from the end user.
+ */
+TPS_PUBLIC char *RA_New_Pin_Response_Msg::GetNewPIN()
+{
+ return m_new_pin;
+}
diff --git a/base/tps/src/msg/RA_SecureId_Request_Msg.cpp b/base/tps/src/msg/RA_SecureId_Request_Msg.cpp
new file mode 100644
index 000000000..064461225
--- /dev/null
+++ b/base/tps/src/msg/RA_SecureId_Request_Msg.cpp
@@ -0,0 +1,69 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Secure ID request message for requesting
+ * Secure ID input from the end user.
+ */
+TPS_PUBLIC RA_SecureId_Request_Msg::RA_SecureId_Request_Msg (int pin_required, int next_value)
+{
+ m_pin_required = pin_required;
+ m_next_value = next_value;
+}
+
+/**
+ * Destructs a Secure ID request.
+ */
+TPS_PUBLIC RA_SecureId_Request_Msg::~RA_SecureId_Request_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_SecureId_Request_Msg::GetType ()
+{
+ return MSG_SECUREID_REQUEST;
+}
+
+/**
+ * Is PIN required?
+ */
+TPS_PUBLIC int RA_SecureId_Request_Msg::IsPinRequired()
+{
+ return m_pin_required;
+}
+
+/**
+ * Is next value required?
+ */
+TPS_PUBLIC int RA_SecureId_Request_Msg::IsNextValue()
+{
+ return m_next_value;
+}
diff --git a/base/tps/src/msg/RA_SecureId_Response_Msg.cpp b/base/tps/src/msg/RA_SecureId_Response_Msg.cpp
new file mode 100644
index 000000000..ff4191a61
--- /dev/null
+++ b/base/tps/src/msg/RA_SecureId_Response_Msg.cpp
@@ -0,0 +1,83 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Secure ID response.
+ */
+TPS_PUBLIC RA_SecureId_Response_Msg::RA_SecureId_Response_Msg (char *value, char *pin)
+{
+ if (value == NULL)
+ m_value = NULL;
+ else
+ m_value = PL_strdup(value);
+ if (pin == NULL)
+ m_pin = NULL;
+ else
+ m_pin = PL_strdup(pin);
+}
+
+/**
+ * Destructs a Secure ID response.
+ */
+TPS_PUBLIC RA_SecureId_Response_Msg::~RA_SecureId_Response_Msg ()
+{
+ if( m_value != NULL ) {
+ PL_strfree( m_value );
+ m_value = NULL;
+ }
+ if( m_pin != NULL ) {
+ PL_strfree( m_pin );
+ m_pin = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_SecureId_Response_Msg::GetType ()
+{
+ return MSG_SECUREID_RESPONSE;
+}
+
+/**
+ * Retrieves the value.
+ */
+TPS_PUBLIC char *RA_SecureId_Response_Msg::GetValue()
+{
+ return m_value;
+}
+
+/**
+ * Retrieves the PIN.
+ */
+TPS_PUBLIC char *RA_SecureId_Response_Msg::GetPIN()
+{
+ return m_pin;
+}
diff --git a/base/tps/src/msg/RA_Status_Update_Request_Msg.cpp b/base/tps/src/msg/RA_Status_Update_Request_Msg.cpp
new file mode 100644
index 000000000..7bb0baefc
--- /dev/null
+++ b/base/tps/src/msg/RA_Status_Update_Request_Msg.cpp
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "msg/RA_Status_Update_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Status_Update_Request_Msg::RA_Status_Update_Request_Msg (int status, const char *info)
+{
+ m_status = status;
+ m_info = PL_strdup((char *) info);
+}
+
+/**
+ * Destructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Status_Update_Request_Msg::~RA_Status_Update_Request_Msg ()
+{
+ if( m_info != NULL ) {
+ PL_strfree( m_info );
+ m_info = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Status_Update_Request_Msg::GetType ()
+{
+ return MSG_STATUS_UPDATE_REQUEST;
+}
+
+TPS_PUBLIC int RA_Status_Update_Request_Msg::GetStatus()
+{
+ return m_status;
+}
+
+TPS_PUBLIC char *RA_Status_Update_Request_Msg::GetInfo()
+{
+ return m_info;
+}
diff --git a/base/tps/src/msg/RA_Status_Update_Response_Msg.cpp b/base/tps/src/msg/RA_Status_Update_Response_Msg.cpp
new file mode 100644
index 000000000..6053c9af6
--- /dev/null
+++ b/base/tps/src/msg/RA_Status_Update_Response_Msg.cpp
@@ -0,0 +1,56 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "msg/RA_Status_Update_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Status_Update_Response_Msg::RA_Status_Update_Response_Msg (int status)
+{
+ m_status = status;
+}
+
+/**
+ * Destructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Status_Update_Response_Msg::~RA_Status_Update_Response_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Status_Update_Response_Msg::GetType ()
+{
+ return MSG_STATUS_UPDATE_RESPONSE;
+}
+
+TPS_PUBLIC int RA_Status_Update_Response_Msg::GetStatus()
+{
+ return m_status;
+}
diff --git a/base/tps/src/msg/RA_Token_PDU_Request_Msg.cpp b/base/tps/src/msg/RA_Token_PDU_Request_Msg.cpp
new file mode 100644
index 000000000..34b3d584b
--- /dev/null
+++ b/base/tps/src/msg/RA_Token_PDU_Request_Msg.cpp
@@ -0,0 +1,63 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Token_PDU_Request_Msg::RA_Token_PDU_Request_Msg (APDU *apdu)
+{
+ m_apdu = apdu;
+}
+
+/**
+ * Destructs a Token PDU request.
+ */
+TPS_PUBLIC RA_Token_PDU_Request_Msg::~RA_Token_PDU_Request_Msg ()
+{
+ if( m_apdu != NULL ) {
+ delete m_apdu;
+ m_apdu = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Token_PDU_Request_Msg::GetType ()
+{
+ return MSG_TOKEN_PDU_REQUEST;
+}
+
+/**
+ * Retrieves the APDU that is targeted for the token.
+ */
+TPS_PUBLIC APDU *RA_Token_PDU_Request_Msg::GetAPDU()
+{
+ return m_apdu;
+}
diff --git a/base/tps/src/msg/RA_Token_PDU_Response_Msg.cpp b/base/tps/src/msg/RA_Token_PDU_Response_Msg.cpp
new file mode 100644
index 000000000..41b11388c
--- /dev/null
+++ b/base/tps/src/msg/RA_Token_PDU_Response_Msg.cpp
@@ -0,0 +1,68 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "apdu/APDU_Response.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a Token PDU response.
+ */
+TPS_PUBLIC RA_Token_PDU_Response_Msg::RA_Token_PDU_Response_Msg (APDU_Response *response)
+{
+ m_response = response;
+}
+
+/**
+ * Destructs a Token PDU response.
+ */
+TPS_PUBLIC RA_Token_PDU_Response_Msg::~RA_Token_PDU_Response_Msg ()
+{
+ if( m_response != NULL ) {
+ delete m_response;
+ m_response = NULL;
+ }
+}
+
+/**
+ * Retrieves the message type.
+ */
+TPS_PUBLIC RA_Msg_Type RA_Token_PDU_Response_Msg::GetType ()
+{
+ return MSG_TOKEN_PDU_RESPONSE;
+}
+
+/**
+ * Retrieves the response from the token.
+ * This response does not follow the standard
+ * APDU format. It is just a sequence of data
+ * with 2 bytes, at the end, that indicates
+ * the status.
+ */
+TPS_PUBLIC APDU_Response *RA_Token_PDU_Response_Msg::GetResponse()
+{
+ return m_response;
+}
diff --git a/base/tps/src/processor/RA_Enroll_Processor.cpp b/base/tps/src/processor/RA_Enroll_Processor.cpp
new file mode 100644
index 000000000..d88d84087
--- /dev/null
+++ b/base/tps/src/processor/RA_Enroll_Processor.cpp
@@ -0,0 +1,5194 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+/**
+ * RA_Enroll_Processor handles initialization and enrollment of the token
+ */
+
+
+/* variable naming convention:
+ * a_ passed as an 'in' argument to a method
+ * o_ passed as an 'out' argument to a method
+ * m_ member variable
+ */
+
+
+#include <string.h>
+#include <time.h>
+#include "pkcs11.h"
+
+// for public key processing
+#include "secder.h"
+#include "pk11func.h"
+#include "cryptohi.h"
+#include "keyhi.h"
+#include "base64.h"
+#include "nssb64.h"
+#include "prlock.h"
+
+#include "cert.h"
+#include "main/RA_Session.h"
+#include "main/RA_Msg.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "main/PKCS11Obj.h"
+#include "engine/RA.h"
+#include "channel/Secure_Channel.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Enroll_Processor.h"
+#include "tus/tus_db.h"
+
+#include "cms/CertEnroll.h"
+#include "httpClient/httpc/response.h"
+#include "main/Memory.h"
+
+#define OP_PREFIX "op.enroll"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+SECStatus PK11_GenerateRandom(unsigned char *,int);
+void PrintPRTime(PRTime, const char *);
+
+
+// This parameter is read from the config file. It is the
+// applet build ID which the administrator wants to set as
+// the 'latest applet' to upgrade to.
+static const char *g_applet_target_version = NULL;
+
+
+/**
+ * this function returns a new allocated string
+ * @param cuid a 20 character string. Usually this is 20 hex
+ * digits representing a token CUID.
+ * @returns a new string which is basically a copy of the input, but
+ * with extra colons. The caller is responsible for freeing the
+ * returned string with PR_Free().
+ */
+
+static char *GetPrettyPrintCUID(const char *cuid)
+{
+ int i,j;
+ char *ret = NULL;
+
+ if (cuid == NULL)
+ return NULL;
+ if (strlen(cuid) != 20)
+ return NULL;
+ ret = (char *)PR_Malloc(20+4+1);
+ j = 0;
+ for (i = 0; i < 24; i++) {
+ if (i == 4 || i == 9 || i == 14 || i == 19) {
+ ret[i] = '-';
+ } else {
+ ret[i] = cuid[j];
+ j++;
+ }
+ }
+ ret[24] = '\0';
+ return ret;
+}
+
+static SECItem *
+PK11_GetPubIndexKeyID(CERTCertificate *cert) {
+ SECKEYPublicKey *pubk;
+ SECItem *newItem = NULL;
+
+ pubk = CERT_ExtractPublicKey(cert);
+ if (pubk == NULL) return NULL;
+
+ switch (pubk->keyType) {
+ case rsaKey:
+ newItem = SECITEM_DupItem(&pubk->u.rsa.modulus);
+ break;
+ case dsaKey:
+ newItem = SECITEM_DupItem(&pubk->u.dsa.publicValue);
+ break;
+ case dhKey:
+ newItem = SECITEM_DupItem(&pubk->u.dh.publicValue);
+ break;
+ case ecKey:
+ newItem = SECITEM_DupItem(&pubk->u.ec.publicValue);
+ break;
+ case fortezzaKey:
+ default:
+ newItem = NULL; /* Fortezza Fix later... */
+ }
+ SECKEY_DestroyPublicKey(pubk);
+ /* make hash of it */
+ return newItem;
+}
+
+
+/**
+ * Constructs a processor for handling enrollment operation.
+ */
+TPS_PUBLIC RA_Enroll_Processor::RA_Enroll_Processor ()
+{
+}
+
+/**
+ * Destructs enrollment processor.
+ */
+TPS_PUBLIC RA_Enroll_Processor::~RA_Enroll_Processor ()
+{
+}
+
+RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *session,
+ CERTCertificate **certificates,
+ char **origins,
+ char **ktypes,
+ int pkcs11obj_enable,
+ PKCS11Obj *pkcs_objx,
+ NameValueSet *extensions,
+ int index, int keyTypeNum,
+ int start_progress,
+ int end_progress,
+ Secure_Channel *channel, Buffer *wrapped_challenge,
+ const char *tokenType,
+ const char *keyType,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ const char *cuid,
+ const char *msn,
+ const char *khex,
+ TokenKeyType key_type,
+ const char *profileId,
+ const char *userid,
+ const char *cert_id,
+ const char *publisher_id,
+ const char *cert_attr_id,
+ const char *pri_attr_id,
+ const char *pub_attr_id,
+ BYTE se_p1, BYTE se_p2, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version)
+{
+ RA_Status status = STATUS_NO_ERROR;
+ int rc = -1;
+ int len = 0;
+ int publish_result = -1;
+ Buffer *public_key = NULL;
+ SECItem si_mod;
+ Buffer *modulus=NULL;
+ SECItem *si_kid = NULL;
+ Buffer *keyid=NULL;
+ SECItem si_exp;
+ Buffer *exponent=NULL;
+ CertEnroll *certEnroll = NULL;
+ Buffer *cert = NULL;
+ Buffer CUID = channel->GetKeyDiversificationData();
+ const char *label = NULL;
+ const char *cuid_label = NULL;
+ const char *pattern;
+ char configname[256];
+ NameValueSet nv;
+ const char *pretty_cuid = NULL;
+
+ const char *FN="RA_Enroll_Processor::DoEnrollment";
+
+ char *cert_string = NULL;
+ SECItem* encodedPublicKeyInfo = NULL;
+ SECItem **ppEncodedPublicKeyInfo = NULL;
+ CERTSubjectPublicKeyInfo* spkix = NULL;
+
+ char *pKey = NULL;
+ char *ivParam = NULL;
+ char *wrappedPrivKey = NULL;
+
+ const char *drmconnid = NULL;
+ bool serverKeygen = false;
+ SECKEYPublicKey *pk_p = NULL;
+
+ char audit_msg[512] = "";
+ char *keyVersion = NULL;
+ char cert_serial[2048] = "";
+ char activity_msg[4096] = "";
+
+ float progress_block_size = (float) (end_progress - start_progress) / keyTypeNum;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Start of keygen/certificate enrollment");
+
+ // get key version for audit logs
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ // check if we need to do key generation (by default, overwrite everything)
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.overwrite",
+ OP_PREFIX, tokenType, keyType);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "looking for config %s", configname);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ // do nothing
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "do overwrite");
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "do not overwrite, if %s exists", cert_id);
+ int num_objs = pkcs_objx->PKCS11Obj::GetObjectSpecCount();
+ char b[3];
+ bool foundObj = false;
+ for (int i = 0; i< num_objs; i++) {
+ ObjectSpec* os = pkcs_objx->GetObjectSpec(i);
+ unsigned long oid = os->GetObjectID();
+ b[0] = (char)((oid >> 24) & 0xff);
+ b[1] = (char)((oid >> 16) & 0xff);
+ b[2] = '\0';
+ /*
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "object id =%c:%c b=%s",b[0], b[1], b);
+ */
+ if (PL_strcasecmp(cert_id, b) == 0) {
+ foundObj = true;
+ break;
+ }
+ }
+
+
+ if (foundObj) {
+ // we already have a certificate there, skip enrollment
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Found certficate. Will not overwrite. Skipped enrollment");
+ return status;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Certficate not found. Continuing with enrollment");
+ }
+ }
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 15/100) /* progress */,
+ "PROGRESS_KEY_GENERATION");
+
+ if (key_type == KEY_TYPE_ENCRYPTION) {// do serverSide keygen?
+
+ PR_snprintf((char *)configname, 256, "%s.serverKeygen.enable", keyTypePrefix);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "looking for config %s", configname);
+ serverKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, false);
+ }
+
+ certEnroll = new CertEnroll();
+
+ if (serverKeygen) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Private key is to be generated on server");
+
+ PR_snprintf((char *)configname, 256, "%s.serverKeygen.drm.conn", keyTypePrefix);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "looking for config %s", configname);
+ drmconnid = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)configname, 256, "%s.serverKeygen.archive", keyTypePrefix);
+ bool archive = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "calling ServerSideKeyGen with userid =%s, archive=%s", userid, archive? "true":"false");
+
+ RA::ServerSideKeyGen(session, cuid, userid,
+ channel->getDrmWrappedDESKey(), &pKey,
+ &wrappedPrivKey, &ivParam, drmconnid,
+ archive, keysize);
+
+ if (pKey == NULL) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to generate key on server. Please check DRM.");
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, pKey is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, failed to generate key on server");
+ goto loser;
+ } else
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "key value = %s", pKey);
+
+
+ if (wrappedPrivKey == NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, wrappedPrivKey is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, wrappedPrivKey is NULL");
+ goto loser;
+ } else
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "wrappedPrivKey = %s", wrappedPrivKey);
+
+ if (ivParam == NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, ivParam is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, ivParam is NULL");
+ goto loser;
+ } else
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ivParam = %s", ivParam);
+
+ /*
+ * the following code converts b64-encoded public key info into SECKEYPublicKey
+ */
+ SECStatus rv;
+ SECItem der;
+ CERTSubjectPublicKeyInfo* spki = NULL;
+
+ der.type = (SECItemType) 0; /* initialize it, since convertAsciiToItem does not set it */
+ rv = ATOB_ConvertAsciiToItem (&der, pKey);
+ if (rv != SECSuccess){
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "failed to convert b64 private key to binary");
+ SECITEM_FreeItem(&der, PR_FALSE);
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to convert b64 private key to binary");
+ goto loser;
+ }else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "decoded private key as: secitem (len=%d)",der.len);
+
+ spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
+
+ if (spki != NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Successfully decoded DER SubjectPublicKeyInfo structure");
+ pk_p = SECKEY_ExtractPublicKey(spki);
+ if (pk_p != NULL)
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Successfully extracted public key from SPKI structure");
+ else
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Failed to extract public key from SPKI");
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Failed to decode SPKI structure");
+ }
+
+ SECITEM_FreeItem(&der, PR_FALSE);
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+
+ }
+
+ } else { //generate keys on token
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Private key is to be generated on token");
+
+ BYTE alg = 0x80;
+
+ if(key_check && key_check->size())
+ alg = 0x81;
+
+ len = channel->StartEnrollment(
+ se_p1, se_p2,
+ wrapped_challenge,
+ key_check,
+ alg /* alg */, keysize,
+ 0x00 /* option */);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "channel->StartEnrollment returned length of public key blob: len=%d", len);
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 45/100) /* progress */,
+ "PROGRESS_READ_PUBLIC_KEY");
+
+ /* read the public key from buffer */
+ if (len <= 0) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Error generating key on token.");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Error generating key on token");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Reading public key buffer from token");
+
+ BYTE iobuf[4];
+ iobuf[0] = 0xff;
+ iobuf[1] = 0xff;
+ iobuf[2] = 0xff;
+ iobuf[3] = 0xff;
+ /* use ReadObject to read IO buffer */
+ public_key = channel->ReadObject(iobuf, 0, len);
+ if (public_key == NULL) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Unable to read public key buffer from token");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Unable to read public key buffer from token");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Successfully read public key buffer");
+
+ RA::DebugBuffer(LL_PER_CONNECTION,FN,
+ "public_key = ", public_key);
+
+ //got public key blob
+ // parse public key blob and check POP
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "challenge size=%d",plaintext_challenge->size());
+ RA::DebugBuffer("RA_Enroll_Processor::process", "challenge = ",
+ plaintext_challenge);
+
+
+ // send status update to the client
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 55/100) /* progress */,
+ "PROGRESS_PARSE_PUBLIC_KEY");
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to Parse Public Key");
+
+ pk_p = certEnroll->ParsePublicKeyBlob(
+ (unsigned char *)(BYTE *)*public_key /*blob*/,
+ plaintext_challenge);
+
+ if (pk_p == NULL) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to parse public key");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Failed to parse public key");
+ goto loser;
+ }
+
+ } //serverKeygen or not
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Keys generated. Proceeding with certificate enrollment");
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ applet_version != NULL ? applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "keys generated");
+
+ if(publisher_id != NULL)
+ {
+ ppEncodedPublicKeyInfo = &encodedPublicKeyInfo;
+
+ }
+
+ pretty_cuid = GetPrettyPrintCUID(cuid);
+
+ nv.Add("pretty_cuid", pretty_cuid);
+ nv.Add("cuid", cuid);
+ nv.Add("msn", msn);
+ nv.Add("userid", userid);
+ nv.Add("profileId", profileId);
+
+ /* populate auth parameters output to nv also */
+ /* so we can reference to the auth parameter by */
+ /* using $auth.cn$, or $auth.mail$ */
+ if (login != NULL) {
+ int s = login->Size();
+ for (int x = 0; x < s; x++) {
+ char namebuf[2048];
+ char *name = login->GetNameAt(x);
+ sprintf(namebuf, "auth.%s", name);
+ nv.Add(namebuf, login->GetValue(name));
+ }
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.cuid_label",
+ OP_PREFIX, tokenType, keyType);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Certificate label '%s'", configname);
+
+ pattern = RA::GetConfigStore()->GetConfigAsString(configname, "$cuid$");
+ cuid_label = MapPattern(&nv, (char *) pattern);
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 60/100) /* progress */,
+ "PROGRESS_ENROLL_CERT");
+
+ cert = certEnroll->EnrollCertificate(
+ pk_p, profileId, userid, cuid_label,
+ connid, audit_msg, ppEncodedPublicKeyInfo);
+
+ if (cert == NULL) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC_CERT_REQ,
+ userid, cuid, msn, "failure", "enrollment", applet_version,
+ keyVersion != NULL ? keyVersion : "",
+ "", connid, audit_msg);
+ goto loser;
+ }
+
+ si_mod = pk_p->u.rsa.modulus;
+ modulus = new Buffer((BYTE*) si_mod.data, si_mod.len);
+
+ /*
+ * RFC 3279
+ * The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ * value of the BIT STRING subjectPublicKey (excluding the tag,
+ * length, and number of unused bits).
+ */
+ spkix = SECKEY_CreateSubjectPublicKeyInfo(pk_p);
+
+ /*
+ * NSS magically multiply the length with 2^3 in cryptohi/seckey.c
+ * Hack:
+ */
+ spkix->subjectPublicKey.len >>= 3;
+ si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
+ spkix->subjectPublicKey.len <<= 3;
+
+
+ keyid = new Buffer((BYTE*) si_kid->data, si_kid->len);
+
+ si_exp = pk_p->u.rsa.publicExponent;
+ exponent = new Buffer((BYTE*) si_exp.data, si_exp.len);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Keyid, modulus and exponent have been extracted from public key");
+
+ SECKEY_DestroySubjectPublicKeyInfo(spkix);
+
+ cert_string = (char *) cert->string();
+ certificates[index] = CERT_DecodeCertFromPackage((char *) cert_string,
+ (int) cert->size());
+ if (certificates[index] != NULL) {
+ RA::ra_tus_print_integer(cert_serial, &certificates[index]->serialNumber);
+ RA::Debug("DoEnrollment", "Received Certificate");
+ RA::Debug("DoEnrollment", cert_serial);
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC_CERT_REQ,
+ userid, cuid, msn, "success", "enrollment", applet_version,
+ (keyVersion != NULL) ? keyVersion : "", cert_serial, connid, "certificate received");
+ }
+ free(cert_string);
+ ktypes[index] = PL_strdup(keyType);
+ origins[index] = PL_strdup(cuid);
+
+ if (serverKeygen) {
+ //do PKCS#8
+
+ BYTE objid[4];
+
+ objid[0] = 0xFF;
+ objid[1] = 0x00;
+ objid[2] = 0xFF;
+ objid[3] = 0xF3;
+ Buffer priv_keyblob;
+ /* url decode wrappedPrivKey */
+ {
+ Buffer *decodeKey = Util::URLDecode(wrappedPrivKey);
+ // RA::DebugBuffer("cfu debug"," private key =",decodeKey);
+ priv_keyblob =
+ Buffer(1, 0x01) + // encryption
+ Buffer(1, 0x09)+ // keytype is RSAPKCS8Pair
+ Buffer(1,(BYTE)(keysize/256)) + // keysize is two bytes
+ Buffer(1,(BYTE)(keysize%256)) +
+ Buffer((BYTE*) *decodeKey, decodeKey->size());
+ delete decodeKey;
+ }
+
+ //inject PKCS#8 private key
+ BYTE perms[6];
+
+ perms[0] = 0x40;
+ perms[1] = 0x00;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ if (channel->CreateObject(objid, perms, priv_keyblob.size()) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: store keys in token failed, channel create object error");
+ goto loser;
+ }
+
+
+ if (channel->WriteObject(objid, (BYTE*)priv_keyblob, priv_keyblob.size()) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: store keys in token failed, channel write object error");
+ goto loser;
+ }
+
+
+ /* url decode the wrapped kek session key and keycheck*/
+ Buffer data;
+ {
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "getKekWrappedDESKey() returns =%s", channel->getKekWrappedDESKey());
+ RA::Debug(LL_PER_PDU, "", "getKeycheck() returns =%s", channel->getKeycheck());
+ */
+ Buffer *decodeKey = Util::URLDecode(channel->getKekWrappedDESKey());
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "des key item len=%d",
+ decodeKey->size());
+ RA::DebugBuffer("cfu debug", "DES key =", decodeKey);
+ */
+ char *keycheck = channel->getKeycheck();
+ Buffer *decodeKeyCheck = Util::URLDecode(keycheck);
+ if (keycheck)
+ PL_strfree(keycheck);
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "keycheck item len=%d",
+ decodeKeyCheck->size());
+ RA::DebugBuffer("cfu debug", "key check=", decodeKeyCheck);
+ */
+
+ //XXX need randomize this later
+
+ // BYTE iv[] = {0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01};
+ // get ivParam
+ Buffer *iv_decoded = Util::URLDecode(ivParam);
+ if (ivParam) {
+ PL_strfree(ivParam);
+ }
+
+ if(iv_decoded == NULL) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: store keys in token failed, iv data not found");
+ delete decodeKey;
+ delete decodeKeyCheck;
+ goto loser;
+ }
+
+ BYTE alg = 0x80;
+ if(decodeKey && decodeKey->size()) {
+ alg = 0x81;
+ }
+
+ data =
+ Buffer((BYTE*)objid, 4)+ // object id
+ Buffer(1,alg) +
+ Buffer(1, (BYTE) decodeKey->size()) + // 1 byte length
+ Buffer((BYTE *) *decodeKey, decodeKey->size())+ // key -encrypted to 3des block
+ // check size
+ // key check
+ Buffer(1, (BYTE) decodeKeyCheck->size()) + //keycheck size
+ Buffer((BYTE *) *decodeKeyCheck , decodeKeyCheck->size())+ // keycheck
+ Buffer(1, iv_decoded->size())+ // IV_Length
+ Buffer((BYTE*)*iv_decoded, iv_decoded->size());
+
+ delete iv_decoded;
+ // RA::DebugBuffer("cfu debug", "ImportKeyEnc data buffer =", &data);
+
+ delete decodeKey;
+ delete decodeKeyCheck;
+ }
+
+ if (channel->ImportKeyEnc(se_p1, se_p2, &data) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: store keys in token failed, channel import key error");
+ goto loser;
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ applet_version != NULL ? applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "server generated keys stored in token");
+
+
+ /*
+ * After keys are injected successfully, then write certificate object apdu
+ * to token
+ */
+
+ } // serverKeygen
+
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 70/100) /* progress */,
+ "PROGRESS_PUBLISH_CERT");
+
+ //Attempt publish if relevant
+ if(ppEncodedPublicKeyInfo)
+ {
+
+ publish_result = DoPublish(cuid,encodedPublicKeyInfo,cert,publisher_id,applet_version);
+
+ }
+
+ if(ppEncodedPublicKeyInfo)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Deleting PublicKeyInfo object.");
+
+ SECITEM_FreeItem(*ppEncodedPublicKeyInfo, PR_TRUE);
+ }
+
+ if(publish_result == 0)
+ {
+ status = STATUS_ERROR_PUBLISH;
+
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Enroll Certificate Publish Failure %d", status);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Enroll Certificate Publish Failure %d",status);
+ PR_snprintf(audit_msg, 512, "publish certificate error");
+ goto loser;
+ }
+
+ if (cert != NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Enroll Certificate Finished");
+ } else {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Enroll Certificate Failure");
+
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "cert is null");
+ goto loser;
+ }
+
+ StatusUpdate(session, extensions,
+ start_progress + (index * progress_block_size) +
+ (progress_block_size * 80/100) /* progress */,
+ "PROGRESS_IMPORT_CERT");
+
+ /* write certificate from CA to netkey */
+ if (pkcs11obj_enable) {
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (cert_id[0] << 24) +
+ (cert_id[1] << 16),
+ cert);
+ pkcs_objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create certificate object on token");
+ rc = channel->CreateCertificate(cert_id, cert);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to create certificate object on token");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Failed to create certificate object on token");
+ goto loser;
+ }
+ }
+
+ // build label
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.label",
+ OP_PREFIX, tokenType, keyType);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "label '%s'", configname);
+ pattern = RA::GetConfigStore()->GetConfigAsString(configname);
+ label = MapPattern(&nv, (char *) pattern);
+
+ if (pkcs11obj_enable) {
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ key_type, cert_attr_id, label, keyid);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (cert_attr_id[0] << 24) +
+ (cert_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create PKCS#11 certificate Attributes");
+ rc = channel->CreatePKCS11CertAttrs(key_type, cert_attr_id, label, keyid);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 Certificate attributes creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "PKCS11 Certificate attributes creation failed");
+ goto loser;
+ }
+ }
+
+ if (pkcs11obj_enable) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Create PKCS11 Private Key Attributes Buffer");
+ Buffer b = channel->CreatePKCS11PriKeyAttrsBuffer(key_type,
+ pri_attr_id, label, keyid, modulus, OP_PREFIX,
+ tokenType, keyTypePrefix);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (pri_attr_id[0] << 24) +
+ (pri_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Create PKCS11 Private Key Attributes");
+ rc = channel->CreatePKCS11PriKeyAttrs(key_type, pri_attr_id, label, keyid, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 private key attributes creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "PKCS11 private key attributes creation failed");
+ goto loser;
+ }
+ }
+
+ if (pkcs11obj_enable) {
+ Buffer b = channel->CreatePKCS11PubKeyAttrsBuffer(key_type,
+ pub_attr_id, label, keyid,
+ exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (pub_attr_id[0] << 24) +
+ (pub_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Create PKCS11 Public Key Attributes");
+ rc = channel->CreatePKCS11PubKeyAttrs(key_type, pub_attr_id, label, keyid,
+ exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 public key attributes creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "PKCS11 public key attributes creation failed");
+ goto loser;
+ }
+ }
+ RA::Debug(LL_PER_CONNECTION,FN, "End of keygen/certificate enrollment");
+
+ PR_snprintf(activity_msg, 4096, "certificate %s stored on token", cert_serial);
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ applet_version != NULL ? applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ activity_msg);
+
+ RA::tdb_activity(session->GetRemoteIP(),
+ (char *) cuid,
+ "enrollment",
+ "success",
+ activity_msg,
+ userid != NULL? userid : "",
+ tokenType);
+
+loser:
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "enrollment",
+ applet_version != NULL ? applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ (char *) cuid,
+ "enrollment",
+ "failure",
+ audit_msg,
+ userid != NULL? userid : "",
+ tokenType);
+ }
+ }
+
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+
+ if( modulus != NULL ) {
+ delete modulus;
+ modulus = NULL;
+ }
+ if( keyid != NULL ) {
+ delete keyid;
+ keyid = NULL;
+ }
+ if( exponent != NULL ) {
+ delete exponent;
+ exponent = NULL;
+ }
+ if( cert != NULL ) {
+ delete cert;
+ cert = NULL;
+ }
+ if( public_key != NULL ) {
+ delete public_key;
+ public_key = NULL;
+ }
+
+ if (pKey !=NULL)
+ PR_Free(pKey);
+
+ if (wrappedPrivKey !=NULL)
+ PR_Free(wrappedPrivKey);
+
+ if( si_kid != NULL ) {
+ SECITEM_FreeItem( si_kid, PR_TRUE );
+ si_kid = NULL;
+ }
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+ if( label != NULL ) {
+ PL_strfree( (char *) label );
+ label = NULL;
+ }
+ if( cuid_label != NULL ) {
+ PL_strfree( (char *) cuid_label );
+ cuid_label = NULL;
+ }
+ if( pretty_cuid != NULL ) {
+ PR_Free( (char *) pretty_cuid );
+ pretty_cuid = NULL;
+ }
+ if (pk_p != NULL) {
+ if (serverKeygen) {
+ SECKEY_DestroyPublicKey(pk_p);
+ } else {
+ free(pk_p);
+ }
+ pk_p = NULL;
+ }
+ return status;
+}
+
+SECStatus getRandomNumber(unsigned long *number) {
+ SECStatus rv;
+
+ if (number == NULL) {
+ return SECFailure;
+ }
+
+ rv = PK11_GenerateRandom((unsigned char *) number, sizeof(unsigned long));
+ return rv;
+}
+
+
+/**
+ * @return true if successfull
+ */
+bool RA_Enroll_Processor::GetCardManagerAppletInfo(
+ RA_Session *a_session, /* in */
+ Buffer *a_cardmanagerAID, /* in */
+ RA_Status &a_status, /* out */
+ char * &msn, /* out */
+ char * &cuid, /* out */
+ Buffer &token_cuid /* out */
+)
+{
+ bool r = true; // result
+ Buffer *cplc_data = NULL;
+ Buffer token_msn;
+
+ SelectApplet(a_session, 0x04, 0x00, a_cardmanagerAID);
+ cplc_data = GetData(a_session);
+ if (cplc_data == NULL) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "Get Data Failed");
+ a_status = STATUS_ERROR_SECURE_CHANNEL;
+ r = false;
+ goto loser;
+ }
+ RA::DebugBuffer("RA_Enroll_Processor::process", "CPLC Data = ",
+ cplc_data);
+ if (cplc_data->size() < 47) {
+ RA::Error("RA_Format_Processor::Process",
+ "Invalid CPLC Size");
+ a_status = STATUS_ERROR_SECURE_CHANNEL;
+ r = false;
+ goto loser;
+ }
+ token_cuid = Buffer(cplc_data->substr(3,4)) +
+ Buffer(cplc_data->substr(19,2)) +
+ Buffer(cplc_data->substr(15,4));
+ RA::DebugBuffer("RA_Enroll_Processor::process", "Token CUID= ",
+ &token_cuid);
+ cuid = Util::Buffer2String(token_cuid);
+ RA::Debug("RA_Enroll_Processor::process", "CUID(String)= '%s'",
+ cuid);
+ token_msn = Buffer(cplc_data->substr(41, 4));
+ RA::DebugBuffer("RA_Enroll_Processor::process", "Token MSN= ",
+ &token_msn);
+ msn = Util::Buffer2String(token_msn);
+ RA::Debug("RA_Enroll_Processor::process", "MSN(String)= '%s'",
+ msn);
+ loser:
+ if( cplc_data != NULL ) {
+ delete cplc_data;
+ }
+
+ return r;
+}
+
+bool RA_Enroll_Processor::GetAppletInfo(
+ RA_Session *a_session, /* in */
+ Buffer *a_aid , /* in */
+ BYTE &o_major_version,
+ BYTE &o_minor_version,
+ BYTE &o_app_major_version,
+ BYTE &o_app_minor_version)
+{
+ int total_mem = 0;
+ int free_mem = 0;
+ Buffer *token_status = NULL;
+ SelectApplet(a_session, 0x04, 0x00, a_aid);
+ token_status = GetStatus(a_session, 0x00, 0x00);
+ if (token_status == NULL) {
+ o_major_version = 0x0;
+ o_minor_version = 0x0;
+ o_app_major_version = 0x0;
+ o_app_minor_version = 0x0;
+ } else {
+ o_major_version = ((BYTE*)*token_status)[0]; // is this protocol version?
+ o_minor_version = ((BYTE*)*token_status)[1];
+ o_app_major_version = ((BYTE*)*token_status)[2]; // and this applet version?
+ o_app_minor_version = ((BYTE*)*token_status)[3];
+
+ BYTE tot_high = ((BYTE*)*token_status)[6];
+ BYTE tot_low = ((BYTE*)*token_status)[7];
+
+ BYTE free_high = ((BYTE*)*token_status)[10];
+ BYTE free_low = ((BYTE*)*token_status)[11];
+
+ total_mem = (tot_high << 8) + tot_low;
+ free_mem = (free_high << 8) + free_low;
+
+ totalAvailableMemory = total_mem;
+ totalFreeMemory = free_mem;
+
+ RA::DebugBuffer("RA_Enroll_Processor::Process AppletInfo Data", "Data=", token_status);
+ delete token_status;
+ }
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Major=%d Minor=%d Applet Major=%d Applet Minor=%d Total Mem %d Free Mem %d",
+ o_major_version, o_minor_version, o_app_major_version, o_app_minor_version,total_mem,free_mem);
+ return true;
+}
+
+
+/**
+ * Query applet for build ID info
+ * 'Pretty'-print it into useful format, along with version info
+ * example input:
+ * a_app_major_version = 1
+ * a_app_minor_version = 3
+ * Examples for the following outputs:
+ * o_av = "1.3.45FC0218"
+ * The caller is responsible for free'ing (o_av)
+ */
+bool RA_Enroll_Processor::FormatAppletVersionInfo(
+ RA_Session *a_session,
+ const char *a_tokenType,
+ char *a_cuid,
+ BYTE a_app_major_version,
+ BYTE a_app_minor_version,
+ RA_Status &o_status, // out
+ char * &o_av // out.
+)
+{
+ bool r=true;
+ char configname[256];
+ char *av=NULL;
+
+ // retrieve the 4-byte applet ID from the token
+ Buffer *tokenBuildID = GetAppletVersion(a_session);
+
+ if (tokenBuildID == NULL) {
+ // If there was no applet on the token
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.emptyToken.enable", OP_PREFIX,
+ a_tokenType);
+ // XXX checks if emptyToken is enabled. This should probably get moved
+ // to the applet update function, and leave this fn only for getting
+ // the version information
+ if (!RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "no applet found and applet upgrade not enabled");
+ o_status = STATUS_ERROR_SECURE_CHANNEL; // XXX incorrect error message
+ r=false;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "secure channel not established", "", a_tokenType); // XXX incorrect error message
+ goto loser;
+ }
+ } else {
+ // if there was an applet on the token:
+ char * bid_string = Util::Buffer2String(*tokenBuildID);
+ RA::Debug("RA_Enroll_Processor", "buildid = %s", bid_string);
+ av = PR_smprintf( "%x.%x.%s",
+ a_app_major_version, a_app_minor_version, bid_string);
+ PR_Free(bid_string);
+ }
+ o_av = (av == NULL) ? strdup("") : av;
+
+ RA::Debug("RA_Enroll_Processor", "final_applet_version = %s", o_av);
+loser:
+ if( tokenBuildID != NULL ) {
+ delete tokenBuildID;
+ }
+ return r;
+}
+
+/**
+ * Checks if we need to upgrade applet.
+ * The version of the current token is passed IN to this function
+ * in o_current_applet_on_token. If the applet is upgraded, this
+ * out parameter will be set to the new applet version id.
+ * maj/minor versions will be also updated if the applet was updated.
+ */
+bool RA_Enroll_Processor::CheckAndUpgradeApplet(
+ RA_Session *a_session,
+ NameValueSet *a_extensions,
+ char *a_cuid,
+ const char *a_tokenType,
+ char *&o_current_applet_on_token,
+ BYTE &o_major_version,
+ BYTE &o_minor_version,
+ Buffer *a_aid,
+ const char *a_msn,
+ const char *a_userid,
+ RA_Status &o_status,
+ char **keyVersion )
+{
+ int rc = 0;
+ const char *FN = "RA_Enroll_Processor::CheckAndUpgradeApplet";
+ bool r = true;
+ const char *applet_dir=NULL;
+ const char *connid = NULL;
+ Buffer *token_status = NULL;
+ char configname[256];
+
+ // You specify the following parameters to get applet upgrade working
+ // *.update.applet.enable=true
+ // *.update.applet.requiredVersion=maj.min.xxxxxxxx
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.encryption", OP_PREFIX, a_tokenType);
+ SecurityLevel security_level = SECURE_MSG_MAC;
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, true))
+ security_level = SECURE_MSG_MAC_ENC;
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.enable", OP_PREFIX, a_tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.requiredVersion", OP_PREFIX, a_tokenType);
+ g_applet_target_version = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (g_applet_target_version == NULL) {
+ RA::Error(FN, "upgrade.version not found");
+ o_status = STATUS_ERROR_MISCONFIGURATION;
+ r = false;
+ goto loser;
+ }
+ /* Bugscape #55826: used case-insensitive check below */
+ if (PL_strcasecmp(g_applet_target_version, o_current_applet_on_token) != 0) {
+ RA::Debug(LL_PER_CONNECTION, FN, "tokenType=%s before updating applet", a_tokenType);
+ /* upgrade applet */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.directory", OP_PREFIX, a_tokenType);
+ applet_dir = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (applet_dir == NULL || strlen(applet_dir) == 0) {
+ RA::Error(LL_PER_CONNECTION, FN,
+ "Failed to read applet directory parameter %s", configname);
+ o_status = STATUS_ERROR_MISCONFIGURATION;
+ r = false;
+ goto loser;
+ }
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, a_tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ RA::Debug(FN, "TKS connection id =%s", connid);
+ //StatusUpdate(a_session, a_extensions, 5, "PROGRESS_UPGRADE_APPLET");
+
+ if (rc = UpgradeApplet(a_session, (char *) OP_PREFIX, (char*) a_tokenType,
+ o_major_version, o_minor_version,
+ g_applet_target_version,
+ applet_dir, security_level,
+ connid, a_extensions,
+ 5,
+ 12,
+ keyVersion) != 1) {
+
+ RA::Debug(FN, "applet upgrade failed");
+ /**
+ * Bugscape #55709: Re-select Net Key Applet ONLY on failure.
+ */
+ SelectApplet(a_session, 0x04, 0x00, a_aid);
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "applet upgrade error", "", a_tokenType);
+ o_status = STATUS_ERROR_UPGRADE_APPLET;
+ r = false;
+
+ if (rc == -1) {
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Failure", "enrollment",
+ *keyVersion != NULL? *keyVersion : "", o_current_applet_on_token, g_applet_target_version, "failed to setup secure channel");
+ } else {
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Success", "enrollment",
+ *keyVersion != NULL? *keyVersion : "", o_current_applet_on_token, g_applet_target_version, "setup secure channel");
+ }
+
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Failure", "enrollment",
+ *keyVersion != NULL? *keyVersion : "",
+ o_current_applet_on_token, g_applet_target_version,
+ "applet upgrade");
+
+ goto loser;
+ } else {
+ // there may be a better place to do this, but worth testing here
+ // RA::tdb_update(a_cuid, g_applet_target_version);
+ }
+
+ // Upgrade Applet reported success
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Success", "enrollment",
+ *keyVersion != NULL? *keyVersion : "", o_current_applet_on_token, g_applet_target_version, "setup secure channel");
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ a_userid, a_cuid, a_msn, "Success", "enrollment",
+ *keyVersion != NULL? *keyVersion : "",
+ o_current_applet_on_token, g_applet_target_version,
+ "applet upgrade");
+
+ o_current_applet_on_token = strdup(g_applet_target_version);
+
+ token_status = GetStatus(a_session, 0x00, 0x00);
+ if (token_status == NULL) {
+ RA::Error(FN, "Get Status Failed");
+ o_status = STATUS_ERROR_SECURE_CHANNEL; // XXX
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "secure channel error", "", a_tokenType);
+ r = false;
+ goto loser;
+ }
+
+ o_major_version = ((BYTE*)*token_status)[2]; // applet version
+ o_minor_version = ((BYTE*)*token_status)[3]; // not protocol version
+loser:
+ if( token_status != NULL ) {
+ delete token_status;
+ }
+ }
+ } else {
+ RA::Debug(FN, "Applet Upgrade has been disabled.");
+ }
+ return r;
+}
+
+/**
+ * Authenticate user with LDAP plugin
+ * @return true if authentication was successful
+ */
+bool RA_Enroll_Processor::AuthenticateUserLDAP(
+ RA_Session *a_session,
+ NameValueSet *a_extensions,
+ char *a_cuid,
+ AuthenticationEntry *a_auth,
+ AuthParams *&login,
+ RA_Status &o_status,
+ const char *a_token_type
+)
+{
+ const char *FN = "RA_Enroll_Processor::AuthenticateUserLDAP";
+ int retry_limit = a_auth->GetAuthentication()->GetNumOfRetries();
+ int retries = 0;
+ int rc;
+ bool r=false;
+
+ RA::Debug(LL_PER_PDU, FN, "LDAP_Authentication is invoked.");
+ rc = a_auth->GetAuthentication()->Authenticate(login);
+
+ RA::Debug(FN, "Authenticate returned: %d", rc);
+
+ // rc: (0:login correct) (-1:LDAP error) (-2:User not found) (-3:Password error)
+
+ // XXX replace with proper enums
+ // XXX evaluate rc==0 as specific case - this is success, it shouldn't be the default
+
+ while ((rc == TPS_AUTH_ERROR_USERNOTFOUND ||
+ rc == TPS_AUTH_ERROR_PASSWORDINCORRECT )
+ && (retries < retry_limit)) {
+ login = RequestLogin(a_session, 0 /* invalid_pw */, 0 /* blocked */);
+ retries++;
+ if (login != NULL)
+ rc = a_auth->GetAuthentication()->Authenticate(login);
+ }
+
+ switch (rc) {
+ case TPS_AUTH_OK:
+ RA::Debug(LL_PER_PDU, FN, "Authentication successful.");
+ r=true;
+ break;
+ case TPS_AUTH_ERROR_LDAP:
+ RA::Error(FN, "Authentication failed. LDAP Error");
+ o_status = STATUS_ERROR_LDAP_CONN;
+ RA::Debug(LL_PER_PDU, FN, "Authentication status=%d rc=%d", o_status,rc);
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_token_type);
+ r = false;
+ break;
+ case TPS_AUTH_ERROR_USERNOTFOUND:
+ RA::Error(FN, "Authentication failed. User not found");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_token_type);
+ r = false;
+ break;
+ case TPS_AUTH_ERROR_PASSWORDINCORRECT:
+ RA::Error(FN, "Authentication failed. Password Incorrect");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::Debug(LL_PER_PDU, FN, "Authentication status=%d rc=%d", o_status,rc);
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_token_type);
+ r = false;
+ break;
+ default:
+ RA::Error(FN, "Undefined LDAP Auth Error.");
+ r = false;
+ break;
+ }
+
+ return r;
+}
+
+/**
+ * Request Login info and user id from user, if necessary
+ * This call will allocate a new Login structure,
+ * and a char* for the user id. The caller is responsible
+ * for freeing this memory
+ * @return true of success, false if failure
+ */
+bool RA_Enroll_Processor::RequestUserId(
+ RA_Session * a_session,
+ NameValueSet *a_extensions,
+ const char * a_configname,
+ const char * a_tokenType,
+ char *a_cuid,
+ AuthParams *& o_login, const char *&o_userid, RA_Status &o_status)
+{
+
+ if (RA::GetConfigStore()->GetConfigAsBool(a_configname, 1)) {
+ if (a_extensions != NULL &&
+ a_extensions->GetValue("extendedLoginRequest") != NULL)
+ {
+ // XXX - extendedLoginRequest
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected");
+ AuthenticationEntry *entry = GetAuthenticationEntry(
+ OP_PREFIX, a_configname, a_tokenType);
+ char **params = NULL;
+ char pb[1024];
+ char *locale = NULL;
+ if (a_extensions != NULL &&
+ a_extensions->GetValue("locale") != NULL)
+ {
+ locale = a_extensions->GetValue("locale");
+ } else {
+ locale = ( char * ) "en"; /* default to english */
+ }
+ int n = entry->GetAuthentication()->GetNumOfParamNames();
+ if (n > 0) {
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected n=%d", n);
+ params = (char **) PR_Malloc(n);
+ for (int i = 0; i < n; i++) {
+ sprintf(pb,"id=%s&name=%s&desc=%s&type=%s&option=%s",
+ entry->GetAuthentication()->GetParamID(i),
+ entry->GetAuthentication()->GetParamName(i, locale),
+ entry->GetAuthentication()->GetParamDescription(i, locale),
+ entry->GetAuthentication()->GetParamType(i),
+ entry->GetAuthentication()->GetParamOption(i)
+ );
+ params[i] = PL_strdup(pb);
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "params[i]=%s", params[i]);
+ }
+ }
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "Extended Login Request detected calling RequestExtendedLogin() locale=%s", locale);
+
+ char *title = PL_strdup(entry->GetAuthentication()->GetTitle(locale));
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "title=%s", title);
+ char *description = PL_strdup(entry->GetAuthentication()->GetDescription(locale));
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "description=%s", description);
+ o_login = RequestExtendedLogin(a_session, 0 /* invalid_pw */, 0 /* blocked */, params, n, title, description);
+
+ if (params != NULL) {
+ for (int nn=0; nn < n; nn++) {
+ if (params[nn] != NULL) {
+ PL_strfree(params[nn]);
+ params[nn] = NULL;
+ }
+ }
+ free(params);
+ params = NULL;
+ }
+
+ if (title != NULL) {
+ PL_strfree(title);
+ title = NULL;
+ }
+
+ if (description != NULL) {
+ PL_strfree(description);
+ description = NULL;
+ }
+
+ if (o_login == NULL) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "login not provided");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid,
+ "enrollment", "failure", "login not found", "", a_tokenType);
+ return false;
+ }
+
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected calling RequestExtendedLogin() login=%x", o_login);
+ o_userid = PL_strdup( o_login->GetUID() );
+ RA::Debug("RA_Enroll_Processor::Process",
+ "userid = '%s'", o_userid);
+ } else {
+ o_login = RequestLogin(a_session, 0 /* invalid_pw */, 0 /* blocked */);
+ if (o_login == NULL) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "login not provided");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid,
+ "enrollment", "failure", "login not found", o_userid, a_tokenType);
+ return false;
+ }
+ o_userid = PL_strdup( o_login->GetUID() );
+ RA::Debug("RA_Enroll_Processor::Process",
+ "userid = '%s'", o_userid);
+ }
+ }
+ return true;
+}
+
+/**
+ * Authenticate the user with the configured authentication plugin
+ * @return true if authentication successful
+ */
+
+bool RA_Enroll_Processor::AuthenticateUser(
+ RA_Session * a_session,
+ const char * a_configname,
+ char *a_cuid,
+ NameValueSet *a_extensions,
+ const char *a_tokenType,
+ AuthParams *& a_login, const char *&o_userid, RA_Status &o_status
+ )
+{
+ bool r=false;
+
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser", "started");
+ if (RA::GetConfigStore()->GetConfigAsBool(a_configname, false)) {
+ if (a_login == NULL) {
+ RA::Error("RA_Enroll_Processor::AuthenticateUser", "Login Request Disabled. Authentication failed.");
+ o_status = STATUS_ERROR_LOGIN;
+ goto loser;
+ }
+
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser",
+ "Authentication enabled");
+ char configname[256];
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, a_tokenType);
+ const char *authid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (authid == NULL) {
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "login not found", "", a_tokenType);
+ goto loser;
+ }
+ AuthenticationEntry *auth = RA::GetAuth(authid);
+
+ if (auth == NULL) {
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_tokenType);
+ goto loser;
+ }
+
+ StatusUpdate(a_session, a_extensions, 2, "PROGRESS_START_AUTHENTICATION");
+
+ char *type = auth->GetType();
+ if (type == NULL) {
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication is missing param type", "", a_tokenType);
+ r = false;
+ goto loser;
+ }
+
+ if (strcmp(type, "LDAP_Authentication") == 0) {
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser", "LDAP started");
+ r = AuthenticateUserLDAP(a_session, a_extensions, a_cuid, auth, a_login, o_status, a_tokenType);
+ o_status = STATUS_ERROR_LOGIN;
+ goto loser;
+ } else {
+ RA::Error("RA_Enroll_Processor::AuthenticateUser", "No Authentication type was found.");
+ o_status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(a_session->GetRemoteIP(), a_cuid, "enrollment", "failure", "authentication error", "", a_tokenType);
+ r = false;
+ goto loser;
+ }
+ } else {
+ r = true;
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser",
+ "Authentication has been disabled.");
+ }
+ loser:
+ return r;
+}
+
+
+
+
+ /**
+ * Checks if the token has the required key version.
+ * If not, we can swap out the keys on the token with another
+ * set of keys
+ */
+
+/* XXX AID's should be member variables */
+bool RA_Enroll_Processor::CheckAndUpgradeSymKeys(
+ //RA_Session * a_session,
+ //NameValueSet *a_extensions,
+ //const char * a_configname,
+ //char *a_cuid,
+ RA_Session *a_session,
+ NameValueSet* a_extensions,
+ char *a_cuid,
+ const char *a_tokenType,
+ char *a_msn,
+ const char *a_applet_version,
+ const char *a_userid,
+ const char *a_key_version,
+ Buffer *a_cardmanagerAID, /* in */
+ Buffer *a_appletAID, /* in */
+ Secure_Channel *&o_channel, /* out */
+ RA_Status &o_status /* out */
+ )
+{
+ char *FN = ( char * ) "RA_EnrollProcessor::CheckAndUpgradeSymKeys";
+ char configname[256];
+ const char *connid = NULL;
+ const char *tksid = NULL;
+ int rc;
+ bool r = false;
+ Buffer key_data_set;
+ char audit_msg[512] = "";
+ char curVer[10];
+ char newVer[10];
+
+ char *curKeyInfoStr = NULL;
+ char *newVersionStr = NULL;
+
+ // the TKS is responsible for doing much of the symmetric keys update
+ // so lets find which TKS we're talking about TKS now.
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, a_tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)configname, 256,"%s.%s.update.symmetricKeys.enable", OP_PREFIX, a_tokenType);
+
+ RA::Debug(FN, "Symmetric Keys %s", configname);
+
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "tokenType=%s configured to update symmetric keys", a_tokenType);
+
+ // the requiredVersion config parameter indicates what key version
+ // the token should have before further operations. If the token
+ // has an older version, we try to change it.
+ PR_snprintf((char *)configname, 256,
+ "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, a_tokenType);
+
+ int requiredV = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+
+ // If there was a secure channel set up, let's clear it out
+ if( o_channel != NULL ) {
+ delete o_channel;
+ o_channel = NULL;
+ }
+ // try to make a secure channel with the 'requiredVersion' keys
+ // If this fails, we know we will have to attempt an upgrade
+ // of the keys
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ o_channel = SetupSecureChannel(a_session,
+ requiredV,
+ defKeyIndex /* default key index */, tksid);
+
+ // If that failed, we need to find out what version of keys
+ // are on the token
+ if (o_channel != NULL) {
+ r = true;
+ } else {
+ /**
+ * Select Card Manager for Put Key operation.
+ */
+ SelectApplet(a_session, 0x04, 0x00, a_cardmanagerAID);
+ /* if the key of the required version is
+ * not found, create them.
+ */
+ // This sends a InitializeUpdate request to the token.
+ // We tell the token to use whatever it thinks is the
+ // default key version (0). It will return the version
+ // of the key it actually used later. (This is accessed
+ // with GetKeyInfoData below)
+ // [ Note: This is not explained very well in the manual
+ // The token can have multiple sets of symmetric keys
+ // Each set is given a version number, which I think is
+ // better thought of as a SLOT. One key slot is populated
+ // with a set of keys when the token is manufactured.
+ // This is then designated as the default key set version.
+ // Later, we will write a new key set with PutKey, and
+ // set it to be the new default]
+ PR_snprintf((char *)configname, 256,"channel.defKeyVersion");
+ int defKeyVer = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ o_channel = SetupSecureChannel(a_session,
+ defKeyVer, /* default key version */
+ defKeyIndex /* default key index */, tksid);
+
+ if (o_channel == NULL) {
+ PR_snprintf(audit_msg, 512, "enrollment processing, failed to create secure channel");
+
+ RA::Error(FN, "failed to establish secure channel");
+ o_status = STATUS_ERROR_SECURE_CHANNEL;
+ goto loser;
+ }
+
+ /* Complete the secure channel handshake */
+ /* XXX need real enumeration of error codes here */
+ rc = o_channel->ExternalAuthenticate();
+ if (rc != 1) {
+ RA::Error(FN, "External authentication in secure channel failed");
+ o_status = STATUS_ERROR_EXTERNAL_AUTH;
+ /* XXX should print out error codes */
+ PR_snprintf(audit_msg, 512, "enrollment processing, external authentication error");
+ goto loser;
+ }
+
+ // Assemble the Buffer with the version information
+ // The second byte is the key offset, which is always 1
+ BYTE nv[2] = { requiredV, 0x01 };
+ Buffer newVersion(nv, 2);
+
+ // GetKeyInfoData will return a buffer which is bytes 11,12 of
+ // the data structure on page 89 of Cyberflex Access Programmer's
+ // Guide
+ // Byte 0 is the key set version.
+ // Byte 1 is the index into that key set
+ Buffer curKeyInfo = o_channel->GetKeyInfoData();
+
+
+ // This code makes a call to the TKS to get a new key set for
+ // the token. The new key set data is written to the Buffer
+ // key_data_set.
+ PR_snprintf((char *)configname, 256,"%s.%s.tks.conn", OP_PREFIX, a_tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ rc = CreateKeySetData(
+ o_channel->GetKeyDiversificationData(),
+ curKeyInfo,
+ newVersion,
+ key_data_set, connid);
+ if (rc != 1) {
+ RA::Error(FN, "failed to create new key set");
+ o_status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "enrollment processing, create card key error");
+ goto loser;
+ }
+
+ StatusUpdate(a_session, a_extensions, 13, "PROGRESS_PUT_KEY");
+
+ // sends a PutKey PDU with the new key set to change the
+ // keys on the token
+ BYTE curVersion = ((BYTE*)curKeyInfo)[0];
+ BYTE curIndex = ((BYTE*)curKeyInfo)[1];
+ rc = o_channel->PutKeys(a_session,
+ curVersion,
+ curIndex,
+ &key_data_set);
+
+
+ curKeyInfoStr = Util::Buffer2String(curKeyInfo);
+ newVersionStr = Util::Buffer2String(newVersion);
+
+ if(curKeyInfoStr != NULL && strlen(curKeyInfoStr) >= 2) {
+ curVer[0] = curKeyInfoStr[0]; curVer[1] = curKeyInfoStr[1]; curVer[2] = 0;
+ }
+ else {
+ curVer[0] = 0;
+ }
+
+ if(newVersionStr != NULL && strlen(newVersionStr) >= 2) {
+ newVer[0] = newVersionStr[0] ; newVer[1] = newVersionStr[1] ; newVer[2] = 0;
+ }
+ else {
+ newVer[0] = 0;
+ }
+
+
+ if (rc!=0) {
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ a_userid != NULL ? a_userid : "", a_cuid != NULL ? a_cuid : "", a_msn != NULL ? a_msn : "", "Failure", "enrollment",
+ a_applet_version != NULL ? a_applet_version : "", curVer, newVer,
+ "key changeover");
+
+ if ((a_cuid != NULL) && (a_tokenType != NULL)) {
+ RA::tdb_activity(a_session->GetRemoteIP(),
+ a_cuid,
+ "enrollment",
+ "failure",
+ "key changeover failed",
+ a_userid != NULL? a_userid : "",
+ a_tokenType);
+ }
+ goto loser;
+ } else {
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ a_userid != NULL ? a_userid : "", a_cuid != NULL ? a_cuid : "", a_msn != NULL ? a_msn : "", "Success", "enrollment",
+ a_applet_version != NULL ? a_applet_version : "", curVer, newVer,
+ "key changeover");
+ }
+
+ /**
+ * Re-select the Applet.
+ */
+ SelectApplet(a_session, 0x04, 0x00, a_appletAID);
+ if( o_channel != NULL ) {
+ delete o_channel;
+ o_channel = NULL;
+ }
+
+ // Make a new secure channel with the new symmetric keys
+ o_channel = SetupSecureChannel(a_session, requiredV,
+ defKeyIndex /* default key index */, tksid);
+ if (o_channel == NULL) {
+ RA::Error(FN, "failed to establish secure channel after reselect");
+ o_status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "enrollment processing, secure channel setup error after reselect");
+ goto loser;
+ } else {
+ RA::Debug(FN, "Key Upgrade has completed successfully.");
+ r = true; // Success!!
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ a_userid != NULL ? a_userid : "", a_cuid != NULL ? a_cuid : "",
+ a_msn != NULL ? a_msn : "", "success", "enrollment", a_applet_version != NULL ? a_applet_version : "",
+ newVer, "enrollment processing, key upgrade completed");
+ }
+
+ }
+ } else {
+
+ RA::Debug(FN, "Key Upgrade has been disabled.");
+
+ if( o_channel != NULL ) {
+ delete o_channel;
+ o_channel = NULL;
+ }
+ PR_snprintf((char *)configname, 256,"channel.defKeyVersion");
+ int defKeyVer = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ o_channel = SetupSecureChannel(a_session,
+ defKeyVer,
+ defKeyIndex /* default key index */, tksid);
+ r = true; // Sucess!!
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ a_userid, a_cuid, a_msn, "success", "enrollment", a_applet_version,
+ a_key_version != NULL? a_key_version: "",
+ "enrollment processing, key upgrade disabled");
+ }
+loser:
+
+ if (curKeyInfoStr != NULL) {
+ PR_Free( (char *) curKeyInfoStr);
+ curKeyInfoStr = NULL;
+ }
+
+ if (newVersionStr != NULL) {
+ PR_Free( (char *) newVersionStr);
+ newVersionStr = NULL;
+ }
+
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ a_userid != NULL ? a_userid : "",
+ a_cuid != NULL ? a_cuid : "",
+ a_msn != NULL ? a_msn : "",
+ "failure",
+ "enrollment",
+ a_applet_version != NULL ? a_applet_version : "",
+ a_key_version != NULL? a_key_version : "",
+ audit_msg);
+
+ if ((a_cuid != NULL) && (a_tokenType != NULL)) {
+ RA::tdb_activity(a_session->GetRemoteIP(),
+ a_cuid,
+ "enrollment",
+ "failure",
+ audit_msg,
+ a_userid != NULL? a_userid : "",
+ a_tokenType);
+ }
+ }
+
+ return r;
+}
+
+/**
+ * Processes the current session.
+ */
+TPS_PUBLIC RA_Status RA_Enroll_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ char *FN = ( char * ) "RA_Enroll_Processor::Process";
+ char configname[256];
+ char *cuid = NULL;
+ char *msn = NULL;
+ PRIntervalTime start, end;
+ RA_Status status = STATUS_NO_ERROR;
+ int rc = -1;
+ Secure_Channel *channel = NULL;
+ Buffer kdd;
+ AuthParams *login = NULL;
+ char *new_pin = NULL;
+#define PLAINTEXT_CHALLENGE_SIZE 16
+#define WRAPPED_CHALLENGE_SIZE 16
+ Buffer *plaintext_challenge =
+ new Buffer(PLAINTEXT_CHALLENGE_SIZE, (BYTE)0);
+ Buffer *wrapped_challenge = new Buffer(WRAPPED_CHALLENGE_SIZE, (BYTE)0);
+ Buffer *key_check = new Buffer(0, (BYTE)0);
+ const char *tokenType = NULL;
+
+ //SecurityLevel security_level = SECURE_MSG_MAC_ENC;
+ BYTE major_version = 0x0;
+ BYTE minor_version = 0x0;
+ BYTE app_major_version = 0x0;
+ BYTE app_minor_version = 0x0;
+ int isPinPresent = 0;
+ Buffer *object = NULL;
+ int seq = 0x00;
+ unsigned long lastFormatVersion = 0x00;
+ unsigned long lastObjectVersion = 0x00;
+ int foundLastObjectVersion = 0;
+ int pkcs11obj_enable = 0;
+ int compress = 0;
+ NameValueSet nv;
+ int o_certNums = 0;
+
+ CertEnroll *certEnroll = NULL;
+
+ Buffer *token_status = NULL;
+ char* appletVersion = NULL;
+ char *final_applet_version = NULL;
+
+ char *keyVersion = PL_strdup( "" );
+ const char *userid = PL_strdup( "" );
+ char *token_state = PL_strdup("inactive");
+ char *khex = NULL;
+
+ Buffer host_challenge = Buffer(8, (BYTE)0);
+ Buffer key_diversification_data;
+ Buffer key_info_data;
+ Buffer card_challenge;
+ Buffer card_cryptogram;
+ const char *connid = NULL;
+ const char *tksid = NULL;
+ const char *authid = NULL;
+ PKCS11Obj *pkcs11objx = NULL;
+ Buffer labelBuffer;
+ char activity_msg[4096];
+ char audit_msg[512] = "";
+
+ Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_CARDMGR_INSTANCE_AID,
+ RA::CFG_DEF_CARDMGR_INSTANCE_AID);
+ Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_INSTANCE_AID);
+ Buffer token_cuid;
+ int maxRetries = 3;
+ const char *pattern = NULL;
+ char *label = NULL;
+ CERTCertificate **certificates = NULL;
+ char **ktypes = NULL;
+ char **origins = NULL;
+ char **tokenTypes = NULL;
+ char *tokentype = NULL;
+ char *profile_state = NULL;
+ RA_Status st;
+ bool renewed = false;
+ bool do_force_format = false;
+
+ RA::Debug("RA_Enroll_Processor::Process", "Client %s",
+ session->GetRemoteIP());
+ RA::Debug(LL_PER_PDU, FN, "Begin enroll process");
+
+ // XXX need to validate all user input (convert to 'string' types)
+ // to ensure that no buffer overruns
+ start = PR_IntervalNow();
+
+ /* Get the card serial number */
+ if (!GetCardManagerAppletInfo(session, CardManagerAID, st, msn, cuid, token_cuid)) goto loser;
+
+ /* Get the applet version information */
+ if (!GetAppletInfo(session, NetKeyAID,
+ /*by ref*/ major_version, minor_version,
+ app_major_version, app_minor_version )) goto loser;
+
+ if (!GetTokenType(OP_PREFIX, major_version, minor_version,
+ cuid, msn, extensions,
+ status, tokenType)) { /* last two are 'out' params */
+ /* ADE figure out what to do here for this line*/
+ // RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "token type not found", "");
+ goto loser;
+ }
+
+ // check if profile is enabled here
+ PR_snprintf((char *)configname, 256, "config.Profiles.%s.state", tokenType);
+ profile_state = (char *) RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((profile_state != NULL) && (PL_strcmp(profile_state, "Enabled") != 0)) {
+ RA::Error(FN, "Profile %s Disabled for CUID %s", tokenType, cuid);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "profile %s disabled", tokenType);
+ goto loser;
+ }
+
+ if (RA::ra_is_token_present(cuid)) {
+ RA::Debug(FN, "Found token %s", cuid);
+ if (RA::ra_is_tus_db_entry_disabled(cuid)) {
+ RA::Error(FN, "CUID %s Disabled", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "token disabled");
+ goto loser;
+ }
+
+ // at this point, token is either active or uninitialized (formatted)
+ // or the adminstrator has called for a force format.
+
+ do_force_format = RA::ra_force_token_format(cuid);
+
+ RA::Debug("RA_Enroll_Processor::Process","force format flag %d", do_force_format);
+
+ if (!RA::ra_allow_token_reenroll(cuid) &&
+ !RA::ra_allow_token_renew(cuid) &&
+ !do_force_format) {
+ RA::Error(FN, "CUID %s Re-Enrolled Disallowed", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "token re-enrollment or renewal disallowed");
+ goto loser;
+ }
+ } else {
+ RA::Debug(FN, "Not Found token %s", cuid);
+ // This is a new token. We need to check our policy to see
+ // if we should allow enrollment. raidzilla #57414
+ PR_snprintf((char *)configname, 256, "%s.allowUnknownToken",
+ OP_PREFIX);
+ if (!RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ RA::Error(FN, "CUID %s Enroll Unknown Token", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "unknown token disallowed");
+ goto loser;
+ }
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "token enabled");
+
+
+ /* XXX - this comment does not belong here
+ *
+ * This is very risky to call initialize and then
+ * external authenticate later on.
+ * The token will be locked if no external authenticate
+ * follows the initialize update.
+ */
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn",
+ OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tksid == NULL) {
+ RA::Error(FN, "TKS Connection Parameter %s Not Found", configname);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "token type TKS connection parameter not found");
+ goto loser;
+ }
+
+ /* figure some more information about the applet version */
+ /* XXX should probably move this further down, since the results
+ of this function aren't used til much later */
+ if (!FormatAppletVersionInfo(session, tokenType, cuid,
+ app_major_version, app_minor_version,
+ status,
+ final_applet_version /*out */)) {
+ PR_snprintf(audit_msg, 512, "FormatAppletVersionInfo error");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.loginRequest.enable", OP_PREFIX, tokenType);
+ if (!RequestUserId(session, extensions, configname, tokenType, cuid, login, userid, status)){
+ PR_snprintf(audit_msg, 512, "RequestUserId error");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.enable", OP_PREFIX, tokenType);
+
+ if (!AuthenticateUser(session, configname, cuid, extensions,
+ tokenType, login, userid, status)){
+ PR_snprintf(audit_msg, 512, "AuthenticateUser error");
+ goto loser;
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "token login successful");
+
+ // get authid for audit log
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, tokenType);
+ authid = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ StatusUpdate(session, extensions, 4, "PROGRESS_APPLET_UPGRADE");
+
+ if(do_force_format) {
+ bool skip_auth = true;
+ if(Format(session,extensions,skip_auth) != STATUS_NO_ERROR ) {
+ PR_snprintf(audit_msg,512, "ForceUpgradeApplet error");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION, "RA_Enroll_Processor::Process",
+ "after Successful ForceUpdgradeApplet, succeeded!");
+
+ PR_snprintf(audit_msg,512, "ForceUpgradeApplet succeeded as per policy.");
+ status = STATUS_NO_ERROR;
+ goto loser;
+
+ }
+ } else {
+ if (! CheckAndUpgradeApplet(
+ session,
+ extensions,
+ cuid,
+ tokenType,
+ final_applet_version,
+ app_major_version, app_minor_version,
+ //appletVersion,
+ NetKeyAID,
+ msn,
+ userid,
+ status,
+ &keyVersion)) {
+ PR_snprintf(audit_msg, 512, "CheckAndUpgradeApplet error");
+ goto loser;
+ }
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "applet upgraded successfully");
+
+ isPinPresent = IsPinPresent(session, 0x0);
+
+ StatusUpdate(session, extensions, 12, "PROGRESS_KEY_UPGRADE");
+
+ if (!CheckAndUpgradeSymKeys(
+ session,
+ extensions,
+ cuid,
+ tokenType,
+ msn,
+ final_applet_version,
+ userid,
+ keyVersion,
+ CardManagerAID,
+ NetKeyAID,
+ channel,
+ status))
+ {
+ PR_snprintf(audit_msg, 512, "CheckAndUpgradeSymKeys error");
+ goto loser;
+ }
+
+ /* we should have a good channel here */
+ if (channel == NULL) {
+ RA::Error(FN, "no good channel");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "secure channel setup error");
+ goto loser;
+ }
+
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ StatusUpdate(session, extensions, 14, "PROGRESS_TOKEN_AUTHENTICATION");
+
+ rc = channel->ExternalAuthenticate();
+ if (rc == -1) {
+ RA::Error(FN, "external authenticate failed");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "external authentication error");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_CONNECTION, FN, "after SetupSecureChannel, succeeded");
+
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.minLen", OP_PREFIX, tokenType);
+ unsigned int minlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 4);
+ PR_snprintf((char *)configname, 256,"%s.%s.pinReset.pin.maxLen", OP_PREFIX, tokenType);
+ unsigned int maxlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 10);
+
+ new_pin = RequestNewPin(session, minlen, maxlen);
+ if (new_pin == NULL) {
+ RA::Error(FN, "new pin request failed");
+
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ PR_snprintf(audit_msg, 512, "new pin request error");
+ goto loser;
+ }
+ RA::Debug(LL_PER_CONNECTION, "RA_Enroll_Processor::Process",
+ "after RequestNewPin, succeeded");
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "RequestNewPin completed successfully");
+
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ if (!isPinPresent) {
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.maxRetries", OP_PREFIX, tokenType);
+ maxRetries = RA::GetConfigStore()->GetConfigAsInt(configname, 0x7f);
+ RA::Debug(LL_PER_CONNECTION, FN,
+ "param=%s maxRetries=%d", configname, maxRetries);
+ rc = channel->CreatePin(0x0,
+ maxRetries,
+ RA::GetConfigStore()->GetConfigAsString("create_pin.string", "password"));
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "create pin failed");
+
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ PR_snprintf(audit_msg, 512, "create pin request error");
+ goto loser;
+ }
+
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "CreatePin completed successfully");
+
+ }
+ }
+
+ rc = channel->ResetPin(0x0, new_pin);
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "reset pin failed");
+
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ PR_snprintf(audit_msg, 512, "reset pin request error");
+ goto loser;
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ "ResetPin completed successfully");
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "after ResetPin, succeeded");
+
+ // to help testing, we may use fix challenge
+ PR_snprintf((char *)configname, 256, "%s.%s.generateChallenge", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ /* generate challenge for enrollment */
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Generate Challenge");
+/*
+ random number generation moved to TKS
+ rc = Util::GetRandomChallenge(*plaintext_challenge);
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "random challenge creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "general challenge error", "", tokenType);
+ goto loser;
+ }
+*/
+
+ }
+ kdd = channel->GetKeyDiversificationData();
+ khex = kdd.toHex();
+ RA::Debug("RA_Enroll_Processor::Process", "cuid=%s", khex);
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ /* wrap challenge with KEK key */
+ rc = EncryptData(kdd,
+ channel->GetKeyInfoData(), *plaintext_challenge, *wrapped_challenge, connid);
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "encryt data failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "challenge encryption error");
+ goto loser;
+ }
+ // read objects back
+ PR_snprintf((char *)configname, 256, "%s.%s.pkcs11obj.enable",
+ OP_PREFIX, tokenType);
+ pkcs11obj_enable = RA::GetConfigStore()->GetConfigAsBool(configname, 1);
+
+ if (pkcs11obj_enable) {
+ pkcs11objx = new PKCS11Obj();
+
+ // read old objects
+ seq = 0x00;
+ lastFormatVersion = 0x0100;
+ // lastObjectVersion = 0;
+ if (getRandomNumber(&lastObjectVersion) != SECSuccess) {
+ RA::Error(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Could not generate a random version number...assigning 0x00");
+ lastObjectVersion = 0x00;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "got random version numer: %ul", lastObjectVersion);
+ }
+
+ foundLastObjectVersion = 0;
+ do {
+ object = ListObjects(session, seq);
+ if (object == NULL) {
+ seq = 0;
+ } else {
+ seq = 1; // get next entry
+ Buffer objectID = object->substr(0, 4);
+ Buffer objectLen = object->substr(4, 4);
+ unsigned long objectIDVal =
+ ((((BYTE *)objectID)[0] << 24)) +
+ ((((BYTE *)objectID)[1] << 16)) +
+ ((((BYTE *)objectID)[2] << 8)) +
+ ((((BYTE *)objectID)[3]));
+ unsigned long objectLenVal =
+ ((((BYTE *)objectLen)[0] << 24)) +
+ ((((BYTE *)objectLen)[1] << 16)) +
+ ((((BYTE *)objectLen)[2] << 8)) +
+ ((((BYTE *)objectLen)[3]));
+
+ Buffer *o = channel->ReadObject((BYTE*)objectID, 0,
+ (int)objectLenVal);
+ if (o == NULL) {
+ status = STATUS_ERROR_CREATE_TUS_TOKEN_ENTRY;
+ PR_snprintf(audit_msg, 512, "error in creating token entry");
+ goto loser;
+ }
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "object read from token");
+
+ if (((unsigned char *)objectID)[0] == 'z' &&
+ ((unsigned char *)objectID)[1] == '0') {
+ lastFormatVersion = (((BYTE*)*o)[0] << 8) +
+ (((BYTE*)*o)[1]);
+ lastObjectVersion = (((BYTE*)*o)[2] << 8) +
+ (((BYTE*)*o)[3]);
+ foundLastObjectVersion = 1;
+
+ //
+ delete pkcs11objx;
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "parsing pkcs11obj read from token");
+ pkcs11objx = PKCS11Obj::Parse(o, 0);
+ seq = 0;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "new pkcs11obj");
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(objectIDVal, o);
+ if (objSpec != NULL) {
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+ }
+
+ delete o;
+ delete object;
+ }
+ } while (seq != 0);
+
+ }
+
+ rc = RA::tdb_add_token_entry((char *)userid, cuid, "uninitialized", tokenType);
+ if (rc == -1) {
+ status = STATUS_ERROR_CREATE_TUS_TOKEN_ENTRY;
+ PR_snprintf(audit_msg, 512, "error in creating uninitialized token entry");
+ goto loser;
+ }
+
+ StatusUpdate(session, extensions, 15, "PROGRESS_PROCESS_PROFILE");
+
+ tokentype = (char *)malloc(256 * sizeof(char)) ;
+ PL_strcpy(tokentype, tokenType);
+ /* generate signing key on netkey */
+ if (!GenerateCertsAfterRecoveryPolicy(login, session, origins, ktypes, tokentype, pkcs11objx,
+ pkcs11obj_enable, extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn, final_applet_version,
+ khex, userid, status, certificates, o_certNums, tokenTypes)) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process"," - GenerateCertsAfterRecoveryPolicy returns false");
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process"," - GenerateCertsAfterRecoveryPolicy returns true");
+ if (status == STATUS_NO_ERROR) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process"," - after GenerateCertsAfterRecoveryPolicy", "status is STATUS_NO_ERROR");
+ if (!GenerateCertificates(login, session, origins, ktypes, tokentype, pkcs11objx,
+ pkcs11obj_enable, extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn, final_applet_version,
+ khex, userid, status, certificates, o_certNums, tokenTypes)) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process - after GenerateCertificates"," returns false might as well clean up token.");
+ bool skip_auth = true;
+ Format(session,extensions,skip_auth);
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process - after GenerateCertificates"," returns true");
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process - after GenerateCertsAfterRecoveryPolicy", "status is %d", status);
+ }
+ }
+
+ if ((status == STATUS_ERROR_RENEWAL_IS_PROCESSED) &&
+ RA::ra_allow_token_renew(cuid)) {
+ renewed = true;
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "renewal happened.. ");
+ }
+
+ // read objects back
+ if (pkcs11obj_enable) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "pkcs11obj enabled");
+ pkcs11objx->SetFormatVersion(lastFormatVersion);
+ if (foundLastObjectVersion) {
+ while (lastObjectVersion == 0xff) {
+ if (getRandomNumber(&lastObjectVersion) != SECSuccess) {
+ RA::Error(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Encounter 0xff, could not generate a random version number...assigning 0x00");
+ lastObjectVersion = 0x00;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Encounter 0xff, got random version numer: %ul", lastObjectVersion);
+ }
+ }
+
+ pkcs11objx->SetObjectVersion(lastObjectVersion+1);
+ } else {
+ pkcs11objx->SetObjectVersion(lastObjectVersion);
+ }
+ pkcs11objx->SetCUID(token_cuid);
+
+ /* add additional certificate objects */
+ PR_snprintf((char *)configname, 256, "%s.certificates.num",
+ OP_PREFIX);
+ int certNum = RA::GetConfigStore()->GetConfigAsInt(configname);
+ if (certNum > 0) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "about to write certificate chain");
+ }
+ for (int i = 0; i < certNum; i++) {
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "root certificate #%d", i);
+
+ PR_snprintf((char *)configname, 256, "%s.certificates.value.%d",
+ OP_PREFIX, i);
+ char *certName = (char *)RA::GetConfigStore()->GetConfigAsString(configname);
+
+ /* retrieve certificate info */
+ PR_snprintf((char *)configname, 256, "%s.certificates.%s.nickName",
+ OP_PREFIX, certName);
+ char *certNickName = (char *)RA::GetConfigStore()->GetConfigAsString(configname);
+ PR_snprintf((char *)configname, 256, "%s.certificates.%s.certId",
+ OP_PREFIX, certName);
+ char *certId = (char *)
+ RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+
+/*
+op.enroll.certificates.num=1
+op.enroll.certificates.value.0=caCert
+op.enroll.certificates.caCert.nickName=caCert0 fpki-tps
+op.enroll.certificates.caCert.certId=C5
+op.enroll.certificates.caCert.certAttrId=c5
+op.enroll.certificates.caCert.label=caCert Label
+ */
+
+ /* retrieve certificate */
+ CERTCertificate *cert = CERT_FindCertByNickname(
+ CERT_GetDefaultCertDB(), certNickName);
+
+ if (cert == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Cannot find certificate %s", certNickName);
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Found certificate %s", certNickName);
+
+ /* add certificate to z object */
+ Buffer *certBuf = new Buffer((BYTE*)cert->derCert.data,
+ (unsigned int)cert->derCert.len);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Certificate buffer created");
+ ObjectSpec *objSpec = ObjectSpec::ParseFromTokenData(
+ (certId[0] << 24) +
+ (certId[1] << 16), certBuf);
+ pkcs11objx->AddObjectSpec(objSpec);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Certificate object Added to PKCS11 Object");
+
+ /* add PK11 attributes */
+ PR_snprintf((char *)configname, 256, "%s.certificates.%s.label",
+ OP_PREFIX, certName);
+ char *certLabel = (char *)RA::GetConfigStore()->GetConfigAsString(configname);
+ PR_snprintf((char *)configname, 256, "%s.certificates.%s.certAttrId",
+ OP_PREFIX, certName);
+ char *certAttrId = (char *)
+ RA::GetConfigStore()->GetConfigAsString(configname, "c0");
+
+ Buffer *keyid = NULL;
+ if (cert->subjectKeyID.data != NULL) {
+ keyid = new Buffer((BYTE*)cert->subjectKeyID.data,
+ (unsigned int)cert->subjectKeyID.len);
+ } else {
+ SECItem *pubKeyData = PK11_GetPubIndexKeyID(cert) ;
+ SECItem *tmpitem = PK11_MakeIDFromPubKey(pubKeyData);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Got Key ID");
+
+
+ keyid = new Buffer((BYTE*)tmpitem->data,
+ (unsigned int)tmpitem->len);
+ }
+
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ KEY_TYPE_ENCRYPTION /* not being used */,
+ certAttrId, certLabel, keyid);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Created buffer for PKCS11 cert attributes");
+ objSpec = ObjectSpec::ParseFromTokenData(
+ (certAttrId[0] << 24) +
+ (certAttrId[1] << 16),
+ &b);
+ pkcs11objx->AddObjectSpec(objSpec);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Added PKCS11 certificate attribute");
+ }
+ }
+
+ // build label
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.tokenName",
+ OP_PREFIX, tokentype);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "tokenName '%s'",
+ configname);
+ pattern = RA::GetConfigStore()->GetConfigAsString(configname, "$cuid$");
+ nv.Add("cuid", cuid);
+ nv.Add("msn", msn);
+ nv.Add("userid", userid);
+ nv.Add("profileId", tokenType);
+
+ /* populate auth parameters output to nv also */
+ /* so we can reference to the auth parameter by */
+ /* using $auth.cn$, or $auth.mail$ */
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "Check login");
+ if (login != NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "Found login");
+ int s = login->Size();
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "login size=%d", s);
+ for (int x = 0; x < s; x++) {
+ char namebuf[2048];
+ char *name = login->GetNameAt(x);
+ sprintf(namebuf, "auth.%s", name);
+ if (strcmp(name,"PASSWORD") != 0) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "Exposed %s=%s", namebuf, login->GetValue(name));
+ }
+ nv.Add(namebuf, login->GetValue(name));
+ }
+ }
+ label = MapPattern(&nv, (char *) pattern);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "labelName '%s'",
+ label);
+ labelBuffer = Buffer((BYTE*)label, strlen(label));
+ pkcs11objx->SetTokenName(labelBuffer);
+
+ // write PKCS11 Obj
+ BYTE objid[4];
+
+ objid[0] = 'z';
+ objid[1] = '0';
+ objid[2] = 0;
+ objid[3] = 0;
+ Buffer xb;
+
+ PR_snprintf((char *)configname, 256, "%s.%s.pkcs11obj.compress.enable",
+ OP_PREFIX, tokentype);
+ compress = RA::GetConfigStore()->GetConfigAsBool(configname, 1);
+
+ if (compress) {
+ xb = pkcs11objx->GetCompressedData();
+ RA::Debug("RA_Enroll_Processor::Process PKCSData", "Compressed Data");
+ } else {
+ xb = pkcs11objx->GetData();
+ RA::Debug("RA_Enroll_Processor::Process PKCSData", "Uncompressed Data");
+ }
+ RA::DebugBuffer("RA_Enroll_Processor::Process PKCSData", "PKCS Data=", &xb);
+
+
+ if(xb.size() == 0) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug("RA_Enroll_Processor::Failure to get token object!"," failed");
+ PR_snprintf(audit_msg, 512, "channel createObject failed");
+ goto loser;
+ }
+
+ if((int) xb.size() > totalAvailableMemory) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug("RA_Enroll_Processor::Failure pkcs11 object may exceed applet memory"," failed");
+ PR_snprintf(audit_msg, 512, "Applet memory exceeded when writing out final token data");
+ bool skip_auth = true;
+ if(!renewed) { //Renewal should leave what they have on the token.
+ Format(session,extensions,skip_auth);
+ }
+ goto loser;
+ }
+
+ BYTE perms[6];
+
+ perms[0] = 0xff;
+ perms[1] = 0xff;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ if (channel->CreateObject(objid, perms, xb.size()) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug("RA_Enroll_Processor::channel createObject"," failed");
+ PR_snprintf(audit_msg, 512, "channel createObject failed");
+ goto loser;
+ }
+ // channel->CreateObject(objid, xb.size());
+ if (channel->WriteObject(objid, (BYTE*)xb, xb.size()) != 1) {
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug("RA_Enroll_Processor::channel writeObject"," failed");
+ PR_snprintf(audit_msg, 512, "channel writeObject failed");
+ goto loser;
+ }
+ }
+
+ StatusUpdate(session, extensions, 90, "PROGRESS_SET_LIFE_CYCLE_STATE");
+
+ // add issuer info to the token
+ PR_snprintf((char *)configname, 256, "%s.%s.issuerinfo.enable",
+ OP_PREFIX, tokenType);
+ RA::Debug("RA_Enroll_Processor", "Getting %s", configname);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ if (channel != NULL) {
+ char issuer[224];
+ for (int i = 0; i < 224; i++) {
+ issuer[i] = 0;
+ }
+ PR_snprintf((char *)configname, 256, "%s.%s.issuerinfo.value",
+ OP_PREFIX, tokenType);
+ char *issuer_val = (char*)RA::GetConfigStore()->GetConfigAsString(
+ configname);
+ RA::Debug("RA_Enroll_Processor",
+ "Before pattern substitution mapping is %s", issuer_val);
+ issuer_val = MapPattern(&nv, (char *) issuer_val);
+ RA::Debug("RA_Enroll_Processor",
+ "After pattern substitution mapping is %s", issuer_val);
+ sprintf(issuer, "%s", issuer_val);
+ RA::Debug("RA_Enroll_Processor", "Set Issuer Info %s", issuer_val);
+ Buffer *info = new Buffer((BYTE*)issuer, 224);
+ rc = channel->SetIssuerInfo(info);
+
+ if (info != NULL) {
+ delete info;
+ info = NULL;
+ }
+ }
+ }
+ /* write lifecycle bit */
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "Set Lifecycle State");
+ rc = channel->SetLifecycleState(0x0f);
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "Set life cycle state failed");
+ status = STATUS_ERROR_MAC_LIFESTYLE_PDU;
+ PR_snprintf(audit_msg, 512, "set life cycle state error");
+ goto loser;
+ }
+
+ rc = channel->Close();
+ if (rc == -1) {
+ RA::Error("RA_Enroll_Processor::Process",
+ "Failed to close channel");
+ status = STATUS_ERROR_CONNECTION;
+ PR_snprintf(audit_msg, 512, "channel not closed");
+ goto loser;
+ }
+
+ StatusUpdate(session, extensions, 100, "PROGRESS_DONE");
+
+ status = STATUS_NO_ERROR;
+
+ sprintf(activity_msg, "applet_version=%s tokenType=%s userid=%s",
+ final_applet_version, tokentype, userid);
+
+ if (renewed) {
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "renewal", "success", activity_msg, userid, tokenType);
+ } else {
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "success", activity_msg, userid, tokenType);
+ }
+ RA::tdb_update((char *)userid, cuid, (char *)final_applet_version, (char *)keyVersion, "active", "", tokenType);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after tdb_update()");
+
+ RA::tdb_update_certificates(cuid, tokenTypes, (char*)userid, certificates, ktypes, origins, o_certNums);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after tdb_update_certificates()");
+
+ rc = 1;
+
+ end = PR_IntervalNow();
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after end");
+
+ /* audit log for successful enrollment */
+ if (renewed) {
+ if (authid != NULL) {
+ PR_snprintf(activity_msg, 4096, "renewal processing completed, authid = %s", authid);
+ } else {
+ PR_snprintf(activity_msg, 4096, "renewal processing completed");
+ }
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC,
+ userid, cuid, msn, "success", "renewal", final_applet_version, keyVersion, activity_msg);
+ } else {
+ if (authid != NULL) {
+ PR_snprintf(activity_msg, 4096, "enrollment processing completed, authid = %s", authid);
+ } else {
+ PR_snprintf(activity_msg, 4096, "enrollment processing completed");
+ }
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid, cuid, msn, "success", "enrollment", final_applet_version, keyVersion, activity_msg);
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after audit, o_certNums=%d",o_certNums);
+
+loser:
+
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ if (renewed) {
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "renewal",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ cuid,
+ "renewal",
+ "failure",
+ audit_msg,
+ userid != NULL? userid : "",
+ tokenType);
+ }
+ } else {
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL ? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ cuid,
+ "enrollment",
+ "failure",
+ audit_msg,
+ userid != NULL? userid : "",
+ tokenType);
+ }
+ }
+ }
+
+ if (tokenTypes != NULL) {
+ for (int nn=0; nn<o_certNums; nn++) {
+ if (tokenTypes[nn] != NULL)
+ PL_strfree(tokenTypes[nn]);
+ tokenTypes[nn] = NULL;
+ }
+ free(tokenTypes);
+ tokenTypes = NULL;
+ }
+ if (certificates != NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "before CERT_DestroyCertificate. certNums=%d", o_certNums);
+ for (int i=0;i < o_certNums; i++) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "CERT_DestroyCertificate: i=%d", i);
+ if (certificates[i] != NULL) {
+ CERT_DestroyCertificate(certificates[i]);
+ }
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "CERT_DestroyCertificate: i=%i done", i);
+ }
+ free(certificates);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "after CERT_DestroyCertificate");
+ }
+
+ if( certEnroll != NULL ) {
+ delete certEnroll;
+ certEnroll = NULL;
+ }
+
+ if (ktypes != NULL) {
+ for (int nn=0; nn < o_certNums; nn++) {
+ if (ktypes[nn] != NULL)
+ PL_strfree(ktypes[nn]);
+ ktypes[nn] = NULL;
+ }
+ free(ktypes);
+ ktypes = NULL;
+ }
+
+ if (origins != NULL) {
+ for (int nn=0; nn < o_certNums; nn++) {
+ if (origins[nn] != NULL)
+ PL_strfree(origins[nn]);
+ origins[nn] = NULL;
+ }
+ free(origins);
+ origins = NULL;
+ }
+
+ if( CardManagerAID != NULL ) {
+ delete CardManagerAID;
+ CardManagerAID = NULL;
+ }
+
+ if( NetKeyAID != NULL ) {
+ delete NetKeyAID;
+ NetKeyAID = NULL;
+ }
+
+ if( login != NULL ) {
+ delete login;
+ login = NULL;
+ }
+
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+
+ if( new_pin != NULL ) {
+ PL_strfree( new_pin );
+ new_pin = NULL;
+ }
+
+ if( key_check != NULL ) {
+ delete key_check;
+ key_check = NULL;
+ }
+
+ if( wrapped_challenge != NULL ) {
+ delete wrapped_challenge;
+ wrapped_challenge = NULL;
+ }
+
+ if( plaintext_challenge != NULL ) {
+ delete plaintext_challenge;
+ plaintext_challenge = NULL;
+ }
+
+ if( token_status != NULL ) {
+ delete token_status;
+ token_status = NULL;
+ }
+
+ if( final_applet_version != NULL ) {
+ PR_Free( (char *) final_applet_version );
+ final_applet_version = NULL;
+ }
+
+ if( appletVersion != NULL ) {
+ PR_Free( (char *) appletVersion );
+ appletVersion = NULL;
+ }
+ if( khex != NULL ) {
+ PR_Free( khex );
+ khex = NULL;
+ }
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ if (token_state != NULL) {
+ PR_Free((char *)token_state);
+ token_state = NULL;
+ }
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( msn != NULL ) {
+ PR_Free( msn );
+ msn = NULL;
+ }
+ if( label != NULL ) {
+ PL_strfree( (char *) label );
+ label = NULL;
+ }
+ if (tokentype != NULL) {
+ PR_Free(tokentype);
+ }
+ if (pkcs11objx != NULL) {
+ delete pkcs11objx;
+ }
+
+#ifdef MEM_PROFILING
+ MEM_dump_unfree();
+#endif
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process", "returning status");
+ return status;
+}
+
+
+bool RA_Enroll_Processor::GenerateCertificates(AuthParams *login, RA_Session *session, char **&origins, char **&ktypes,
+ char *tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ NameValueSet *extensions, Secure_Channel *channel, Buffer *wrapped_challenge,
+ Buffer *key_check, Buffer *plaintext_challenge, char *cuid, char *msn,
+ const char *final_applet_version, char *khex, const char *userid, RA_Status &o_status,
+ CERTCertificate **&certificates, int &o_certNums, char **&tokenTypes) {
+
+ bool noFailedCerts = true;
+ bool r=true;
+ int keyTypeNum = 0;
+ int i = 0;
+ char configname[256];
+ const char *FN = "RA_Enroll_Processor::GenerateCertificates";
+ RA_Status lastErrorStatus = STATUS_NO_ERROR;
+
+
+ RA::Debug(LL_PER_CONNECTION,FN, "tokenType=%s", tokenType);
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.keyType.num", OP_PREFIX, tokenType);
+ keyTypeNum = RA::GetConfigStore()->GetConfigAsInt(configname);
+ if (keyTypeNum == 0) {
+ r = false;
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Profile parameters are not found");
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ ktypes = (char **) malloc (sizeof(char *) * keyTypeNum);
+ origins = (char **) malloc (sizeof(char *) * keyTypeNum);
+ tokenTypes = (char **) malloc (sizeof(char *) * keyTypeNum);
+
+ certificates = (CERTCertificate **) malloc (sizeof(CERTCertificate *) * keyTypeNum);
+ o_certNums = keyTypeNum;
+ for (i=0; i<keyTypeNum; i++) {
+ certificates[i] = NULL;
+ ktypes[i] = NULL;
+ origins[i] = NULL;
+ tokenTypes[i] = NULL;
+
+ }
+ for (i=0; i<keyTypeNum; i++) {
+
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.keyType.value.%d", OP_PREFIX, tokenType, i);
+ const char *keyTypeValue = RA::GetConfigStore()->GetConfigAsString(configname, "signing");
+
+ r = GenerateCertificate(login,keyTypeNum, keyTypeValue, i, session, origins, ktypes, tokenType,
+ pkcs11objx, pkcs11obj_enable, extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn, final_applet_version,
+ khex, userid, o_status, certificates);
+
+ RA::Debug("GenerateCertificates","configname %s result %d",configname,r);
+
+ tokenTypes[i] = PL_strdup(tokenType);
+ if(r == false) {
+ noFailedCerts = false;
+ lastErrorStatus = o_status;
+ break;
+ }
+
+ }
+
+ if (noFailedCerts == true) {
+ //In this special case of re-enroll
+ //Revoke current certs for this token
+ // before the just enrolled certs are written to the db
+ char error_msg[512];
+ bool success = RevokeCertificates(session, cuid,error_msg,(char *)final_applet_version,
+ NULL,(char *)tokenType,(char *)userid,o_status
+ );
+
+ RA::Debug("GenerateCertificates","Revoke result %d ",(int) success);
+
+ if (!success) {
+ //Don't blow the whole thing up for this.
+ RA::Debug("GenerateCertificates","Revocation failure %s ",error_msg);
+ }
+
+ }
+ loser:
+ if(lastErrorStatus != STATUS_NO_ERROR) {
+ o_status = lastErrorStatus;
+ }
+ return noFailedCerts;
+}
+
+bool RA_Enroll_Processor::GenerateCertificate(AuthParams *login, int keyTypeNum, const char *keyTypeValue, int i, RA_Session *session,
+ char **origins, char **ktypes, char *tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ NameValueSet *extensions, Secure_Channel *channel, Buffer *wrapped_challenge,
+ Buffer *key_check, Buffer *plaintext_challenge, char *cuid, char *msn,
+ const char *final_applet_version, char *khex, const char *userid,
+ RA_Status &o_status, CERTCertificate **certificates)
+{
+ bool r = true;
+ char configname[256];
+ char keyTypePrefix[200];
+ const char *FN="RA_Enroll_Processor::GenerateCertificate";
+
+ PR_snprintf((char *)keyTypePrefix, 256, "%s.%s.keyGen.%s", OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::GenerateCertificate","keyTypePrefix is %s",keyTypePrefix);
+ PR_snprintf((char *)configname, 256, "%s.ca.profileId", keyTypePrefix);
+ const char *profileId = RA::GetConfigStore()->GetConfigAsString(configname, "");
+ PR_snprintf((char *)configname, 256,"%s.certId", keyTypePrefix);
+ const char *certId = RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+ PR_snprintf((char *)configname, 256, "%s.certAttrId", keyTypePrefix);
+ const char *certAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "c0");
+ PR_snprintf((char *)configname, 256, "%s.privateKeyAttrId", keyTypePrefix);
+ const char *priKeyAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "k0");
+ PR_snprintf((char *)configname, 256,"%s.publicKeyAttrId", keyTypePrefix);
+ const char *pubKeyAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "k1");
+ PR_snprintf((char *)configname, 256, "%s.keySize", keyTypePrefix);
+ int keySize = RA::GetConfigStore()->GetConfigAsInt(configname, 1024);
+
+ PR_snprintf((char *)configname, 256, "%s.publisherId", keyTypePrefix);
+ const char *publisherId = RA::GetConfigStore()->GetConfigAsString(configname, NULL);
+
+ PR_snprintf((char *)configname, 256, "%s.keyUsage", keyTypePrefix);
+ int keyUsage = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.keyUser", keyTypePrefix);
+ int keyUser = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.privateKeyNumber", keyTypePrefix);
+ int priKeyNumber = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.publicKeyNumber", keyTypePrefix);
+ int pubKeyNumber = RA::GetConfigStore()->GetConfigAsInt(configname, 1);
+
+
+ // get key capabilites to determine if the key type is SIGNING,
+ // ENCRYPTION, or SIGNING_AND_ENCRYPTION
+ PR_snprintf((char *)configname, 256, "%s.private.keyCapabilities.sign", keyTypePrefix);
+ bool isSigning = RA::GetConfigStore()->GetConfigAsBool(configname);
+ PR_snprintf((char *)configname, 256, "%s.public.keyCapabilities.encrypt", keyTypePrefix);
+ bool isEncrypt = RA::GetConfigStore()->GetConfigAsBool(configname);
+ int keyTypeEnum = 0;
+
+ if ((isSigning) &&
+ (isEncrypt)) {
+ keyTypeEnum = KEY_TYPE_SIGNING_AND_ENCRYPTION;
+ } else if (isSigning) {
+ keyTypeEnum = KEY_TYPE_SIGNING;
+ } else if (isEncrypt) {
+ keyTypeEnum = KEY_TYPE_ENCRYPTION;
+ }
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "key type is %d",keyTypeEnum);
+
+ PR_snprintf((char *)configname, 256, "%s.ca.conn", keyTypePrefix);
+ const char *caconnid = RA::GetConfigStore()->GetConfigAsString(configname);
+ certificates[i] = NULL;
+ ktypes[i] = NULL;
+ origins[i] = NULL;
+
+ o_status = DoEnrollment(login, session, certificates, origins, ktypes, pkcs11obj_enable,
+ pkcs11objx, extensions, i, keyTypeNum,
+ 15 /* start progress */,
+ 90 /* end progress */, channel, wrapped_challenge,
+ tokenType,
+ keyTypeValue,
+ key_check,
+ plaintext_challenge,
+ cuid,
+ msn,
+ khex, (TokenKeyType)keyTypeEnum, profileId, userid, certId,publisherId, certAttrId, priKeyAttrId,
+ pubKeyAttrId, (keyUser << 4)+priKeyNumber,
+ (keyUsage << 4)+pubKeyNumber, keySize, caconnid, keyTypePrefix,(char *)final_applet_version);
+
+ if (o_status != STATUS_NO_ERROR) {
+ r = false;
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Got a status error from DoEnrollment: %d", o_status);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "enrollment error", "", tokenType);
+ goto loser;
+ }
+
+ loser:
+
+ return r;
+}
+
+bool RA_Enroll_Processor::GenerateCertsAfterRecoveryPolicy(AuthParams *login, RA_Session *session, char **&origins, char **&ktypes,
+ char *&tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ NameValueSet *extensions, Secure_Channel *channel, Buffer *wrapped_challenge,
+ Buffer *key_check, Buffer *plaintext_challenge, char *cuid, char *msn,
+ const char *final_applet_version, char *khex, const char *userid, RA_Status &o_status,
+ CERTCertificate **&certificates, int &o_certNums, char **&tokenTypes)
+{
+ LDAPMessage *ldapResult = NULL;
+ LDAPMessage *e = NULL;
+ int nEntries = 0;
+ char filter[512];
+ char configname[512];
+ char tokenStatus[100];
+ char *tokenid = NULL;
+ int rc = -1;
+ bool r=true;
+ o_status = STATUS_NO_ERROR;
+ char *origTokenType = NULL;
+
+ const char *FN="RA_Enroll_Process::GenerateCertsAfterRecoveryPolicy";
+ PR_snprintf(filter, 512, "tokenUserID=%s", userid);
+
+ rc = RA::ra_find_tus_token_entries_no_vlv(filter, &ldapResult, 1);
+
+ if (rc != LDAP_SUCCESS) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Cant find any tokens associated with the userid=%s. "
+ "There should be at least one token.", userid);
+ r = false;
+ o_status = STATUS_ERROR_INACTIVE_TOKEN_NOT_FOUND;
+ goto loser;
+ } else {
+ nEntries = RA::ra_get_number_of_entries(ldapResult);
+ for (e = RA::ra_get_first_entry(ldapResult); e != NULL; e = RA::ra_get_next_entry(e)) {
+ struct berval ** attr_values = RA::ra_get_attribute_values(e, "tokenStatus");
+
+ if ((attr_values == NULL) || (attr_values[0] == NULL)) {
+ RA::Debug(LL_PER_CONNECTION,FN, "Error obtaining token status");
+ r = false;
+ o_status = STATUS_ERROR_BAD_STATUS;
+ if (attr_values != NULL) {
+ RA::ra_free_values(attr_values);
+ attr_values = NULL;
+ }
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_CONNECTION,FN, "tokenStatus = %s",
+ attr_values[0]->bv_val);
+
+ strncpy(tokenStatus, attr_values[0]->bv_val, 100);
+ // free attr_values
+ if (attr_values != NULL) {
+ RA::ra_free_values(attr_values);
+ attr_values = NULL;
+ }
+ tokenid = RA::ra_get_token_id(e);
+ RA::Debug(LL_PER_CONNECTION,FN, "tokenID = %s", tokenid);
+ int cmp_result = PL_strcasecmp(tokenid, cuid);
+ free(tokenid);
+ if (cmp_result == 0) {
+ if (PL_strcasecmp(tokenStatus, "uninitialized") == 0 ) {
+ if (nEntries == 1) {
+ // need to do enrollment outside
+ break;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "There are multiple token entries for user %s.", userid);
+
+ if (RA::ra_tus_has_active_tokens((char *)userid) == 0) {
+ r = false;
+ o_status = STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN;
+ RA::Debug(LL_PER_CONNECTION,FN, "User already has one active token.");
+ goto loser;
+ } else {
+ // 1) current token is in active state
+ // 2) there are no other active tokens for this user
+ // 3) that means the previous one is the lost one
+ // get the most recent previous token:
+ LDAPMessage *prev = RA::ra_get_next_entry(e);
+ char *reason = RA::ra_get_token_reason(prev);
+ char *lostTokenCUID = RA::ra_get_token_id(prev);
+
+ // if the previous one is lost, then check lost reason
+ origTokenType = PL_strdup(tokenType);
+ if (PL_strcasecmp(reason, "keyCompromise") == 0) {
+ r = ProcessRecovery(login, reason, session, origins, ktypes,
+ tokenType, pkcs11objx, pkcs11obj_enable,
+ extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn,
+ final_applet_version, khex, userid,
+ o_status, certificates, lostTokenCUID, o_certNums, tokenTypes, origTokenType);
+
+ break;
+ } else if (PL_strcasecmp(reason, "onHold") == 0) {
+ // then the inactive one becomes the temp token
+ // No recovery scheme, basically we are going to
+ // do the brand new enrollment
+ PR_snprintf(configname, 512, "op.enroll.%s.temporaryToken.tokenType", tokenType);
+ char *tempTokenType = (char *)(RA::GetConfigStore()->GetConfigAsString(configname, "userKeyTemporary"));
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Token type for temporary token: %s", tempTokenType);
+ PL_strcpy(tokenType, tempTokenType);
+ r = ProcessRecovery(login, reason, session, origins, ktypes,
+ tokenType, pkcs11objx, pkcs11obj_enable,
+ extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn,
+ final_applet_version, khex, userid,
+ o_status, certificates, lostTokenCUID, o_certNums, tokenTypes, origTokenType);
+
+ break;
+ } else if (PL_strcasecmp(reason, "destroyed") == 0) {
+ r = ProcessRecovery(login, reason, session, origins, ktypes,
+ tokenType, pkcs11objx, pkcs11obj_enable,
+ extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn,
+ final_applet_version, khex, userid,
+ o_status, certificates, lostTokenCUID, o_certNums, tokenTypes, origTokenType);
+
+ break;
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_NO_SUCH_LOST_REASON;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "No such lost reason=%s for this cuid=%s",
+ reason, cuid);
+ goto loser;
+ }
+ }
+ }
+ } else if (strcmp(tokenStatus, "active") == 0) {
+ r = true;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "This is the active token. You can re-enroll if the re-enroll=true; or renew if renew=true.");
+ if (RA::ra_allow_token_renew(cuid)) {
+ // renewal allowed instead of re-enroll
+ r = ProcessRenewal(login, session, ktypes, origins,
+ tokenType, pkcs11objx, pkcs11obj_enable,
+ channel,
+ cuid, msn,
+ final_applet_version, userid,
+ o_status, certificates, o_certNums,
+ tokenTypes);
+ if (r == true) {
+ RA::Debug(LL_PER_CONNECTION,FN, "ProcessRenewal returns true");
+ } else
+ goto loser;
+ }
+ break;
+ } else if (strcmp(tokenStatus, "terminated") == 0) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "terminated token cuid=%s", cuid);
+ r = false;
+ o_status = STATUS_ERROR_CONTACT_ADMIN;
+ goto loser;
+ } else if (strcmp(tokenStatus, "lost") == 0) {
+ char *reason = RA::ra_get_token_reason(e);
+ if (strcmp(reason, "keyCompromise") == 0) {
+ r = false;
+ o_status = STATUS_ERROR_UNUSABLE_TOKEN_KEYCOMPROMISE;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "This token cannot be reused because it has been reported lost");
+ goto loser;
+ } else if (strcmp(reason, "onHold") == 0) {
+ if (RA::ra_tus_has_active_tokens((char *)userid) == 0) {
+ r = false;
+ o_status = STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "User already has an active token.");
+ goto loser;
+ } else { // change it back to active token
+ r = false;
+ o_status = STATUS_ERROR_CONTACT_ADMIN;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "User needs to contact administrator to report lost token (it should be put on Hold).");
+ break;
+ }
+ } else if (strcmp(reason, "destroyed") == 0) {
+ r = false;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "This destroyed lost case should not be executed because the token is so damaged. It should not get here");
+ o_status = STATUS_ERROR_TOKEN_DISABLED;
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "No such lost reason=%s for this cuid=%s", reason, cuid);
+ r = false;
+ o_status = STATUS_ERROR_NO_SUCH_LOST_REASON;
+ goto loser;
+ }
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "No such token status for this cuid=%s", cuid);
+ r = false;
+ o_status = STATUS_ERROR_NO_SUCH_TOKEN_STATE;
+ goto loser;
+ }
+ } else { // cuid != cuid of the current token
+ continue;
+/*
+ if (RA::ra_tus_has_active_tokens((char *)userid) == 0) {
+ r = false;
+ o_status = STATUS_ERROR_HAS_AT_LEAST_ONE_ACTIVE_TOKEN;
+ RA::Debug("RA_Enroll_Processor::GenerateCertsAfterRecoveryPolicy", "You already have one active token.");
+ goto loser;
+ } else
+ continue;
+*/
+ }
+ }
+ }
+
+ loser:
+ if (origTokenType != NULL) {
+ PL_strfree(origTokenType);
+ origTokenType = NULL;
+ }
+ if (rc == 0)
+ if (ldapResult != NULL)
+ ldap_msgfree(ldapResult);
+
+
+RA::Debug("RA_Enroll_Processor::GenerateCertsAfterRecoveryPolicy", "returning boolean = %d", r);
+ return r;
+}
+
+/*
+ * cfu - check if a cert is within the renewal grace period
+ * utilize passed in grace period values.
+ */
+bool RA_Enroll_Processor::isCertRenewable(CERTCertificate *cert, int graceBefore, int graceAfter){
+ PRTime timeBefore, timeAfter, now;
+
+ //Grace period input in days
+ RA::Debug("RA_Enroll_Processor::isCertRenewable","graceBefore %d graceAfter %d",graceBefore,graceAfter);
+ PRTime graceBefore64, graceAfter64,microSecondsPerSecond;
+ PRInt64 graceBeforeSeconds,graceAfterSeconds;
+
+ LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC);
+
+ //Get number of microseconds in each grace period value.
+ LL_I2L(graceBeforeSeconds, graceBefore * 60 * 60 * 24);
+ LL_I2L(graceAfterSeconds,graceAfter * 60 * 60 * 24);
+
+ LL_MUL(graceBefore64, microSecondsPerSecond,graceBeforeSeconds);
+ LL_MUL(graceAfter64, microSecondsPerSecond,graceAfterSeconds);
+
+ PRTime lowerBound, upperBound;
+
+ DER_DecodeTimeChoice(&timeBefore, &cert->validity.notBefore);
+ DER_DecodeTimeChoice(&timeAfter, &cert->validity.notAfter);
+
+ PrintPRTime(timeBefore,"timeBefore");
+ PrintPRTime(timeAfter,"timeAfter");
+
+ now = PR_Now();
+
+ //Calculate lower and upper legal bounds for time
+ LL_SUB(lowerBound,timeAfter, graceBefore64);
+ LL_ADD(upperBound,timeAfter,graceAfter64);
+
+ PrintPRTime(lowerBound,"lowerBound");
+ PrintPRTime(now,"now");
+ PrintPRTime(upperBound,"upperBound");
+
+ if(LL_CMP(now,>=, lowerBound) && LL_CMP(now,<=,upperBound)) {
+ RA::Debug("RA_Enroll_Processor::isCertRenewable","returning true!");
+ return true;
+ }
+
+ RA::Debug("RA_Enroll_Processor::isCertRenewable","returning false!");
+
+ return false;
+}
+
+/*
+ * cfu
+ * DoRenewal - use i_cert's serial number for renewal
+ * i_cert - cert to renew
+ * o_cert - cert newly issued
+ */
+bool RA_Enroll_Processor::DoRenewal(const char *connid, const char *profileId, CERTCertificate *i_cert,
+CERTCertificate **o_cert, char *error_msg, int *error_code)
+{
+ RA_Status status = STATUS_NO_ERROR;
+ bool r = true;
+ CertEnroll *certRenewal = NULL;
+ Buffer *cert = NULL;
+ char *cert_string = NULL;
+
+ error_msg[0] =0;
+ *error_code=0; //assume undefined
+
+ PRUint64 snum = DER_GetInteger(&(i_cert)->serialNumber);
+ RA::Debug("RA_Enroll_Processor::DoRenewal", "begins renewal for serial number %u with profileId=%s", (int)snum, profileId);
+
+ certRenewal = new CertEnroll();
+ cert = certRenewal->RenewCertificate(snum, connid, profileId, error_msg);
+
+ if (error_msg[0] != 0) { // We can assume a non grace period error here.
+ *error_code = 1;
+ }
+// this is where renewal happens .. audit log for fail/ success here?
+ if (cert == NULL) {
+ r = false;
+ RA::Debug("RA_Enroll_Processor::DoRenewal", "Renewal failed for serial number %d", snum);
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ goto loser;
+ }
+ RA::Debug("RA_Enroll_Processor::DoRenewal", "Renewal suceeded for serial number %d", snum);
+
+ cert_string = (char *) cert->string();
+ *o_cert = CERT_DecodeCertFromPackage((char *) cert_string,
+ (int) cert->size());
+ if (o_cert != NULL) {
+ char msg[2048];
+ RA::ra_tus_print_integer(msg, &(o_cert[0])->serialNumber);
+ RA::Debug("DoRenewal", "Received newly issued Certificate");
+ RA::Debug("DoRenewal serial=", msg);
+ RA::Debug("DoRenewal", "yes");
+ } else {
+ r = false;
+ }
+ free(cert_string);
+
+loser:
+ if( certRenewal != NULL ) {
+ delete certRenewal;
+ certRenewal = NULL;
+ }
+ if( cert != NULL ) {
+ delete cert;
+ cert = NULL;
+ }
+ return r;
+}
+
+#define RENEWAL_FAILURE 1
+#define RENEWAL_FAILURE_GRACE 2
+
+/*
+* Renewal logic
+* 1. Create Optional local TPS grace period per token profile,
+* per token type, such as signing or encryption.
+* This grace period must match how the CA is configured. Ex:
+* op.enroll.userKey.renewal.encryption.enable=true
+* op.enroll.userKey.renewal.encryption.gracePeriod.enable=true
+* op.enroll.userKey.renewal.encryption.gracePeriod.before=30
+* op.enroll.userKey.renewal.encryption.gracePeriod.after=30
+* 2. In case of a grace period failure the code will go on
+* and attempt to renew the next certificate in the list.
+* 3. In case of any other code failure, the code will abort
+* and leave the token untouched, while informing the user
+* with an error message.
+*
+*
+*/
+bool RA_Enroll_Processor::ProcessRenewal(AuthParams *login, RA_Session *session, char **&ktypes,
+ char **&origins,
+ char *tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ Secure_Channel *channel,
+ const char *cuid, char *msn,
+ const char *final_applet_version, const char *userid,
+ RA_Status &o_status, CERTCertificate **&certificates,
+ int &o_certNums, char **&tokenTypes)
+{
+ bool r = true;
+ o_status = STATUS_ERROR_RENEWAL_IS_PROCESSED;
+ char keyTypePrefix[256];
+ char configname[256];
+ char filter[256];
+ LDAPMessage *result = NULL;
+ const char *pretty_cuid = NULL;
+ char audit_msg[512] = "";
+ char *keyVersion = NULL;
+ int renewal_failure_found = 0;
+
+ int maxCertUpdate = 25;
+ char *renewedCertUpdateList[25];
+ int renewedCertUpdateCount = 0;
+ int renew_error = 0;
+
+ int i = 0;
+ const char *FN="RA_Enroll_Processor::ProcessRenewal";
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "starts");
+
+ // get key version for audit logs
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ // e.g. op.enroll.userKey.renewal.keyType.num
+ // renewal params will just have to match that of the previous
+ // enrollment tps profile. Will try to be smarter later...
+ PR_snprintf(configname, 256, "op.enroll.%s.renewal.keyType.num",
+ tokenType);
+ int keyTypeNum = RA::GetConfigStore()->GetConfigAsInt(configname, -1);
+ if (keyTypeNum == -1) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Missing the configuration parameter for %s", configname);
+ goto loser;
+ }
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "keyType.num=%d", keyTypeNum);
+
+ o_certNums = keyTypeNum;
+ certificates = (CERTCertificate **) malloc (sizeof(CERTCertificate *) * keyTypeNum);
+ ktypes = (char **) malloc (sizeof(char *) * keyTypeNum);
+ origins = (char **) malloc (sizeof(char *) * keyTypeNum);
+ tokenTypes = (char **) malloc (sizeof(char *) * keyTypeNum);
+
+ for (i=0; i<keyTypeNum; i++) {
+ certificates[i] = NULL;
+ ktypes[i] = NULL;
+ origins[i] = NULL;
+ tokenTypes[i] = NULL;
+ }
+
+ for (i=0; i<keyTypeNum; i++) {
+ bool renewable = true;
+ // e.g. op.enroll.userKey.renewal.keyType.value.0=signing
+ // e.g. op.enroll.userKey.renewal.keyType.value.1=encryption
+ PR_snprintf(configname, 256, "op.enroll.%s.renewal.keyType.value.%d", tokenType, i);
+ const char *keyTypeValue = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+
+ if (keyTypeValue == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Missing the configuration parameter for %s", configname);
+ goto loser;
+ }
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "keyType == %s ", keyTypeValue);
+ TokenKeyType key_type = KEY_TYPE_ENCRYPTION;
+ if (strcmp(keyTypeValue, "signing") == 0)
+ key_type = KEY_TYPE_SIGNING;
+ else if (strcmp(keyTypeValue, "encryption") == 0)
+ key_type = KEY_TYPE_ENCRYPTION;
+ else
+ key_type = KEY_TYPE_SIGNING_AND_ENCRYPTION;
+
+ // e.g. op.enroll.userKey.renewal.signing.enable=true
+ PR_snprintf(configname, 256, "op.enroll.%s.renewal.%s.enable", tokenType, keyTypeValue);
+ renewable = RA::GetConfigStore()->GetConfigAsBool(configname);
+
+ if (!renewable) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "renewal not enabled");
+ continue;
+ }
+
+ // set allowable $$ config patterns
+ NameValueSet nv;
+ pretty_cuid = GetPrettyPrintCUID(cuid);
+
+ nv.Add("pretty_cuid", pretty_cuid);
+ nv.Add("cuid", cuid);
+ nv.Add("msn", msn);
+ nv.Add("userid", userid);
+ //nv.Add("profileId", profileId);
+
+ /* populate auth parameters output to nv also */
+ /* so we can reference to the auth parameter by */
+ /* using $auth.cn$, or $auth.mail$ */
+ if (login != NULL) {
+ int s = login->Size();
+ for (int x = 0; x < s; x++) {
+ char namebuf[2048];
+ char *name = login->GetNameAt(x);
+ sprintf(namebuf, "auth.%s", name);
+ nv.Add(namebuf, login->GetValue(name));
+ }
+ }
+
+ /*
+ * Get certs from the tokendb for this token to find out about
+ * renewal possibility
+ */
+
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "Renew the certs for %s", keyTypeValue);
+ PR_snprintf(filter, 256, "(&(tokenKeyType=%s)(tokenID=%s))",
+ keyTypeValue, cuid);
+ int rc = RA::ra_find_tus_certificate_entries_by_order_no_vlv(filter,
+ &result, 1);
+
+ tokenTypes[i] = PL_strdup(tokenType);
+ if (rc == LDAP_SUCCESS) {
+ bool renewed = false;
+ const char *caconnid;
+ const char *profileId;
+ PR_snprintf(keyTypePrefix, 256, "op.enroll.%s.keyGen.%s", tokenType,keyTypeValue);
+ PR_snprintf(configname, 256, "op.enroll.%s.renewal.%s.enable", tokenType, keyTypeValue);
+ PR_snprintf((char *)configname, 256,"op.enroll.%s.renewal.%s.certId", tokenType, keyTypeValue);
+ char *certId = (char *)RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+ PR_snprintf((char *)configname, 256, "op.enroll.%s.renewal.%s.certAttrId", tokenType, keyTypeValue);
+ char *certAttrId = (char *)RA::GetConfigStore()->GetConfigAsString(configname, "c0");
+ //PR_snprintf((char *)configname, 256, "%s.privateKeyAttrId", keyTypePrefix);
+ //const char *priKeyAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "k0");
+ //PR_snprintf((char *)configname, 256,"%s.publicKeyAttrId", keyTypePrefix);
+ //const char *pubKeyAttrId = RA::GetConfigStore()->GetConfigAsString(configname, "k1");
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "certId=%s, certAttrId=%s",certId, certAttrId);
+
+ char finalCertId[3];
+ char finalCertAttrId[3];
+
+ finalCertId[0] = certId[0];
+ finalCertId[1] = certId[1];
+ finalCertId[2] = 0;
+
+ finalCertAttrId[0] = certAttrId[0];
+ finalCertAttrId[1] = certAttrId[1];
+ finalCertAttrId[2] = 0;
+
+ LDAPMessage *e= NULL;
+ char *attr_status = NULL;
+ for( e = RA::ra_get_first_entry( result );
+ e != NULL;
+ e = RA::ra_get_next_entry( e ) ) {
+ attr_status = RA::ra_get_cert_status( e );
+ if( (strcmp( attr_status, "revoked" ) == 0) ||
+ (strcmp( attr_status, "renewed" ) == 0) ) {
+ if (attr_status != NULL) {
+ PL_strfree(attr_status);
+ attr_status = NULL;
+ }
+ continue;
+ }
+
+ const char *label= NULL;
+ const char *pattern= NULL;
+ Buffer *certbuf = NULL;
+
+ // retrieve the most recent certificate to start
+
+ CERTCertificate **certs = RA::ra_get_certificates(e);
+ CERTCertificate *o_cert = NULL;
+ SECKEYPublicKey *pk_p = NULL;
+ SECItem si_mod;
+ Buffer *modulus=NULL;
+ SECItem *si_kid = NULL;
+ Buffer *keyid=NULL;
+ SECItem si_exp;
+ Buffer *exponent=NULL;
+ CERTSubjectPublicKeyInfo* spkix = NULL;
+
+ bool graceEnabled = false;
+ int graceBefore = 0;
+ int graceAfter = 0;
+
+ if (certs[0] != NULL) {
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Certificate to check for renew");
+
+ // check if renewable (note: CA makes the final decision)
+ /* testing...pass through for now
+ if (!isCertRenewable(certs[0])) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Cert outside of renewal period");
+ r = false;
+ goto rloser;
+ }
+ */
+
+ // op.enroll.userKey.renewal.signing.ca.conn
+ // op.enroll.userKey.renewal.encryption.ca.conn
+ PR_snprintf(configname, 256,
+ "op.enroll.%s.renewal.%s.ca.conn", tokenType, keyTypeValue);
+ caconnid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (caconnid == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Missing the configuration parameter for %s", configname);
+ goto rloser;
+ }
+
+ // op.enroll.userKey.renewal.signing.ca.profileId
+ // op.enroll.userKey.renewal.encryption.ca.profileId
+ PR_snprintf(configname, 256,
+ "op.enroll.%s.renewal.%s.ca.profileId", tokenType, keyTypeValue);
+ profileId = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (profileId == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Missing the configuration parameter for %s", configname);
+ goto rloser;
+ }
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal","got profileId=%s",profileId);
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "begin renewal");
+
+
+ PR_snprintf(configname,256,
+ "op.enroll.%s.renewal.%s.gracePeriod.enable",tokenType,keyTypeValue);
+
+ graceEnabled = RA::GetConfigStore()->GetConfigAsBool(configname,0);
+
+ if(graceEnabled) {
+
+ PR_snprintf(configname,256,
+ "op.enroll.%s.renewal.%s.gracePeriod.before",tokenType,keyTypeValue);
+
+ graceBefore = RA::GetConfigStore()->GetConfigAsInt(configname,0);
+
+ PR_snprintf(configname,256,
+ "op.enroll.%s.renewal.%s.gracePeriod.after",tokenType,keyTypeValue);
+
+ graceAfter = RA::GetConfigStore()->GetConfigAsInt(configname,0);
+ // check if renewable (note: CA makes the final decision)
+ if (!isCertRenewable(certs[0],graceBefore,graceAfter)) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Cert outside of renewal period");
+ renewal_failure_found = RENEWAL_FAILURE_GRACE;
+ //Since this is merely a grace period failure for one cert
+ //let's keep going.
+ r = true;
+ goto rloser;
+ }
+
+ }
+
+ // send renewal request to CA
+ // o_cert is the cert gotten back
+ r = DoRenewal(caconnid, profileId, certs[0], &o_cert, audit_msg, &renew_error);
+ if (r == false) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "after DoRenewal failure. o_cert %p renew_error %d",o_cert,renew_error);
+ o_status = STATUS_ERROR_MAC_ENROLL_PDU;
+ //Assume a renewal grace failure here since we can't obtain the reason.
+ //This is the most likely error and there is a chance the next renewal may succeed.
+ if ( renew_error == 0) { //Assume undefined error is error coming from CA
+ renewal_failure_found = RENEWAL_FAILURE_GRACE;
+ } else {
+ renewal_failure_found = RENEWAL_FAILURE;
+ }
+ char snum[2048];
+ RA::ra_tus_print_integer(snum, &(certs[0])->serialNumber);
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC_CERT_REQ,
+ userid, cuid, msn, "failure", "renewal", final_applet_version,
+ keyVersion != NULL ? keyVersion : "",
+ snum, caconnid, audit_msg);
+ //Since this is merely a grace period or renewal failure for one cert
+ //let's keep it going
+
+ if (renew_error == 0) { //undefined error means probably grace period, forgive that.
+ r = true;
+ }
+ goto rloser;
+ }
+
+ // got cert...
+
+ // build label
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.label",
+ OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "label '%s'", configname);
+ pattern = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ if(pattern == NULL)
+ {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "no configured cert label!");
+ renewal_failure_found = RENEWAL_FAILURE;
+ PR_snprintf(audit_msg,512, "No cert label configured for cert!");
+ goto rloser;
+ }
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "pattern '%s'",pattern);
+
+ label = MapPattern(&nv, (char *) pattern);
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "label '%s'",label);
+
+ if (o_cert != NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "got cert!!");
+// tmp_c = NSSBase64_EncodeItem(0, 0, 0, &(o_cert)->derCert);
+// RA::Debug("RA_Enroll_Processor::ProcessRenewal", "after NSSBase64_EncodeItem");
+
+ char snum[2048];
+ RA::ra_tus_print_integer(snum, &o_cert->serialNumber);
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC_CERT_REQ,
+ userid, cuid, msn, "success", "renewal", final_applet_version,
+ keyVersion != NULL ? keyVersion : "",
+ snum, caconnid, "certificate renewed");
+ } else {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "no cert!!");
+ PR_snprintf(audit_msg, 512, "No cert returned from DoRenewal");
+ goto rloser;
+ }
+
+ ktypes[i] = PL_strdup(keyTypeValue);
+ origins[i] = PL_strdup(cuid);
+ certificates[i] = o_cert;
+ //o_certNums++;
+
+ // For the encrytion cert we actually need to calculate the proper certId and certAttrId
+ // since we now leave previous encryption certs on the token to allow dencryption of old
+ // Emails by the user.
+
+ if( key_type == KEY_TYPE_ENCRYPTION) {
+
+ int new_cert_id = GetNextFreeCertIdNumber(pkcs11objx);
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Encryption cert, calculated new cert id: %d",new_cert_id);
+
+ //Is the calculated cert id reasonable based on the current state of the
+ // token and the expected renewal configuration.
+ if( !(new_cert_id > keyTypeNum ) || new_cert_id > 9) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "RA_Enroll_Processor::ProcessRenewal","Possible misconfiguration or out of sync token!");
+ PR_snprintf(audit_msg, 512, "Renewal of cert failed, misconfiguration or out of sync token!");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+
+ }
+
+ finalCertId[0]= 'C';
+ finalCertId[1] = '0' + new_cert_id;
+
+ finalCertAttrId[0] = 'c';
+ finalCertAttrId[1] = '0' + new_cert_id;
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "finalCertId %s finalCertAttrId %s", finalCertId, finalCertAttrId);
+ }
+
+ // write certificate to token
+ certbuf = new Buffer(o_cert->derCert.data, o_cert->derCert.len);
+ if (pkcs11obj_enable)
+ {
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (finalCertId[0] << 24) +
+ (finalCertId[1] << 16),
+ certbuf);
+ pkcs11objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Not implemented");
+ renewal_failure_found = RENEWAL_FAILURE;
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: pkcs11obj_enable = false not implemented");
+ goto rloser;
+/*
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create certificate object on token");
+ rc = channel->CreateCertificate(certId, certbuf);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to create certificate object on token");
+
+ o_status = STATUS_ERROR_MAC_ENROLL_PDU;
+ goto rloser;
+ }
+*/
+ }
+
+ if (o_cert->subjectKeyID.data != NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "subjectKeyID found in cert");
+//later, add code to check if keys really exist on token!
+ keyid = new Buffer((BYTE*)o_cert->subjectKeyID.data,
+ (unsigned int)o_cert->subjectKeyID.len);
+
+ } else {// should always have keyid
+//use existing original keyid
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal", "no subjectKeyID found in cert, use existing");
+ keyid = new Buffer((BYTE*)certs[0]->subjectKeyID.data,
+ (unsigned int)certs[0]->subjectKeyID.len);
+ }
+
+ if (pkcs11obj_enable)
+ {
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ key_type , finalCertAttrId, label, keyid);
+ if (b == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: CreatePKCS11CertAttrsBuffer returns null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (finalCertAttrId[0] << 24) +
+ (finalCertAttrId[1] << 16),
+ &b);
+ if (objSpec == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: ParseFromTokenData returns null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+
+ //We need to massage the fixedAttributes of this object to allow the CKA_ID value
+ //of the original encryption cert to be available for coolkey to read.
+ // Coolkey only deals in a one byte index 0 - n, ex: "01".
+ // Coolkey uses the final byte of the "fixedAttributes" property of each object
+ // to identify the object. This value needs to be the same for each cert and its
+ // corresponding key pair. See ObjectSpec::ParseAttributes.
+
+ if (key_type == KEY_TYPE_ENCRYPTION) {
+
+ unsigned long currentFixedAttributes = objSpec->GetFixedAttributes();
+ unsigned long modifiedFixedAttributes = currentFixedAttributes;
+
+ // Here we want the original encryption cert's id number.
+ int val = (certId[1] - '0');
+
+ modifiedFixedAttributes &= (BYTE) 0xFFFFFFF0;
+ modifiedFixedAttributes |= (BYTE) val;
+ objSpec->SetFixedAttributes(modifiedFixedAttributes);
+
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "original fixed Attributes %lu modified ones %lu",
+ currentFixedAttributes,modifiedFixedAttributes);
+ }
+
+ pkcs11objx->AddObjectSpec(objSpec);
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Not implemented");
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: pkcs11obj_enable = false not implemented");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+/*
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create PKCS#11 certificate Attributes");
+ rc = channel->CreatePKCS11CertAttrs(keyTypeValue, certAttrId, label, keyid);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 Certificate attributes creation failed");
+ o_status = STATUS_ERROR_MAC_ENROLL_PDU;
+ goto rloser;
+ }
+*/
+ }
+
+ spkix = &(o_cert->subjectPublicKeyInfo);
+ if (spkix == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: subjectPublicKeyInfo is null");
+ goto rloser;
+ }
+ pk_p = SECKEY_ExtractPublicKey(spkix);
+ if (pk_p == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: ExtractPublicKey is null");
+ goto rloser;
+ }
+ SECKEY_DestroySubjectPublicKeyInfo(spkix);
+
+ /* fill in keyid, modulus, and exponent */
+
+ si_mod = pk_p->u.rsa.modulus;
+ modulus = new Buffer((BYTE*) si_mod.data, si_mod.len);
+ if (modulus == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: modulus is null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ spkix = SECKEY_CreateSubjectPublicKeyInfo(pk_p);
+ if (spkix == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: CreateSubjectPublicKeyInfo returns null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+
+ /*
+ * RFC 3279
+ * The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ * value of the BIT STRING subjectPublicKey (excluding the tag,
+ * length, and number of unused bits).
+ */
+ spkix->subjectPublicKey.len >>= 3;
+ si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
+ if (si_kid == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: si_kid is null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ spkix->subjectPublicKey.len <<= 3;
+ SECKEY_DestroySubjectPublicKeyInfo(spkix);
+
+ if (keyid == NULL)
+ keyid = new Buffer((BYTE*) si_kid->data, si_kid->len);
+ if (keyid == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: keyid is null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ si_exp = pk_p->u.rsa.publicExponent;
+ exponent = new Buffer((BYTE*) si_exp.data, si_exp.len);
+ if (exponent == NULL) {
+ PR_snprintf(audit_msg, 512, "Write cert to token failed: exponent is null");
+ renewal_failure_found = RENEWAL_FAILURE;
+ goto rloser;
+ }
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "Keyid, modulus and exponent have been extracted from public key");
+
+ renewed = true;
+
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "renewal",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "Cert written to token successfully");
+
+
+ rloser:
+
+ if( keyid != NULL ) {
+ delete keyid;
+ keyid = NULL;
+ }
+ if( label != NULL ) {
+ PL_strfree( (char *) label );
+ label = NULL;
+ }
+ if(renewal_failure_found == RENEWAL_FAILURE) {
+ RA::Debug("RA_Enroll_Processor_ProcessRenewal", "A renewal in list failed other than grace period error, aborting.");
+ goto loser;
+ }
+ }
+ break;
+ } //for
+ if((strcmp( attr_status, "active" ) == 0) &&
+ renewed) {
+ char *cn = RA::ra_get_cert_cn(e);
+ if(renewedCertUpdateCount < ( maxCertUpdate -1)) //unlikely scenario this fails
+ renewedCertUpdateList[renewedCertUpdateCount++] = PL_strdup(cn);
+ // Let's hold off on the celebration until the end.
+ // RA::ra_update_cert_status(cn, "renewed");
+ if (cn != NULL) {
+ PL_strfree(cn);
+ cn = NULL;
+ }
+ }
+ if( attr_status != NULL ) {
+ PL_strfree( attr_status );
+ attr_status = NULL;
+ }
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_LDAP_CONN;
+ goto loser;
+ }
+ RA::Debug("RA_Enroll_Processor::ProcessRenewal",
+ "Filter to find certificates = %s", filter);
+ }
+
+loser:
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_RENEWAL, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "renewal",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+ }
+
+ //Let's wait until all the certs are processed to actually update the renewal status
+ RA::Debug("RA_Enroll_Process::ProcessRenewal","renewedCertUpdateCount %d", renewedCertUpdateCount);
+ if(renewedCertUpdateCount > 0) {
+ for(int rr = 0; rr < renewedCertUpdateCount; rr++) {
+ if(renewedCertUpdateList[rr]) {
+ if(renewal_failure_found != RENEWAL_FAILURE) {
+ RA::Debug("RA_Enroll_Process::ProcessRenewal","updating to renewed status of cn= %s", renewedCertUpdateList[rr]);
+ RA::ra_update_cert_status(renewedCertUpdateList[rr],"renewed");
+ }
+ PL_strfree(renewedCertUpdateList[rr]);
+ renewedCertUpdateList[rr] = NULL;
+ }
+ }
+ } else {
+ // All certs failed to renew
+ RA::Debug("RA_Enroll_Process::ProcessRenewal","All certs failed to renew, bailing with error");
+ o_status = STATUS_ERROR_MAC_ENROLL_PDU;
+ r = false;
+
+ }
+
+ if( pretty_cuid != NULL ) {
+ PR_Free( (char *) pretty_cuid );
+ pretty_cuid = NULL;
+ }
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+
+ return r;
+}
+
+bool RA_Enroll_Processor::ProcessRecovery(AuthParams *login, char *reason, RA_Session *session, char **&origins, char **&ktypes,
+ char *tokenType, PKCS11Obj *pkcs11objx, int pkcs11obj_enable,
+ NameValueSet *extensions, Secure_Channel *channel, Buffer *wrapped_challenge,
+ Buffer *key_check, Buffer *plaintext_challenge, char *cuid, char *msn,
+ const char *final_applet_version, char *khex, const char *userid,
+ RA_Status &o_status, CERTCertificate **&certificates, char *lostTokenCUID,
+ int &o_certNums, char **&tokenTypes, char *origTokenType)
+{
+ bool r = true;
+ o_status = STATUS_ERROR_RECOVERY_IS_PROCESSED;
+ char keyTypePrefix[256];
+ char configname[256];
+ char filter[256];
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ char *o_pub = NULL;
+ char *o_priv = NULL;
+ const char *connid = NULL;
+ bool tksServerKeygen = false;
+ bool serverKeygen = false;
+ bool archive = false;
+ const char *pretty_cuid = NULL;
+ char audit_msg[512] = "";
+ char *keyVersion = NULL;
+ char *ivParam = NULL;
+
+ int i = 0;
+ int totalNumCerts = 0;
+ int actualCertIndex = 0;
+ int legalScheme = 0;
+ int isGenerateandRecover = 0;
+ const char *FN="RA_Enroll_Processor::ProcessRecovery";
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","entering...");
+ // get key version for audit logs
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.recovery.%s.keyType.num",
+ tokenType, reason);
+ int keyTypeNum = RA::GetConfigStore()->GetConfigAsInt(configname, -1);
+ if (keyTypeNum == -1) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ //We will have to rifle through the configuration to see if there any recovery operations with
+ //scheme "GenerateNewKeyandRecoverLast" which allows for recovering the old key AND generating a new
+ // one for the encryption type only. If this scheme is present, the number of certs for bump by
+ // 1 for each occurance.
+
+ totalNumCerts = 0;
+ for(i = 0; i<keyTypeNum; i++) {
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.recovery.%s.keyType.value.%d", tokenType, reason, i);
+ const char *keyTypeValue = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+
+ if (keyTypeValue == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.%s.recovery.%s.scheme", tokenType, keyTypeValue, reason);
+ char *scheme = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+ if (scheme == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ //If we are doing "GenerateNewKeyandRecoverLast, we will create two certificates
+ //for that particular round.
+ if(PL_strcasecmp(scheme, "GenerateNewKeyandRecoverLast") == 0) {
+
+ //Make sure someone doesn't try "GenerateNewKeyandRecoverLast" with a signing key.
+
+ if(PL_strcasecmp(keyTypeValue,"encryption" ) != 0) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Invalid config param for %s. Can't use GenerateNewKeyandRecoveLaste scheme with non encryption key",
+ configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+ totalNumCerts ++;
+ }
+ totalNumCerts ++;
+ }
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","totalNumCerts %d ",totalNumCerts);
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "keyTypenum=%d", keyTypeNum);
+
+
+ if(!(totalNumCerts > keyTypeNum)) {
+ totalNumCerts = keyTypeNum;
+ }
+
+ o_certNums = totalNumCerts;
+ certificates = (CERTCertificate **) malloc (sizeof(CERTCertificate *) * totalNumCerts);
+ ktypes = (char **) malloc (sizeof(char *) * totalNumCerts);
+ origins = (char **) malloc (sizeof(char *) * totalNumCerts);
+ tokenTypes = (char **) malloc (sizeof(char *) * totalNumCerts);
+
+ for(i = 0; i < totalNumCerts; i++) {
+ ktypes[i] = NULL;
+ origins[i] = NULL;
+ tokenTypes[i] = NULL;
+ certificates[i] = NULL;
+ }
+
+ //Iterate through number of key types. Iteration will be modified in case we have to insert extra
+ //certificates due to the "GenerateNewKeyandRecoverLast" scheme.
+
+ actualCertIndex = 0;
+ legalScheme = 0;
+ for (i=0; i<keyTypeNum; i++) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","Top cert loop: i %d actualCertIndex %d",i,actualCertIndex);
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.recovery.%s.keyType.value.%d", tokenType, reason, i);
+ const char *keyTypeValue = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "keyType == %s ", keyTypeValue);
+
+ if (keyTypeValue == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+ PR_snprintf(configname, 256, "op.enroll.%s.keyGen.%s.recovery.%s.scheme", tokenType, keyTypeValue, reason);
+ char *scheme = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+ if (scheme == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ // set allowable $$ config patterns
+ NameValueSet nv;
+ pretty_cuid = GetPrettyPrintCUID(cuid);
+
+ nv.Add("pretty_cuid", pretty_cuid);
+ nv.Add("cuid", cuid);
+ nv.Add("msn", msn);
+ nv.Add("userid", userid);
+ //nv.Add("profileId", profileId);
+
+ /* populate auth parameters output to nv also */
+ /* so we can reference to the auth parameter by */
+ /* using $auth.cn$, or $auth.mail$ */
+ if (login != NULL) {
+ int s = login->Size();
+ for (int x = 0; x < s; x++) {
+ char namebuf[2048];
+ char *name = login->GetNameAt(x);
+ sprintf(namebuf, "auth.%s", name);
+ nv.Add(namebuf, login->GetValue(name));
+ }
+ }
+ //Check for the special scheme where we generate a new cert and
+ //recover the last one.
+
+ if(PL_strcasecmp(scheme, "GenerateNewKeyandRecoverLast") == 0) {
+ isGenerateandRecover = 1;
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Scheme %s: GenerateNewKeyandRecoverLast case!",scheme);
+ } else {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Scheme %s: Not GenerateNewKeyandRecoverLast case!",scheme);
+ isGenerateandRecover = 0;
+ }
+
+ if ((PL_strcasecmp(scheme, "GenerateNewKey") == 0) || isGenerateandRecover) {
+ legalScheme = 1;
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "Generate new key for %s", keyTypeValue);
+ r = GenerateCertificate(login, keyTypeNum, keyTypeValue, actualCertIndex, session, origins, ktypes, tokenType,
+ pkcs11objx, pkcs11obj_enable, extensions, channel, wrapped_challenge,
+ key_check, plaintext_challenge, cuid, msn, final_applet_version,
+ khex, userid, o_status, certificates);
+ tokenTypes[actualCertIndex] = PL_strdup(tokenType);
+ if (o_status == STATUS_NO_ERROR)
+ o_status = STATUS_ERROR_RECOVERY_IS_PROCESSED;
+ }
+
+ if ((PL_strcasecmp(scheme, "RecoverLast") == 0) || isGenerateandRecover) {
+ RA::Debug("RA_Enroll_Processor::RecoverLast", "Recover the key for %s", keyTypeValue);
+ // Special case for GenerateandRecover scenario.
+
+ legalScheme = 1;
+ if(isGenerateandRecover) {
+ RA::Debug("RA_Enroll_Processor::RecoverLast",
+ "Generate extra recoverd cert for GenerateNewKeyandRecoverLast");
+
+ actualCertIndex ++;
+ }
+ PR_snprintf(filter, 256, "(&(tokenKeyType=%s)(tokenID=%s))",
+ keyTypeValue, lostTokenCUID);
+ int rc = RA::ra_find_tus_certificate_entries_by_order_no_vlv(filter,
+ &result, 1);
+
+ tokenTypes[actualCertIndex] = PL_strdup(origTokenType);
+ char **attr = (char **) malloc (sizeof(char *) * totalNumCerts);
+ if (rc == LDAP_SUCCESS) {
+ // retrieve the most recent certificate, we just recover the most
+ // recent one
+ e = RA::ra_get_first_entry(result);
+ if (e != NULL) {
+ CERTCertificate **certs = RA::ra_get_certificates(e);
+ if (certs[0] != NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Certificate used to restore the private key");
+ PR_snprintf(configname, 256,
+ "op.enroll.%s.keyGen.%s.serverKeygen.drm.conn", tokenType, keyTypeValue);
+ const char *drmconnid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (drmconnid == NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Missing the configuration parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. Missing the configuration parameter for %s", configname);
+ goto loser;
+ }
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "begin recovery code");
+
+ SECKEYPublicKey *pk_p = NULL;
+ SECItem si_mod;
+ Buffer *modulus=NULL;
+ SECItem *si_kid = NULL;
+ Buffer *keyid=NULL;
+ SECItem si_exp;
+ Buffer *exponent=NULL;
+ CERTSubjectPublicKeyInfo* spkix = NULL;
+
+ //Now we have to get the original config params for the encryption cert and keys
+
+ //XXX these attr functions shouldn't take config params
+ PR_snprintf(keyTypePrefix, 256, "op.enroll.%s.keyGen.encryption", tokenType);
+
+ PR_snprintf((char *)configname, 256, "%s.keySize", keyTypePrefix);
+ int keysize = RA::GetConfigStore()->GetConfigAsInt(configname, 1024);
+
+ PR_snprintf((char *)configname, 256, "%s.keyUsage", keyTypePrefix);
+ int keyUsage = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.keyUser", keyTypePrefix);
+ int keyUser = RA::GetConfigStore()->GetConfigAsInt(configname, 0);
+
+ PR_snprintf((char *)configname, 256, "%s.certId",keyTypePrefix);
+
+ const char *origCertId = RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+
+ //actually adjust the crucial values based on this extra certificate
+ //being generated.
+
+ int highestCertId = 0;
+ int newCertId = 0;
+ if(isGenerateandRecover) {
+ //find highest cert id number.
+ for(int j=0; j < keyTypeNum; j++) {
+ PR_snprintf((char *)configname, 256,"%s.certId", keyTypePrefix);
+ const char *cId = RA::GetConfigStore()->GetConfigAsString(configname, "C0");
+ int id_int = 0;
+ if(cId) {
+ id_int = cId[1] - '0';
+ }
+
+ if (id_int > highestCertId)
+ highestCertId = id_int;
+ }
+ highestCertId++;
+ } else {
+ highestCertId = origCertId[1] - '0';
+ }
+
+ newCertId = highestCertId;
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","Calculated new CertID %d.",newCertId);
+
+ char certId[3];
+ char certAttrId[3];
+ char privateKeyAttrId[3];
+ char publicKeyAttrId[3];
+ int pubKeyNumber=0;
+ int priKeyNumber=0;
+
+ certId[0] = 'C';
+ certId[1] = '0' + newCertId;
+ certId[2] = 0;
+
+ certAttrId[0] = 'c';
+ certAttrId[1] = '0' + newCertId;
+ certAttrId[2] = 0;
+
+ pubKeyNumber = 2 * newCertId + 1;
+ priKeyNumber = 2 * newCertId;
+
+ privateKeyAttrId[0] = 'k';
+ privateKeyAttrId[1] = '0' + priKeyNumber;
+ privateKeyAttrId[2] = 0;
+
+ publicKeyAttrId[0] = 'k';
+ publicKeyAttrId[1] = '0' + pubKeyNumber;
+ publicKeyAttrId[2] = 0;
+
+ RA::Debug(
+ "RA_Enroll_Processor::ProcessRecovery",
+ "certId %s certAttrId %s privateKeyAttrId %s publicKeyAtrId %s priKeyNum %d pubKeyNum %d",
+ certId,certAttrId,privateKeyAttrId,publicKeyAttrId,priKeyNumber, pubKeyNumber);
+
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.label",
+ OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "label '%s'", configname);
+ const char *pattern = RA::GetConfigStore()->GetConfigAsString(configname);
+ const char* label = MapPattern(&nv, (char *) pattern);
+
+ BYTE objid[4];
+
+ objid[0] = 0xFF;
+ objid[1] = 0x00;
+ objid[2] = 0xFF;
+ objid[3] = 0xF3;
+
+ char *tmp_c = NULL;
+ if (certs[0] != NULL) {
+ tmp_c = NSSBase64_EncodeItem(0, 0, 0, &(certs[0]->derCert));
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after NSSBase64_EncodeItem");
+ } else {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "no cert!!");
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. no cert");
+ goto rloser;
+ }
+
+ if ((tmp_c == NULL) || (strcmp(tmp_c,"")==0)) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "NSSBase64_EncodeItem failed");
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. NSSBase64_EncodeItem failed");
+ goto rloser;
+ }
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "NSSBase64_EncodeItem succeeded");
+ attr[0] = PL_strdup(tmp_c);
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "b64 encoded cert =%s",attr[0]);
+
+ if( newCertId > 9) {
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "RA_Enroll_Processor::ProcessRecovery","Possible misconfiguration or out of sync token!");
+ PR_snprintf(audit_msg, 512,
+ "Renewal of cert failed, misconfiguration or out of sync token!");
+ goto rloser;
+ }
+
+ // get serverKeygen and archive, check if they are enabled.
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.serverKeygen.enable",
+ OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "looking for config %s", configname);
+ serverKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.serverKeygen.archive",
+ OP_PREFIX, tokenType, keyTypeValue);
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ "looking for config %s", configname);
+ archive = RA::GetConfigStore()->GetConfigAsBool(configname, 0);
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ tksServerKeygen = false;
+ if (connid != NULL) {
+ PR_snprintf((char *)configname, 256, "conn.%s.serverKeygen", connid);
+ tksServerKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, 0);
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_NO_TKS_CONNID;
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::ProcessRecovery", "Missing tks.connid");
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. Missing tks.connid");
+ goto rloser;
+ }
+
+ if (tksServerKeygen && archive && serverKeygen) {
+ RA::RecoverKey(session, lostTokenCUID, userid,
+ channel->getDrmWrappedDESKey(),
+ attr[0], &o_pub, &o_priv,
+ (char *)drmconnid,&ivParam);
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_KEY_ARCHIVE_OFF;
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::ProcessRecovery", "Archival is turned off");
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. Archival is turned off");
+ goto rloser;
+ }
+
+ if (o_pub == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::DoEnrollment()", "RecoverKey called, o_pub is NULL");
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. o_pub is NULL");
+ goto rloser;
+ } else
+ RA::Debug(LL_PER_PDU, "DoEnrollment", "o_pub = %s", o_pub);
+
+
+ if (o_priv == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::DoEnrollment()", "RecoverKey called, o_priv is NULL");
+ /* XXX
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ goto rloser;
+ */
+ } else
+ RA::Debug(LL_PER_PDU, "DoEnrollment", "o_priv = %s", o_priv);
+
+ if (ivParam == NULL) {
+ RA::Debug(LL_PER_CONNECTION,"RA_Enroll_Processor::ProcessRecovery",
+ "ProcessRecovery called, ivParam is NULL");
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ PR_snprintf(audit_msg, 512, "RA_Enroll_Processor::ProcessRecovery called, ivParam is NULL");
+ goto rloser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,"ProcessRecovery",
+ "ivParam = %s", ivParam);
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::ProcessRecovery()", "key injection for RecoverKey occurs here");
+ /*
+ * the following code converts b64-encoded public key info into SECKEYPublicKey
+ */
+ SECStatus rv;
+ SECItem der;
+ CERTSubjectPublicKeyInfo* spki;
+
+ der.type = (SECItemType) 0; /* initialize it, since convertAsciiToItem does not set it */
+ rv = ATOB_ConvertAsciiToItem (&der, o_pub);
+ if (rv != SECSuccess){
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key, rv is failure");
+ SECITEM_FreeItem(&der, PR_FALSE);
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. after converting public key, rv is failure");
+ goto rloser;
+ }else {
+ RA::Debug(LL_PER_PDU, "ProcessRecovery", "item len=%d, item type=%d",der.len, der.type);
+
+ spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
+ SECITEM_FreeItem(&der, PR_FALSE);
+
+ if (spki != NULL) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key spki is not NULL");
+ pk_p = SECKEY_ExtractPublicKey(spki);
+ if (pk_p != NULL)
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key pk_p is not NULL");
+ else
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key, pk_p is NULL");
+ } else
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery", "after converting public key, spki is NULL");
+
+ }
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+
+ if( pk_p == NULL ) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "pk_p is NULL; unable to continue");
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. pk_p is NULL; unable to continue");
+ goto rloser;
+ }
+
+ // XXX - Add serial number and public key to audit log
+ //get serial number for audit log
+ //char msg[2048];
+ //RA::ra_tus_print_integer(msg, &certs[0]->serialNumber);
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "key recovered successfully");
+
+
+ /* fill in keyid, modulus, and exponent */
+
+ si_mod = pk_p->u.rsa.modulus;
+ modulus = new Buffer((BYTE*) si_mod.data, si_mod.len);
+
+ spkix = SECKEY_CreateSubjectPublicKeyInfo(pk_p);
+
+ /*
+ * RFC 3279
+ * The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ * value of the BIT STRING subjectPublicKey (excluding the tag,
+ * length, and number of unused bits).
+ */
+ spkix->subjectPublicKey.len >>= 3;
+ si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
+ spkix->subjectPublicKey.len <<= 3;
+ SECKEY_DestroySubjectPublicKeyInfo(spkix);
+
+ keyid = new Buffer((BYTE*) si_kid->data, si_kid->len);
+ si_exp = pk_p->u.rsa.publicExponent;
+ exponent = new Buffer((BYTE*) si_exp.data, si_exp.len);
+
+ RA::Debug(LL_PER_PDU, "RA_Enroll_Processor::Process",
+ " keyid, modulus and exponent are retrieved");
+
+ ktypes[actualCertIndex] = PL_strdup(keyTypeValue);
+ // We now store the token id of the original token
+ // that generates this certificate so we can
+ // tell if the certificate should be operated
+ // on or not during formation operation
+ origins[actualCertIndex] = PL_strdup(lostTokenCUID);
+ certificates[actualCertIndex] = certs[0];
+
+
+ // Create KeyBlob for private key, but first b64 decode it
+ /* url decode o_priv */
+ {
+ Buffer priv_keyblob;
+ Buffer *decodeKey = Util::URLDecode(o_priv);
+ //RA::DebugBuffer("cfu debug"," private key =",decodeKey);
+ priv_keyblob =
+ Buffer(1, 0x01) + // encryption
+ Buffer(1, 0x09)+ // keytype is RSAPKCS8Pair
+ Buffer(1,(BYTE)(keysize/256)) + // keysize is two bytes
+ Buffer(1,(BYTE)(keysize%256)) +
+ Buffer((BYTE*) *decodeKey, decodeKey->size());
+ delete decodeKey;
+
+ //inject PKCS#8 private key
+ BYTE perms[6];
+
+ perms[0] = 0x40;
+ perms[1] = 0x00;
+ perms[2] = 0x40;
+ perms[3] = 0x00;
+ perms[4] = 0x40;
+ perms[5] = 0x00;
+
+ if (channel->CreateObject(objid, perms, priv_keyblob.size()) != 1) {
+ r = false;
+ PR_snprintf(audit_msg, 512, "Failed to write key to token. CreateObject failed.");
+ goto rloser;
+ }
+
+ if (channel->WriteObject(objid, (BYTE*)priv_keyblob, priv_keyblob.size()) != 1) {
+ r = false;
+ PR_snprintf(audit_msg, 512, "Failed to write key to token. WriteObject failed.");
+ goto rloser;
+ }
+ }
+
+ /* url decode the wrapped kek session key and keycheck*/
+ {
+ Buffer data;
+ /*
+ RA::Debug(LL_PER_PDU, "", "getKekWrappedDESKey() returns =%s", channel->getKekWrappedDESKey());
+ RA::Debug(LL_PER_PDU, "", "getKeycheck() returns =%s", channel->getKeycheck());
+ */
+ Buffer *decodeKey = Util::URLDecode(channel->getKekWrappedDESKey());
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "des key item len=%d",
+ decodeKey->size());
+ RA::DebugBuffer("cfu debug", "DES key =", decodeKey);
+ */
+ char *keycheck = channel->getKeycheck();
+ Buffer *decodeKeyCheck = Util::URLDecode(keycheck);
+ if (keycheck)
+ PL_strfree(keycheck);
+
+ /*
+ RA::Debug(LL_PER_PDU, "", "keycheck item len=%d",
+ decodeKeyCheck->size());
+ RA::DebugBuffer("cfu debug", "key check=", decodeKeyCheck);
+ */
+
+ BYTE alg = 0x80;
+ if(decodeKey && decodeKey->size()) {
+ alg = 0x81;
+ }
+
+ //Get iv data returned by DRM
+
+ Buffer *iv_decoded = Util::URLDecode(ivParam);
+ if (ivParam) {
+ PL_strfree(ivParam);
+ }
+
+ if(iv_decoded == NULL) {
+ r = false;
+ PR_snprintf(audit_msg, 512, "ProcessRecovery: store keys in token failed, iv data not found");
+ delete decodeKey;
+ delete decodeKeyCheck;
+ goto rloser;
+ }
+
+ data =
+ Buffer((BYTE*)objid, 4)+ // object id
+ Buffer(1,alg) +
+ //Buffer(1, 0x08) + // key type is DES3: 8
+ Buffer(1, (BYTE) decodeKey->size()) + // 1 byte length
+ Buffer((BYTE *) *decodeKey, decodeKey->size())+ // key -encrypted to 3des block
+ // check size
+ // key check
+ Buffer(1, (BYTE) decodeKeyCheck->size()) + //keycheck size
+ Buffer((BYTE *) *decodeKeyCheck , decodeKeyCheck->size())+ // keycheck
+ Buffer(1, iv_decoded->size())+ // IV_Length
+ Buffer((BYTE*)*iv_decoded, iv_decoded->size());
+
+ //RA::DebugBuffer("cfu debug", "ImportKeyEnc data buffer =", &data);
+
+ delete decodeKey;
+ delete decodeKeyCheck;
+ delete iv_decoded;
+
+ if (channel->ImportKeyEnc((keyUser << 4)+priKeyNumber,
+ (keyUsage << 4)+pubKeyNumber, &data) != 1) {
+ r = false;
+ PR_snprintf(audit_msg, 512, "Failed to write key to token. ImportKeyEnc failed.");
+ goto rloser;
+ }
+ }
+
+ {
+ Buffer *certbuf = new Buffer(certs[0]->derCert.data, certs[0]->derCert.len);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (certId[0] << 24) +
+ (certId[1] << 16),
+ certbuf);
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+ {
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ KEY_TYPE_ENCRYPTION , certAttrId, label, keyid);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (certAttrId[0] << 24) +
+ (certAttrId[1] << 16),
+ &b);
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+
+ {
+ Buffer b = channel->CreatePKCS11PriKeyAttrsBuffer(KEY_TYPE_ENCRYPTION,
+ privateKeyAttrId, label, keyid, modulus, OP_PREFIX,
+ tokenType, keyTypePrefix);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (privateKeyAttrId[0] << 24) +
+ (privateKeyAttrId[1] << 16),
+ &b);
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+
+ {
+ Buffer b = channel->CreatePKCS11PubKeyAttrsBuffer(KEY_TYPE_ENCRYPTION,
+ publicKeyAttrId, label, keyid,
+ exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (publicKeyAttrId[0] << 24) +
+ (publicKeyAttrId[1] << 16),
+ &b);
+ pkcs11objx->AddObjectSpec(objSpec);
+ }
+
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "key written to token successfully");
+
+ rloser:
+
+ if( modulus != NULL ) {
+ delete modulus;
+ modulus = NULL;
+ }
+ if( keyid != NULL ) {
+ delete keyid;
+ keyid = NULL;
+ }
+ if( exponent != NULL ) {
+ delete exponent;
+ exponent = NULL;
+ }
+ if( attr[0] != NULL ) {
+ PR_Free(attr[0]);
+ attr[0] = NULL;
+ }
+ if( o_pub != NULL ) {
+ PR_Free(o_pub);
+ o_pub = NULL;
+ }
+
+ if (o_priv !=NULL) {
+ PR_Free(o_priv);
+ o_priv = NULL;
+ }
+
+ if( si_kid != NULL ) {
+ SECITEM_FreeItem( si_kid, PR_TRUE );
+ si_kid = NULL;
+ }
+ if( label != NULL ) {
+ PL_strfree( (char *) label );
+ label = NULL;
+ }
+
+ }
+ }
+ } else {
+ r = false;
+ o_status = STATUS_ERROR_LDAP_CONN;
+ goto loser;
+ }
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Filter to find certificates = %s", filter);
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Recover key for %s", keyTypeValue);
+
+ //Unrevoke this successfully recovered certificate
+ if ( o_status == STATUS_ERROR_RECOVERY_IS_PROCESSED && e != NULL) {
+ char *statusString = NULL;
+ int statusNum = UnrevokeRecoveredCert(e, statusString);
+
+ // Error from the CA log and get out
+ if (statusNum != 0) {
+ r = false;
+ o_status = STATUS_ERROR_RECOVERY_FAILED;
+ if (statusString == NULL || strlen(statusString) == 0) {
+ statusString = PL_strdup("Unknown Key Recovery Error.");
+ }
+ RA::Debug("RA_Enroll::Prcessor::ProcessRecovery", "Unrevoke statusString: %s",statusString);
+ PR_snprintf(audit_msg, 512, "Key Recovery failed. Can not unrevoke recovered certificate! %s",statusString);
+ if (statusString) {
+ PL_strfree(statusString);
+ }
+ goto loser;
+ }
+
+ if (statusString) {
+ PL_strfree(statusString);
+ }
+ }
+ }
+ if( !legalScheme) {
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "Misconfigure parameter for %s", configname);
+ r = false;
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ goto loser;
+ }
+
+ actualCertIndex++;
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","leaving cert loop... ");
+ }
+
+ loser:
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_ENROLLMENT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "enrollment",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+ }
+
+ if( pretty_cuid != NULL ) {
+ PR_Free( (char *) pretty_cuid );
+ pretty_cuid = NULL;
+ }
+ if( result != NULL ) {
+ ldap_msgfree( result );
+ }
+
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery","leaving whole function...");
+ return r;
+}
+
+int RA_Enroll_Processor::DoPublish(const char *cuid,SECItem *encodedPublicKeyInfo,Buffer *cert,const char *publisher_id,char *applet_version)
+{
+
+ int res = 0;
+
+ CERTCertificate *certObj = NULL;
+ const char *FN="DoPublish";
+
+ unsigned char *public_key_data = NULL;
+ int public_key_len = 0;
+ PRTime not_before,not_after;
+
+ // 1980 epoch offset
+
+ PRTime ul_1980 = ((365 * 10 + 2) * 86400);
+
+
+ if(! encodedPublicKeyInfo)
+ {
+ return 0;
+ }
+
+
+ RA::Debug(LL_PER_CONNECTION,FN, "1980 epoch offset %u ",ul_1980);
+
+ PRUint32 ul_not_before, ul_not_after;
+
+ int key_type = 1;
+
+ RA::Debug(LL_PER_CONNECTION,FN, "We got a public key back. Now attempt publish operation.");
+
+ public_key_data = encodedPublicKeyInfo->data;
+ public_key_len = encodedPublicKeyInfo->len;
+
+ unsigned long applet_version_long = 0;
+
+ char *end = NULL;
+
+ if(applet_version)
+ {
+ applet_version_long = (unsigned long) strtol((const char *)applet_version,&end,16);
+ }
+ if(cuid)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "cuid %s public_key_len %ud",cuid,public_key_len);
+
+ }
+ if(cert)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "cert.size() %ld. cert %s",cert->size(),(char *) (BYTE *) cert);
+
+ certObj = CERT_DecodeCertFromPackage((char *) cert->string(), (int) cert->size());
+ }
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "certObj %p.",certObj);
+
+ if(certObj && cuid != NULL)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "We got pointer to Certificate data.");
+ CERT_GetCertTimes (certObj, &not_before, &not_after);
+
+ ul_not_before = ( PRUint32 )( not_before/1000000 );
+ ul_not_after = ( PRUint32 )( not_after/1000000 );
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Cert date not_before %u not_after %u.",ul_not_before,ul_not_after);
+
+ // Convert to 1980 epoch time
+
+ ul_not_before -= (PRUint32) ul_1980;
+ ul_not_after -= (PRUint32) ul_1980;
+
+
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Cert date, after 1980 translation, not_before %ul not_after %ul.",ul_not_before,ul_not_after);
+
+
+ PublisherEntry *publish = RA::getPublisherById(publisher_id);
+
+ if(publish != NULL)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "publisher %s ",publish->id);
+ }
+ else
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "publisher %s not found ",publisher_id);
+
+ }
+
+ res = 0;
+ if(publish && publish->publisher )
+ {
+ IPublisher *pb = publish->publisher;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "publisher %p ",pb);
+ res = pb->publish((unsigned char *) cuid,(int) strlen(cuid),(long) key_type,(unsigned char *) public_key_data,(int) public_key_len,(unsigned long)ul_not_before,(unsigned long) ul_not_after,applet_version_long,applet_version_long - ul_1980);
+
+ }
+ if(!res)
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Publish failed.");
+ }
+ else
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Publish success.");
+ }
+ }
+ else
+ {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "No Publish failed Either cuid or certObj is NULL.");
+ }
+
+ if(certObj)
+ {
+
+ CERT_DestroyCertificate(certObj);
+ }
+ return res;
+}
+
+int RA_Enroll_Processor::GetNextFreeCertIdNumber(PKCS11Obj *pkcs11objx)
+{
+ if(!pkcs11objx)
+ return 0;
+
+ //Look through the objects actually currently on the token
+ //to determine an appropriate free certificate id
+
+ int num_objs = pkcs11objx->PKCS11Obj::GetObjectSpecCount();
+ char objid[2];
+
+ int highest_cert_id = 0;
+ for (int i = 0; i< num_objs; i++) {
+ ObjectSpec* os = pkcs11objx->GetObjectSpec(i);
+ unsigned long oid = os->GetObjectID();
+ objid[0] = (char)((oid >> 24) & 0xff);
+ objid[1] = (char)((oid >> 16) & 0xff);
+
+ if(objid[0] == 'C') { //found a certificate
+
+ int id_int = objid[1] - '0';
+
+ if(id_int > highest_cert_id) {
+ highest_cert_id = id_int;
+ }
+ }
+ }
+
+ RA::Debug(LL_PER_CONNECTION,
+ "RA_Enroll_Processor::GetNextFreeCertIdNumber",
+ "returning id number: %d", highest_cert_id + 1);
+ return highest_cert_id + 1;
+}
+
+//Unrevoke a cert that has been recovered
+int RA_Enroll_Processor::UnrevokeRecoveredCert(const LDAPMessage *e, char *&statusString)
+{
+ char configname[256];
+ CertEnroll certEnroll;
+ //Default to error return
+ int statusNum = 0;
+ char serial[100]="";
+
+ RA::Debug("RA_Enroll_Processor::ProcessRecovery",
+ "About to unrevoke recovered certificate.");
+
+ if (e == NULL) {
+ return 1;
+ }
+
+ char *attr_serial= RA::ra_get_cert_serial( (LDAPMessage *) e );
+ char *attr_tokenType = RA::ra_get_cert_tokenType( (LDAPMessage *) e );
+ char *attr_keyType = RA::ra_get_cert_type( (LDAPMessage *) e );
+
+ // does the config say we have to revoke this cert?
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.recovery."
+ "onHold.revokeCert",
+ attr_tokenType, attr_keyType );
+
+ RA::Debug("RA_Enroll_Processor::UnrevokeRecoveredCert",
+ "Recovered Cert Unrevoke config value %s \n", configname);
+ bool revokeCert = RA::GetConfigStore()->
+ GetConfigAsBool( configname, false );
+ if( revokeCert ) {
+ // Assume the worst
+ statusNum = 1;
+ // Get the conn to the CA
+ PR_snprintf( ( char * ) configname, 256,
+ "op.enroll.%s.keyGen.%s.ca.conn",
+ attr_tokenType, attr_keyType );
+
+ char *connid = ( char * )
+ RA::GetConfigStore()->
+ GetConfigAsString( configname );
+
+ if (connid) {
+ PR_snprintf( serial, 100, "0x%s", attr_serial );
+
+ //Actually make call to the CA to unrevoke
+ statusNum = certEnroll.UnrevokeCertificate(serial, connid, statusString);
+
+ RA::Debug("RA_Enroll_Processor::UnrevokeRecoveredCert",
+ "Recovered Cert statusNum %d statusString %s \n", statusNum, statusString);
+ }
+ }
+
+ if (attr_serial) {
+ PL_strfree(attr_serial);
+ }
+
+ if (attr_tokenType) {
+ PL_strfree(attr_tokenType);
+ }
+
+ if (attr_keyType) {
+ PL_strfree(attr_keyType);
+ }
+ return statusNum;
+}
+
+void PrintPRTime(PRTime theTime, const char *theName)
+{
+ struct tm t;
+ PRExplodedTime explode;
+ char buffer[256];
+
+ if(!theName)
+ return;
+
+ PR_ExplodeTime (theTime, PR_LocalTimeParameters, &explode);
+
+ t.tm_sec = explode.tm_sec;
+ t.tm_min = explode.tm_min;
+ t.tm_hour = explode.tm_hour;
+ t.tm_mday = explode.tm_mday;
+ t.tm_mon = explode.tm_month;
+ t.tm_year = explode.tm_year - 1900;
+ t.tm_wday = explode.tm_wday;
+ t.tm_yday = explode.tm_yday;
+
+ PL_strncpy(buffer, asctime (&t), 256);
+ buffer[256 - 1] = 0;
+
+ RA::Debug("PrintPRTime","Date/Time: %s %s",theName,buffer);
+}
diff --git a/base/tps/src/processor/RA_Format_Processor.cpp b/base/tps/src/processor/RA_Format_Processor.cpp
new file mode 100644
index 000000000..b09a7495b
--- /dev/null
+++ b/base/tps/src/processor/RA_Format_Processor.cpp
@@ -0,0 +1,70 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+
+#include "main/RA_Session.h"
+#include "main/RA_Msg.h"
+#include "main/Buffer.h"
+#include "main/Util.h"
+#include "engine/RA.h"
+#include "channel/Secure_Channel.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Format_Processor.h"
+#include "cms/CertEnroll.h"
+#include "httpClient/httpc/response.h"
+#include "main/Memory.h"
+#include "tus/tus_db.h"
+#include "ldap.h"
+
+#define OP_PREFIX "op.format"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a processor for handling upgrade operation.
+ */
+TPS_PUBLIC RA_Format_Processor::RA_Format_Processor ()
+{
+}
+
+/**
+ * Destructs upgrade processor.
+ */
+TPS_PUBLIC RA_Format_Processor::~RA_Format_Processor ()
+{
+}
+
+/**
+ * Processes the current session.
+ */
+TPS_PUBLIC RA_Status RA_Format_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ bool skip_auth = false;
+ return Format(session,extensions,skip_auth);
+}
diff --git a/base/tps/src/processor/RA_Pin_Reset_Processor.cpp b/base/tps/src/processor/RA_Pin_Reset_Processor.cpp
new file mode 100644
index 000000000..b776b55a4
--- /dev/null
+++ b/base/tps/src/processor/RA_Pin_Reset_Processor.cpp
@@ -0,0 +1,1013 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "engine/RA.h"
+#include "main/Util.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "channel/Secure_Channel.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Pin_Reset_Processor.h"
+#include "main/Memory.h"
+#include "tus/tus_db.h"
+#define OP_PREFIX "op.pinReset"
+static const char *expected_version = NULL;
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a processor for hanlding pin reset operation.
+ */
+TPS_PUBLIC RA_Pin_Reset_Processor::RA_Pin_Reset_Processor()
+{
+}
+
+/**
+ * Destructs pin reset processor.
+ */
+TPS_PUBLIC RA_Pin_Reset_Processor::~RA_Pin_Reset_Processor()
+{
+}
+
+/**
+ * Process the current session.
+ */
+TPS_PUBLIC RA_Status RA_Pin_Reset_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ struct berval **tokenOwner=NULL;
+ char configname[256];
+ const char *tokenType = NULL;
+ char *cuid = NULL;
+ const char *msn = NULL;
+ PRIntervalTime start, end;
+ RA_Status status = STATUS_NO_ERROR;
+ int rc = -1;
+ AuthParams *login = NULL;
+ Secure_Channel *channel = NULL;
+ char *new_pin = NULL;
+ unsigned int minlen = 0, maxlen = 0;
+ const char *applet_dir;
+ bool upgrade_enc = false;
+ char curVer[10];
+ char newVer[10];
+
+ char *curKeyInfoStr = NULL;
+ char *newVersionStr = NULL;
+
+ SecurityLevel security_level = SECURE_MSG_MAC_ENC;
+ Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_CARDMGR_INSTANCE_AID,
+ RA::CFG_DEF_CARDMGR_INSTANCE_AID);
+ Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_INSTANCE_AID);
+
+ int i;
+ Buffer key_data_set;
+ Buffer *token_status = NULL;
+ Buffer *buildID = NULL;
+ char *policy = NULL;
+ char *tmp_policy = NULL;
+ const char* required_version = NULL;
+ const char *appletVersion = NULL;
+ const char *final_applet_version = NULL;
+ char *keyVersion = PL_strdup( "" );
+ const char *userid = PL_strdup( "" );
+ BYTE major_version = 0x0;
+ BYTE minor_version = 0x0;
+ BYTE app_major_version = 0x0;
+ BYTE app_minor_version = 0x0;
+ char *token_userid = NULL;
+
+ Buffer host_challenge = Buffer(8, (BYTE)0);
+ Buffer key_diversification_data;
+ Buffer key_info_data;
+ Buffer card_challenge;
+ Buffer card_cryptogram;
+ Buffer token_cuid;
+ Buffer token_msn;
+ const char *connId = NULL;
+ const char *connid = NULL;
+ const char *tksid = NULL;
+ const char *authid = NULL;
+ AuthParams *authParams = NULL;
+ start = PR_IntervalNow();
+ Buffer *cplc_data = NULL;
+ char activity_msg[4096];
+ LDAPMessage *e = NULL;
+ LDAPMessage *ldapResult = NULL;
+ int maxReturns = 10;
+ char audit_msg[512] = "";
+ char *profile_state = NULL;
+ int key_change_over_success = 0;
+
+
+ RA::Debug("RA_Pin_Reset_Processor::Process", "Client %s", session->GetRemoteIP());
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "RA_Pin_Reset_Processor::Process");
+
+
+ SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ cplc_data = GetData(session);
+ if (cplc_data == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "Get Data Failed");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Get Data Failed, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ RA::DebugBuffer("RA_Pin_Reset_Processor::process", "CPLC Data = ",
+ cplc_data);
+ if (cplc_data->size() < 47) {
+ RA::Error("RA_Format_Processor::Process",
+ "Invalid CPLC Size");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Invalid CPLC Size, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ token_cuid = Buffer(cplc_data->substr(3,4)) +
+ Buffer(cplc_data->substr(19,2)) +
+ Buffer(cplc_data->substr(15,4));
+ RA::DebugBuffer("RA_Pin_Reset_Processor::process", "Token CUID= ",
+ &token_cuid);
+ cuid = Util::Buffer2String(token_cuid);
+
+ token_msn = Buffer(cplc_data->substr(41, 4));
+ RA::DebugBuffer("RA_Pin_Reset_Processor::process", "Token MSN= ",
+ &token_msn);
+ msn = Util::Buffer2String(token_msn);
+
+ /**
+ * Checks if the netkey has the required applet version.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ token_status = GetStatus(session, 0x00, 0x00);
+ if (token_status == NULL) {
+ major_version = 0x0;
+ minor_version = 0x0;
+ app_major_version = 0x0;
+ app_minor_version = 0x0;
+ } else {
+ major_version = ((BYTE*)*token_status)[0];
+ minor_version = ((BYTE*)*token_status)[1];
+ app_major_version = ((BYTE*)*token_status)[2];
+ app_minor_version = ((BYTE*)*token_status)[3];
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "Major=%d Minor=%d", major_version, minor_version);
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "Applet Major=%d Applet Minor=%d", app_major_version, app_minor_version);
+
+ if (!RA::ra_is_token_present(cuid)) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "CUID %s Not Present", cuid);
+ status = STATUS_ERROR_DB;
+ PR_snprintf(audit_msg, 512, "CUID Not Present, status = STATUS_ERROR_DB");
+ goto loser;
+ }
+
+ // retrieve CUID
+
+ if (!GetTokenType(OP_PREFIX, major_version,
+ minor_version, cuid, msn,
+ extensions, status, tokenType)) {
+ PR_snprintf(audit_msg, 512, "Failed to get token type");
+ goto loser;
+ }
+
+ // check if profile is enabled
+ PR_snprintf((char *)configname, 256, "config.Profiles.%s.state", tokenType);
+ profile_state = (char *) RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((profile_state != NULL) && (PL_strcmp(profile_state, "Enabled") != 0)) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Profile %s Disabled for CUID %s", tokenType, cuid);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "profile %s disabled", tokenType);
+ goto loser;
+ }
+
+ if (RA::ra_is_tus_db_entry_disabled(cuid)) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "CUID %s Disabled", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "Token disabled, status = STATUS_ERROR_DISABLED_TOKEN");
+ goto loser;
+ }
+
+ // we know cuid and msn here
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "token enabled");
+
+ if (!RA::ra_is_token_pin_resetable(cuid)) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "CUID %s Cannot Pin Reset", cuid);
+ status = STATUS_ERROR_NOT_PIN_RESETABLE;
+ PR_snprintf(audit_msg, 512, "token cannot pin reset, status = STATUS_ERROR_PIN_RESETABLE");
+ goto loser;
+ }
+
+ // we know cuid and msn here
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "pin reset allowed");
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn",
+ OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tksid == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "TKS Connection Parameter %s Not Found", configname);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "TKS Connection Parameter %s Not Found, status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND", configname);
+ goto loser;
+ }
+
+ buildID = GetAppletVersion(session);
+ if (buildID == NULL) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.emptyToken.enable", OP_PREFIX,
+ tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ appletVersion = PL_strdup( "unknown" );
+ } else {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "no applet found and applet upgrade not enabled");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "no applet found and applet upgrade not enabled, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ } else {
+ char * buildid = Util::Buffer2String(*buildID);
+ RA::Debug("RA_Pin_Reset_Processor", "buildid = %s", buildid);
+ char version[13];
+ PR_snprintf((char *) version, 13,
+ "%x.%x.%s", app_major_version, app_minor_version,
+ buildid);
+ appletVersion = strdup(version);
+ if (buildid != NULL) {
+ PR_Free(buildid);
+ buildid = NULL;
+ }
+ }
+
+ final_applet_version = strdup(appletVersion);
+ RA::Debug("RA_Pin_Reset_Processor", "final_applet_version = %s", final_applet_version);
+
+ /**
+ * Checks if we need to upgrade applet.
+ */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.requiredVersion", OP_PREFIX, tokenType);
+ required_version = RA::GetConfigStore()->GetConfigAsString(configname);
+ expected_version = PL_strdup(required_version);
+
+ if (expected_version == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "misconfiguration for upgrade");
+ status = STATUS_ERROR_MISCONFIGURATION;
+ PR_snprintf(audit_msg, 512, "misconfiguration for upgrade, status = STATUS_ERROR_MISCONFIGURATION");
+ goto loser;
+ }
+ /* Bugscape #55826: used case-insensitive check below */
+ if (PL_strcasecmp(expected_version, appletVersion) != 0) {
+ /* upgrade applet */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.directory", OP_PREFIX, tokenType);
+ applet_dir = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (applet_dir == NULL || strlen(applet_dir) == 0) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Failed to get %s", applet_dir);
+ PR_snprintf(audit_msg, 512, "Failed to get %s", applet_dir);
+ goto loser;
+ }
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.encryption", OP_PREFIX, tokenType);
+ upgrade_enc = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+ if (!upgrade_enc)
+ security_level = SECURE_MSG_MAC;
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ int upgrade_rc = UpgradeApplet(session, (char *) OP_PREFIX, (char*)tokenType, major_version, minor_version,
+ expected_version, applet_dir, security_level, connid, extensions, 30, 70, &keyVersion);
+ if (upgrade_rc != 1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "upgrade failure");
+ status = STATUS_ERROR_UPGRADE_APPLET;
+ /**
+ * Bugscape #55709: Re-select Net Key Applet ONLY on failure.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+
+ if (upgrade_rc == -1) {
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Failure", "pin_reset",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "failed to setup secure channel");
+ } else {
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "pin_reset",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel");
+ }
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Failure", "pin_reset",
+ keyVersion != NULL? keyVersion : "",
+ appletVersion, expected_version, "applet upgrade");
+ goto loser;
+ }
+
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "pin_reset",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel");
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "pin_reset",
+ keyVersion != NULL? keyVersion : "",
+ appletVersion, expected_version, "applet upgrade");
+
+ final_applet_version = expected_version;
+ }
+ }
+
+ /**
+ * Checks if the netkey has the required key version.
+ */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ int requiredVersion = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connId = RA::GetConfigStore()->GetConfigAsString(configname);
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ channel = SetupSecureChannel(session, requiredVersion,
+ 0x00 /* default key index */, connId);
+ if (channel == NULL) {
+
+ /* if version 0x02 key not found, create them */
+ SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ channel = SetupSecureChannel(session,
+ 0x00, /* default key version */
+ 0x00 /* default key index */, connId);
+
+ if (channel == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "setup secure channel failure");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "setup secure channel failure, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+
+ rc = channel->ExternalAuthenticate();
+ if (rc != 1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "External authentication in secure channel failed");
+ status = STATUS_ERROR_EXTERNAL_AUTH;
+ PR_snprintf(audit_msg, 512, "External authentication in secure channel failed, status = STATUS_ERROR_EXTERNAL_AUTH");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ int v = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ Buffer curKeyInfo = channel->GetKeyInfoData();
+ BYTE nv[2] = { v, 0x01 };
+ Buffer newVersion(nv, 2);
+ PR_snprintf((char *)configname, 256,"%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ rc = CreateKeySetData(
+ channel->GetKeyDiversificationData(),
+ curKeyInfo,
+ newVersion,
+ key_data_set, connid);
+ if (rc != 1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "failed to create new key set");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "failed to create new key set, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+
+ BYTE curVersion = ((BYTE*)curKeyInfo)[0];
+ BYTE curIndex = ((BYTE*)curKeyInfo)[1];
+ rc = channel->PutKeys(session,
+ curVersion,
+ curIndex,
+ &key_data_set);
+
+ curKeyInfoStr = Util::Buffer2String(curKeyInfo);
+ newVersionStr = Util::Buffer2String(newVersion);
+
+ if(curKeyInfoStr != NULL && strlen(curKeyInfoStr) >= 2) {
+ curVer[0] = curKeyInfoStr[0]; curVer[1] = curKeyInfoStr[1]; curVer[2] = 0;
+ }
+ else {
+ curVer[0] = 0;
+ }
+
+ if(newVersionStr != NULL && strlen(newVersionStr) >= 2) {
+ newVer[0] = newVersionStr[0] ; newVer[1] = newVersionStr[1] ; newVer[2] = 0;
+ }
+ else {
+ newVer[0] = 0;
+ }
+
+ if (rc!=0) {
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Failure", "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "", curVer, newVer,
+ "key changeover failed");
+ }
+
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connId = RA::GetConfigStore()->GetConfigAsString(configname);
+ channel = SetupSecureChannel(session,
+ RA::GetConfigStore()->GetConfigAsInt(configname, 0x00),
+ 0x00 /* default key index */, connId);
+ if (channel == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "setup secure channel failure");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "setup secure channel failure, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Success", "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "", curVer, newVer,
+ "key changeover");
+ key_change_over_success = 1;
+ } else { key_change_over_success = 1; }
+ } else {
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connId = RA::GetConfigStore()->GetConfigAsString(configname);
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ channel = SetupSecureChannel(session,
+ 0x00,
+ 0x00 /* default key index */, connId);
+ }
+
+ /* we should have a good channel here */
+ if (channel == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "no channel creation failure");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "no channel creation failure, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+ if (channel != NULL) {
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.loginRequest.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ if (extensions != NULL &&
+ extensions->GetValue("extendedLoginRequest") != NULL)
+ {
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected");
+ AuthenticationEntry *entry = GetAuthenticationEntry(
+ OP_PREFIX, configname, tokenType);
+ char **params = NULL;
+ char pb[1024];
+ char *locale = NULL;
+ if (extensions != NULL &&
+ extensions->GetValue("locale") != NULL)
+ {
+ locale = extensions->GetValue("locale");
+ } else {
+ locale = ( char * ) "en"; /* default to english */
+ }
+ int n = entry->GetAuthentication()->GetNumOfParamNames();
+ if (n > 0) {
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected n=%d", n);
+ params = (char **) PR_Malloc(n);
+ for (int i = 0; i < n; i++) {
+ sprintf(pb,"id=%s&name=%s&desc=%s&type=%s&option=%s",
+ entry->GetAuthentication()->GetParamID(i),
+ entry->GetAuthentication()->GetParamName(i, locale),
+ entry->GetAuthentication()->GetParamDescription(i,
+locale),
+ entry->GetAuthentication()->GetParamType(i),
+ entry->GetAuthentication()->GetParamOption(i)
+ );
+ params[i] = PL_strdup(pb);
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "params[i]=%s", params[i]);
+ }
+ }
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "Extended Login Request detected calling RequestExtendedLogin() locale=%s", locale);
+
+ char *title = PL_strdup(entry->GetAuthentication()->GetTitle(locale));
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "title=%s", title);
+ char *description = PL_strdup(entry->GetAuthentication()->GetDescription(locale));
+ RA::Debug("RA_Enroll_Processor::RequestUserId", "description=%s", description);
+ login = RequestExtendedLogin(session, 0 /* invalid_pw */, 0 /* blocked */, params, n, title, description);
+
+ RA::Debug("RA_Enroll_Processor::RequestUserId",
+ "Extended Login Request detected calling RequestExtendedLogin() login=%x", login);
+
+ if (params != NULL) {
+ for (int nn=0; nn < n; nn++) {
+ if (params[nn] != NULL) {
+ PL_strfree(params[nn]);
+ params[nn] = NULL;
+ }
+ }
+ free(params);
+ params = NULL;
+ }
+
+ if (title != NULL) {
+ PL_strfree(title);
+ title = NULL;
+ }
+
+ if (description != NULL) {
+ PL_strfree(description);
+ description = NULL;
+ }
+
+ } else {
+ login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */);
+ }
+ if (login == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "login not provided");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "login not provided, status = STATUS_ERROR_LOGIN");
+
+ goto loser;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ userid = PL_strdup( login->GetUID() );
+ }
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 30 /* progress */,
+ "PROGRESS_START_AUTHENTICATION");
+ }
+
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "userid obtained");
+
+ PR_snprintf(configname, 256, "cn=%s", cuid);
+ rc = RA::ra_find_tus_token_entries(configname, maxReturns, &ldapResult, 0);
+
+ if (rc == 0) {
+ for (e = RA::ra_get_first_entry(ldapResult); e != NULL;
+ e = RA::ra_get_next_entry(e)) {
+ tokenOwner = RA::ra_get_attribute_values(e, "tokenUserID");
+ if ((tokenOwner != NULL) && (tokenOwner[0] != NULL) &&
+ (tokenOwner[0]->bv_val != NULL) && (strlen(tokenOwner[0]->bv_val) > 0) &&
+ (strcmp(userid, tokenOwner[0]->bv_val) != 0)) {
+ status = STATUS_ERROR_NOT_TOKEN_OWNER;
+ PR_snprintf(audit_msg, 512, "token owner mismatch, status = STATUS_ERROR_NOT_TOKEN_OWNER");
+ goto loser;
+ }
+ }
+ } else {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Error in ldap connection with token database.");
+ status = STATUS_ERROR_LDAP_CONN;
+ PR_snprintf(audit_msg, 512, "Error in ldap connection with token database, status = STATUS_ERROR_LDAP_CONN");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, false)) {
+ if (login == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Login Request Disabled. Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "Login Request Disabled. status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, tokenType);
+ authid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (authid == NULL) {
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "authid is null, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ AuthenticationEntry *auth = RA::GetAuth(authid);
+
+ if(auth == NULL)
+ {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Authentication manager is NULL . Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "Authentication manager is NULL, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ char *type = auth->GetType();
+ if (type == NULL) {
+ status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "authentication is missing param type", "", tokenType);
+ PR_snprintf(audit_msg, 512, "authentication is missing param type, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ if (strcmp(type, "LDAP_Authentication") == 0) {
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "LDAP_Authentication is invoked.");
+ int passwd_retries = auth->GetAuthentication()->GetNumOfRetries();
+ int retries = 0;
+ authParams = new AuthParams();
+ authParams->SetUID(login->GetUID());
+ authParams->SetPassword(login->GetPassword());
+ rc = auth->GetAuthentication()->Authenticate(authParams);
+
+ RA::Debug("RA_Pin_Reset_Processor::Process",
+ "Authenticate returns: %d", rc);
+
+ while ((rc == -2 || rc == -3) && (retries < passwd_retries)) {
+ login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */);
+ if (login == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Login Request Disabled. Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "Login Request Disabled, r=-2 or -3. status= STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ retries++;
+ authParams->SetUID(login->GetUID());
+ authParams->SetPassword(login->GetPassword());
+ rc = auth->GetAuthentication()->Authenticate(authParams);
+ }
+
+ if (rc == -1) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LDAP_CONN;
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication status = %d", status);
+ PR_snprintf(audit_msg, 512, "authentication failed, rc=-1, status = STATUS_ERROR_LDAP_CONN");
+ goto loser;
+ }
+
+ if (rc == -2 || rc == -3) {
+ RA::Error("RA_Pin_Reset_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication status = %d", status);
+ PR_snprintf(audit_msg, 512, "authentication failed, rc=-2 or rc=-3, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication successful.");
+ } else {
+ RA::Error("RA_Pin_Reset_Processor::Process", "No Authentication type was found.");
+ status = STATUS_ERROR_LOGIN;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "authentication error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "No Authentication type was found. status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "Authentication has been disabled.");
+ }
+
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "authentication successful");
+
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "SetupSecureChannel");
+
+#if 0
+ if (RA::GetConfigStore()->GetConfigAsBool("tus.enable", 0)) {
+ if (IsTokenDisabledByTus(channel)) {
+ status = STATUS_ERROR_TOKEN_DISABLED;
+ goto loser;
+ }
+ }
+#endif
+
+ /* check if the user owns the token */
+ token_userid = RA::ra_get_token_userid(cuid);
+ if (token_userid == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "No user owns the token '%s'", cuid);
+ status = STATUS_ERROR_TOKEN_DISABLED;
+ PR_snprintf(audit_msg, 512, "No user owns the token, status = STATUS_ERROR_TOKEN_DISABLED");
+ goto loser;
+ } else {
+ if (strcmp(token_userid, userid) != 0) {
+ RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "User does not own the token '%s'", cuid);
+ status = STATUS_ERROR_TOKEN_DISABLED;
+ PR_snprintf(audit_msg, 512, "User does not own the token. status = STATUS_ERROR_TOKEN_DISABLED");
+ goto loser;
+ }
+ }
+
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "login successful");
+
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "ExternalAuthenticate");
+ rc = channel->ExternalAuthenticate();
+ if (rc == -1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "External Authenticate failed.");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "external authentication error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "External Authenticate failed, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+ RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "RequestNewPin");
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.minLen", OP_PREFIX, tokenType);
+ minlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 4);
+ PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.maxLen", OP_PREFIX, tokenType);
+ maxlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 10);
+ new_pin = RequestNewPin(session, minlen, maxlen);
+ if (new_pin == NULL) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "Set Pin failed.");
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "request new pin error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "RequestNewPin failed, status = STATUS_ERROR_MAC_RESET_PIN_PDU");
+ goto loser;
+ }
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 70 /* progress */,
+ "PROGRESS_PIN_RESET");
+ }
+
+ rc = channel->ResetPin(0x0, new_pin);
+ if (rc == -1) {
+ status = STATUS_ERROR_MAC_RESET_PIN_PDU;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "ereset pin error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "ResetPin failed, status = STATUS_ERROR_MAC_RESET_PIN_PDU");
+ goto loser;
+ }
+
+ rc = channel->Close();
+ if (rc == -1) {
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "Failed to close channel");
+ status = STATUS_ERROR_CONNECTION;
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "secure channel close error", "", tokenType);
+ PR_snprintf(audit_msg, 512, "Failed to close channel, status = STATUS_ERROR_CONNECTION");
+ goto loser;
+ }
+
+
+ //Update the KeyInfo in case of successful key changeover
+ if (key_change_over_success != 0) {
+ RA::tdb_update( userid != NULL ? userid : (char *) "",
+ cuid != NULL ? cuid : (char *) "" ,
+ final_applet_version != NULL ? (char *) final_applet_version : (char *) "" ,
+ keyVersion != NULL ? keyVersion : (char *) "","active", "",
+ tokenType != NULL ? tokenType : (char *) "");
+ }
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "ResetPin successful");
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 100 /* progress */,
+ "PROGRESS_DONE");
+ }
+
+ end = PR_IntervalNow();
+
+ rc = 1;
+
+ if (RA::ra_is_token_present(cuid)) {
+ /*
+ * we want to have a tus policy to change PIN_RESET=YES
+ * parameter to PIN_RESET=NO
+ */
+ if (RA::ra_is_token_pin_resetable(cuid)) {
+ policy = RA::ra_get_token_policy(cuid);
+ RA::Error("RA_Pin_Reset_Processor::Process",
+ "Policy %s is %s", cuid, policy);
+ tmp_policy = PL_strstr(policy, "PIN_RESET=YES");
+ if (tmp_policy != NULL) {
+ tmp_policy[10] = 'N';
+ tmp_policy[11] = 'O';
+ for (i = 12; tmp_policy[i] != '\0'; i++)
+ tmp_policy[i] = tmp_policy[i+1];
+ rc = RA::ra_update_token_policy(cuid, policy);
+ if (rc != 0) {
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "failed to reset token policy");
+ }
+ }
+ }
+ }
+
+ sprintf(activity_msg, "applet_version=%s tokenType=%s",
+ (char *)final_applet_version, tokenType);
+ RA::tdb_activity(session->GetRemoteIP(), (char *)cuid, "pin reset", "success", activity_msg, userid, tokenType);
+
+ /* audit log for successful pin reset */
+ if (authid != NULL) {
+ sprintf(activity_msg, "pin_reset processing completed, authid = %s", authid);
+ } else {
+ sprintf(activity_msg, "pin_reset processing completed");
+ }
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid, cuid, msn, "success", "pin_reset", final_applet_version, keyVersion!=NULL? keyVersion: "", activity_msg);
+
+loser:
+ if (strlen(audit_msg) > 0) {
+ RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "pin_reset",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ cuid,
+ "pin_reset",
+ "failure",
+ audit_msg,
+ userid != NULL ? userid : "",
+ tokenType);
+ }
+ }
+
+ if (curKeyInfoStr != NULL) {
+ PR_Free( (char *) curKeyInfoStr);
+ curKeyInfoStr = NULL;
+ }
+
+ if (newVersionStr != NULL) {
+ PR_Free( (char *) newVersionStr);
+ newVersionStr = NULL;
+ }
+
+ if( token_status != NULL ) {
+ delete token_status;
+ token_status = NULL;
+ }
+ if( CardManagerAID != NULL ) {
+ delete CardManagerAID;
+ CardManagerAID = NULL;
+ }
+ if( NetKeyAID != NULL ) {
+ delete NetKeyAID;
+ NetKeyAID = NULL;
+ }
+ if( login != NULL ) {
+ delete login;
+ login = NULL;
+ }
+ if( new_pin != NULL ) {
+ PL_strfree( new_pin );
+ new_pin = NULL;
+ }
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ if( cuid != NULL ) {
+ PR_Free( (char *) cuid );
+ cuid = NULL;
+ }
+ if( msn != NULL ) {
+ PR_Free( (char *) msn );
+ msn = NULL;
+ }
+ if( buildID != NULL ) {
+ delete buildID;
+ buildID = NULL;
+ }
+ if( appletVersion != NULL ) {
+ PR_Free( (char *) appletVersion );
+ appletVersion = NULL;
+ }
+ if( final_applet_version != NULL ) {
+ PR_Free( (char *) final_applet_version );
+ final_applet_version = NULL;
+ }
+ if( keyVersion != NULL ) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ if( authParams != NULL ) {
+ delete authParams;
+ authParams = NULL;
+ }
+ if( cplc_data != NULL ) {
+ delete cplc_data;
+ cplc_data = NULL;
+ }
+
+ if (tokenOwner != NULL) {
+ ldap_value_free_len(tokenOwner);
+ tokenOwner = NULL;
+ }
+
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ ldapResult = NULL;
+ }
+
+#ifdef MEM_PROFILING
+ MEM_dump_unfree();
+#endif
+
+ return status;
+} /* Process */
diff --git a/base/tps/src/processor/RA_Processor.cpp b/base/tps/src/processor/RA_Processor.cpp
new file mode 100644
index 000000000..a9947555b
--- /dev/null
+++ b/base/tps/src/processor/RA_Processor.cpp
@@ -0,0 +1,3506 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "plstr.h"
+#include "engine/RA.h"
+#include "main/Buffer.h"
+#include "main/Base.h"
+#include "main/Util.h"
+#include "main/RA_Session.h"
+#include "main/RA_Msg.h"
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/Util.h"
+#include "httpClient/httpc/http.h"
+#include "httpClient/httpc/request.h"
+#include "httpClient/httpc/response.h"
+#include "httpClient/httpc/engine.h"
+#include "processor/RA_Processor.h"
+#include "cms/HttpConnection.h"
+#include "cms/CertEnroll.h"
+#include "msg/RA_Status_Update_Request_Msg.h"
+#include "msg/RA_Status_Update_Response_Msg.h"
+#include "msg/RA_Login_Request_Msg.h"
+#include "msg/RA_Login_Response_Msg.h"
+#include "msg/RA_Extended_Login_Request_Msg.h"
+#include "msg/RA_Extended_Login_Response_Msg.h"
+#include "msg/RA_ASQ_Request_Msg.h"
+#include "msg/RA_ASQ_Response_Msg.h"
+#include "msg/RA_New_Pin_Request_Msg.h"
+#include "msg/RA_New_Pin_Response_Msg.h"
+#include "msg/RA_SecureId_Request_Msg.h"
+#include "msg/RA_SecureId_Response_Msg.h"
+#include "msg/RA_Token_PDU_Request_Msg.h"
+#include "msg/RA_Token_PDU_Response_Msg.h"
+#include "apdu/Lifecycle_APDU.h"
+#include "apdu/Format_Muscle_Applet_APDU.h"
+#include "apdu/Initialize_Update_APDU.h"
+#include "apdu/Get_Version_APDU.h"
+#include "apdu/External_Authenticate_APDU.h"
+#include "apdu/Create_Object_APDU.h"
+#include "apdu/Get_Status_APDU.h"
+#include "apdu/Get_Data_APDU.h"
+#include "apdu/Set_Pin_APDU.h"
+#include "apdu/Read_Buffer_APDU.h"
+#include "apdu/Write_Object_APDU.h"
+#include "apdu/List_Objects_APDU.h"
+#include "apdu/Generate_Key_APDU.h"
+#include "apdu/List_Pins_APDU.h"
+#include "apdu/Create_Pin_APDU.h"
+#include "apdu/Put_Key_APDU.h"
+#include "apdu/Select_APDU.h"
+#include "apdu/APDU_Response.h"
+#include "channel/Secure_Channel.h"
+#include "main/Memory.h"
+
+#if 0
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "tus/tus_db.h"
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/**
+ * Constructs a base processor.
+ */
+RA_Processor::RA_Processor ()
+{
+ totalAvailableMemory = 0;
+ totalFreeMemory = 0;
+}
+
+
+/**
+ * Destructs processor.
+ */
+RA_Processor::~RA_Processor ()
+{
+}
+
+AuthenticationEntry *RA_Processor::GetAuthenticationEntry(
+ const char *prefix, const char * a_configname, const char *a_tokenType)
+{
+ AuthenticationEntry *auth = NULL;
+
+ if (!RA::GetConfigStore()->GetConfigAsBool(a_configname, false))
+ return NULL;
+
+ RA::Debug("RA_Enroll_Processor::AuthenticateUser",
+ "Authentication enabled");
+ char configname[256];
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", prefix, a_tokenType);
+ const char *authid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (authid == NULL) {
+ goto loser;
+ }
+ auth = RA::GetAuth(authid);
+ return auth;
+loser:
+ return NULL;
+}
+
+
+void RA_Processor::StatusUpdate(RA_Session *a_session,
+ NameValueSet *a_extensions,
+ int a_status, const char *a_info)
+{
+ if (a_extensions != NULL) {
+ if (a_extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(a_session, a_status, a_info);
+ }
+ }
+}
+
+void RA_Processor::StatusUpdate(RA_Session *session,
+ int status, const char *info)
+{
+ RA_Status_Update_Request_Msg *status_update_request_msg = NULL;
+ RA_Status_Update_Response_Msg *status_update_response_msg = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::StatusUpdate",
+ "RA_Processor::StatusUpdate");
+
+ status_update_request_msg = new RA_Status_Update_Request_Msg(
+ status, info);
+ session->WriteMsg(status_update_request_msg);
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::StatusUpdate",
+ "Sent status_update_msg");
+
+ status_update_response_msg = (RA_Status_Update_Response_Msg *)
+ session->ReadMsg();
+ if (status_update_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::StatusUpdate",
+ "No Status Update Response Msg Received");
+ goto loser;
+ }
+ if (status_update_response_msg->GetType() != MSG_STATUS_UPDATE_RESPONSE) {
+ RA::Error("Secure_Channel::StatusUpdate",
+ "Invalid Msg Type");
+ goto loser;
+ }
+
+loser:
+ if( status_update_request_msg != NULL ) {
+ delete status_update_request_msg;
+ status_update_request_msg = NULL;
+ }
+ if( status_update_response_msg != NULL ) {
+ delete status_update_response_msg;
+ status_update_response_msg = NULL;
+ }
+
+} /* StatusUpdate */
+
+/**
+ * Requests login ID and password from user.
+ */
+AuthParams *RA_Processor::RequestExtendedLogin(RA_Session *session,
+ int invalid_pw, int blocked,
+ char **parameters, int len, char *title, char *description)
+{
+ RA_Extended_Login_Request_Msg *login_request_msg = NULL;
+ RA_Extended_Login_Response_Msg *login_response_msg = NULL;
+ AuthParams *login = NULL;
+ AuthParams *c = NULL;
+ int i = 0;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::RequestExtendedLogin",
+ "RA_Processor::RequestExtendedLogin %s %s",
+ title, description);
+
+ login_request_msg = new RA_Extended_Login_Request_Msg(
+ invalid_pw, blocked, parameters, len, title, description);
+ session->WriteMsg(login_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::RequestExtendedLogin",
+ "Sent login_request_msg");
+
+ login_response_msg = (RA_Extended_Login_Response_Msg *)
+ session->ReadMsg();
+ if (login_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::RequestExtendedLogin",
+ "No Extended Login Response Msg Received");
+ goto loser;
+ }
+ if (login_response_msg->GetType() != MSG_EXTENDED_LOGIN_RESPONSE) {
+ RA::Error("Secure_Channel::Login_Request",
+ "Invalid Msg Type");
+ goto loser;
+ }
+
+ login = new AuthParams();
+ c = login_response_msg->GetAuthParams();
+ for (i = 0; i < c->Size(); i++) {
+ login->Add(c->GetNameAt(i), c->GetValue(c->GetNameAt(i)));
+ }
+
+loser:
+ if( login_request_msg != NULL ) {
+ delete login_request_msg;
+ login_request_msg = NULL;
+ }
+ if( login_response_msg != NULL ) {
+ delete login_response_msg;
+ login_response_msg = NULL;
+ }
+
+ return login;
+} /* RequestExtendedLogin */
+
+/**
+ * Requests login ID and password from user.
+ */
+AuthParams *RA_Processor::RequestLogin(RA_Session *session,
+ int invalid_pw, int blocked)
+{
+ RA_Login_Request_Msg *login_request_msg = NULL;
+ RA_Login_Response_Msg *login_response_msg = NULL;
+ AuthParams *login = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Login_Request",
+ "RA_Processor::Login_Request");
+
+ login_request_msg = new RA_Login_Request_Msg(
+ invalid_pw, blocked);
+ session->WriteMsg(login_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::Login_Request",
+ "Sent login_request_msg");
+
+ login_response_msg = (RA_Login_Response_Msg *)
+ session->ReadMsg();
+ if (login_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::Login_Request",
+ "No Login Response Msg Received");
+ goto loser;
+ }
+ if (login_response_msg->GetType() != MSG_LOGIN_RESPONSE) {
+ RA::Error("Secure_Channel::Login_Request",
+ "Invalid Msg Type");
+ goto loser;
+ }
+ login = new AuthParams();
+ login->Add("UID", login_response_msg->GetUID());
+ login->Add("PASSWORD", login_response_msg->GetPassword());
+
+loser:
+ if( login_request_msg != NULL ) {
+ delete login_request_msg;
+ login_request_msg = NULL;
+ }
+ if( login_response_msg != NULL ) {
+ delete login_response_msg;
+ login_response_msg = NULL;
+ }
+
+ return login;
+} /* RequestLogin */
+
+/**
+ * Upgrade the applet to the current session with the new version.
+ */
+int RA_Processor::UpgradeApplet(RA_Session *session, char *prefix, char *tokenType, BYTE major_version, BYTE minor_version, const char *new_version, const char *applet_dir, SecurityLevel security_level, const char *connid,
+ NameValueSet *extensions,
+ int start_progress,
+ int end_progress,
+ char **key_version)
+{
+ Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_INSTANCE_AID);
+ Buffer *OldAAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_OLD_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_OLD_INSTANCE_AID);
+ Buffer *OldPAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_OLD_FILE_AID,
+ RA::CFG_DEF_NETKEY_OLD_FILE_AID);
+ Buffer *NetKeyPAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_FILE_AID,
+ RA::CFG_DEF_NETKEY_FILE_AID);
+ Buffer *PIN = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_SO_PIN,
+ RA::CFG_DEF_APPLET_SO_PIN);
+ Buffer empty;
+ PRFileDesc *f = NULL;
+ char path[4096];
+ char configname[4096];
+ PRFileInfo info;
+ PRStatus status;
+ int rc = 0;
+ Secure_Channel *channel = NULL;
+ int size_to_send = 0;
+ char *dataf = NULL;
+ int block_size;
+ BYTE refControl;
+ int count;
+ Buffer programFile;
+ Buffer tag;
+ Buffer length;
+ Buffer tbsProgramFile;
+ unsigned int totalLen;
+ int num_loops;
+ float progress_block_size;
+ int x_blocksize;
+ int instance_size;
+ int applet_memory_size;
+ int defKeyVer;
+ int defKeyIndex;
+ char *ext;
+
+ if (applet_dir == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Failed to get upgrade.directory");
+ goto loser;
+ }
+ sprintf(configname, "general.applet_ext");
+ ext = (char*)RA::GetConfigStore()->GetConfigAsString(configname, "ijc");
+ sprintf(path, "%s/%s.%s", applet_dir, new_version, ext);
+ RA::Debug("RA_Processor::UpgradeApplet", "path = %s", path);
+ status = PR_GetFileInfo(path, &info);
+ if (status != PR_SUCCESS) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Failed to get file info");
+ goto loser;
+ }
+ f = PR_Open(path, PR_RDONLY, 400);
+ if (f == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Failed to open '%s'", path);
+ goto loser;
+ }
+ dataf = (char *)malloc(info.size);
+ PR_Read(f, dataf, info.size);
+ if( f != NULL ) {
+ PR_Close( f );
+ f = NULL;
+ }
+
+ /* Select Applet - Select Card manager */
+ SelectCardManager(session, prefix, tokenType);
+
+ PR_snprintf((char *)configname, 256,"channel.blockSize");
+ x_blocksize = RA::GetConfigStore()->GetConfigAsInt(configname, 0xf8);
+ PR_snprintf((char *)configname, 256,"channel.instanceSize");
+ instance_size = RA::GetConfigStore()->GetConfigAsInt(configname, 18000);
+
+ PR_snprintf((char *)configname, 256,"channel.appletMemorySize");
+
+ applet_memory_size = RA::GetConfigStore()->GetConfigAsInt(configname, 5000);
+
+ PR_snprintf((char *)configname, 256,"channel.defKeyVersion");
+ defKeyVer = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ channel = SetupSecureChannel(session, defKeyVer, defKeyIndex, security_level, connid);
+ if (channel == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "channel creation failure");
+ rc = -1;
+ goto loser;
+ }
+
+ // get keyVersion
+ if (channel != NULL) {
+ *key_version = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ if (channel->ExternalAuthenticate() == -1) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "failed to external authenticate during upgrade");
+ goto loser;
+ }
+
+ /* Delete File - Delete 627601ff000000 (CoolKey Instance) */
+ rc = channel->DeleteFileX(session, NetKeyAID);
+ if (rc != 1) {
+ /* it is ok to fail to delete file */
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Warning: failed to delete file", NetKeyAID);
+ }
+
+ if (RA::GetConfigStore()->GetConfigAsBool(RA::CFG_APPLET_DELETE_NETKEY_OLD, true)) {
+ /* Delete File - Delete a00000000101 */
+ rc = channel->DeleteFileX(session, OldAAID);
+ if (rc != 1) {
+ /* it is ok to fail to delete file */
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Warning: failed to delete file", OldAAID);
+ }
+ /* Delete File - Delete a000000001 */
+ rc = channel->DeleteFileX(session, OldPAID);
+ if (rc != 1) {
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::UpgradeApplet",
+ "Warning: failed to delete file", OldPAID);
+ }
+ }
+
+ /* Delete File - Delete 627601ff0000 */
+ channel->DeleteFileX(session, NetKeyPAID);
+
+ /* Install Applet - Install applet instance */
+ channel->InstallLoad(session,
+ *NetKeyPAID,
+ empty,
+ info.size);
+
+ /* Multiple Load Program File - Load 627601ff0000 */
+ programFile = Buffer ((BYTE *)dataf, info.size);
+ if( dataf != NULL ) {
+ free( dataf );
+ dataf = NULL;
+ }
+ tag = Buffer(1, 0xC4);
+ tbsProgramFile = tag + length + programFile;
+ totalLen = tbsProgramFile.size();
+ if( programFile.size() < 128 ) {
+ length = Buffer(1, programFile.size());
+ } else if( programFile.size() <= 255 ) {
+ length = Buffer(2, 0);
+ ((BYTE*)length)[0] = 0x81;
+ ((BYTE*)length)[1] = programFile.size();
+ } else {
+ length = Buffer(3, 0);
+ ((BYTE*)length)[0] = 0x82;
+ ((BYTE*)length)[1] = (programFile.size() >> 8) & 0xff;
+ ((BYTE*)length)[2] = programFile.size() & 0xff;
+ }
+ tbsProgramFile = tag + length + programFile;
+ totalLen = tbsProgramFile.size();
+
+ size_to_send = totalLen;
+ if (security_level == SECURE_MSG_MAC_ENC) {
+ // need leave room for possible encryption padding
+ block_size = x_blocksize - 0x10;
+ } else {
+ block_size = x_blocksize - 8;
+ }
+
+ // rough number is good enough
+ num_loops = size_to_send / block_size;
+ progress_block_size = (float) (end_progress - start_progress) / num_loops;
+
+ count = 0;
+ refControl = 0x00; // intermediate block
+ do {
+ if (size_to_send < block_size) {
+ block_size = size_to_send;
+ // last block
+ refControl = 0x80;
+ }
+ if (size_to_send - block_size == 0) {
+ // last block
+ refControl = 0x80;
+ }
+ Buffer d = tbsProgramFile.substr(totalLen - size_to_send, block_size);
+ channel->LoadFile(session, (BYTE)refControl, (BYTE)count, &d);
+
+ size_to_send -= block_size;
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session,
+ start_progress + (count * progress_block_size) /* progress */,
+ "PROGRESS_APPLET_BLOCK");
+ }
+ count++;
+ } while (size_to_send > 0);
+
+
+ /* Install Applet - Install applet instance */
+ channel->InstallApplet(session,
+ *NetKeyPAID,
+ *NetKeyAID,
+ 0 /* appPrivileges */,
+ instance_size /* instanceSize */,
+ applet_memory_size /* appletMemorySize */);
+
+ /* Select File - Select 627601ff000000 */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+
+ rc = 1;
+loser:
+ if( NetKeyAID != NULL ) {
+ delete NetKeyAID;
+ NetKeyAID = NULL;
+ }
+ if( OldAAID != NULL ) {
+ delete OldAAID;
+ OldAAID = NULL;
+ }
+ if( OldPAID != NULL ) {
+ delete OldPAID;
+ OldPAID = NULL;
+ }
+ if( NetKeyPAID != NULL ) {
+ delete NetKeyPAID;
+ NetKeyPAID = NULL;
+ }
+ if( PIN != NULL ) {
+ delete PIN;
+ PIN = NULL;
+ }
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ if( dataf != NULL ) {
+ free( dataf );
+ dataf = NULL;
+ }
+
+ return rc;
+}
+
+char *RA_Processor::MapPattern(NameValueSet *nv, char *pattern)
+{
+ int i=0,x=0,j=0,z=0;
+ unsigned int q = 0;
+ char token[4096];
+ char result[4096];
+ char *value;
+
+ if (pattern == NULL)
+ return NULL;
+ i = strlen(pattern);
+ for (x = 0; x < i; x++) {
+ if (pattern[x] == '$') {
+ if (pattern[x+1] == '$') {
+ result[z] = pattern[x];
+ z++;
+ x++;
+ } else {
+ x++;
+ j = 0;
+ while (pattern[x] != '$') {
+ token[j] = pattern[x];
+ j++;
+ x++;
+ }
+ token[j] = '\0';
+ value = nv->GetValue(token);
+ if (value != NULL) {
+ for (q = 0; q < strlen(value); q++) {
+ result[z] = value[q];
+ z++;
+ }
+
+ }
+ }
+ } else {
+ result[z] = pattern[x];
+ z++;
+ }
+ }
+ result[z] = '\0';
+
+ return PL_strdup(result);
+}
+
+int RA_Processor::FormatMuscleApplet(RA_Session *session,
+ unsigned short memSize,
+ Buffer &PIN0, BYTE pin0Tries,
+ Buffer &unblockPIN0, BYTE unblock0Tries,
+ Buffer &PIN1, BYTE pin1Tries,
+ Buffer &unblockPIN1, BYTE unblock1Tries,
+ unsigned short objCreationPermissions,
+ unsigned short keyCreationPermissions,
+ unsigned short pinCreationPermissions)
+{
+ int rc = 0;
+ APDU_Response *format_response = NULL;
+ RA_Token_PDU_Request_Msg *format_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *format_response_msg = NULL;
+ Format_Muscle_Applet_APDU *format_apdu = NULL;
+ // Buffer *mac = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "RA_Processor::FormatMuscle");
+
+ format_apdu = new Format_Muscle_Applet_APDU(memSize, PIN0, pin0Tries,
+ unblockPIN0, unblock0Tries,
+ PIN1, pin1Tries,
+ unblockPIN1, unblock1Tries,
+ objCreationPermissions,
+ keyCreationPermissions,
+ pinCreationPermissions);
+ format_request_msg =
+ new RA_Token_PDU_Request_Msg(format_apdu);
+ session->WriteMsg(format_request_msg);
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "Sent format_request_msg");
+
+ format_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (format_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (format_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "Invalid Message Type");
+ goto loser;
+ }
+ format_response = format_response_msg->GetResponse();
+ if (!(format_response->GetSW1() == 0x90 &&
+ format_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::FormatMuscle",
+ "Bad Response");
+ goto loser;
+ }
+ rc = 1;
+
+loser:
+ if( format_request_msg != NULL ) {
+ delete format_request_msg;
+ format_request_msg = NULL;
+ }
+ if( format_response_msg != NULL ) {
+ delete format_response_msg;
+ format_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Determine the Token Type. The user can set up mapping rules in the
+ * config file which allow different operations depending on the
+ * CUID, applet version, ATR, etc.
+ */
+bool RA_Processor::GetTokenType(const char *prefix, int major_version, int minor_version, const char *cuid, const char *msn, NameValueSet *extensions,
+ RA_Status &o_status /* out */, const char *&o_tokenType /* out */)
+{
+ const char *e_tokenATR = NULL;
+ const char *tokenATR = NULL;
+ const char *e_tokenType = NULL;
+ const char *tokenType = NULL;
+ const char *tokenCUIDStart = NULL;
+ const char *tokenCUIDEnd = NULL;
+ const char *targetTokenType = NULL;
+ const char *majorVersion = NULL;
+ const char *minorVersion = NULL;
+ const char *order = NULL;
+ char *order_x = NULL;
+ const char *mappingId = NULL;
+ char configname[256];
+ int start_pos = 0, done = 0;
+ unsigned int end_pos = 0;
+ const char *cuid_x = NULL;
+ int rc=0;
+
+ cuid_x = cuid;
+
+ sprintf(configname, "%s.mapping.order", prefix);
+ order = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (order == NULL) {
+ RA::Error("RA_Processor::GetTokenType", "Token type is not found");
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "cannot find config ", configname);
+ return false; /* no mapping found */
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Starting:");
+ order_x = PL_strdup(order);
+
+ start_pos = 0;
+ end_pos = 0;
+ done = 0;
+ while (1)
+ {
+ if (done) {
+ break;
+ }
+ end_pos = start_pos;
+ while ((end_pos < strlen(order)) && (order_x[end_pos] != ',')) {
+ end_pos++;
+ }
+ if (end_pos < strlen(order)) {
+ order_x[end_pos] = '\0';
+ done = 0;
+ } else {
+ done = 1;
+ }
+ mappingId = &order_x[start_pos];
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "mappingId='%s'", mappingId);
+
+ start_pos = end_pos + 1;
+
+ sprintf(configname, "%s.mapping.%s.target.tokenType", prefix,
+ mappingId);
+ targetTokenType = RA::GetConfigStore()->GetConfigAsString(configname);
+
+
+ if (targetTokenType == NULL) {
+ break;
+ }
+ sprintf(configname, "%s.mapping.%s.filter.tokenType", prefix,
+ mappingId);
+ tokenType = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "tokenType: %s",tokenType);
+
+ if (tokenType != NULL && strlen(tokenType) > 0) {
+ if (extensions == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ e_tokenType = extensions->GetValue("tokenType");
+ if (e_tokenType == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ if (strcmp(tokenType, e_tokenType) != 0) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.tokenATR", prefix,
+ mappingId);
+ tokenATR = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tokenATR != NULL && strlen(tokenATR) > 0) {
+ if (extensions == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ e_tokenATR = extensions->GetValue("tokenATR");
+ if (e_tokenATR == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ if (strcmp(tokenATR, e_tokenATR) != 0) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.tokenCUID.start", prefix,
+ mappingId);
+ tokenCUIDStart = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tokenCUIDStart != NULL && strlen(tokenCUIDStart) > 0) {
+ if (cuid_x == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "cuid_x=%s tokenCUIDStart=%s %d", cuid_x, tokenCUIDStart,
+ PL_strcasecmp(cuid_x, tokenCUIDStart));
+
+ if(strlen(tokenCUIDStart) != 20)
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Invalid tokenCUIDStart: %s",tokenCUIDStart);
+ continue;
+ }
+
+ char *pend = NULL;
+ rc = strtol((const char *) tokenCUIDStart, &pend, 16);
+
+ if(*pend != '\0')
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Invalid tokenCUIDStart: %s",tokenCUIDStart);
+
+ continue;
+ }
+
+ if (PL_strcasecmp(cuid_x, tokenCUIDStart) < 0) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.tokenCUID.end", prefix,
+ mappingId);
+ tokenCUIDEnd = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tokenCUIDEnd != NULL && strlen(tokenCUIDEnd) > 0) {
+ if (cuid_x == NULL) {
+ continue; /* mapping not matched, next mapping */
+ }
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "cuid_x=%s tokenCUIDEnd=%s %d", cuid_x, tokenCUIDEnd,
+ PL_strcasecmp(cuid_x, tokenCUIDEnd));
+
+ if(strlen(tokenCUIDEnd) != 20)
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Invalid tokenCUIDEnd: %s",tokenCUIDEnd);
+ continue;
+ }
+
+ char *pend = NULL;
+ rc = strtol((const char *) tokenCUIDEnd, &pend, 16);
+
+ if(*pend != '\0')
+ {
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetTokenType",
+ "Invalid tokenCUIDEnd: %s",tokenCUIDEnd);
+
+ continue;
+ }
+
+ if (PL_strcasecmp(cuid_x, tokenCUIDEnd) > 0) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.appletMajorVersion",
+ prefix, mappingId);
+ majorVersion = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (majorVersion != NULL && strlen(majorVersion) > 0) {
+ if (major_version != atoi(majorVersion)) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+ sprintf(configname, "%s.mapping.%s.filter.appletMinorVersion",
+ prefix, mappingId);
+ minorVersion = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (minorVersion != NULL && strlen(minorVersion) > 0) {
+ if (minor_version != atoi(minorVersion)) {
+ continue; /* mapping not matched, next mapping */
+ }
+ }
+
+ if( order_x != NULL ) {
+ PL_strfree( order_x );
+ order_x = NULL;
+ }
+ RA::Debug("RA_Processor::GetTokenType",
+ "Selected Token type is '%s'", targetTokenType);
+ o_tokenType = targetTokenType;
+ return true;
+ }
+
+
+ if( order_x != NULL ) {
+ PL_strfree( order_x );
+ order_x = NULL;
+ }
+ RA::Error("RA_Processor::GetTokenType", "Token type is not found");
+ o_status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+
+ return false;
+}
+
+int RA_Processor::SelectCardManager(RA_Session *session, char *prefix, char *tokenType)
+{
+ char configname[256];
+ int rc;
+ PR_snprintf((char *)configname, 256, "%s.%s.cardmgr_instance", prefix, tokenType);
+ const char *cardmgr_instance =
+ RA::GetConfigStore()->GetConfigAsString(configname);
+ Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ cardmgr_instance, RA::CFG_DEF_CARDMGR_INSTANCE_AID);
+ rc = SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ if( CardManagerAID != NULL ) {
+ delete CardManagerAID;
+ CardManagerAID = NULL;
+ }
+ return rc;
+}
+
+/**
+ * GetData
+ */
+Buffer *RA_Processor::GetData(RA_Session *session)
+{
+ Buffer data;
+ Buffer *status = NULL;
+ APDU_Response *get_data_response = NULL;
+ RA_Token_PDU_Request_Msg *get_data_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *get_data_response_msg = NULL;
+ Get_Data_APDU *get_data_apdu = NULL;
+ Buffer get_status_data;
+
+ get_data_apdu =
+ new Get_Data_APDU();
+ get_data_request_msg =
+ new RA_Token_PDU_Request_Msg(get_data_apdu);
+ session->WriteMsg(get_data_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetData",
+ "Sent get_data_request_msg");
+
+ get_data_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (get_data_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetData",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (get_data_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetData",
+ "Invalid Message Type");
+ goto loser;
+ }
+ get_data_response =
+ get_data_response_msg->GetResponse();
+ if (get_data_response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::GetData",
+ "No Response From Token");
+ goto loser;
+ }
+ data = get_data_response->GetData();
+
+ if (!(get_data_response->GetSW1() == 0x90 &&
+ get_data_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetData",
+ "Bad Response");
+ goto loser;
+ }
+
+ status = new Buffer(data.substr(0, data.size()));
+
+loser:
+
+ if( get_data_request_msg != NULL ) {
+ delete get_data_request_msg;
+ get_data_request_msg = NULL;
+ }
+ if( get_data_response_msg != NULL ) {
+ delete get_data_response_msg;
+ get_data_response_msg = NULL;
+ }
+
+ return status;
+}
+
+Buffer *RA_Processor::ListObjects(RA_Session *session, BYTE seq)
+{
+ Buffer data;
+ Buffer *status = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *request_msg = NULL;
+ RA_Token_PDU_Response_Msg *response_msg = NULL;
+ List_Objects_APDU *list_objects_apdu = NULL;
+ Buffer get_status_data;
+
+ list_objects_apdu =
+ new List_Objects_APDU(seq);
+ request_msg =
+ new RA_Token_PDU_Request_Msg(list_objects_apdu);
+ session->WriteMsg(request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::ListObjects",
+ "Sent request_msg");
+
+ response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::ListObjects",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::ListObjects",
+ "Invalid Message Type");
+ goto loser;
+ }
+ response = response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::ListObjects",
+ "No Response From Token");
+ goto loser;
+ }
+
+ if (!(response->GetSW1() == 0x90 &&
+ response->GetSW2() == 0x00)) {
+ // RA::Error(LL_PER_PDU, "RA_Processor::ListObjects",
+ // "Bad Response");
+ goto loser;
+ }
+
+ data = response->GetData();
+
+ status = new Buffer(data.substr(0, data.size()));
+
+loser:
+
+ if( request_msg != NULL ) {
+ delete request_msg;
+ request_msg = NULL;
+ }
+ if( response_msg != NULL ) {
+ delete response_msg;
+ response_msg = NULL;
+ }
+
+ return status;
+}
+
+/**
+ * GetStatus
+ */
+Buffer *RA_Processor::GetStatus(RA_Session *session, BYTE p1, BYTE p2)
+{
+ Buffer data;
+ Buffer *status = NULL;
+ APDU_Response *get_status_response = NULL;
+ RA_Token_PDU_Request_Msg *get_status_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *get_status_response_msg = NULL;
+ Get_Status_APDU *get_status_apdu = NULL;
+ Buffer get_status_data;
+
+ get_status_apdu =
+ new Get_Status_APDU();
+ get_status_request_msg =
+ new RA_Token_PDU_Request_Msg(get_status_apdu);
+ session->WriteMsg(get_status_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetStatus",
+ "Sent get_status_request_msg");
+
+ get_status_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (get_status_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetStatus",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (get_status_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetStatus",
+ "Invalid Message Type");
+ goto loser;
+ }
+ get_status_response =
+ get_status_response_msg->GetResponse();
+ if (get_status_response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::GetStatus",
+ "No Response From Token");
+ goto loser;
+ }
+ data = get_status_response->GetData();
+
+ if (!(get_status_response->GetSW1() == 0x90 &&
+ get_status_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetStatus",
+ "Bad Response");
+ goto loser;
+ }
+
+ status = new Buffer(data.substr(0, data.size()));
+
+loser:
+
+ if( get_status_request_msg != NULL ) {
+ delete get_status_request_msg;
+ get_status_request_msg = NULL;
+ }
+ if( get_status_response_msg != NULL ) {
+ delete get_status_response_msg;
+ get_status_response_msg = NULL;
+ }
+
+ return status;
+}
+
+int RA_Processor::CreatePin(RA_Session *session, BYTE pin_number,
+ BYTE max_retries, char *pin)
+{
+ int rc = -1;
+ Create_Pin_APDU *create_pin_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Secure_Channel::IsPinPresent");
+ Buffer pin_buffer = Buffer((BYTE*)pin, strlen(pin));
+ create_pin_apdu = new Create_Pin_APDU(pin_number, max_retries,
+ pin_buffer);
+
+ /*
+ mac = ComputeAPDUMac(set_pin_apdu);
+ set_pin_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ create_pin_apdu);
+ session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::CreatePin",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::CreatePin",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::CreatePin",
+ "Invalid Message Type");
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::CreatePin",
+ "No Response From Token");
+ goto loser;
+ }
+
+ rc = 1;
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+}
+int RA_Processor::IsPinPresent(RA_Session *session, BYTE pin_number)
+{
+ int rc = -1;
+ Buffer data;
+ List_Pins_APDU *list_pins_apdu = NULL;
+ APDU_Response *response = NULL;
+ RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
+ Buffer *mac = NULL;
+
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Secure_Channel::IsPinPresent");
+ list_pins_apdu = new List_Pins_APDU(2);
+
+ /*
+ mac = ComputeAPDUMac(set_pin_apdu);
+ set_pin_apdu->SetMAC(*mac);
+ */
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ list_pins_apdu);
+ session->WriteMsg(token_pdu_request_msg);
+ RA::Debug("Secure_Channel::IsPinPresent",
+ "Sent token_pdu_request_msg");
+
+ token_pdu_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (token_pdu_response_msg == NULL)
+ {
+ RA::Error("Secure_Channel::IsPinReset",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (token_pdu_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::IsPinReset",
+ "Invalid Message Type");
+ goto loser;
+ }
+ response = token_pdu_response_msg->GetResponse();
+ if (response == NULL) {
+ RA::Error("Secure_Channel::IsPinReset",
+ "No Response From Token");
+ goto loser;
+ }
+ data = response->GetData();
+ if (data.size() < 2) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::IsPinReset",
+ "Invalid Response From Token");
+ goto loser;
+ }
+
+ if (pin_number < 8) {
+ rc = ((((BYTE*)data)[1] & (1 << pin_number)) > 0);
+ } else {
+ rc = ((((BYTE*)data)[0] & (1 << (pin_number - 8))) > 0);
+ }
+
+loser:
+ if( mac != NULL ) {
+ delete mac;
+ mac = NULL;
+ }
+ if( token_pdu_request_msg != NULL ) {
+ delete token_pdu_request_msg;
+ token_pdu_request_msg = NULL;
+ }
+ if( token_pdu_response_msg != NULL ) {
+ delete token_pdu_response_msg;
+ token_pdu_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Select applet.
+ *
+ * Global Platform Open Platform Card Specification
+ * Version 2.0.1 Page 9-22
+ *
+ * Sample Data:
+ *
+ * _____________ CLA
+ * | __________ INS
+ * | | _______ P1
+ * | | | ____ P2
+ * | | | | _ Len
+ * | | | | |
+ * 00 A4 04 00 07
+ * 53 4C 42 47 49 4E 41
+ */
+int RA_Processor::SelectApplet(RA_Session *session, BYTE p1, BYTE p2, Buffer *aid)
+{
+ int rc = 0;
+ APDU_Response *select_response = NULL;
+ RA_Token_PDU_Request_Msg *select_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *select_response_msg = NULL;
+ Select_APDU *select_apdu = NULL;
+
+ if (aid != NULL) {
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::SelectApplet",
+ "RA_Processor::SelectApplet with aid= ", aid);
+ }
+
+ select_apdu = new Select_APDU(p1, p2, *aid);
+ select_request_msg =
+ new RA_Token_PDU_Request_Msg(select_apdu);
+ session->WriteMsg(select_request_msg);
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::SelectApplet",
+ "Sent select_request_msg");
+
+ select_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (select_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::SelectApplet",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (select_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::SelectApplet",
+ "Invalid Message Type");
+ goto loser;
+ }
+ select_response = select_response_msg->GetResponse();
+ if (select_response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::SelectApplet",
+ "No Response From Token");
+ goto loser;
+ }
+ if (select_response->GetData().size() < 2) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::SelectApplet",
+ "Invalid Response From Token");
+ goto loser;
+ }
+ if (!(select_response->GetSW1() == 0x90 &&
+ select_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::SelectApplet",
+ "Bad Response");
+ goto loser;
+ }
+
+
+loser:
+ if( select_request_msg != NULL ) {
+ delete select_request_msg;
+ select_request_msg = NULL;
+ }
+ if( select_response_msg != NULL ) {
+ delete select_response_msg;
+ select_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Get Build ID from Net Key Applet.
+ * @returns a buffer with 4 bytes of data. This is the applet ID.
+ * The caller is responsible for freeing the buffer with
+ * the 'delete' operator.
+ */
+Buffer *RA_Processor::GetAppletVersion(RA_Session *session)
+{
+ Buffer data;
+ Buffer *buildID = NULL;
+ APDU_Response *get_version_response = NULL;
+ RA_Token_PDU_Request_Msg *get_version_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *get_version_response_msg = NULL;
+ Get_Version_APDU *get_version_apdu = NULL;
+ Buffer get_version_data;
+
+ get_version_apdu =
+ new Get_Version_APDU();
+ get_version_request_msg =
+ new RA_Token_PDU_Request_Msg(get_version_apdu);
+ session->WriteMsg(get_version_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "Sent get_version_request_msg");
+
+ get_version_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (get_version_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (get_version_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "Invalid Message Type");
+ goto loser;
+ }
+ get_version_response =
+ get_version_response_msg->GetResponse();
+ if (get_version_response == NULL) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::GetAppletVersion",
+ "No Response From Token");
+ goto loser;
+ }
+ data = get_version_response->GetData();
+ if (!(get_version_response->GetSW1() == 0x90 &&
+ get_version_response->GetSW2() == 0x00)) {
+ RA::Error(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "Bad Response");
+ goto loser;
+ }
+
+ /* Sample: 3FBAB4BF9000 */
+ if (data.size() != 6) {
+ RA::Error(LL_PER_PDU, "Secure_Channel::GetAppletVersion",
+ "Invalid Applet Version");
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::GetAppletVersion",
+ "Bad Applet Version: ",
+ &data);
+ goto loser;
+ }
+
+ buildID = new Buffer(data.substr(0, 4));
+
+/*
+ buildID = (get_version_data[0] << 24) | (get_version_data[1] << 16) |
+ (get_version_data[2] << 8) | get_version_data[3];
+
+*/
+
+loser:
+
+ if( get_version_request_msg != NULL ) {
+ delete get_version_request_msg;
+ get_version_request_msg = NULL;
+ }
+ if( get_version_response_msg != NULL ) {
+ delete get_version_response_msg;
+ get_version_response_msg = NULL;
+ }
+ return buildID;
+}
+
+/*
+ * this one sets the security level
+ */
+Secure_Channel *RA_Processor::SetupSecureChannel(RA_Session *session,
+ BYTE key_version, BYTE key_index, SecurityLevel security_level,
+ const char *connId)
+{
+ Secure_Channel *channel = SetupSecureChannel(session, key_version, key_index, connId);
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel","Resetting security level ...");
+
+ /* Bugscape Bug #55774: Prevent NetKey RA from crashing . . . */
+ if( channel != NULL ) {
+ channel->SetSecurityLevel(security_level);
+ } else {
+ RA::Error( LL_PER_PDU, "RA_Processor::SetupSecureChannel", "%s %s",
+ "Failed to create a secure channel - potentially due to an",
+ "RA/TKS key mismatch or differing RA/TKS key versions." );
+ }
+ return channel;
+
+}
+
+int RA_Processor::InitializeUpdate(RA_Session *session,
+ BYTE key_version, BYTE key_index,
+ Buffer &key_diversification_data,
+ Buffer &key_info_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge, const char *connId)
+{
+ int rc = -1;
+ APDU_Response *initialize_update_response = NULL;
+ RA_Token_PDU_Request_Msg *initialize_update_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *initialize_update_response_msg = NULL;
+ Initialize_Update_APDU *initialize_update_apdu = NULL;
+ Buffer update_response_data;
+ char configname[256];
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "RA_Processor::InitializeUpdate");
+
+
+ PR_snprintf((char *) configname, 256, "conn.%s.generateHostChallenge", connId);
+ bool gen_host_challenge_tks = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+
+ if(gen_host_challenge_tks) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Generate host challenge on TKS.");
+ rc = ComputeRandomData(host_challenge, (int) host_challenge.size(), connId);
+ } else {
+ rc = Util::GetRandomChallenge(host_challenge);
+ }
+
+ if(rc == -1) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Failed to generate host challenge");
+ goto loser;
+
+ }
+
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Generated Host Challenge",
+ &host_challenge);
+
+ initialize_update_apdu =
+ new Initialize_Update_APDU(key_version, key_index, host_challenge);
+ initialize_update_request_msg =
+ new RA_Token_PDU_Request_Msg(initialize_update_apdu);
+ session->WriteMsg(initialize_update_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Sent initialize_update_request_msg");
+
+ initialize_update_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (initialize_update_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (initialize_update_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Invalid Message Type");
+ goto loser;
+ }
+ initialize_update_response =
+ initialize_update_response_msg->GetResponse();
+ update_response_data = initialize_update_response->GetData();
+
+ if (!(initialize_update_response->GetSW1() == 0x90 &&
+ initialize_update_response->GetSW2() == 0x00)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Key version mismatch - key changeover to follow");
+ goto loser;
+ }
+
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Update Response Data", &update_response_data);
+
+ /**
+ * Initialize Update response:
+ * Key Diversification Data - 10 bytes
+ * Key Information Data - 2 bytes
+ * Card Challenge - 8 bytes
+ * Card Cryptogram - 8 bytes
+ */
+ if (initialize_update_response->GetData().size() < 10) {
+ RA::Error(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Invalid Initialize Update Response Size");
+ goto loser;
+ }
+ key_diversification_data = Buffer(update_response_data.substr(0, 10));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Key Diversification Data", &key_diversification_data);
+ key_info_data = Buffer(update_response_data.substr(10, 2));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Key Info Data", &key_info_data);
+ card_challenge = Buffer(update_response_data.substr(12, 8));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Card Challenge", &card_challenge);
+ card_cryptogram = Buffer(update_response_data.substr(20, 8));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::InitializeUpdate",
+ "Card Cryptogram", &card_cryptogram);
+
+ rc = 1;
+
+loser:
+ if( initialize_update_request_msg != NULL ) {
+ delete initialize_update_request_msg;
+ initialize_update_request_msg = NULL;
+ }
+ if( initialize_update_response_msg != NULL ) {
+ delete initialize_update_response_msg;
+ initialize_update_response_msg = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Setup secure channel between RA and the token.
+ */
+Secure_Channel *RA_Processor::SetupSecureChannel(RA_Session *session,
+ BYTE key_version, BYTE key_index, const char *connId)
+{
+ Secure_Channel *channel = NULL;
+ APDU_Response *initialize_update_response = NULL;
+ RA_Token_PDU_Request_Msg *initialize_update_request_msg = NULL;
+ RA_Token_PDU_Response_Msg *initialize_update_response_msg = NULL;
+ Initialize_Update_APDU *initialize_update_apdu = NULL;
+ Buffer update_response_data;
+ Buffer host_challenge = Buffer(8, (BYTE)0);
+ Buffer key_diversification_data;
+ Buffer key_info_data;
+ Buffer card_challenge;
+ Buffer card_cryptogram;
+ char configname[256];
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::Setup_Secure_Channel");
+
+ PR_snprintf((char *) configname, 256, "conn.%s.generateHostChallenge", connId);
+ bool gen_host_challenge_tks = RA::GetConfigStore()->GetConfigAsBool(configname, false);
+
+ int rc = 0;
+ if(gen_host_challenge_tks) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Generate host challenge on TKS.");
+ rc = ComputeRandomData(host_challenge, (int) host_challenge.size(), connId);
+ } else {
+ rc = Util::GetRandomChallenge(host_challenge);
+ }
+
+ if(rc == -1) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::SetupSecureChannel",
+ "Failed to generate host challenge");
+ goto loser;
+
+ }
+
+
+
+ /* if (Util::GetRandomChallenge(host_challenge) != PR_SUCCESS)
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Failed to generate host challenge");
+ goto loser;
+ }
+
+*/
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Generated Host Challenge",
+ &host_challenge);
+
+ initialize_update_apdu =
+ new Initialize_Update_APDU(key_version, key_index, host_challenge);
+ initialize_update_request_msg =
+ new RA_Token_PDU_Request_Msg(initialize_update_apdu);
+ session->WriteMsg(initialize_update_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Sent initialize_update_request_msg");
+
+ initialize_update_response_msg = (RA_Token_PDU_Response_Msg *)
+ session->ReadMsg();
+ if (initialize_update_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "No Token PDU Response Msg Received");
+ goto loser;
+ }
+ if (initialize_update_response_msg->GetType() != MSG_TOKEN_PDU_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Invalid Message Type");
+ goto loser;
+ }
+ initialize_update_response =
+ initialize_update_response_msg->GetResponse();
+ update_response_data = initialize_update_response->GetData();
+
+ if (!(initialize_update_response->GetSW1() == 0x90 &&
+ initialize_update_response->GetSW2() == 0x00)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Key version mismatch - key changeover to follow");
+ goto loser;
+ }
+
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Update Response Data", &update_response_data);
+
+ /**
+ * Initialize Update response:
+ * Key Diversification Data - 10 bytes
+ * Key Information Data - 2 bytes
+ * Card Challenge - 8 bytes
+ * Card Cryptogram - 8 bytes
+ */
+ if (initialize_update_response->GetData().size() < 28) {
+ RA::Error(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Invalid Initialize Update Response Size");
+ goto loser;
+ }
+ key_diversification_data = Buffer(update_response_data.substr(0, 10));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Key Diversification Data", &key_diversification_data);
+ key_info_data = Buffer(update_response_data.substr(10, 2));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Key Info Data", &key_info_data);
+ card_challenge = Buffer(update_response_data.substr(12, 8));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Card Challenge", &card_challenge);
+ card_cryptogram = Buffer(update_response_data.substr(20, 8));
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "Card Cryptogram", &card_cryptogram);
+
+ channel = GenerateSecureChannel(
+ session, connId,
+ key_diversification_data,
+ key_info_data,
+ card_challenge,
+ card_cryptogram,
+ host_challenge);
+
+loser:
+ if( initialize_update_request_msg != NULL ) {
+ delete initialize_update_request_msg;
+ initialize_update_request_msg = NULL;
+ }
+ if( initialize_update_response_msg != NULL ) {
+ delete initialize_update_response_msg;
+ initialize_update_response_msg = NULL;
+ }
+
+ return channel;
+} /* SetupSecureChannel */
+
+/**
+ * Requests secure ID.
+ */
+SecureId *RA_Processor::RequestSecureId(RA_Session *session)
+{
+ SecureId *secure_id = NULL;
+ RA_SecureId_Request_Msg *secureid_request_msg = NULL;
+ RA_SecureId_Response_Msg *secureid_response_msg = NULL;
+ char *value;
+ char *pin;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::SecureId_Request",
+ "RA_Processor::SecureId_Request");
+
+ secureid_request_msg = new RA_SecureId_Request_Msg(
+ 0 /* pin_required */, 0 /* next_value */);
+ session->WriteMsg(secureid_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::SecureId_Request",
+ "Sent secureid_request_msg");
+
+ secureid_response_msg = (RA_SecureId_Response_Msg *)
+ session->ReadMsg();
+ if (secureid_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::SecureId_Request",
+ "No SecureID Response Msg Received");
+ goto loser;
+ }
+
+ if (secureid_response_msg->GetType() != MSG_SECUREID_RESPONSE) {
+ RA::Error("Secure_Channel::SecureId_Request",
+ "Invalid Msg Type");
+ goto loser;
+ }
+
+ value = secureid_response_msg->GetValue();
+ pin = secureid_response_msg->GetPIN();
+
+ secure_id = new SecureId(value, pin);
+
+loser:
+
+ if( secureid_request_msg != NULL ) {
+ delete secureid_request_msg;
+ secureid_request_msg = NULL;
+ }
+ if( secureid_response_msg != NULL ) {
+ delete secureid_response_msg;
+ secureid_response_msg = NULL;
+ }
+ return secure_id;
+} /* RequestSecureId */
+
+/**
+ * Requests new pin for token.
+ */
+char *RA_Processor::RequestNewPin(RA_Session *session, unsigned int min, unsigned int max)
+{
+ char *new_pin = NULL;
+ RA_New_Pin_Request_Msg *new_pin_request_msg = NULL;
+ RA_New_Pin_Response_Msg *new_pin_response_msg = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "RA_Processor::New_Pin_Request");
+
+ new_pin_request_msg = new RA_New_Pin_Request_Msg(
+ min, max);
+ session->WriteMsg(new_pin_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "Sent new_pin_request_msg");
+
+ new_pin_response_msg = (RA_New_Pin_Response_Msg *)
+ session->ReadMsg();
+ if (new_pin_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "No New Pin Response Msg Received");
+ goto loser;
+ }
+
+ if (new_pin_response_msg->GetType() != MSG_NEW_PIN_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "Invalid Message Type");
+ goto loser;
+ }
+
+ if (new_pin_response_msg->GetNewPIN() == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::New_Pin_Request",
+ "No New Pin");
+ goto loser;
+ }
+
+ new_pin = PL_strdup(new_pin_response_msg->GetNewPIN());
+
+ if (strlen(new_pin) < min) {
+ RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "The length of the new pin is shorter than the mininum length (%d)", min);
+ if( new_pin != NULL ) {
+ PL_strfree( new_pin );
+ new_pin = NULL;
+ }
+ new_pin = NULL;
+ goto loser;
+ } else if (strlen(new_pin) > max) {
+ RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process",
+ "The length of the new pin is longer than the maximum length (%d)", max);
+ if( new_pin != NULL ) {
+ PL_strfree( new_pin );
+ new_pin = NULL;
+ }
+ new_pin = NULL;
+ goto loser;
+ }
+
+loser:
+
+ if( new_pin_request_msg != NULL ) {
+ delete new_pin_request_msg;
+ new_pin_request_msg = NULL;
+ }
+ if( new_pin_response_msg != NULL ) {
+ delete new_pin_response_msg;
+ new_pin_response_msg = NULL;
+ }
+
+ return new_pin;
+} /* RequestNewPin */
+
+/**
+ * Requests A Security Question (ASQ) from user.
+ */
+char *RA_Processor::RequestASQ(RA_Session *session, char *question)
+{
+ char *answer = NULL;
+ RA_ASQ_Request_Msg *asq_request_msg = NULL;
+ RA_ASQ_Response_Msg *asq_response_msg = NULL;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "RA_Processor::ASQ_Request");
+
+ asq_request_msg = new RA_ASQ_Request_Msg(question);
+ session->WriteMsg(asq_request_msg);
+ RA::Debug(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "Sent asq_request_msg");
+
+ asq_response_msg = (RA_ASQ_Response_Msg *)
+ session->ReadMsg();
+ if (asq_response_msg == NULL)
+ {
+ RA::Error(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "No ASQ Response Msg Received");
+ goto loser;
+ }
+ if (asq_response_msg->GetType() != MSG_ASQ_RESPONSE) {
+ RA::Error(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "Invalid Message Type");
+ goto loser;
+ }
+
+ if (asq_response_msg->GetAnswer() == NULL) {
+ RA::Error(LL_PER_PDU, "RA_Processor::ASQ_Request",
+ "No ASQ Answer");
+ goto loser;
+ }
+ answer = PL_strdup(asq_response_msg->GetAnswer());
+
+loser:
+ if( asq_request_msg != NULL ) {
+ delete asq_request_msg;
+ asq_request_msg = NULL;
+ }
+ if( asq_response_msg != NULL ) {
+ delete asq_response_msg;
+ asq_response_msg = NULL;
+ }
+
+ return answer;
+} /* RequestASQ */
+
+/**
+ * Creates a secure channel between RA and the token.
+ * challenges are sent to TKS which generates
+ * host cryptogram, and session key.
+ */
+Secure_Channel *RA_Processor::GenerateSecureChannel(
+ RA_Session *session, const char *connId,
+ Buffer &key_diversification_data, /* CUID */
+ Buffer &key_info_data,
+ Buffer &card_challenge,
+ Buffer &card_cryptogram,
+ Buffer &host_challenge)
+{
+ PK11SymKey *session_key = NULL;
+ Buffer *host_cryptogram = NULL;
+ char configname[256];
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel");
+
+ PK11SymKey *enc_session_key = NULL;
+
+
+ // desKey_s will be assigned to channel and will be destroyed when channel closed
+ char *drm_desKey_s = NULL;
+ char *kek_desKey_s = NULL;
+ char *keycheck_s = NULL;
+
+ session_key = RA::ComputeSessionKey(session, key_diversification_data,
+ key_info_data, card_challenge,
+ host_challenge, &host_cryptogram,
+ card_cryptogram, &enc_session_key,
+ &drm_desKey_s, &kek_desKey_s,
+ &keycheck_s, connId);
+ if (session_key == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get session_key");
+ return NULL;
+ }
+
+ // is serversideKeygen on?
+ PR_snprintf((char *) configname, 256, "conn.%s.serverKeygen", connId);
+ bool serverKeygen = RA::GetConfigStore()->GetConfigAsBool(configname, false);
+
+ if (serverKeygen) {
+ if ((drm_desKey_s == NULL) || (strcmp(drm_desKey_s, "")==0)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get drm_desKey_s");
+ return NULL;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - drm_desKey_s = %s", drm_desKey_s);
+ }
+ if ((kek_desKey_s == NULL) || (strcmp(kek_desKey_s,"")==0)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get kek_desKey_s");
+ return NULL;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - kek_desKey_s = %s", kek_desKey_s);
+ }
+ if ((keycheck_s == NULL) || (strcmp(keycheck_s,"")==0)) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get keycheck_s");
+ return NULL;
+ }
+
+ if (enc_session_key == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get enc_session_key");
+ return NULL;
+ }
+ if (host_cryptogram == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - did not get host_cryptogram");
+ return NULL;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Setup_Secure_Channel",
+ "RA_Processor::GenerateSecureChannel - keycheck_s = %s", keycheck_s);
+ }
+ }
+/*
+ host_cryptogram = RA::ComputeHostCryptogram(
+ card_challenge, host_challenge);
+*/
+
+
+ Secure_Channel *channel = new Secure_Channel(session, session_key,
+ enc_session_key,
+ drm_desKey_s, kek_desKey_s, keycheck_s,
+ key_diversification_data, key_info_data,
+ card_challenge, card_cryptogram,
+ host_challenge, *host_cryptogram);
+
+ if( host_cryptogram != NULL ) {
+ delete host_cryptogram;
+ host_cryptogram = NULL;
+ }
+
+ if (channel != NULL) {
+ // this can be overridden by individual processor later
+ channel->SetSecurityLevel(RA::GetGlobalSecurityLevel());
+ } else {
+ if( session_key != NULL ) {
+ PK11_FreeSymKey( session_key );
+ session_key = NULL;
+ }
+ if( enc_session_key != NULL ) {
+ PK11_FreeSymKey( enc_session_key );
+ enc_session_key = NULL;
+ }
+
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::GenerateSecureChannel", "complete");
+ return channel;
+} /* GenerateSecureChannel */
+
+int RA_Processor::CreateKeySetData(Buffer &CUID, Buffer &version,
+ Buffer &NewMasterVer, Buffer &out, const char *connid)
+{
+ char body[5000];
+ char configname[256];
+ HttpConnection *tksConn = NULL;
+ tksConn = RA::GetTKSConn(connid);
+ if (tksConn == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::CreateKeySetData", "Failed to get TKSConnection %s", connid);
+ RA::Error(LL_PER_PDU, "RA_Processor::CreateKeySetData", "Failed to get TKSConnection %s", connid);
+ return -1;
+ } else {
+ // PRLock *tks_lock = RA::GetTKSLock();
+ int tks_curr = RA::GetCurrentIndex(tksConn);
+ int currRetries = 0;
+ char *cuid = Util::SpecialURLEncode(CUID);
+ char *versionID = Util::SpecialURLEncode(version);
+ char *masterV = Util::SpecialURLEncode(NewMasterVer);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.keySet", connid);
+ const char *keySet = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)body, 5000,
+ "newKeyInfo=%s&CUID=%s&KeyInfo=%s&keySet=%s", masterV, cuid, versionID,keySet);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.createKeySetData", connid);
+ const char *servletID = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( versionID != NULL ) {
+ PR_Free( versionID );
+ versionID = NULL;
+ }
+ if( masterV != NULL ) {
+ PR_Free( masterV );
+ masterV = NULL;
+ }
+
+ tks_curr = RA::GetCurrentIndex(tksConn);
+
+ PSHttpResponse * response = tksConn->getResponse(tks_curr, servletID, body);
+ ConnectionInfo *connInfo = tksConn->GetFailoverList();
+ char **hostport = connInfo->GetHostPortList();
+
+ if (response == NULL)
+ RA::Debug(LL_PER_PDU, "The CreateKeySetData response from TKS ",
+ "at %s is NULL.", hostport[tks_curr]);
+ else
+ RA::Debug(LL_PER_PDU, "The CreateKeySetData response from TKS ",
+ "at % is not NULL.", hostport[tks_curr]);
+
+ while (response == NULL) {
+ RA::Failover(tksConn, connInfo->GetHostPortListLen());
+ tks_curr = RA::GetCurrentIndex(tksConn);
+
+ RA::Debug(LL_PER_PDU, "RA is reconnecting to TKS ",
+ "at %s for createKeySetData.", hostport[tks_curr]);
+
+ if (++currRetries >= tksConn->GetNumOfRetries()) {
+ RA::Debug(LL_PER_PDU, "Used up all the retries. Response is NULL","");
+ RA::Error(LL_PER_PDU, "RA_Processor::CreateKeySetData","Failed connecting to TKS after %d retries", currRetries);
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return -1;
+ }
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ }
+
+ int status = 0;
+
+ Buffer *keydataset = NULL;
+ if (response != NULL) {
+ RA::Debug(LL_PER_PDU,"Response is not ","NULL");
+ char * content = response->getContent();
+ if (content == NULL) {
+ RA::Debug(LL_PER_PDU,"TKSConnection::CreateKeySetData","Content Is NULL");
+ } else {
+ RA::Debug(LL_PER_PDU,"TKSConnection::CreateKeySetData","Content Is '%s'",
+ content);
+ }
+ if (content != NULL) {
+ char *statusStr = strstr((char *)content, "status=0&");
+ if (statusStr == NULL) {
+ status = 1;
+ char *p = strstr((char *)content, "status=");
+ if(p != NULL) {
+ status = int(p[7]) - 48;
+ } else {
+ status = 4;
+ return -1;
+ }
+ } else {
+ status = 0;
+ char *p = &content[9];
+ char *rcStr = strstr((char *)p, "keySetData=");
+ if (rcStr != NULL) {
+ rcStr = &rcStr[11];
+ if (!strcmp(rcStr, "%00")) {
+ return -1;
+ }
+ keydataset = Util::URLDecode(rcStr);
+ }
+ }
+ }
+ }
+
+ if (keydataset == NULL)
+ {
+ RA::Debug(LL_PER_PDU, "RA_Processor:CreateKeySetData",
+ "Key Set Data is NULL");
+
+ return -1;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor:CreateKeySetData", "Status of CreateKeySetData=%d", status);
+ RA::Debug(LL_PER_PDU, "finish CreateKeySetData", "");
+
+ if (status > 0) {
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return -1;
+ } else {
+ out = *keydataset;
+ if( keydataset != NULL ) {
+ delete keydataset;
+ keydataset = NULL;
+ }
+ }
+
+ if( response != NULL ) {
+ response->freeContent();
+ delete response;
+ response = NULL;
+ }
+
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return 1;
+ }
+ BYTE kek_key[] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+ BYTE key[] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+ Buffer old_kek_key(kek_key, 16);
+ Buffer new_auth_key(key, 16);
+ Buffer new_mac_key(key, 16);
+ Buffer new_kek_key(key, 16);
+
+
+ Util::CreateKeySetData(
+ NewMasterVer,
+ old_kek_key,
+ new_auth_key,
+ new_mac_key,
+ new_kek_key,
+ out);
+
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return 1;
+}
+
+
+/**
+ * Input data wrapped by KEK key in TKS.
+ */
+int RA_Processor::EncryptData(Buffer &CUID, Buffer &version, Buffer &in, Buffer &out, const char *connid)
+{
+ char body[5000];
+ char configname[256];
+#define PLAINTEXT_CHALLENGE_SIZE 16
+ // khai, here we wrap the input with the KEK key
+ // in TKS
+ HttpConnection *tksConn = NULL;
+ char kek_key[16] = {
+ 0x40, 0x41, 0x42, 0x43,
+ 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b,
+ 0x4c, 0x4d, 0x4e, 0x4f
+ };
+ int status = 0;
+
+ tksConn = RA::GetTKSConn(connid);
+ if (tksConn == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::EncryptData", "Failed to get TKSConnection %s", connid);
+ RA::Debug(LL_PER_PDU, "RA_Processor::EncryptData", "Failed to get TKSConnection %s", connid);
+ return -1;
+ } else {
+ int tks_curr = RA::GetCurrentIndex(tksConn);
+ int currRetries = 0;
+ char *data = NULL;
+ Buffer *zerob = new Buffer(PLAINTEXT_CHALLENGE_SIZE, (BYTE)0);
+ if (!(in == *zerob))
+ data = Util::SpecialURLEncode(in);
+ else
+ RA::Debug(LL_PER_PDU, "RA_Processor::EncryptData","Challenge to be generated on TKS");
+
+ if (zerob != NULL) {
+ delete zerob;
+ }
+
+ char *cuid = Util::SpecialURLEncode(CUID);
+ char *versionID = Util::SpecialURLEncode(version);
+
+ PR_snprintf((char *)configname, 256, "conn.%s.keySet", connid);
+ const char *keySet = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ PR_snprintf((char *)body, 5000, "data=%s&CUID=%s&KeyInfo=%s&keySet=%s",
+ ((data != NULL)? data:""), cuid, versionID,keySet);
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.encryptData", connid);
+ const char *servletID = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( versionID != NULL ) {
+ PR_Free( versionID );
+ versionID = NULL;
+ }
+
+ PSHttpResponse *response = tksConn->getResponse(tks_curr, servletID, body);
+ ConnectionInfo *connInfo = tksConn->GetFailoverList();
+ char **hostport = connInfo->GetHostPortList();
+ if (response == NULL)
+ RA::Debug(LL_PER_PDU, "The encryptedData response from TKS ",
+ "at %s is NULL.", hostport[tks_curr]);
+ else
+ RA::Debug(LL_PER_PDU, "The encryptedData response from TKS ",
+ "at %s is not NULL.", hostport[tks_curr]);
+
+ while (response == NULL) {
+ RA::Failover(tksConn, connInfo->GetHostPortListLen());
+ tks_curr = RA::GetCurrentIndex(tksConn);
+ RA::Debug(LL_PER_PDU, "RA is reconnecting to TKS ",
+ "at %s for encryptData.", hostport[tks_curr]);
+
+ if (++currRetries >= tksConn->GetNumOfRetries()) {
+ RA::Debug(LL_PER_PDU, "Used up all the retries. Response is NULL","");
+ RA::Error(LL_PER_PDU, "RA_Processor::EncryptData", "Failed connecting to TKS after %d retries", currRetries);
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return -1;
+ }
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ }
+
+ Buffer *encryptedData = NULL;
+ // preEncData is only useful when data is null, and data is to be randomly
+ // generated on TKS
+ Buffer *preEncData = NULL;
+ status = 0;
+ if (response != NULL) {
+ RA::Debug(LL_PER_PDU, "EncryptData Response is not ","NULL");
+ char *content = response->getContent();
+ if (content != NULL) {
+ char *statusStr = strstr((char *)content, "status=0&");
+ if (statusStr == NULL) {
+ char *p = strstr((char *)content, "status=");
+
+ if(p != NULL) {
+ status = int(p[7]) - 48;
+ } else {
+ status = 4;
+ return -1;
+ }
+ } else {
+ status = 0;
+ char *p = &content[9];
+ // get pre-encryption data
+ char *preStr = strstr((char *)p, "data=");
+ if (preStr != NULL) {
+ p = &preStr[5];
+ char pstr[PLAINTEXT_CHALLENGE_SIZE*3+1];
+ strncpy(pstr, p, PLAINTEXT_CHALLENGE_SIZE*3);
+ pstr[PLAINTEXT_CHALLENGE_SIZE*3] = '\0';
+ preEncData = Util::URLDecode(pstr);
+//RA::DebugBuffer("RA_Processor::EncryptData", "preEncData=", preEncData);
+ }
+
+ // get encrypted data
+ p = &content[9];
+ char *rcStr = strstr((char *)p, "encryptedData=");
+ if (rcStr != NULL) {
+ rcStr = &rcStr[14];
+ encryptedData = Util::URLDecode(rcStr);
+//RA::DebugBuffer("RA_Processor::EncryptData", "encryptedData=", encryptedData);
+ }
+ }
+ }
+ }
+ if (encryptedData == NULL)
+ RA::Debug(LL_PER_PDU, "RA_Processor:GetEncryptedData",
+ "Encrypted Data is NULL");
+
+ RA::Debug(LL_PER_PDU, "EncryptedData ", "status=%d", status);
+ RA::Debug(LL_PER_PDU, "finish EncryptedData", "");
+ if ((status > 0) || (preEncData == NULL) || (encryptedData == NULL)) {
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ if( data != NULL ) {
+ PR_Free( data );
+ data = NULL;
+ }
+ return -1;
+ } else {
+ out = *encryptedData;
+ if( encryptedData != NULL ) {
+ delete encryptedData;
+ encryptedData = NULL;
+ }
+ if (data != NULL) {
+ RA::Debug(LL_PER_PDU, "EncryptedData ", "challenge overwritten by TKS");
+ PR_Free( data );
+ data = NULL;
+ }
+ in = *preEncData;
+
+ if( preEncData != NULL ) {
+ delete preEncData;
+ preEncData = NULL;
+ }
+ }
+ if( response != NULL ) {
+ response->freeContent();
+ delete response;
+ response = NULL;
+ }
+
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return 1;
+ }
+
+ Buffer kek_buffer = Buffer((BYTE*)kek_key, 16);
+ status = Util::EncryptData(kek_buffer, in, out);
+#if 0
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::EncryptData", "Encrypted Data",
+ &out);
+ Buffer out1 = Buffer(16, (BYTE)0);
+ status = Util::DecryptData(kek_buffer, out, out1);
+ RA::DebugBuffer(LL_PER_PDU, "RA_Processor::EncryptData", "Clear Data",
+ &out1);
+#endif
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ return status;
+}
+
+int RA_Processor::ComputeRandomData(Buffer &data_out, int dataSize, const char *connid)
+{
+ char body[5000];
+ char configname[256];
+ HttpConnection *tksConn = NULL;
+ int status = -1;
+ Buffer *decodedRandomData = NULL;
+ PSHttpResponse *response = NULL;
+
+ //check for absurd dataSize values
+ if(dataSize <= 0 || dataSize > 1024) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData", "Invalid dataSize requested %d", dataSize);
+ return -1;
+ }
+
+ tksConn = RA::GetTKSConn(connid);
+ if (tksConn == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData", "Failed to get TKSConnection %s", connid);
+ return -1;
+ } else {
+ int tks_curr = RA::GetCurrentIndex(tksConn);
+ int currRetries = 0;
+
+ PR_snprintf((char *)body, 5000, "dataNumBytes=%d"
+ , dataSize );
+
+ PR_snprintf((char *)configname, 256, "conn.%s.servlet.computeRandomData", connid);
+ const char *servletID = RA::GetConfigStore()->GetConfigAsString(configname);
+
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ ConnectionInfo *connInfo = tksConn->GetFailoverList();
+ char **hostport = connInfo->GetHostPortList();
+ if (response == NULL)
+ RA::Debug(LL_PER_PDU, "The ComputeRandomData response from TKS ",
+ "at %s is NULL.", hostport[tks_curr]);
+ else
+ RA::Debug(LL_PER_PDU, "The ComputeRandomData response from TKS ",
+ "at %s is not NULL.", hostport[tks_curr]);
+
+ while (response == NULL) {
+ RA::Failover(tksConn, connInfo->GetHostPortListLen());
+ tks_curr = RA::GetCurrentIndex(tksConn);
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData: RA is reconnecting to TKS ",
+ "at %s for ComputeRandomData.", hostport[tks_curr]);
+
+ if (++currRetries >= tksConn->GetNumOfRetries()) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData: Used up all the retries. Response is NULL","");
+ RA::Error(LL_PER_PDU, "RA_Processor::ComputeRandomData", "Failed connecting to TKS after %d retries", currRetries);
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+ status = -1;
+ goto loser;
+ }
+ response = tksConn->getResponse(tks_curr, servletID, body);
+ }
+
+ status = 0;
+ if (response != NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData Response is not ","NULL");
+ char *content = response->getContent();
+ if (content != NULL) {
+ char *statusStr = strstr((char *)content, "status=0&");
+ if (statusStr == NULL) {
+ char *p = strstr((char *)content, "status=");
+
+ if(p != NULL) {
+ status = int(p[7]) - 48;
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::ComputeRandomData status from TKS is ","status %d",status);
+ status = -1;
+ } else {
+ status = -1;
+ goto loser;
+ }
+ } else {
+ status = 0;
+ // skip over "status=0&"
+ char *p = &content[9];
+
+ // get random data
+ char *dataStr = strstr((char *)p, "DATA=");
+ if (dataStr != NULL) {
+ // skip over "DATA="
+ p = &dataStr[5];
+
+ char *dstr = new char[ dataSize *3 + 1];
+ if(!dstr) {
+ status = -1;
+ goto loser;
+ }
+ strncpy(dstr, p, dataSize * 3);
+ dstr[dataSize*3] = '\0';
+ decodedRandomData = Util::URLDecode(dstr);
+ RA::DebugBuffer("RA_Processor::ComputeRandomData", "decodedRandomData=", decodedRandomData);
+
+ if(dstr) {
+ data_out = *decodedRandomData;
+ delete [] dstr;
+ dstr = NULL;
+ }
+ if(decodedRandomData) {
+ delete decodedRandomData;
+ decodedRandomData = NULL;
+ }
+ }
+ }
+ }
+ }
+ }
+loser:
+ if( response != NULL ) {
+ response->freeContent();
+ delete response;
+ response = NULL;
+ }
+
+ if (tksConn != NULL) {
+ RA::ReturnTKSConn(tksConn);
+ }
+
+ return status;
+}
+
+bool RA_Processor::RevokeCertificates(RA_Session *session, char *cuid,char *audit_msg,
+ char *final_applet_version,
+ char *keyVersion,
+ char *tokenType,
+ char *userid,
+ RA_Status &status )
+{
+ const char *OP_PREFIX = "op.format";
+ char *statusString = NULL;
+ char configname[256];
+ char filter[512];
+ char activity_msg[512];
+ char serial[100];
+ int rc = 0;
+ int statusNum;
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ bool revocation_failed = false;
+
+ RA::Debug("RA_Processor::RevokeCertificates","RevokeCertificates! cuid %s",cuid);
+ PR_snprintf((char *)filter, 256, "(tokenID=%s)", cuid);
+ rc = RA::ra_find_tus_certificate_entries_by_order(filter, 100, &result, 1);
+ if (rc == 0) {
+ CertEnroll *certEnroll = new CertEnroll();
+ for (e = RA::ra_get_first_entry(result); e != NULL; e = RA::ra_get_next_entry(e)) {
+ char *attr_status = RA::ra_get_cert_status(e);
+ if (strcmp(attr_status, "revoked") == 0) {
+ if (attr_status != NULL) {
+ PL_strfree(attr_status);
+ attr_status = NULL;
+ }
+ rc = RA::ra_delete_certificate_entry(e);
+ continue;
+ }
+ char *attr_serial= RA::ra_get_cert_serial(e);
+ /////////////////////////////////////////////////
+ // Raidzilla Bug #57803:
+ // If the certificate is not originally created for this
+ // token, we should not revoke the certificate here.
+ //
+ // To figure out if this certificate is originally created
+ // for this token, we check the tokenOrigin attribute.
+ /////////////////////////////////////////////////
+ char *origin = RA::ra_get_cert_attr_byname(e, "tokenOrigin");
+ if (origin != NULL) {
+ RA::Debug("RA_Processor::RevokeCertificates", "Origin is %s, Current is %s", origin, cuid);
+ if (strcmp(origin, cuid) != 0) {
+ // skip this certificate, no need to do nothing
+ // We did not create this originally
+
+ rc = RA::ra_delete_certificate_entry(e);
+ continue;
+ }
+ } else {
+ RA::Debug("RA_Processor::RevokeCertificates", "Origin is not present");
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.revokeCert", OP_PREFIX, tokenType);
+ bool revokeCert = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+ if (revokeCert) {
+ char *attr_cn = RA::ra_get_cert_cn(e);
+ PR_snprintf((char *)configname, 256, "%s.%s.ca.conn", OP_PREFIX,
+ tokenType);
+ char *connid = (char *)(RA::GetConfigStore()->GetConfigAsString(configname));
+ if (connid == NULL) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::RevokeCertificates", "Failed to get connection.");
+ status = STATUS_ERROR_REVOKE_CERTIFICATES_FAILED;
+ PR_snprintf(audit_msg, 512, "Failed to connect to CA, status = STATUS_ERROR_REVOKE_CERTIFICATES_FAILED");
+
+ revocation_failed = true;
+ goto loser;
+ }
+ PR_snprintf(serial, 100, "0x%s", attr_serial);
+
+ // if the certificates are revoked_on_hold, dont do
+ // anything because the certificates may be referenced
+ // by more than one token.
+ if (strcmp(attr_status, "revoked_on_hold") == 0) {
+ RA::Debug("RA_Processor::RevokeCertificates", "This is revoked_on_hold certificate, skip it.");
+ if (attr_status != NULL) {
+ PL_strfree(attr_status);
+ attr_status = NULL;
+ }
+ if (attr_serial != NULL) {
+ PL_strfree(attr_serial);
+ attr_serial = NULL;
+ }
+ if (attr_cn != NULL) {
+ PL_strfree(attr_cn);
+ attr_cn = NULL;
+ }
+
+ rc = RA::ra_delete_certificate_entry(e);
+ continue;
+ }
+ statusNum = certEnroll->RevokeCertificate("1", serial, connid, statusString);
+ RA::Debug("RA_Processor::RevokeCertificates", "Revoke cert %s status %d",serial,statusNum);
+
+ if (statusNum == 0) {
+ RA::Audit(EV_FORMAT, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Success", "revoke", serial, connid, "");
+ PR_snprintf(activity_msg, 512, "certificate %s revoked", serial);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "format", "success", activity_msg, "", tokenType);
+ RA::ra_update_cert_status(attr_cn, "revoked");
+ } else {
+ RA::Audit(EV_FORMAT, AUDIT_MSG_CERT_STATUS_CHANGE, userid,
+ "Failure", "revoke", serial, connid, statusString);
+ PR_snprintf(activity_msg, 512, "error in revoking certificate %s: %s", serial, statusString);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "format", "failure", activity_msg, "", tokenType);
+ revocation_failed = true;
+ }
+
+ if (attr_status != NULL) {
+ PL_strfree(attr_status);
+ attr_status = NULL;
+ }
+ if (attr_serial != NULL) {
+ PL_strfree(attr_serial);
+ attr_serial = NULL;
+ }
+ if (attr_cn != NULL) {
+ PL_strfree(attr_cn);
+ attr_cn = NULL;
+ }
+ if (statusString != NULL) {
+ PR_Free(statusString);
+ statusString = NULL;
+ }
+ }
+ rc = RA::ra_delete_certificate_entry(e);
+ }
+ if (result != NULL)
+ ldap_msgfree(result);
+ if (certEnroll != NULL)
+ delete certEnroll;
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::RevokeCertificates", "Failed to revoke certificates on this token. Certs not found.");
+ status = STATUS_ERROR_REVOKE_CERTIFICATES_FAILED;
+ PR_snprintf(audit_msg, 512, "Failed to revoke certificates on this token. Certs not found. status = STATUS_ERROR_REVOKE_CERTIFICATES_FAILED");
+ revocation_failed = true;
+ goto loser;
+ }
+
+ rc = 0;
+ if (keyVersion != NULL) {
+ rc = RA::tdb_update("", cuid, (char *)final_applet_version, keyVersion, "uninitialized", "", tokenType);
+ }
+
+ if (rc != 0) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::RevokeCertificates",
+ "Failed to update the token database");
+ status = STATUS_ERROR_UPDATE_TOKENDB_FAILED;
+ PR_snprintf(audit_msg, 512, "Revoked certificates but failed to update the token database, status = STATUS_ERROR_UPDATE_TOKENDB_FAILED");
+ goto loser;
+ }
+
+loser:
+
+ return !revocation_failed;
+}
+
+RA_Status RA_Processor::Format(RA_Session *session, NameValueSet *extensions, bool skipAuth)
+{
+ const char *OP_PREFIX="op.format";
+ char configname[256];
+ char *cuid = NULL;
+ char *msn = NULL;
+ const char *tokenType = NULL;
+ PRIntervalTime start, end;
+ RA_Status status = STATUS_NO_ERROR;
+ int rc = -1;
+ Secure_Channel *channel = NULL;
+ Buffer kdd;
+ AuthParams *login = NULL;
+ // char *new_pin = NULL;
+ const char *applet_dir;
+ bool upgrade_enc = false;
+ SecurityLevel security_level = SECURE_MSG_MAC_ENC;
+
+ Buffer *buildID = NULL;
+ Buffer *token_status = NULL;
+ const char* required_version = NULL;
+ const char *appletVersion = NULL;
+ const char *final_applet_version = NULL;
+ const char *userid = PL_strdup( "" );
+ // BYTE se_p1 = 0x00;
+ // BYTE se_p2 = 0x00;
+ const char *expected_version;
+ int requiredV = 0;
+ const char *tksid = NULL;
+ const char *authid = NULL;
+ AuthParams *authParams = NULL;
+ Buffer host_challenge = Buffer(8, (BYTE)0);
+ Buffer key_diversification_data;
+ Buffer key_info_data;
+ Buffer card_challenge;
+ Buffer card_cryptogram;
+ Buffer *cplc_data = NULL;
+ char activity_msg[4096];
+ LDAPMessage *ldapResult = NULL;
+ LDAPMessage *e = NULL;
+ LDAPMessage *result = NULL;
+ char filter[512];
+ Buffer curKeyInfo;
+ BYTE curVersion;
+ char *curKeyInfoStr = NULL;
+ char *newVersionStr = NULL;
+ bool tokenFound = false;
+ int finalKeyVersion = 0;
+ char *keyVersion = NULL;
+ char *xuserid = NULL;
+ char audit_msg[512] = "";
+ char *profile_state = NULL;
+
+ Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_CARDMGR_INSTANCE_AID,
+ RA::CFG_DEF_CARDMGR_INSTANCE_AID);
+ Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer(
+ RA::CFG_APPLET_NETKEY_INSTANCE_AID,
+ RA::CFG_DEF_NETKEY_INSTANCE_AID);
+ Buffer key_data_set;
+ Buffer token_cuid;
+ Buffer token_msn;
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Begin upgrade process");
+
+ BYTE major_version = 0x0;
+ BYTE minor_version = 0x0;
+ BYTE app_major_version = 0x0;
+ BYTE app_minor_version = 0x0;
+ const char *connid = NULL;
+ int upgrade_rc;
+
+ start = PR_IntervalNow();
+
+ RA::Debug("RA__Processor::Format", "Client %s", session->GetRemoteIP());
+
+
+ SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ cplc_data = GetData(session);
+ if (cplc_data == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "Get Data Failed");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Get Data Failed, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ RA::DebugBuffer("RA_Processor::Format", "CPLC Data = ",
+ cplc_data);
+ if (cplc_data->size() < 47) {
+ RA::Error("RA_Format_Processor::Process",
+ "Invalid CPLC Size");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Invalid CPLC Size, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ token_cuid = Buffer(cplc_data->substr(3,4)) +
+ Buffer(cplc_data->substr(19,2)) +
+ Buffer(cplc_data->substr(15,4));
+ RA::DebugBuffer("RA_Processor::Format", "Token CUID= ",
+ &token_cuid);
+ cuid = Util::Buffer2String(token_cuid);
+
+ token_msn = Buffer(cplc_data->substr(41, 4));
+ RA::DebugBuffer("RA_Processor::Format", "Token MSN= ",
+ &token_msn);
+ msn = Util::Buffer2String(token_msn);
+
+
+ /**
+ * Checks if the netkey has the required applet version.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ token_status = GetStatus(session, 0x00, 0x00);
+ if (token_status == NULL) {
+ major_version = 0;
+ minor_version = 0;
+ app_major_version = 0x0;
+ app_minor_version = 0x0;
+ } else {
+ major_version = ((BYTE*)*token_status)[0];
+ minor_version = ((BYTE*)*token_status)[1];
+ app_major_version = ((BYTE*)*token_status)[2];
+ app_minor_version = ((BYTE*)*token_status)[3];
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Major=%d Minor=%d", major_version, minor_version);
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Applet Major=%d Applet Minor=%d", app_major_version, app_minor_version);
+
+ if (!GetTokenType(OP_PREFIX, major_version,
+ minor_version, cuid, msn,
+ extensions, status, tokenType)) {
+ PR_snprintf(audit_msg, 512, "Failed to get token type");
+ goto loser;
+ }
+
+ // check if profile is enabled
+ PR_snprintf((char *)configname, 256, "config.Profiles.%s.state", tokenType);
+ profile_state = (char *) RA::GetConfigStore()->GetConfigAsString(configname);
+ if ((profile_state != NULL) && (PL_strcmp(profile_state, "Enabled") != 0)) {
+ RA::Error("RA_Format_Processor::Process", "Profile %s Disabled for CUID %s", tokenType, cuid);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "profile %s disabled", tokenType);
+ goto loser;
+ }
+
+ if (RA::ra_is_token_present(cuid)) {
+ RA::Debug("RA_Processor::Format",
+ "Found token %s", cuid);
+
+ if (RA::ra_is_tus_db_entry_disabled(cuid)) {
+ RA::Error("RA_Format_Processor::Process",
+ "CUID %s Disabled", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "CUID %s Disabled, status=STATUS_ERROR_DISABLED_TOKEN", cuid);
+ goto loser;
+ }
+ } else {
+ RA::Debug("RA_Processor::Format",
+ "Not Found token %s", cuid);
+ // This is a new token. We need to check our policy to see
+ // if we should allow enrollment. raidzilla #57414
+ PR_snprintf((char *)configname, 256, "%s.allowUnknownToken",
+ OP_PREFIX);
+ if (!RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+ RA::Error("Process", "CUID %s Format Unknown Token", cuid);
+ status = STATUS_ERROR_DISABLED_TOKEN;
+ PR_snprintf(audit_msg, 512, "Unknown token disallowed, status=STATUS_ERROR_DISABLED_TOKEN");
+ goto loser;
+ }
+
+ }
+
+ // we know cuid and msn here
+ RA::Audit(EV_FORMAT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "format",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "token enabled");
+
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn",
+ OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (tksid == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "TKS Connection Parameter %s Not Found", configname);
+ status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND;
+ PR_snprintf(audit_msg, 512, "TKS Connection Parameter %s Not Found, status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND", configname);
+ goto loser;
+ }
+
+ buildID = GetAppletVersion(session);
+ if (buildID == NULL) {
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.emptyToken.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ appletVersion = PL_strdup( "" );
+ } else {
+ RA::Error("RA_Format_Processor::Process",
+ "no applet found and applet upgrade not enabled");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "No applet found and applet upgrade not enabled, status = STATUS_ERROR_SECURE_CHANNEL");
+ goto loser;
+ }
+ } else {
+ char * buildid = Util::Buffer2String(*buildID);
+ RA::Debug("RA_Processor::Format", "buildid = %s", buildid);
+ char version[13];
+ PR_snprintf((char *) version, 13,
+ "%x.%x.%s", app_major_version, app_minor_version,
+ buildid);
+ appletVersion = strdup(version);
+ if (buildid != NULL) {
+ PR_Free(buildid);
+ buildid=NULL;
+ }
+ }
+
+ final_applet_version = strdup(appletVersion);
+ RA::Debug("RA_Processor::Format", "final_applet_version = %s", final_applet_version);
+
+ /**
+ * Checks if we need to upgrade applet.
+ */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.requiredVersion", OP_PREFIX, tokenType);
+
+ required_version = RA::GetConfigStore()->GetConfigAsString(
+ configname);
+ expected_version = PL_strdup(required_version);
+
+ if (expected_version == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "upgrade.version not found");
+ status = STATUS_ERROR_MISCONFIGURATION;
+ PR_snprintf(audit_msg, 512, "Upgrade version not found, status = STATUS_ERROR_MISCONFIGURATION");
+ goto loser;
+ }
+ /* upgrade applet */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.directory", OP_PREFIX, tokenType);
+ applet_dir = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (applet_dir == NULL || strlen(applet_dir) == 0) {
+ RA::Error(LL_PER_PDU, "RA_Processor::UpdateApplet",
+ "Failed to get %s", applet_dir);
+ status = STATUS_ERROR_MISCONFIGURATION;
+ PR_snprintf(audit_msg, 512, "Failed to get %s, status = STATUS_ERROR_MISCONFIGURATION", applet_dir);
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.loginRequest.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1) && !skipAuth) {
+ if (extensions != NULL &&
+ extensions->GetValue("extendedLoginRequest") != NULL)
+ {
+ RA::Debug("RA_rocessor::Format",
+ "Extended Login Request detected");
+ AuthenticationEntry *entry = GetAuthenticationEntry(
+ OP_PREFIX, configname, tokenType);
+ char **params = NULL;
+ char pb[1024];
+ char *locale = NULL;
+ if (extensions != NULL &&
+ extensions->GetValue("locale") != NULL)
+ {
+ locale = extensions->GetValue("locale");
+ } else {
+ locale = ( char * ) "en"; /* default to english */
+ }
+ int n = entry->GetAuthentication()->GetNumOfParamNames();
+ if (n > 0) {
+ RA::Debug("RA_Processor::Format",
+ "Extended Login Request detected n=%d", n);
+ params = (char **) PR_Malloc(n);
+ for (int i = 0; i < n; i++) {
+ sprintf(pb,"id=%s&name=%s&desc=%s&type=%s&option=%s",
+ entry->GetAuthentication()->GetParamID(i),
+ entry->GetAuthentication()->GetParamName(i, locale),
+ entry->GetAuthentication()->GetParamDescription(i,
+locale),
+ entry->GetAuthentication()->GetParamType(i),
+ entry->GetAuthentication()->GetParamOption(i)
+ );
+ params[i] = PL_strdup(pb);
+ RA::Debug("RA_Processor::Format",
+ "params[i]=%s", params[i]);
+ }
+ }
+ RA::Debug("RA_rocessor::Format", "Extended Login Request detected calling RequestExtendedLogin() locale=%s", locale);
+
+ char *title = PL_strdup(entry->GetAuthentication()->GetTitle(locale));
+ RA::Debug("RA_Processor::Format", "title=%s", title);
+ char *description = PL_strdup(entry->GetAuthentication()->GetDescription(locale));
+ RA::Debug("RA_Processor::Format", "description=%s", description);
+ login = RequestExtendedLogin(session, 0 /* invalid_pw */, 0 /* blocked */, params, n, title, description);
+
+ if (params != NULL) {
+ for (int nn=0; nn < n; nn++) {
+ if (params[nn] != NULL) {
+ PL_strfree(params[nn]);
+ params[nn] = NULL;
+ }
+ }
+ free(params);
+ params = NULL;
+ }
+
+ if (title != NULL) {
+ PL_strfree(title);
+ title = NULL;
+ }
+
+ if (description != NULL) {
+ PL_strfree(description);
+ description = NULL;
+ }
+
+
+ RA::Debug("RA_Processor::Format",
+ "Extended Login Request detected calling RequestExtendedLogin() login=%x", login);
+ } else {
+ login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */);
+ }
+ if (login == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "login not provided");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "login not provided, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ if (login->GetUID() == NULL) {
+ userid = NULL;
+ } else {
+ userid = PL_strdup( login->GetUID() );
+ }
+ }
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 2 /* progress */,
+ "PROGRESS_START_AUTHENTICATION");
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, false) && !skipAuth) {
+ if (login == NULL) {
+ RA::Error("RA_Format_Processor::Process", "Login Request Disabled. Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "login request disabled, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, tokenType);
+ authid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if (authid == NULL) {
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "login not found, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ AuthenticationEntry *auth = RA::GetAuth(authid);
+
+ if(auth == NULL)
+ {
+ RA::Error("RA_Format_Processor::Process", "Authentication manager is NULL . Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "authentication manager is NULL, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ char *type = auth->GetType();
+ if (type == NULL) {
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "authentication is missing param type, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ if (strcmp(type, "LDAP_Authentication") == 0) {
+ RA::Debug(LL_PER_PDU, "RA_Format_Processor::Process",
+ "LDAP_Authentication is invoked.");
+ int passwd_retries = auth->GetAuthentication()->GetNumOfRetries();
+ int retries = 0;
+ authParams = new AuthParams();
+ authParams->SetUID(login->GetUID());
+ authParams->SetPassword(login->GetPassword());
+ rc = auth->GetAuthentication()->Authenticate(authParams);
+
+ RA::Debug("RA_Format_Processor::Process",
+ "Authenticate returns: %d", rc);
+
+ while ((rc == -2 || rc == -3) && (retries < passwd_retries)) {
+ login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */);
+ retries++;
+ if (login == NULL || login->GetUID() == NULL) {
+ RA::Error("RA_Format_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "authentication failed, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ authParams->SetUID(login->GetUID());
+ authParams->SetPassword(login->GetPassword());
+ rc = auth->GetAuthentication()->Authenticate(authParams);
+ }
+
+ if (rc == -1) {
+ RA::Error("RA_Format_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LDAP_CONN;
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format", "Authentication status = %d", status);
+ PR_snprintf(audit_msg, 512, "Authentication failed, status = STATUS_ERROR_LDAP_CONN");
+ goto loser;
+ }
+
+ if (rc == -2 || rc == -3) {
+ RA::Error("RA_Format_Processor::Process", "Authentication failed.");
+ status = STATUS_ERROR_LOGIN;
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format", "Authentication status = %d", status);
+ PR_snprintf(audit_msg, 512, "Authentication failed, rc=-2 or -3, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format", "Authentication successful.");
+ } else {
+ RA::Error("RA_Format_Processor::Process", "No Authentication type was found.");
+ status = STATUS_ERROR_LOGIN;
+ PR_snprintf(audit_msg, 512, "No Authentication type found, status = STATUS_ERROR_LOGIN");
+ goto loser;
+ }
+ } else {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Authentication has been disabled.");
+ }
+
+ // check if it is the token owner
+ xuserid = RA::ra_get_token_userid(cuid);
+ if (xuserid != NULL && strcmp(xuserid, "") != 0) {
+ if (login != NULL) {
+ if (strcmp(login->GetUID(), xuserid) != 0) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Token owner mismatched");
+ status = STATUS_ERROR_NOT_TOKEN_OWNER;
+ PR_snprintf(audit_msg, 512, "Token owner mismatched, status = STATUS_ERROR_NOT_TOKEN_OWNER");
+ goto loser;
+ }
+ }
+ }
+
+ // we know cuid, msn and userid here
+ RA::Audit(EV_FORMAT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "success",
+ "format",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ "logged into token");
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 10 /* progress */,
+ "PROGRESS_APPLET_UPGRADE");
+ }
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.encryption", OP_PREFIX, tokenType);
+ upgrade_enc = RA::GetConfigStore()->GetConfigAsBool(configname, true);
+ if (!upgrade_enc)
+ security_level = SECURE_MSG_MAC;
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ upgrade_rc = UpgradeApplet(session,(char *) OP_PREFIX, (char*)tokenType, major_version,
+ minor_version, expected_version, applet_dir, security_level, connid,
+ extensions, 10, 90, &keyVersion);
+ if (upgrade_rc != 1) {
+ RA::Debug("RA_Processor::Format",
+ "applet upgrade failed");
+ status = STATUS_ERROR_UPGRADE_APPLET;
+ /**
+ * Bugscape #55709: Re-select Net Key Applet ONLY on failure.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "format", "failure", "applet upgrade error", "", tokenType);
+ // rc = -1 denotes Secure Channel Failure
+
+ if (rc == -1) {
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Failure", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "failed to setup secure channel");
+ } else {
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel");
+ }
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Failure", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "applet upgrade");
+
+ goto loser;
+ }
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel");
+
+ RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE,
+ userid, cuid, msn, "Success", "format",
+ keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "applet upgrade");
+
+ if( final_applet_version != NULL ) {
+ PR_Free( (char *) final_applet_version );
+ final_applet_version = NULL;
+ }
+
+ final_applet_version = expected_version;
+
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 90 /* progress */,
+ "PROGRESS_KEY_UPGRADE");
+ }
+
+ // add issuer info to the token
+ PR_snprintf((char *)configname, 256, "%s.%s.issuerinfo.enable",
+ OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) {
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ channel = SetupSecureChannel(session, 0x00,
+ defKeyIndex /* default key index */, connid);
+ rc = channel->ExternalAuthenticate();
+ if (channel != NULL) {
+ char issuer[224];
+ for (int i = 0; i < 224; i++) {
+ issuer[i] = 0;
+ }
+ PR_snprintf((char *)configname, 256, "%s.%s.issuerinfo.value",
+ OP_PREFIX, tokenType);
+ char *issuer_val = (char*)RA::GetConfigStore()->GetConfigAsString(
+ configname);
+ sprintf(issuer, "%s", issuer_val);
+ RA::Debug("RA_Processor::Format", "Set Issuer Info %s", issuer_val);
+ Buffer *info = new Buffer((BYTE*)issuer, 224);
+ rc = channel->SetIssuerInfo(info);
+
+ if (info != NULL) {
+ delete info;
+ info = NULL;
+ }
+ }
+ }
+
+ /**
+ * Checks if the netkey has the required key version.
+ */
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.enable", OP_PREFIX, tokenType);
+ if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) {
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ requiredV = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ channel = SetupSecureChannel(session, requiredV,
+ defKeyIndex /* default key index */, tksid);
+ if (channel == NULL) {
+ /**
+ * Select Card Manager for Put Key operation.
+ */
+ SelectApplet(session, 0x04, 0x00, CardManagerAID);
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 92 /* progress */,
+ "PROGRESS_SETUP_SECURE_CHANNEL");
+ }
+ /* if the key of the required version is
+ * not found, create them.
+ */
+ PR_snprintf((char *)configname, 256,"channel.defKeyVersion");
+ int defKeyVer = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ PR_snprintf((char *)configname, 256,"channel.defKeyIndex");
+ int defKeyIndex = RA::GetConfigStore()->GetConfigAsInt(configname, 0x0);
+ channel = SetupSecureChannel(session,
+ defKeyVer, /* default key version */
+ defKeyIndex /* default key index */, tksid);
+
+ if (channel == NULL) {
+ RA::Error("RA_Upgrade_Processor::Process",
+ "failed to establish secure channel");
+ status = STATUS_ERROR_SECURE_CHANNEL;
+ PR_snprintf(audit_msg, 512, "Failed to establish secure channel");
+ goto loser;
+ }
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 94 /* progress */,
+ "PROGRESS_EXTERNAL_AUTHENTICATE");
+ }
+
+ rc = channel->ExternalAuthenticate();
+
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ int v = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ curKeyInfo = channel->GetKeyInfoData();
+ BYTE nv[2] = { v, 0x01 };
+ Buffer newVersion(nv, 2);
+ PR_snprintf((char *)configname, 256,"%s.%s.tks.conn", OP_PREFIX, tokenType);
+ connid = RA::GetConfigStore()->GetConfigAsString(configname);
+ rc = CreateKeySetData(
+ channel->GetKeyDiversificationData(),
+ curKeyInfo,
+ newVersion,
+ key_data_set, connid);
+ if (rc != 1) {
+ RA::Error("RA_Format_Processor::Process",
+ "failed to create new key set");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512, "create key set error, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+ curVersion = ((BYTE*)curKeyInfo)[0];
+
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 96 /* progress */,
+ "PROGRESS_PUT_KEYS");
+ }
+
+ BYTE curIndex = ((BYTE*)curKeyInfo)[1];
+ rc = channel->PutKeys(session,
+ curVersion,
+ curIndex,
+ &key_data_set);
+
+
+ // need to check return value of rc
+ // and create audit log for failure
+
+ curKeyInfoStr = Util::Buffer2String(curKeyInfo);
+ newVersionStr = Util::Buffer2String(newVersion);
+
+ char curVer[10];
+ char newVer[10];
+
+ if(curKeyInfoStr != NULL && strlen(curKeyInfoStr) >= 2) {
+ curVer[0] = curKeyInfoStr[0]; curVer[1] = curKeyInfoStr[1]; curVer[2] = 0;
+ }
+ else {
+ curVer[0] = 0;
+ }
+
+ if(newVersionStr != NULL && strlen(newVersionStr) >= 2) {
+ newVer[0] = newVersionStr[0] ; newVer[1] = newVersionStr[1] ; newVer[2] = 0;
+ }
+ else {
+ newVer[0] = 0;
+ }
+
+ if (rc != 0) {
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Failure", "format",
+ final_applet_version != NULL ? final_applet_version : "", curVer, newVer,
+ "key changeover failed");
+ // do we goto loser here?
+ }
+
+ finalKeyVersion = ((int) ((BYTE *)newVersion)[0]);
+ /**
+ * Re-select Net Key Applet.
+ */
+ SelectApplet(session, 0x04, 0x00, NetKeyAID);
+ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType);
+ requiredV = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00);
+ PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType);
+ tksid = RA::GetConfigStore()->GetConfigAsString(configname);
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 98 /* progress */,
+ "PROGRESS_SETUP_SECURE_CHANNEL");
+ }
+
+
+ channel = SetupSecureChannel(session, requiredV,
+ defKeyIndex /* default key index */, tksid);
+ if (channel == NULL) {
+ RA::Error("RA_Format_Processor::Process",
+ "failed to establish secure channel after reselect");
+ status = STATUS_ERROR_CREATE_CARDMGR;
+ PR_snprintf(audit_msg, 512,"failed to establish secure channel after reselect, status = STATUS_ERROR_CREATE_CARDMGR");
+ goto loser;
+ }
+
+ RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER,
+ userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Success", "format",
+ final_applet_version != NULL ? final_applet_version : "", curVer, newVer,
+ "key changeover");
+
+ }
+ }
+
+ PR_snprintf((char *)filter, 256, "(cn=%s)", cuid);
+ rc = RA::ra_find_tus_token_entries(filter, 100, &result, 0);
+ if (rc == 0) {
+ for (e = RA::ra_get_first_entry(result); e != NULL; e = RA::ra_get_next_entry(e)) {
+ tokenFound = true;
+ break;
+ }
+ if (result != NULL)
+ ldap_msgfree(result);
+ }
+
+ // get keyVersion
+ if (channel != NULL) {
+ if (keyVersion != NULL) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+ keyVersion = Util::Buffer2String(channel->GetKeyInfoData());
+ }
+
+ // need to revoke all the certificates on this token
+ if (tokenFound) {
+
+ //Now we call a separate function, the audit_msg will get filled in there if needed.
+
+ bool success = RevokeCertificates(session, cuid,audit_msg,(char *)final_applet_version,
+ keyVersion,(char *)tokenType,(char *)userid,status
+ );
+
+ if(!success) {
+ goto loser;
+ }
+
+ } else {
+ rc = RA::tdb_update("", cuid, (char *)final_applet_version, keyVersion, "uninitialized", "", tokenType);
+ if (rc != 0) {
+ RA::Debug(LL_PER_PDU, "RA_Processor::Format",
+ "Failed to update the token database");
+ status = STATUS_ERROR_UPDATE_TOKENDB_FAILED;
+ PR_snprintf(audit_msg, 512, "Failed to update the token database, status = STATUS_ERROR_UPDATE_TOKENDB_FAILED");
+ goto loser;
+ }
+ }
+
+ // send status update to the client
+ if (extensions != NULL &&
+ extensions->GetValue("statusUpdate") != NULL) {
+ StatusUpdate(session, 100 /* progress */,
+ "PROGRESS_DONE");
+ }
+
+ status = STATUS_NO_ERROR;
+ rc = 1;
+
+ end = PR_IntervalNow();
+
+ sprintf(activity_msg, "applet_version=%s tokenType=%s",
+ final_applet_version, tokenType);
+ RA::tdb_activity(session->GetRemoteIP(), cuid, "format", "success", activity_msg, userid, tokenType);
+
+ /* audit log for successful format */
+ if (authid != NULL) {
+ sprintf(activity_msg, "format processing complete, authid = %s", authid);
+ } else {
+ sprintf(activity_msg, "format processing complete");
+ }
+ RA::Audit(EV_FORMAT, AUDIT_MSG_PROC,
+ userid, cuid, msn, "success", "format", final_applet_version,
+ keyVersion != NULL? keyVersion : "", activity_msg);
+
+loser:
+ if (strlen(audit_msg) > 0) { // a failure occurred
+ RA::Audit(EV_FORMAT, AUDIT_MSG_PROC,
+ userid != NULL ? userid : "",
+ cuid != NULL ? cuid : "",
+ msn != NULL ? msn : "",
+ "failure",
+ "format",
+ final_applet_version != NULL ? final_applet_version : "",
+ keyVersion != NULL? keyVersion : "",
+ audit_msg);
+
+ if ((cuid != NULL) && (tokenType != NULL)) {
+ RA::tdb_activity(session->GetRemoteIP(),
+ cuid,
+ "format",
+ "failure",
+ audit_msg,
+ userid != NULL? userid : "",
+ tokenType);
+ }
+ }
+
+ if (curKeyInfoStr != NULL) {
+ PR_Free( (char *) curKeyInfoStr);
+ curKeyInfoStr = NULL;
+ }
+
+ if (newVersionStr != NULL) {
+ PR_Free( (char *) newVersionStr);
+ newVersionStr = NULL;
+ }
+
+ if (keyVersion != NULL) {
+ PR_Free( (char *) keyVersion );
+ keyVersion = NULL;
+ }
+
+ if (ldapResult != NULL) {
+ ldap_msgfree(ldapResult);
+ }
+
+ if( cplc_data != NULL ) {
+ delete cplc_data;
+ cplc_data = NULL;
+ }
+ if( CardManagerAID != NULL ) {
+ delete CardManagerAID;
+ CardManagerAID = NULL;
+ }
+ if( NetKeyAID != NULL ) {
+ delete NetKeyAID;
+ NetKeyAID = NULL;
+ }
+ if( channel != NULL ) {
+ delete channel;
+ channel = NULL;
+ }
+ if( token_status != NULL ) {
+ delete token_status;
+ token_status = NULL;
+ }
+ if( buildID != NULL ) {
+ delete buildID;
+ buildID = NULL;
+ }
+ if( appletVersion != NULL ) {
+ PR_Free( (char *) appletVersion );
+ appletVersion = NULL;
+ }
+ if( final_applet_version != NULL ) {
+ PR_Free( (char *) final_applet_version );
+ final_applet_version = NULL;
+ }
+ if( userid != NULL ) {
+ PR_Free( (char *) userid );
+ userid = NULL;
+ }
+ if( cuid != NULL ) {
+ PR_Free( cuid );
+ cuid = NULL;
+ }
+ if( msn != NULL ) {
+ PR_Free( msn );
+ msn = NULL;
+ }
+ if( authParams != NULL ) {
+ delete authParams;
+ authParams = NULL;
+ }
+ if( login != NULL ) {
+ delete login;
+ login = NULL;
+ }
+
+#ifdef MEM_PROFILING
+ MEM_dump_unfree();
+#endif
+
+ RA::Debug("RA_Processor::Format"," returning status %d", status);
+ return status;
+}
+
+/**
+ * Process the current session. It does nothing in the base
+ * class.
+ */
+RA_Status RA_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ return STATUS_NO_ERROR;
+} /* Process */
+
diff --git a/base/tps/src/processor/RA_Renew_Processor.cpp b/base/tps/src/processor/RA_Renew_Processor.cpp
new file mode 100644
index 000000000..5caa329b4
--- /dev/null
+++ b/base/tps/src/processor/RA_Renew_Processor.cpp
@@ -0,0 +1,57 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "engine/RA.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Renew_Processor.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a renew processor.
+ */
+TPS_PUBLIC RA_Renew_Processor::RA_Renew_Processor()
+{
+}
+
+/**
+ * Destructs a renew processor.
+ */
+TPS_PUBLIC RA_Renew_Processor::~RA_Renew_Processor()
+{
+}
+
+/**
+ * Processes the current session.
+ */
+TPS_PUBLIC RA_Status RA_Renew_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ RA::Debug("RA_Renew_Processor::Process",
+ "RA_Renew_Processor::Process");
+
+ return STATUS_NO_ERROR;
+}
diff --git a/base/tps/src/processor/RA_Unblock_Processor.cpp b/base/tps/src/processor/RA_Unblock_Processor.cpp
new file mode 100644
index 000000000..0bdbcfa2b
--- /dev/null
+++ b/base/tps/src/processor/RA_Unblock_Processor.cpp
@@ -0,0 +1,58 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "engine/RA.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "processor/RA_Processor.h"
+#include "processor/RA_Unblock_Processor.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs the unblock processor.
+ */
+TPS_PUBLIC RA_Unblock_Processor::RA_Unblock_Processor()
+{
+} /* RA_Unblock_Processor */
+
+/**
+ * Destructs the unblock processor.
+ */
+TPS_PUBLIC RA_Unblock_Processor::~RA_Unblock_Processor()
+{
+} /* RA_Unblock_Processor */
+
+/**
+ * Processes the current session.
+ */
+TPS_PUBLIC RA_Status RA_Unblock_Processor::Process(RA_Session *session, NameValueSet *extensions)
+{
+ RA::Debug("RA_Unblock_Processor::Process", "Client %s", session->GetRemoteIP());
+
+ RA::Debug("RA_Unblock_Processor::Process",
+ "RA_Unblock_Processor::Process");
+ return STATUS_NO_ERROR;
+} /* Process */
diff --git a/base/tps/src/selftests/SelfTest.cpp b/base/tps/src/selftests/SelfTest.cpp
new file mode 100644
index 000000000..71266d581
--- /dev/null
+++ b/base/tps/src/selftests/SelfTest.cpp
@@ -0,0 +1,220 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#include "cert.h"
+#include "certt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "engine/RA.h"
+#include "main/ConfigStore.h"
+#include "selftests/SelfTest.h"
+#include "selftests/TPSPresence.h"
+#include "selftests/TPSValidity.h"
+#include "selftests/TPSSystemCertsVerification.h"
+
+
+const char *SelfTest::CFG_SELFTEST_STARTUP = "selftests.container.order.startup";
+const char *SelfTest::CFG_SELFTEST_ONDEMAND = "selftests.container.order.onDemand";
+const int SelfTest::nTests = 3;
+const char *SelfTest::TEST_NAMES[SelfTest::nTests] = { TPSPresence::TEST_NAME, TPSValidity::TEST_NAME, TPSSystemCertsVerification::TEST_NAME };
+
+int SelfTest::isInitialized = 0;
+int SelfTest::StartupSystemCertsVerificationRun = 0;
+
+SelfTest::SelfTest()
+{
+}
+
+SelfTest::~SelfTest()
+{
+}
+
+void SelfTest::Initialize (ConfigStore *cfg)
+{
+ if (SelfTest::isInitialized == 0) {
+ SelfTest::isInitialized = 1;
+ TPSPresence::Initialize (cfg);
+ TPSValidity::Initialize (cfg);
+ TPSSystemCertsVerification::Initialize (cfg);
+ SelfTest::isInitialized = 2;
+ }
+ RA::SelfTestLog("SelfTest::Initialize", "%s", ((isInitialized==2)?"successfully completed":"failed"));
+}
+
+// Error codes:
+// -1 - missing cert db handle
+// 2 - missing cert
+// -3 - missing cert nickname
+// 4 - secCertTimeExpired
+// 5 - secCertTimeNotValidYet
+// critical errors are negative
+
+int SelfTest::runStartUpSelfTests (const char *nickname)
+{
+ int rc = 0;
+ CERTCertificate *cert = 0;
+
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "per cert selftests starting for %s", nickname);
+ if (TPSPresence::isStartupEnabled()) {
+ rc = TPSPresence::runSelfTest(nickname, &cert);
+ }
+ if (rc != 0 && TPSPresence::isStartupCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Critical TPSPresence self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Noncritical TPSPresence self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "TPSPresence self test has been successfully completed.");
+ }
+ if (TPSValidity::isStartupEnabled()) {
+ rc = TPSValidity::runSelfTest(nickname, cert);
+ }
+ if (cert != 0) {
+ CERT_DestroyCertificate (cert);
+ cert = 0;
+ }
+ if (rc != 0 && TPSValidity::isStartupCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Critical TPSValidity self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Noncritical TPSValidity self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "TPSValidity self test has been successfully completed.");
+ }
+
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "per cert selftests done for %s", nickname);
+ return 0;
+}
+
+int SelfTest::runStartUpSelfTests ()
+{
+ int rc = 0;
+
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "general selftests starting");
+ /* this only needs to run once at startup */
+ if (SelfTest::StartupSystemCertsVerificationRun == 0) {
+ if (TPSSystemCertsVerification::isStartupEnabled()) {
+ rc = TPSSystemCertsVerification::runSelfTest();
+ }
+ if (rc != 0 && TPSSystemCertsVerification::isStartupCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Critical TPSSystemCertsVerification self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "Noncritical TPSSystemCertsVerification self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "TPSSystemCertsVerification self test has been successfully completed.");
+ }
+ SelfTest::StartupSystemCertsVerificationRun = 1;
+ }
+
+ RA::SelfTestLog("SelfTest::runStartUpSelfTests", "general selftests done");
+ return 0;
+}
+
+int SelfTest::runOnDemandSelfTests ()
+{
+ int rc = 0;
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "starting");
+ if (TPSPresence::isOnDemandEnabled()) {
+ rc = TPSPresence::runSelfTest();
+ }
+ if (rc != 0 && TPSPresence::isOnDemandCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Critical TPSPresence self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Noncritical TPSPresence self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "TPSPresence self test has been successfully completed.");
+ }
+ if (TPSValidity::isOnDemandEnabled()) {
+ rc = TPSValidity::runSelfTest();
+ }
+ if (rc != 0 && TPSValidity::isOnDemandCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Critical TPSValidity self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Noncritical TPSValidity self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "TPSValidity self test has been successfully completed.");
+ }
+
+ if (TPSSystemCertsVerification::isOnDemandEnabled()) {
+ rc = TPSSystemCertsVerification::runSelfTest();
+ }
+ if (rc != 0 && TPSSystemCertsVerification::isOnDemandCritical()) {
+ if (rc > 0) rc *= -1;
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Critical TPSSystemCertsVerification self test failure: %d", rc);
+ return rc;
+ } else if (rc != 0) {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "Noncritical TPSSystemCertsVerification self test failure: %d", rc);
+ } else {
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "TPSSystemCertsVerification self test has been successfully completed.");
+ }
+ RA::SelfTestLog("SelfTest::runOnDemandSelfTests", "done");
+ return rc;
+}
+
+int SelfTest::isOnDemandEnabled ()
+{
+ int n = 0;
+ if (TPSPresence::isOnDemandEnabled()) n++;
+ if (TPSValidity::isOnDemandEnabled()) n += 2;
+ if (TPSSystemCertsVerification::isOnDemandEnabled()) n += 4;
+ return n;
+}
+
+int SelfTest::isOnDemandCritical ()
+{
+ int n = 0;
+ if (TPSPresence::isOnDemandCritical()) n++;
+ if (TPSValidity::isOnDemandCritical()) n += 2;
+ if (TPSSystemCertsVerification::isOnDemandCritical()) n += 4;
+ return n;
+}
+
diff --git a/base/tps/src/selftests/TPSPresence.cpp b/base/tps/src/selftests/TPSPresence.cpp
new file mode 100644
index 000000000..7f37fd0fb
--- /dev/null
+++ b/base/tps/src/selftests/TPSPresence.cpp
@@ -0,0 +1,204 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#include "cert.h"
+#include "certt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "engine/RA.h"
+#include "main/ConfigStore.h"
+#include "selftests/TPSPresence.h"
+
+
+int TPSPresence::initialized = 0;
+bool TPSPresence::startupEnabled = false;
+bool TPSPresence::onDemandEnabled = false;
+bool TPSPresence::startupCritical = false;
+bool TPSPresence::onDemandCritical = false;
+char *TPSPresence::nickname = 0;
+const char *TPSPresence::UNINITIALIZED_NICKNAME = "[HSM_LABEL][NICKNAME]";
+const char *TPSPresence::NICKNAME_NAME = "selftests.plugin.TPSPresence.nickname";
+const char *TPSPresence::CRITICAL_TEST_NAME = "TPSPresence:critical";
+const char *TPSPresence::TEST_NAME = "TPSPresence";
+
+//default constructor
+TPSPresence::TPSPresence()
+{
+}
+
+TPSPresence::~TPSPresence()
+{
+}
+
+void TPSPresence::Initialize (ConfigStore *cfg)
+{
+ if (TPSPresence::initialized == 0) {
+ TPSPresence::initialized = 1;
+ const char* s = cfg->GetConfigAsString(CFG_SELFTEST_STARTUP);
+ if (s != 0) {
+ if (PL_strstr (s, TPSPresence::CRITICAL_TEST_NAME) != 0) {
+ startupCritical = true;
+ startupEnabled = true;
+ } else if (PL_strstr (s, TPSPresence::TEST_NAME) != 0) {
+ startupEnabled = true;
+ }
+ }
+ const char* d = cfg->GetConfigAsString(CFG_SELFTEST_ONDEMAND);
+ if (d != 0) {
+ if (PL_strstr (d, TPSPresence::CRITICAL_TEST_NAME) != 0) {
+ onDemandCritical = true;
+ onDemandEnabled = true;
+ } else if (PL_strstr (d, TPSPresence::TEST_NAME) != 0) {
+ onDemandEnabled = true;
+ }
+ }
+ char* n = (char*)(cfg->GetConfigAsString(TPSPresence::NICKNAME_NAME));
+ if (n != 0 && PL_strlen(n) > 0) {
+ if (PL_strstr (n, TPSPresence::UNINITIALIZED_NICKNAME) != NULL) {
+ TPSPresence::initialized = 0;
+ } else {
+ TPSPresence::nickname = n;
+ }
+
+ TPSPresence::nickname = n;
+ }
+ if (TPSPresence::initialized == 1) {
+ TPSPresence::initialized = 2;
+ }
+ }
+ RA::SelfTestLog("TPSPresence::Initialize", "%s", ((initialized==2)?"successfully completed":"failed"));
+}
+
+// Error codes:
+// -1 - missing cert db handle
+// 2 - missing cert
+// -3 - missing cert nickname
+// 4 - secCertTimeExpired
+// 5 - secCertTimeNotValidYet
+// critical errors are negative
+
+int TPSPresence::runSelfTest ()
+{
+ int rc = 0;
+
+ if (TPSPresence::initialized == 2) {
+ if (TPSPresence::nickname != 0 && PL_strlen(TPSPresence::nickname) > 0) {
+ rc = TPSPresence::runSelfTest (TPSPresence::nickname);
+ } else {
+ rc = -3;
+ }
+ }
+
+ return rc;
+}
+
+int TPSPresence::runSelfTest (const char *nick_name)
+{
+ int rc = 0;
+ CERTCertDBHandle *handle = 0;
+ CERTCertificate *cert = 0;
+
+ if (TPSPresence::initialized == 2) {
+ if (nick_name != 0 && PL_strlen(nick_name) > 0) {
+ handle = CERT_GetDefaultCertDB();
+ if (handle != 0) {
+ cert = CERT_FindCertByNickname( handle, (char *) nick_name);
+ if (cert != 0) {
+ CERT_DestroyCertificate (cert);
+ cert = 0;
+ } else {
+ rc = 2;
+ }
+ } else {
+ rc = -1;
+ }
+ } else {
+ rc = TPSPresence::runSelfTest ();
+ }
+ }
+
+ return rc;
+}
+
+int TPSPresence::runSelfTest (const char *nick_name, CERTCertificate **cert)
+{
+ int rc = 0;
+ CERTCertDBHandle *handle = 0;
+
+ if (TPSPresence::initialized == 2) {
+ handle = CERT_GetDefaultCertDB();
+ if (handle != 0) {
+ *cert = CERT_FindCertByNickname( handle, (char *) nick_name);
+ if (*cert == NULL) {
+ rc = 2;
+ }
+ } else {
+ rc = 1;
+ }
+ }
+
+ return rc;
+}
+
+bool TPSPresence::isStartupEnabled ()
+{
+ return startupEnabled;
+}
+
+bool TPSPresence::isOnDemandEnabled ()
+{
+ return onDemandEnabled;
+}
+
+bool TPSPresence::isStartupCritical ()
+{
+ return startupCritical;
+}
+
+bool TPSPresence::isOnDemandCritical ()
+{
+ return onDemandCritical;
+}
+
+
diff --git a/base/tps/src/selftests/TPSSystemCertsVerification.cpp b/base/tps/src/selftests/TPSSystemCertsVerification.cpp
new file mode 100644
index 000000000..a89d18d04
--- /dev/null
+++ b/base/tps/src/selftests/TPSSystemCertsVerification.cpp
@@ -0,0 +1,149 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#include "cert.h"
+#include "certt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "engine/RA.h"
+#include "main/ConfigStore.h"
+#include "selftests/TPSSystemCertsVerification.h"
+
+
+int TPSSystemCertsVerification::initialized = 0;
+bool TPSSystemCertsVerification::startupEnabled = false;
+bool TPSSystemCertsVerification::onDemandEnabled = false;
+bool TPSSystemCertsVerification::startupCritical = false;
+bool TPSSystemCertsVerification::onDemandCritical = false;
+const char *TPSSystemCertsVerification::CRITICAL_TEST_NAME = "TPSSystemCertsVerification:critical";
+const char *TPSSystemCertsVerification::TEST_NAME = "TPSSystemCertsVerification";
+// for testing if system is initialized
+const char *TPSSystemCertsVerification::UNINITIALIZED_NICKNAME = "[HSM_LABEL][NICKNAME]";
+const char *TPSSystemCertsVerification::SUBSYSTEM_NICKNAME= "tps.cert.subsystem.nickname";
+
+
+//default constructor
+TPSSystemCertsVerification::TPSSystemCertsVerification()
+{
+}
+
+TPSSystemCertsVerification::~TPSSystemCertsVerification()
+{
+}
+
+void TPSSystemCertsVerification::Initialize (ConfigStore *cfg)
+{
+ if (TPSSystemCertsVerification::initialized == 0) {
+ TPSSystemCertsVerification::initialized = 1;
+ const char* s = cfg->GetConfigAsString(CFG_SELFTEST_STARTUP);
+ if (s != NULL) {
+ if (PL_strstr (s, TPSSystemCertsVerification::CRITICAL_TEST_NAME) != NULL) {
+ startupCritical = true;
+ startupEnabled = true;
+ } else if (PL_strstr (s, TPSSystemCertsVerification::TEST_NAME) != NULL) {
+ startupEnabled = true;
+ }
+ }
+ const char* d = cfg->GetConfigAsString(CFG_SELFTEST_ONDEMAND);
+ if (d != NULL) {
+ if (PL_strstr (d, TPSSystemCertsVerification::CRITICAL_TEST_NAME) != NULL) {
+ onDemandCritical = true;
+ onDemandEnabled = true;
+ } else if (PL_strstr (d, TPSSystemCertsVerification::TEST_NAME) != NULL) {
+ onDemandEnabled = true;
+ }
+ }
+ char* n = (char*)(cfg->GetConfigAsString(TPSSystemCertsVerification::SUBSYSTEM_NICKNAME));
+ if (n != NULL && PL_strlen(n) > 0) {
+ if (PL_strstr (n, TPSSystemCertsVerification::UNINITIALIZED_NICKNAME) != NULL) {
+ TPSSystemCertsVerification::initialized = 0;
+ }
+ }
+ if (TPSSystemCertsVerification::initialized == 1) {
+ TPSSystemCertsVerification::initialized = 2;
+ }
+ }
+ RA::SelfTestLog("TPSSystemCertsVerification::Initialize", "%s", ((initialized==2)?"successfully completed":"failed"));
+}
+
+// Error codes:
+// -1 - failed system certs verification
+// critical errors are negative
+
+int TPSSystemCertsVerification::runSelfTest ()
+{
+ int rc = 0;
+
+ if (TPSSystemCertsVerification::initialized == 2) {
+ rc = RA::verifySystemCerts();
+ if (rc == true) {
+ return 0;
+ } else {
+ rc = -1;
+ }
+ }
+
+ return rc;
+}
+
+bool TPSSystemCertsVerification::isStartupEnabled ()
+{
+ return startupEnabled;
+}
+
+bool TPSSystemCertsVerification::isOnDemandEnabled ()
+{
+ return onDemandEnabled;
+}
+
+bool TPSSystemCertsVerification::isStartupCritical ()
+{
+ return startupCritical;
+}
+
+bool TPSSystemCertsVerification::isOnDemandCritical ()
+{
+ return onDemandCritical;
+}
+
diff --git a/base/tps/src/selftests/TPSValidity.cpp b/base/tps/src/selftests/TPSValidity.cpp
new file mode 100644
index 000000000..e70263e80
--- /dev/null
+++ b/base/tps/src/selftests/TPSValidity.cpp
@@ -0,0 +1,215 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2010 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+
+#include "cert.h"
+#include "certt.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "engine/RA.h"
+#include "main/ConfigStore.h"
+#include "selftests/TPSValidity.h"
+
+
+int TPSValidity::initialized = 0;
+bool TPSValidity::startupEnabled = false;
+bool TPSValidity::onDemandEnabled = false;
+bool TPSValidity::startupCritical = false;
+bool TPSValidity::onDemandCritical = false;
+char *TPSValidity::nickname = 0;
+const char *TPSValidity::UNINITIALIZED_NICKNAME = "[HSM_LABEL][NICKNAME]";
+const char *TPSValidity::NICKNAME_NAME = "selftests.plugin.TPSValidity.nickname";
+const char *TPSValidity::CRITICAL_TEST_NAME = "TPSValidity:critical";
+const char *TPSValidity::TEST_NAME = "TPSValidity";
+
+
+//default constructor
+TPSValidity::TPSValidity()
+{
+}
+
+TPSValidity::~TPSValidity()
+{
+}
+
+void TPSValidity::Initialize (ConfigStore *cfg)
+{
+ if (TPSValidity::initialized == 0) {
+ TPSValidity::initialized = 1;
+ const char* s = cfg->GetConfigAsString(CFG_SELFTEST_STARTUP);
+ if (s != NULL) {
+ if (PL_strstr (s, TPSValidity::CRITICAL_TEST_NAME) != NULL) {
+ startupCritical = true;
+ startupEnabled = true;
+ } else if (PL_strstr (s, TPSValidity::TEST_NAME) != NULL) {
+ startupEnabled = true;
+ }
+ }
+ const char* d = cfg->GetConfigAsString(CFG_SELFTEST_ONDEMAND);
+ if (d != NULL) {
+ if (PL_strstr (d, TPSValidity::CRITICAL_TEST_NAME) != NULL) {
+ onDemandCritical = true;
+ onDemandEnabled = true;
+ } else if (PL_strstr (d, TPSValidity::TEST_NAME) != NULL) {
+ onDemandEnabled = true;
+ }
+ }
+ char* n = (char*)(cfg->GetConfigAsString(TPSValidity::NICKNAME_NAME));
+ if (n != NULL && PL_strlen(n) > 0) {
+ if (PL_strstr (n, TPSValidity::UNINITIALIZED_NICKNAME) != NULL) {
+ TPSValidity::initialized = 0;
+ } else {
+ TPSValidity::nickname = n;
+ }
+ }
+ if (TPSValidity::initialized == 1) {
+ TPSValidity::initialized = 2;
+ }
+ }
+ RA::SelfTestLog("TPSValidity::Initialize", "%s", ((initialized==2)?"successfully completed":"failed"));
+}
+
+// Error codes:
+// -1 - missing cert db handle
+// 2 - missing cert
+// -3 - missing cert nickname
+// 4 - secCertTimeExpired
+// 5 - secCertTimeNotValidYet
+// critical errors are negative
+
+int TPSValidity::runSelfTest ()
+{
+ int rc = 0;
+
+ if (TPSValidity::initialized == 2) {
+ if (TPSValidity::nickname != NULL && PL_strlen(TPSValidity::nickname) > 0) {
+ rc = TPSValidity::runSelfTest (TPSValidity::nickname);
+ } else {
+ rc = -3;
+ }
+ }
+
+ return rc;
+}
+
+int TPSValidity::runSelfTest (const char *nick_name)
+{
+ SECCertTimeValidity certTimeValidity;
+ PRTime now;
+ int rc = 0;
+ CERTCertDBHandle *handle = 0;
+ CERTCertificate *cert = 0;
+
+ if (TPSValidity::initialized == 2) {
+ handle = CERT_GetDefaultCertDB();
+ if (handle != 0) {
+ cert = CERT_FindCertByNickname( handle, (char *) nick_name);
+ if (cert != 0) {
+ now = PR_Now();
+ certTimeValidity = CERT_CheckCertValidTimes (cert, now, PR_FALSE);
+ if (certTimeValidity == secCertTimeExpired) {
+ rc = 4;
+ } else if (certTimeValidity == secCertTimeNotValidYet) {
+ rc = 5;
+ }
+ CERT_DestroyCertificate (cert);
+ cert = 0;
+ } else {
+ rc = 2;
+ }
+ } else {
+ rc = -1;
+ }
+ }
+
+ return rc;
+}
+
+int TPSValidity::runSelfTest (const char *nick_name, CERTCertificate *cert)
+{
+ SECCertTimeValidity certTimeValidity;
+ PRTime now;
+ int rc = 0;
+
+ if (TPSValidity::initialized == 2) {
+ if (cert != 0) {
+ now = PR_Now();
+ certTimeValidity = CERT_CheckCertValidTimes (cert, now, PR_FALSE);
+ if (certTimeValidity == secCertTimeExpired) {
+ rc = 4;
+ } else if (certTimeValidity == secCertTimeNotValidYet) {
+ rc = 5;
+ }
+ CERT_DestroyCertificate (cert);
+ cert = 0;
+ } else if (nick_name != 0 && PL_strlen(nick_name) > 0) {
+ rc = TPSValidity::runSelfTest (nick_name);
+ } else {
+ rc = TPSValidity::runSelfTest ();
+ }
+ }
+
+ return rc;
+
+}
+
+bool TPSValidity::isStartupEnabled ()
+{
+ return startupEnabled;
+}
+
+bool TPSValidity::isOnDemandEnabled ()
+{
+ return onDemandEnabled;
+}
+
+bool TPSValidity::isStartupCritical ()
+{
+ return startupCritical;
+}
+
+bool TPSValidity::isOnDemandCritical ()
+{
+ return onDemandCritical;
+}
+
diff --git a/base/tps/src/test/Test_ConfigStore.cfg b/base/tps/src/test/Test_ConfigStore.cfg
new file mode 100644
index 000000000..60f8e8675
--- /dev/null
+++ b/base/tps/src/test/Test_ConfigStore.cfg
@@ -0,0 +1,28 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation;
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301 USA
+#
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+integer=100
+string=steve
+sub1.integer=500
+sub1.string=paul
+sub1.sub2.integer=1000
+sub1.sub2.string=jim
+
+
diff --git a/base/tps/src/test/Test_ConfigStore.cpp b/base/tps/src/test/Test_ConfigStore.cpp
new file mode 100644
index 000000000..d81a67b03
--- /dev/null
+++ b/base/tps/src/test/Test_ConfigStore.cpp
@@ -0,0 +1,79 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+
+#include "main/ConfigStore.h"
+
+
+// This is needed to resolve a symbol expected by the linker
+int __nsapi30_table;
+
+ConfigStore getsubstore(ConfigStore& config, char *subname)
+{
+ printf("Getting sub store : %s\n", subname);
+ ConfigStore sub2 = config.GetSubStore(subname);
+ const char *t = sub2.GetConfigAsString("string");
+ printf("substore string : %s\n", t);
+
+
+ printf("returning substore to parent\n");
+ return sub2;
+}
+
+int main()
+{
+ int i;
+ const char *s;
+
+ ConfigStore *cfg = ConfigStore::CreateFromConfigFile("Test_ConfigStore.cfg");
+
+ printf("TOP LEVEL\n");
+ i = cfg->GetConfigAsInt("integer");
+ printf("int : %d\n",i);
+ s = cfg->GetConfigAsString("string");
+ printf("string : %s\n",s);
+
+
+ printf("\nSUB1 LEVEL\n");
+ ConfigStore subcfg = cfg->GetSubStore("sub1");
+ i = subcfg.GetConfigAsInt("integer");
+ printf("int : %d\n",i);
+ s = subcfg.GetConfigAsString("string");
+ printf("string : %s\n",s);
+ s = subcfg["string"];
+ printf("[string] : %s\n",s);
+
+ printf("\nSUB2 LEVEL in method\n");
+ ConfigStore sub2cfg = getsubstore(subcfg,"sub2");
+ printf("accessing sub2 from main\n");
+ i = sub2cfg.GetConfigAsInt("integer");
+ printf("int : %d\n",i);
+
+
+ printf("\nTOP LEVEL AGAIN\n");
+ i = cfg->GetConfigAsInt("integer");
+ printf("int : %d\n",i);
+ s = cfg->GetConfigAsString("string");
+
+ ConfigStore subcfg2 = cfg->GetSubStore("level2");
+
+
+}
+
diff --git a/base/tps/src/tus/CMakeLists.txt b/base/tps/src/tus/CMakeLists.txt
new file mode 100644
index 000000000..3148d9e59
--- /dev/null
+++ b/base/tps/src/tus/CMakeLists.txt
@@ -0,0 +1,50 @@
+project(tokendb_library C)
+
+set(TOKENDB_PUBLIC_INCLUDE_DIRS
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${TPS_INCLUDE_DIR}
+ CACHE INTERNAL "tokendb public include directories"
+)
+
+set(TOKENDB_PRIVATE_INCLUDE_DIRS
+ ${TOKENDB_PUBLIC_INCLUDE_DIRS}
+ ${CMAKE_BINARY_DIR}
+ ${NSPR_INCLUDE_DIRS}
+ ${NSS_INCLUDE_DIRS}
+ ${SVRCORE_INCLUDE_DIRS}
+ ${LDAP_INCLUDE_DIRS}
+)
+
+set(TOKENDB_SHARED_LIBRARY
+ tokendb_library
+ CACHE INTERNAL "tokendb shared library"
+)
+
+set(TOKENDB_LINK_LIBRARIES
+ ${NSPR_LIBRARIES}
+ ${NSS_LIBRARIES}
+ ${SVRCORE_LIBRARIES}
+ ${LDAP_LIBRARIES}
+)
+
+set(tokendb_library_SRCS
+ tus_db.c
+)
+
+include_directories(${TOKENDB_PRIVATE_INCLUDE_DIRS})
+
+add_library(${TOKENDB_SHARED_LIBRARY} SHARED ${tokendb_library_SRCS})
+target_link_libraries(${TOKENDB_SHARED_LIBRARY} ${TOKENDB_LINK_LIBRARIES})
+
+set_target_properties(${TOKENDB_SHARED_LIBRARY}
+ PROPERTIES
+ OUTPUT_NAME
+ tokendb
+)
+
+install(
+ TARGETS
+ ${TOKENDB_SHARED_LIBRARY}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}/tps
+)
diff --git a/base/tps/src/tus/tus_db.c b/base/tps/src/tus/tus_db.c
new file mode 100644
index 000000000..c865bc371
--- /dev/null
+++ b/base/tps/src/tus/tus_db.c
@@ -0,0 +1,4515 @@
+/* --- BEGIN COPYRIGHT BLOCK ---
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ * All rights reserved.
+ * --- END COPYRIGHT BLOCK ---
+ */
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "nspr.h"
+#include "pk11func.h"
+#include "cryptohi.h"
+#include "keyhi.h"
+#include "base64.h"
+#include "nssb64.h"
+#include "prlock.h"
+#include "secder.h"
+#include "cert.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "plstr.h"
+#include "prmem.h"
+#include "prprf.h"
+#include "prtime.h"
+
+#include "tus/tus_db.h"
+
+static char *tokenActivityAttributes[] = { TOKEN_ID,
+ TOKEN_CUID,
+ TOKEN_OP,
+ TOKEN_USER,
+ TOKEN_MSG,
+ TOKEN_RESULT,
+ TOKEN_IP,
+ TOKEN_C_DATE,
+ TOKEN_M_DATE,
+ TOKEN_TYPE,
+ NULL };
+static char *tokenAttributes[] = { TOKEN_ID,
+ TOKEN_USER,
+ TOKEN_STATUS,
+ TOKEN_APPLET,
+ TOKEN_KEY_INFO,
+ TOKEN_MODS,
+ TOKEN_C_DATE,
+ TOKEN_M_DATE,
+ TOKEN_RESETS,
+ TOKEN_ENROLLMENTS,
+ TOKEN_RENEWALS,
+ TOKEN_RECOVERIES,
+ TOKEN_POLICY,
+ TOKEN_REASON,
+ TOKEN_TYPE,
+ NULL };
+static char *tokenCertificateAttributes[] = { TOKEN_ID,
+ TOKEN_CUID,
+ TOKEN_USER,
+ TOKEN_STATUS,
+ TOKEN_C_DATE,
+ TOKEN_M_DATE,
+ TOKEN_SUBJECT,
+ TOKEN_ISSUER,
+ TOKEN_SERIAL,
+ TOKEN_CERT,
+ TOKEN_TYPE,
+ TOKEN_NOT_BEFORE,
+ TOKEN_NOT_AFTER,
+ TOKEN_KEY_TYPE,
+ TOKEN_STATUS,
+ NULL };
+
+static char *userAttributes[] = {USER_ID,
+ USER_SN,
+ USER_GIVENNAME,
+ USER_CN,
+ USER_CERT,
+ C_TIME,
+ M_TIME,
+ PROFILE_ID,
+ NULL};
+
+static char *viewUserAttributes[] = {USER_ID,
+ USER_SN,
+ USER_CN,
+ C_TIME,
+ M_TIME,
+ NULL};
+
+static char *tokenStates[] = { STATE_UNINITIALIZED,
+ STATE_ACTIVE,
+ STATE_DISABLED,
+ NULL };
+
+#ifdef __cplusplus
+}
+#endif
+
+static char *ssl = NULL; /* true or false */
+static char *host = NULL;
+static int port = 0;
+static char *userBaseDN = NULL;
+static char *baseDN = NULL;
+static char *activityBaseDN = NULL;
+static char *certBaseDN = NULL;
+static char *bindDN = NULL;
+static char *bindPass = NULL;
+static char *defaultPolicy = NULL;
+
+static int ccHost = 0;
+static int ccBaseDN = 0;
+static int ccBindDN = 0;
+static int ccBindPass = 0;
+
+static LDAP *ld = NULL;
+static int bindStatus = -1;
+
+static PRFileDesc *debug_fd = NULL;
+static PRFileDesc *audit_fd = NULL;
+
+extern void audit_log(const char *func_name, const char *userid, const char *msg);
+
+char *get_pwd_from_conf(char *filepath, char *name);
+static int tus_check_conn();
+
+TPS_PUBLIC int valid_berval(struct berval **b)
+{
+ if ((b != NULL) && (b[0] != NULL) && (b[0]->bv_val != NULL))
+ return 1;
+ return 0;
+}
+
+TPS_PUBLIC void set_tus_db_port(int number)
+{
+ port = number;
+}
+
+TPS_PUBLIC void set_tus_db_hostport(char *name)
+{
+ char *s = NULL;
+
+ s = PL_strstr(name, ":");
+ if (s == NULL) {
+ set_tus_db_port(389);
+ } else {
+ set_tus_db_port(atoi(s+1));
+ s[0] = '\0';
+ }
+ set_tus_db_host(name);
+}
+
+TPS_PUBLIC void set_tus_db_host(char *name)
+{
+ if( ccHost > 0 && host != NULL ) {
+ PL_strfree( host );
+ host = NULL;
+ }
+ if( name != NULL ) {
+ host = PL_strdup( name );
+ }
+ ccHost++;
+}
+
+TPS_PUBLIC void set_tus_db_baseDN(char *dn)
+{
+ if( ccBaseDN > 0 && baseDN != NULL ) {
+ PL_strfree( baseDN );
+ baseDN = NULL;
+ }
+ if( dn != NULL ) {
+ baseDN = PL_strdup( dn );
+ }
+ ccBaseDN++;
+}
+
+TPS_PUBLIC void set_tus_db_userBaseDN(char *dn)
+{
+ if( userBaseDN != NULL ) {
+ PL_strfree( userBaseDN );
+ userBaseDN = NULL;
+ }
+ if( dn != NULL ) {
+ userBaseDN = PL_strdup( dn );
+ }
+}
+
+TPS_PUBLIC void set_tus_db_activityBaseDN(char *dn)
+{
+ if( activityBaseDN != NULL ) {
+ PL_strfree( activityBaseDN );
+ activityBaseDN = NULL;
+ }
+ if( dn != NULL ) {
+ activityBaseDN = PL_strdup( dn );
+ }
+}
+
+TPS_PUBLIC void set_tus_db_certBaseDN(char *dn)
+{
+ if( certBaseDN != NULL ) {
+ PL_strfree( certBaseDN );
+ certBaseDN = NULL;
+ }
+ if( dn != NULL ) {
+ certBaseDN = PL_strdup( dn );
+ }
+}
+
+TPS_PUBLIC void set_tus_db_bindDN(char *dn)
+{
+ if( ccBindDN > 0 && bindDN != NULL ) {
+ PL_strfree( bindDN );
+ bindDN = NULL;
+ }
+ if( dn != NULL ) {
+ bindDN = PL_strdup( dn );
+ }
+ ccBindDN++;
+}
+
+TPS_PUBLIC void set_tus_db_bindPass(char *p)
+{
+ if( ccBindPass > 0 && bindPass != NULL ) {
+ PL_strfree( bindPass );
+ bindPass = NULL;
+ }
+ if( p != NULL ) {
+ bindPass = PL_strdup( p );
+ }
+ ccBindPass++;
+}
+
+TPS_PUBLIC int is_tus_db_initialized()
+{
+ return ((ld != NULL && bindStatus == LDAP_SUCCESS)? 1: 0);
+}
+
+TPS_PUBLIC int get_tus_db_config(char *cfg_name)
+{
+ PRFileInfo info;
+ PRFileDesc *fd = NULL;
+ PRUint32 size;
+ int k, n, p;
+ char *buf = NULL;
+ char *s = NULL;
+ char *v = NULL;
+
+ if (PR_GetFileInfo (cfg_name, &info) != PR_SUCCESS)
+ return 0;
+ size = info.size;
+ size++;
+ buf = (char *)PR_Malloc(size);
+ if (buf == NULL)
+ return 0;
+
+ fd = PR_Open(cfg_name, PR_RDONLY, 400);
+ if (fd == NULL) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+
+ k = 0;
+ while ((n = PR_Read(fd, &buf[k], size-k-1)) > 0) {
+ k += n;
+ if ((PRUint32)(k+1) >= size) break;
+ }
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+ if (n < 0 || ((PRUint32)(k+1) > size)) {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ buf[k] = '\0';
+
+ if ((s = PL_strstr(buf, "tokendb.hostport=")) != NULL) {
+
+ s += 17;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_hostport(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.port=")) != NULL) {
+
+ s += 13;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ p = atoi(s);
+ set_tus_db_port(p);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.ssl=")) != NULL) {
+
+ s += 12;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ if (strcmp(s, "") != 0) {
+ ssl = PL_strdup( s );
+ }
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.auditLog=")) != NULL) {
+
+ s += 17;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ if (strcmp(s, "") != 0) {
+ audit_fd = PR_Open(s, PR_RDWR | PR_CREATE_FILE | PR_APPEND,
+ 400 | 200);
+ }
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.host=")) != NULL) {
+
+ s += 13;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_host(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.defaultPolicy=")) != NULL) {
+
+ s += 22;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ defaultPolicy = PL_strdup( s );
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.userBaseDN=")) != NULL) {
+ s += 19;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_userBaseDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if ((s = PL_strstr(buf, "tokendb.baseDN=")) != NULL) {
+ s += 15;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_baseDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.activityBaseDN=")) != NULL) {
+ s += strlen("tokendb.activityBaseDN=");
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_activityBaseDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.certBaseDN=")) != NULL) {
+ s += strlen("tokendb.certBaseDN=");
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_certBaseDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.bindDN=")) != NULL) {
+ s += 15;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ set_tus_db_bindDN(s);
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+ if ((s = PL_strstr(buf, "tokendb.bindPassPath=")) != NULL) {
+ s += 21;
+ v = s;
+ while (*s != '\x0D' && *s != '\x0A' && *s != '\0' &&
+ (PRUint32)(s - buf) < size) {
+ s++;
+ }
+ n = s - v;
+ s = PL_strndup(v, n);
+ if (s != NULL) {
+ /* read tokendbBindPass from bindPassPath */
+ char *p = NULL;
+ p = get_pwd_from_conf(s, "tokendbBindPass");
+ set_tus_db_bindPass(p);
+ if (p) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "freeing p - %s\n", p);
+ PR_Free( p );
+ }
+ PL_strfree( s );
+ s = NULL;
+ } else {
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if( buf != NULL ) {
+ PR_Free( buf );
+ buf = NULL;
+ }
+
+ tus_db_end();
+
+ return 1;
+}
+
+
+TPS_PUBLIC char *tus_authenticate(char *cert)
+{
+ char *dst;
+ int len;
+ int certlen;
+ int rc = -1;
+#define MAX_FILTER_LEN 4096
+ char filter[MAX_FILTER_LEN];
+ char searchBase[MAX_FILTER_LEN];
+ struct berval **v = NULL;
+ char *userid = NULL;
+ LDAPMessage *result = NULL;
+ LDAPMessage *entry = NULL;
+ int i,j;
+ char *certX = NULL;
+ int tries;
+
+ tus_check_conn();
+ if (cert == NULL)
+ return NULL;
+
+ certlen = strlen(cert);
+
+ certX = malloc(certlen);
+ j = 0;
+ for (i = 0; i < certlen; i++) {
+ if (cert[i] != '\n' && cert[i] != '\r') {
+ certX[j++] = cert[i];
+ }
+ }
+ certX[j++] = '\0';
+ dst = malloc(3 * strlen(certX) / 4);
+ len = base64_decode(certX, ( unsigned char * ) dst);
+ free(certX);
+
+ if (len <= 0) {
+ if (dst != NULL) free(dst);
+ return NULL;
+ }
+
+ PR_snprintf(filter, MAX_FILTER_LEN, "(userCertificate=");
+
+ for (i = 0; i < len; i++) {
+ char c = dst[i];
+ PR_snprintf(filter, MAX_FILTER_LEN, "%s\\%02x", filter, (c & 0xff) );
+ }
+ PR_snprintf(filter, MAX_FILTER_LEN, "%s)", filter);
+ PR_snprintf(searchBase, MAX_FILTER_LEN, "ou=People, %s", userBaseDN);
+
+ if (dst != NULL) free(dst);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s(ld, searchBase, LDAP_SCOPE_SUBTREE,
+ filter, NULL, 0, NULL, NULL, NULL, 0, &result)) == LDAP_SUCCESS )
+ {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (rc != LDAP_SUCCESS) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return NULL;
+ }
+
+ if (result == NULL)
+ return NULL;
+
+ entry = get_first_entry (result);
+ if (entry == NULL) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return NULL;
+ }
+
+ v = ldap_get_values_len(ld, entry, "uid");
+ if (v == NULL) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return NULL;
+ }
+
+ if (valid_berval(v) && PL_strlen(v[0]->bv_val) > 0) {
+ userid = PL_strdup(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+
+ return userid;
+}
+
+/*********
+ * tus_authorize
+ * parameters passed in:
+ * char * group ("TUS Agents", "TUS Operators", "TUS Administrators")
+ * const char* userid
+ * returns : 1 if userid is member of that group
+ * 0 otherwise
+ **/
+
+TPS_PUBLIC int tus_authorize(const char *group, const char *userid)
+{
+ int rc;
+ char filter[4096];
+ int tries;
+ LDAPMessage *result = NULL;
+
+ PR_snprintf(filter, 4096,
+ "(&(cn=%s)(member=uid=%s,*))", group ,userid);
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s(ld, userBaseDN, LDAP_SCOPE_SUBTREE,
+ filter, NULL, 0, NULL, NULL, NULL, 0, &result)) == LDAP_SUCCESS )
+ {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (rc != LDAP_SUCCESS) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return 0;
+ }
+ if (ldap_count_entries (ld, result) <= 0) {
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return 0;
+ }
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+ return 1;
+}
+
+/******
+ * get_authorized_profiles()
+ * params: userid
+ * : is_admin (1 if user is in admin group, 0 otherwise
+ * returns: ldap filter with the tokenTypes the user has access to - to be appended
+ * to any other user search filer.
+ * examples: (|(tokenType=foo)(tokenType=bar)
+ * example: (!(tokenType=foo)(tokenType=no_token_type)) -- if user is an admin, always
+ * add no_token_type to catch admin events
+ * example: NO_PROFILES -- not an admin, and no profiles
+ * exmaple: (tokenType=no_token_type) : admin with no other tokens
+ *
+ * Caller must free the result (char*)
+ **/
+TPS_PUBLIC char *get_authorized_profiles(const char *userid, int is_admin)
+{
+ int status;
+ char filter[512];
+ char ret[4096] = "";
+ char *profile_filter = NULL;
+ struct berval **vals = NULL;
+ int nVals;
+ int i;
+
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+
+// Debug("TUS","get_authorized_profiles");
+ PR_snprintf(filter, 512, "(uid=%s)", userid);
+ status = find_tus_user_entries_no_vlv(filter, &result, 0);
+
+ if (status == LDAP_SUCCESS) {
+
+ e = get_first_entry(result);
+
+ vals = get_attribute_values(e,"profileID");
+ if (valid_berval(vals)) {
+ nVals = ldap_count_values_len(vals);
+ if (nVals == 1) {
+ if (PL_strstr(vals[0]->bv_val, ALL_PROFILES)) {
+ if (is_admin) {
+ // all profiles
+ PR_snprintf(ret, 4096, ALL_PROFILES);
+ } else {
+ // all profile except admin no token events
+ PR_snprintf(ret, 4096, "(!(tokenType=%s))", NO_TOKEN_TYPE);
+ }
+ } else {
+ if (is_admin) {
+ PL_strcat(ret, "(|(tokenType=");
+ PL_strcat(ret, NO_TOKEN_TYPE);
+ PL_strcat(ret, ")(tokenType=");
+ PL_strcat(ret, vals[0]->bv_val);
+ PL_strcat(ret, "))");
+ } else {
+ PL_strcat(ret, "(tokenType=");
+ PL_strcat(ret, vals[0]->bv_val);
+ PL_strcat(ret, ")");
+ }
+ }
+ } else if (nVals > 1) {
+ for( i = 0; vals[i] != NULL; i++ ) {
+ if (i==0) {
+ PL_strcat(ret, "(|");
+ if (is_admin) {
+ PL_strcat(ret, "(tokenType=");
+ PL_strcat(ret, NO_TOKEN_TYPE);
+ PL_strcat(ret, ")");
+ }
+ }
+ if (vals[i]->bv_val != NULL) {
+ PL_strcat(ret, "(tokenType=");
+ PL_strcat(ret, vals[i]->bv_val);
+ PL_strcat(ret, ")");
+ }
+ }
+ PL_strcat(ret, ")");
+ } else if (nVals == 0) {
+ if (is_admin) {
+ PR_snprintf(ret, 4096, "(tokenType=%s)", NO_TOKEN_TYPE);
+ } else {
+ PR_snprintf(ret, 4096, NO_PROFILES);
+ }
+ } else { //error
+ return NULL;
+ }
+ } else {
+ if (is_admin) {
+ PR_snprintf(ret, 4096, "(tokenType=%s)", NO_TOKEN_TYPE);
+ } else {
+ PR_snprintf(ret, 4096, NO_PROFILES);
+ }
+ }
+ } else {
+ // log error message here
+ PR_snprintf(ret, 4096, NO_PROFILES);
+ }
+
+ profile_filter = PL_strdup(ret);
+
+ if (vals != NULL) {
+ free_values(vals, 1);
+ vals = NULL;
+ }
+
+ if (result != NULL) {
+ free_results(result);
+ result = NULL;
+ }
+
+ e = NULL;
+
+ return profile_filter;
+}
+
+static int tus_check_conn()
+{
+ int version = LDAP_VERSION3;
+ int status = -1;
+ char ldapuri[1024];
+
+/* for production, make sure this variable is not defined.
+ * Leaving it defined results in weird Apache SSL timeout errors */
+/*#define DEBUG_TOKENDB*/
+
+#ifdef DEBUG_TOKENDB
+ debug_fd = PR_Open("/tmp/debugTUSdb.log",
+ PR_RDWR | PR_CREATE_FILE | PR_APPEND,
+ 400 | 200);
+#endif
+ if (ld == NULL) {
+ if (ssl != NULL && strcmp(ssl, "true") == 0) {
+ /* enabling SSL */
+ snprintf(ldapuri, 1024, "ldaps://%s:%i", host, port);
+ } else {
+ snprintf(ldapuri, 1024, "ldap://%s:%i", host, port);
+ }
+ status = ldap_initialize(&ld, ldapuri);
+ if (ld == NULL) {
+ return status;
+ }
+
+ // This option was supported by mozldap but is not supported by openldap.
+ // Code to provide this functionality needs to be written - FIXME
+ /*if ((status = ldap_set_option (ld, LDAP_OPT_RECONNECT, LDAP_OPT_ON)) != LDAP_SUCCESS) {
+ return status;
+ }*/
+
+ if ((status = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_SUCCESS) {
+ return status;
+ }
+ }
+ if (ld != NULL && bindStatus != LDAP_SUCCESS) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ bindStatus = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (bindStatus != LDAP_SUCCESS) {
+ return bindStatus;
+ }
+ }
+
+ return LDAP_SUCCESS;
+}
+
+TPS_PUBLIC int tus_db_init(char **errorMsg)
+{
+ return LDAP_SUCCESS;
+}
+
+TPS_PUBLIC void tus_db_end()
+{
+ if (ld != NULL) {
+ if (ldap_unbind_ext_s(ld, NULL, NULL) == LDAP_SUCCESS) {
+ ld = NULL;
+ bindStatus = -1;
+ }
+ }
+}
+
+TPS_PUBLIC void tus_db_cleanup()
+{
+ if (ssl != NULL) {
+ PL_strfree(ssl);
+ ssl = NULL;
+ }
+ if (host != NULL) {
+ PL_strfree(host);
+ host = NULL;
+ }
+ if (userBaseDN != NULL) {
+ PL_strfree(userBaseDN);
+ userBaseDN = NULL;
+ }
+ if (baseDN != NULL) {
+ PL_strfree(baseDN);
+ baseDN = NULL;
+ }
+ if (activityBaseDN != NULL) {
+ PL_strfree(activityBaseDN);
+ activityBaseDN = NULL;
+ }
+ if(certBaseDN != NULL) {
+ PL_strfree(certBaseDN);
+ certBaseDN = NULL;
+ }
+ if(bindDN != NULL) {
+ PL_strfree(bindDN);
+ bindDN = NULL;
+ }
+ if(bindPass != NULL) {
+ PL_strfree(bindPass);
+ bindPass = NULL;
+ }
+ if(defaultPolicy != NULL) {
+ PL_strfree(defaultPolicy);
+ defaultPolicy = NULL;
+ }
+ if (debug_fd != NULL) {
+ PR_Close(debug_fd);
+ debug_fd = NULL;
+ }
+ if (audit_fd != NULL) {
+ PR_Close(audit_fd);
+ audit_fd = NULL;
+ }
+}
+
+/*****
+ * tus_print_integer
+ * summary: prints serial number as hex string
+ * modeled on SECU_PrintInteger. The length
+ * 4 below is arbitrary - but works!
+ * params: out - output hexidecimal string
+ * data - serial number as SECItem
+ */
+TPS_PUBLIC void tus_print_integer(char *out, SECItem *i)
+{
+ int iv;
+
+ if (!i || !i->len || !i->data) {
+ sprintf(out, "(null)");
+ } else if (i->len > 4) {
+ tus_print_as_hex(out, i);
+ } else {
+ if (i->type == siUnsignedInteger && *i->data & 0x80) {
+ /* Make sure i->data has zero in the highest byte
+ * if i->data is an unsigned integer */
+ SECItem tmpI;
+ char data[] = {0, 0, 0, 0, 0};
+
+ PORT_Memcpy(data + 1, i->data, i->len);
+ tmpI.len = i->len + 1;
+ tmpI.data = (void*)data;
+
+ iv = DER_GetInteger(&tmpI);
+ } else {
+ iv = DER_GetInteger(i);
+ }
+ sprintf(out, "%x", iv);
+ }
+}
+
+/***
+ * tus_print_as_hex
+ * summary: prints serial number as a hex string, needed
+ * because DER_GetInteger only works for small numbers
+ * modeled on SECU_PrintAsHex
+ * params: out - output hexidecimal string
+ * data - serial number as SECItem
+ */
+TPS_PUBLIC void tus_print_as_hex(char *out, SECItem *data)
+{
+ unsigned i;
+ int isString = 1;
+ char tmp[32];
+
+ PR_snprintf(out, 2, "");
+
+ /* take a pass to see if it's all printable. */
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+ if (!val || !isprint(val)) {
+ isString = 0;
+ break;
+ }
+ }
+
+ if (!isString) {
+ for (i = 0; i < data->len; i++) {
+ PR_snprintf(tmp, 32, "%02x", data->data[i]);
+ PL_strcat(out, tmp);
+ }
+ } else {
+ for (i = 0; i < data->len; i++) {
+ unsigned char val = data->data[i];
+
+ PR_snprintf(tmp, 32, "%c", val);
+ PL_strcat(out, tmp);
+ }
+ }
+ PL_strcat(out, '\0');
+}
+
+char **parse_number_change(int n)
+{
+ char tmp[32];
+ int l;
+ char **v = NULL;
+
+ PR_snprintf(tmp, 32, "%d", n);
+ l = PL_strlen(tmp);
+
+ if ((v = allocate_values(1, l+1)) == NULL) {
+ return NULL;
+ }
+ PL_strcpy(v[0], tmp);
+
+ return v;
+}
+
+TPS_PUBLIC int update_cert_status (char *cn, const char *status)
+{
+ char dn[256];
+ int len;
+ int tries;
+ int rc = -1;
+ char **v = NULL;
+ LDAPMod **mods = NULL;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, certBaseDN) < 0)
+ return -1;
+
+ mods = allocate_modifications(2);
+ if (mods == NULL)
+ return -1;
+
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = tokenAttributes[I_TOKEN_M_DATE];
+ mods[0]->mod_values = v;
+ if (status != NULL && PL_strlen(status) > 0) {
+ len = PL_strlen(status);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], status);
+
+ mods[1]->mod_op = LDAP_MOD_REPLACE;
+ mods[1]->mod_type = "tokenStatus";
+ mods[1]->mod_values = v;
+ }
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int update_token_policy (char *cn, char *policy)
+{
+ char dn[256];
+ int len, k;
+ int tries;
+ int rc = -1;
+ char **v = NULL;
+ LDAPMod **mods = NULL;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ mods = allocate_modifications(2);
+ if (mods == NULL)
+ return -1;
+
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = tokenAttributes[I_TOKEN_M_DATE];
+ mods[0]->mod_values = v;
+ k = 1;
+ if (policy != NULL && PL_strlen(policy) > 0) {
+ len = PL_strlen(policy);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], policy);
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = tokenAttributes[I_TOKEN_POLICY];
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int update_tus_db_entry_with_mods (const char *agentid, const char *cn, LDAPMod **mods)
+{
+ char dn[256];
+ int tries;
+ int rc = -1;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ return rc;
+}
+
+/****
+ * update_tus_general_db_entry
+ * summary: internal function to modify a general db entry using ldap_modify_ext_s
+ * params: agentid - who is doing this modification (for audit logging)
+ * dn - dn to modify
+ * mods - NULL terminated list of modifications to apply
+ **/
+int update_tus_general_db_entry(const char *agentid, const char *dn, LDAPMod **mods)
+{
+ int tries;
+ int rc = -1;
+
+ tus_check_conn();
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/***
+ * update_user_db_entry
+ * summary: modifies an existing user entry
+ * params : agentid - agent that is performing this action (for audit log purposes)
+ * uid, lastName, firstName, userCN, userCert - for entry to be added
+ * returns: ldap return code
+ * */
+TPS_PUBLIC int update_user_db_entry(const char *agentid, char *uid, char *lastName, char *firstName, char *userCN, char *userCert)
+{
+ char dn[256];
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod *mods[5];
+ int rc = -1;
+ int certlen=0;
+ int i,j;
+ char *certX = NULL;
+ char *dst = NULL;
+
+ char *sn_values[] = {lastName, NULL};
+ char *givenName_values[] = {firstName, NULL};
+ char *cn_values[] = {userCN, NULL};
+ struct berval berval;
+ struct berval *cert_values[2];
+
+ a01.mod_op = LDAP_MOD_REPLACE;
+ a01.mod_type = USER_SN;
+ a01.mod_values = sn_values;
+
+ a02.mod_op = LDAP_MOD_REPLACE;
+ a02.mod_type = USER_CN;
+ a02.mod_values = cn_values;
+
+ a03.mod_op = LDAP_MOD_REPLACE;
+ a03.mod_type = USER_GIVENNAME;
+ a03.mod_values = ((firstName != NULL && PL_strlen(firstName) > 0)? givenName_values: NULL);
+
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+
+ certlen = strlen(userCert);
+
+ certX = malloc(certlen);
+ j = 0;
+ for (i = 0; i < certlen; i++) {
+ if (userCert[i] != '\n' && userCert[i] != '\r') {
+ certX[j++] = userCert[i];
+ }
+ }
+ certX[j++] = '\0';
+ dst = malloc(3 * strlen(certX) / 4);
+ certlen = base64_decode(certX, ( unsigned char * ) dst);
+ free(certX);
+
+ if (certlen > 0) {
+ berval.bv_len = certlen;
+ berval.bv_val = ( char * ) dst;
+ cert_values[0] = &berval;
+ cert_values[1] = NULL;
+
+ a04.mod_op =LDAP_MOD_REPLACE |LDAP_MOD_BVALUES;
+ a04.mod_type = "userCertificate";
+ a04.mod_bvalues = cert_values;
+
+ mods[3] = &a04;
+ } else {
+ mods[3] = NULL;
+ }
+
+ mods[4] = NULL;
+
+ if (PR_snprintf(dn, 255, "uid=%s, ou=People, %s", uid, userBaseDN) < 0 )
+ return -1;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (dst != NULL) free(dst);
+ if (rc == LDAP_SUCCESS)
+ audit_log("modify_user", agentid, uid);
+
+ return rc;
+}
+
+TPS_PUBLIC int update_tus_db_entry (const char *agentid, char *cn, const char *uid, char *keyInfo, const char *status, char *applet_version, const char *reason, const char* token_type)
+{
+ char dn[256];
+ int len, k;
+ int tries;
+ int rc = -1;
+ char **v = NULL;
+ LDAPMod **mods = NULL;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ if (keyInfo == NULL && token_type == NULL)
+ mods = allocate_modifications(5);
+ else if (keyInfo == NULL || token_type == NULL)
+ mods = allocate_modifications(6);
+ else
+ mods = allocate_modifications(7);
+ if (mods == NULL)
+ return -1;
+
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = tokenAttributes[I_TOKEN_M_DATE];
+ mods[0]->mod_values = v;
+ k = 1;
+ if (applet_version != NULL && PL_strlen(applet_version) > 0) {
+ len = PL_strlen(applet_version);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], applet_version);
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = tokenAttributes[I_TOKEN_APPLET];
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ /* for userid */
+ if (uid != NULL && PL_strlen(uid) > 0)
+ len = PL_strlen(uid);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = "tokenUserID";
+ if (uid != NULL && PL_strlen(uid) > 0)
+ PL_strcpy(v[0], uid);
+ else
+ v[0] = "";
+ mods[k]->mod_values = v;
+ k++;
+
+ if (status != NULL && PL_strlen(status) > 0) {
+ len = PL_strlen(status);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], status);
+
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = tokenAttributes[I_TOKEN_STATUS];
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ /* for tokenReason */
+ if (reason != NULL && PL_strlen(reason) > 0)
+ len = PL_strlen(reason);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = "tokenReason";
+ if (reason != NULL && PL_strlen(reason) > 0)
+ PL_strcpy(v[0], reason);
+ else
+ v[0] = "";
+ mods[k]->mod_values = v;
+ k++;
+
+ /* for keyinfo */
+ if (keyInfo != NULL) {
+ if (keyInfo != NULL && PL_strlen(keyInfo) > 0)
+ len = PL_strlen(keyInfo);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = tokenAttributes[I_TOKEN_KEY_INFO];
+ if (keyInfo != NULL && PL_strlen(keyInfo) > 0)
+ PL_strcpy(v[0], keyInfo);
+ else
+ v[0] = "";
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ /* for token_type */
+ if (token_type != NULL) {
+ if (token_type != NULL && PL_strlen(token_type) > 0)
+ len = PL_strlen(token_type);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[k]->mod_op = LDAP_MOD_REPLACE;
+ mods[k]->mod_type = TOKEN_TYPE;
+ if (len > 0)
+ PL_strcpy(v[0], token_type);
+ else
+ v[0] = "";
+ mods[k]->mod_values = v;
+ k++;
+ }
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+
+ return rc;
+}
+
+int check_and_modify_tus_db_entry (char *userid, char *cn, char *check, LDAPMod **mods)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ if (check == NULL) {
+ return -1;
+ }
+
+ struct berval check_ber;
+ check_ber.bv_val = check;
+ check_ber.bv_len = strlen(check);
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_compare_ext_s(ld, dn, get_number_of_modifications_name(), &check_ber, NULL, NULL))
+ == LDAP_COMPARE_TRUE) {
+ break;
+ } else {
+ if (rc != LDAP_SERVER_DOWN && rc != LDAP_CONNECT_ERROR) {
+ return rc;
+ }
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ return rc;
+ }
+ }
+ }
+ if (tries >= MAX_RETRIES)
+ return rc;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ /* audit log */
+ if (rc == LDAP_SUCCESS) {
+ audit_log("check_and_modify_token", userid, cn);
+ }
+
+ return rc;
+}
+
+int modify_tus_db_entry (char *userid, char *cn, LDAPMod **mods)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+ if (ld == NULL) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "tus_db mod: ld null...no ldap");
+ return -1;
+ }
+ if (mods == NULL) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "tus_db mod: mods null, can't modify");
+ return -1;
+ }
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+ if (debug_fd)
+ PR_fprintf(debug_fd, "tus_db mod: modifying :%s\n",dn);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "tus_db mod: tries=%d\n",tries);
+ if ((rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (rc == LDAP_SUCCESS) {
+ audit_log("modify_token", userid, cn);
+ }
+
+ return rc;
+}
+
+int add_certificate (char *tokenid, char *origin, char *tokenType, char *userid, CERTCertificate *certificate, char *ktype, const char *status)
+{
+ PRExplodedTime time;
+ PRTime now;
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod a05;
+ LDAPMod a06;
+ LDAPMod a07;
+ LDAPMod a08;
+ LDAPMod a09;
+ LDAPMod a10;
+ LDAPMod a11;
+ LDAPMod a12;
+ LDAPMod a13;
+ LDAPMod a14;
+ LDAPMod a15;
+ LDAPMod a16;
+ LDAPMod *mods[17];
+ int rc = 0, tries = 0;
+ char dn[2049];
+ char cdate[256];
+ char name[2048];
+ char x_not_before[2048];
+ char x_not_after[2048];
+ char serialnumber[2048];
+ char *serial_values[2];
+ char *cn_values[2];
+ char *issuer_values[2];
+ char *subject_values[2];
+ char *cdate_values[2];
+ char *id_values[2];
+ char *userid_values[2];
+ char *type_values[2];
+ char *key_type_values[2];
+ char *origin_values[2];
+ char *status_values[2];
+ char *not_before_values[2];
+ char *not_after_values[2];
+ PRThread *ct;
+ struct berval berval;
+ struct berval *cert_values[2];
+ char *objectClass_values[] = { "top", "tokenCert", NULL };
+ PRTime not_before,not_after;
+ char zcdate[256];
+
+ tus_check_conn();
+ ct = PR_GetCurrentThread();
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ /* unique id per activity */
+ tus_print_integer(serialnumber, &certificate->serialNumber);
+
+ PR_snprintf(name, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ /* unique id per activity */
+ PR_snprintf(zcdate, 256, "%s.%04d%02d%02d%02d%02d%02d",
+ serialnumber,
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ cn_values[0] = zcdate;
+ cn_values[1] = NULL;
+
+ a01.mod_op = 0;
+ a01.mod_type = TOKEN_ID;
+ a01.mod_values = cn_values;
+
+ a02.mod_op = 0;
+ a02.mod_type = "objectClass";
+ a02.mod_values = objectClass_values;
+
+ cdate_values[0] = cdate;
+ cdate_values[1] = NULL;
+ a03.mod_op = 0;
+ a03.mod_type = TOKEN_C_DATE;
+ a03.mod_values = cdate_values;
+
+ a04.mod_op = 0;
+ a04.mod_type = TOKEN_M_DATE;
+ a04.mod_values = cdate_values;
+
+ id_values[0] = tokenid;
+ id_values[1] = NULL;
+ a05.mod_op = 0;
+ a05.mod_type = TOKEN_CUID;
+ a05.mod_values = id_values;
+
+ userid_values[0] = userid;
+ userid_values[1] = NULL;
+ a06.mod_op = 0;
+ a06.mod_type = TOKEN_USER;
+ a06.mod_values = userid_values;
+
+ berval.bv_len = certificate->derCert.len;
+ berval.bv_val = ( char * ) certificate->derCert.data;
+ cert_values[0] = &berval;
+ cert_values[1] = NULL;
+
+ a07.mod_op = LDAP_MOD_BVALUES;
+ a07.mod_type = TOKEN_CERT;
+ a07.mod_values = ( char ** ) cert_values;
+
+ subject_values[0] = certificate->subjectName;
+ subject_values[1] = NULL;
+ a08.mod_op = 0;
+ a08.mod_type = TOKEN_SUBJECT;
+ a08.mod_values = subject_values;
+
+ issuer_values[0] = certificate->issuerName;
+ issuer_values[1] = NULL;
+ a09.mod_op = 0;
+ a09.mod_type = TOKEN_ISSUER;
+ a09.mod_values = issuer_values;
+
+ serial_values[0] = serialnumber;
+ serial_values[1] = NULL;
+ a10.mod_op = 0;
+ a10.mod_type = TOKEN_SERIAL;
+ a10.mod_values = serial_values;
+
+ type_values[0] = tokenType;
+ type_values[1] = NULL;
+ a11.mod_op = 0;
+ a11.mod_type = TOKEN_TYPE;
+ a11.mod_values = type_values;
+
+ key_type_values[0] = ktype;
+ key_type_values[1] = NULL;
+ a12.mod_op = 0;
+ a12.mod_type = TOKEN_KEY_TYPE;
+ a12.mod_values = key_type_values;
+
+ status_values[0] = ( char * ) status;
+ status_values[1] = NULL;
+ a13.mod_op = 0;
+ a13.mod_type = TOKEN_STATUS;
+ a13.mod_values = status_values;
+
+ CERT_GetCertTimes (certificate, &not_before, &not_after);
+
+ PR_ExplodeTime(not_before, PR_LocalTimeParameters, &time);
+ PR_snprintf(x_not_before, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ not_before_values[0] = x_not_before;
+ not_before_values[1] = NULL;
+ a14.mod_op = 0;
+ a14.mod_type = TOKEN_NOT_BEFORE;
+ a14.mod_values = not_before_values;
+
+ PR_ExplodeTime(not_after, PR_LocalTimeParameters, &time);
+ PR_snprintf(x_not_after, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ not_after_values[0] = x_not_after;
+ not_after_values[1] = NULL;
+ a15.mod_op = 0;
+ a15.mod_type = TOKEN_NOT_AFTER;
+ a15.mod_values = not_after_values;
+
+ origin_values[0] = origin;
+ origin_values[1] = NULL;
+ a16.mod_op = 0;
+ a16.mod_type = TOKEN_ORIGIN;
+ a16.mod_values = origin_values;
+
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+ mods[3] = &a04;
+ mods[4] = &a05;
+ mods[5] = &a06;
+ mods[6] = &a07;
+ mods[7] = &a08;
+ mods[8] = &a09;
+ mods[9] = &a10;
+ mods[10] = &a11;
+ mods[11] = &a12;
+ mods[12] = &a13;
+ mods[13] = &a14;
+ mods[14] = &a15;
+ mods[15] = &a16;
+ mods[16] = NULL;
+
+ if (PR_snprintf(dn, 2048, "cn=%s,%s", cn_values[0], certBaseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+int add_activity (const char *ip, const char *id, const char *op, const char *result, const char *msg, const char *userid, const char *token_type)
+{
+ PRExplodedTime time;
+ PRTime now;
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod a05;
+ LDAPMod a06;
+ LDAPMod a07;
+ LDAPMod a08;
+ LDAPMod a09;
+ LDAPMod a10;
+ LDAPMod a11;
+ LDAPMod *mods[12];
+ int rc = 0, tries = 0;
+ char dn[256];
+ char cdate[256];
+ char zcdate[256];
+ char *cn_values[2];
+ char *objectClass_values[] = { "top", "tokenActivity", NULL };
+ char *cdate_values[2];
+ char *id_values[2];
+ char *result_values[2];
+ char *op_values[2];
+ char *msg_values[2];
+ char *ip_values[2];
+ char *userid_values[2];
+ char *token_type_values[2];
+ PRThread *ct;
+
+ tus_check_conn();
+ id_values[0] = (char *) id;
+ id_values[1] = NULL;
+ result_values[0] = ( char * ) result;
+ result_values[1] = NULL;
+ op_values[0] = ( char * ) op;
+ op_values[1] = NULL;
+ msg_values[0] = ( char * ) msg;
+ msg_values[1] = NULL;
+ ip_values[0] = (char *) ip;
+ ip_values[1] = NULL;
+ userid_values[0] = (char *) userid;
+ userid_values[1] = NULL;
+ token_type_values[0] = (char *) token_type;
+ token_type_values[1] = NULL;
+
+ ct = PR_GetCurrentThread();
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ /* unique id per activity */
+ PR_snprintf(zcdate, 256, "%04d%02d%02d%02d%02d%02d%06d.%x",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec, time.tm_usec, ct);
+
+ cn_values[0] = zcdate;
+ cn_values[1] = NULL;
+
+ a01.mod_op = 0;
+ a01.mod_type = TOKEN_ID;
+ a01.mod_values = cn_values;
+
+ a02.mod_op = 0;
+ a02.mod_type = "objectClass";
+ a02.mod_values = objectClass_values;
+
+ cdate_values[0] = cdate;
+ cdate_values[1] = NULL;
+ a03.mod_op = 0;
+ a03.mod_type = TOKEN_C_DATE;
+ a03.mod_values = cdate_values;
+
+ a04.mod_op = 0;
+ a04.mod_type = TOKEN_M_DATE;
+ a04.mod_values = cdate_values;
+
+ a05.mod_op = 0;
+ a05.mod_type = TOKEN_CUID;
+ a05.mod_values = id_values;
+
+ a06.mod_op = 0;
+ a06.mod_type = TOKEN_OP;
+ a06.mod_values = op_values;
+
+ a07.mod_op = 0;
+ a07.mod_type = TOKEN_MSG;
+ a07.mod_values = msg_values;
+
+ a08.mod_op = 0;
+ a08.mod_type = TOKEN_RESULT;
+ a08.mod_values = result_values;
+
+ a09.mod_op = 0;
+ a09.mod_type = TOKEN_IP;
+ a09.mod_values = ip_values;
+
+ a10.mod_op = 0;
+ a10.mod_type = TOKEN_USER;
+ a10.mod_values = userid_values;
+
+ a11.mod_op = 0;
+ a11.mod_type = TOKEN_TYPE;
+ a11.mod_values = token_type_values;
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+ mods[3] = &a04;
+ mods[4] = &a05;
+ mods[5] = &a06;
+ mods[6] = &a07;
+ mods[7] = &a08;
+ mods[8] = &a09;
+ mods[9] = &a10;
+ mods[10] = &a11;
+ mods[11] = NULL;
+
+ if (PR_snprintf(dn, 255, "cn=%s,%s", zcdate, activityBaseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * add_tus_general_db_entry
+ * summary: internal function to add a general ldap entry
+ * params: dn = dn to add
+ * mods = NULL terminated list of modifications (contains attribute values)
+ * returns: LDAP return code
+ **/
+int add_tus_general_db_entry (char *dn, LDAPMod **mods)
+{
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+
+ }
+ return rc;
+}
+
+int add_tus_db_entry (char *cn, LDAPMod **mods)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+int add_new_tus_db_entry (const char *userid, char *cn, const char *uid, int flag, const char *status, char *applet_version, char *key_info, const char* token_type)
+{
+ PRExplodedTime time;
+ PRTime now;
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod a05;
+ LDAPMod a06;
+ LDAPMod a07;
+ LDAPMod a08;
+ LDAPMod a09;
+ LDAPMod a10;
+ LDAPMod a11;
+ LDAPMod a12;
+ LDAPMod a13;
+ LDAPMod a14;
+ LDAPMod a15;
+ LDAPMod a16;
+ LDAPMod *mods[17];
+ int rc = 0, tries = 0;
+ char dn[256];
+ char cdate[256];
+ char *cn_values[2];
+ char *objectClass_values[] = { "top", "tokenRecord", NULL };
+ char *cdate_values[2];
+ char *modified_values[] = { "0", NULL };
+ char *uid_values[] = { "", NULL };
+ char *status_values[] = { "", NULL };
+ char *aid_values[] = { "", NULL };
+ char *resets_values[] = { "0", NULL };
+ char *enrollments_values[] = { "0", NULL };
+ char *renewals_values[] = { "0", NULL };
+ char *recoveries_values[] = { "0", NULL };
+ char *key_info_values[] = { "", NULL };
+ char *reason_values[] = { "", NULL };
+ char *policy_values[2];
+ char *token_type_values[]= {"", NULL };
+
+ tus_check_conn();
+ cn_values[0] = cn;
+ cn_values[1] = NULL;
+
+ policy_values[0] = defaultPolicy;
+ policy_values[1] = NULL;
+
+ if (uid != NULL) uid_values[0] = ( char * ) uid;
+ if (key_info != NULL) key_info_values[0] = key_info;
+ status_values[0] = ( char * ) status;
+ token_type_values[0] = ( char *) token_type;
+
+ a01.mod_op = 0;
+ a01.mod_type = TOKEN_ID;
+ a01.mod_values = cn_values;
+
+ a02.mod_op = 0;
+ a02.mod_type = "objectClass";
+ a02.mod_values = objectClass_values;
+
+ cdate_values[0] = cdate;
+ cdate_values[1] = NULL;
+ a03.mod_op = 0;
+ a03.mod_type = TOKEN_C_DATE;
+ a03.mod_values = cdate_values;
+
+ a04.mod_op = 0;
+ a04.mod_type = TOKEN_M_DATE;
+ a04.mod_values = cdate_values;
+
+ a05.mod_op = 0;
+ a05.mod_type = TOKEN_MODS;
+ a05.mod_values = modified_values;
+
+ a06.mod_op = 0;
+ a06.mod_type = TOKEN_USER;
+ a06.mod_values = uid_values;
+
+ a07.mod_op = 0;
+ a07.mod_type = TOKEN_STATUS;
+ a07.mod_values = status_values;
+
+ a08.mod_op = 0;
+ a08.mod_type = TOKEN_APPLET;
+ if (applet_version != NULL) {
+ aid_values[0] = applet_version;
+ }
+ a08.mod_values = aid_values;
+
+ a09.mod_op = 0;
+ a09.mod_type = TOKEN_RESETS;
+ a09.mod_values = resets_values;
+
+ a10.mod_op = 0;
+ a10.mod_type = TOKEN_ENROLLMENTS;
+ a10.mod_values = enrollments_values;
+
+ a11.mod_op = 0;
+ a11.mod_type = TOKEN_RENEWALS;
+ a11.mod_values = renewals_values;
+
+ a12.mod_op = 0;
+ a12.mod_type = TOKEN_RECOVERIES;
+ a12.mod_values = recoveries_values;
+
+ a13.mod_op = 0;
+ a13.mod_type = TOKEN_KEY_INFO;
+ a13.mod_values = key_info_values;
+
+ a14.mod_op = 0;
+ a14.mod_type = TOKEN_POLICY;
+ a14.mod_values = policy_values;
+
+ a15.mod_op = 0;
+ a15.mod_type = TOKEN_REASON;
+ a15.mod_values = reason_values;
+
+ a16.mod_op = 0;
+ a16.mod_type = TOKEN_TYPE;
+ a16.mod_values = token_type_values;
+
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+ mods[3] = &a04;
+ mods[4] = &a05;
+ mods[5] = &a06;
+ mods[6] = &a07;
+ mods[7] = &a08;
+ mods[8] = &a09;
+ mods[9] = &a10;
+ mods[10] = &a11;
+ mods[11] = &a12;
+ mods[12] = &a13;
+ mods[13] = &a14;
+ mods[14] = &a15;
+ mods[15] = &a16;
+ mods[16] = NULL;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+
+ PR_snprintf(cdate, 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_add_ext_s(ld, dn, mods, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ /* audit log */
+ if (rc == LDAP_SUCCESS) {
+ audit_log("add_token", userid, cn);
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int add_default_tus_db_entry (const char *uid, const char *agentid, char *cn, const char *status, char *applet_version, char *key_info, const char *token_type)
+{
+ return add_new_tus_db_entry (agentid, cn, uid, 0, status, applet_version, key_info, token_type);
+}
+
+/****
+ * add_user_db_entry
+ * summary: adds a new user entry
+ * params: agentid - user who is performing this change (for audit log)
+ * :userid, userPassword, sn, givenName, cn, userCert - details for user to be added
+ * returns: ldap return code
+ */
+TPS_PUBLIC int add_user_db_entry(const char *agentid, char *userid, char *userPassword, char *sn, char *givenName, char *cn, char *userCert)
+{
+ LDAPMod a01;
+ LDAPMod a02;
+ LDAPMod a03;
+ LDAPMod a04;
+ LDAPMod a05;
+ LDAPMod a06;
+ LDAPMod a07;
+ LDAPMod *mods[8];
+ int rc = 0;
+ char dn[256];
+ int i,j, certlen;
+ char *dst = NULL;
+ char *certX = NULL;
+ char *userid_values[] = {userid, NULL};
+ char *objectClass_values[] = { "top", "person", "organizationalPerson", "inetOrgPerson", "tpsProfileId", NULL };
+ char *userPassword_values[] = { userPassword, NULL };
+ char *sn_values[] = {sn, NULL};
+ char *cn_values[] = {cn, NULL};
+ char *givenName_values[] = {givenName, NULL};
+ struct berval berval;
+ struct berval *userCert_values[2];
+
+ a01.mod_op = 0;
+ a01.mod_type = USER_ID;
+ a01.mod_values = userid_values;
+
+ a02.mod_op = 0;
+ a02.mod_type = "objectClass";
+ a02.mod_values = objectClass_values;
+
+ a03.mod_op =0;
+ a03.mod_type = USER_PASSWORD;
+ a03.mod_values = userPassword_values;
+
+ a04.mod_op = 0;
+ a04.mod_type = USER_SN;
+ a04.mod_values = sn_values;
+
+ a05.mod_op =0;
+ a05.mod_type = USER_CN;
+ a05.mod_values = cn_values;
+
+ a06.mod_op =0;
+ a06.mod_type = USER_GIVENNAME;
+ a06.mod_values = givenName_values;
+
+ mods[0] = &a01;
+ mods[1] = &a02;
+ mods[2] = &a03;
+ mods[3] = &a04;
+ mods[4] = &a05;
+ if (givenName != NULL && PL_strlen(givenName) > 0) {
+ mods[5] = &a06;
+ }
+
+ // now handle certificate
+ certlen = strlen(userCert);
+
+ certX = malloc(certlen);
+ j = 0;
+ for (i = 0; i < certlen; i++) {
+ if (userCert[i] != '\n' && userCert[i] != '\r') {
+ certX[j++] = userCert[i];
+ }
+ }
+ certX[j++] = '\0';
+ dst = malloc(3 * strlen(certX) / 4);
+ certlen = base64_decode(certX, ( unsigned char * ) dst);
+ free(certX);
+
+ if (certlen > 0) {
+ berval.bv_len = certlen;
+ berval.bv_val = ( char * ) dst;
+ userCert_values[0] = &berval;
+ userCert_values[1] = NULL;
+
+ a07.mod_op = LDAP_MOD_BVALUES;
+ a07.mod_type = USER_CERT;
+ a07.mod_bvalues = userCert_values;
+
+ if (givenName != NULL && PL_strlen(givenName) > 0) {
+ mods[6] = &a07;
+ } else {
+ mods[5] = &a07;
+ }
+ } else {
+ if (givenName == NULL || PL_strlen(givenName) == 0) {
+ mods[5] = NULL;
+ }
+ mods[6] = NULL;
+ }
+
+ mods[7] = NULL;
+
+ if (PR_snprintf(dn, 255, "uid=%s,ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ rc = add_tus_general_db_entry(dn, mods);
+ if (dst != NULL) free(dst);
+
+ if (rc != LDAP_SUCCESS) {
+ return rc;
+ }
+
+ audit_log("add_user", agentid, userid);
+ return rc;
+}
+
+/**
+ * add_user_to_role_db_entry
+ * summary: adds user to be member of group (administrators, agents, operators)
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be added to role
+ * : role - Operators, Agents or Administrators
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int add_user_to_role_db_entry(const char *agentid, char *userid, const char *role) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char userdn[256];
+ char msg[256];
+ char *userid_values[2];
+
+ if (PR_snprintf(userdn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ userid_values[0] = userdn;
+ userid_values[1] = NULL;
+
+ a01.mod_op = LDAP_MOD_ADD;
+ a01.mod_type = GROUP_MEMBER;
+ a01.mod_values = userid_values;
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ if (PR_snprintf(dn, 255, "cn=TUS %s,ou=groups, %s", role, userBaseDN) < 0)
+ return -1;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Added role %s to user %s", role, userid);
+ audit_log("add_user_to_role", agentid, msg);
+ }
+ return rc;
+}
+
+/**
+ * delete_user_to_role_db_entry
+ * summary: removes user from role group (administrators, agents, operators)
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be removed from role
+ * : role - Operators, Agents or Administrators
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int delete_user_from_role_db_entry(const char *agentid, char *userid, const char *role) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char userdn[256];
+ char *userid_values[2];
+ char msg[256];
+
+ if (PR_snprintf(userdn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ userid_values[0] = userdn;
+ userid_values[1] = NULL;
+
+ a01.mod_op = LDAP_MOD_DELETE;
+ a01.mod_type = GROUP_MEMBER;
+ a01.mod_values = userid_values;
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ if (PR_snprintf(dn, 255, "cn=TUS %s,ou=groups, %s", role, userBaseDN) < 0)
+ return -1;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Deleted role %s from user %s", role, userid);
+ audit_log("delete_user_from_role", agentid, msg);
+ }
+
+ return rc;
+}
+
+/**
+ * delete_profile_from_user
+ * summary: removes attribute profileID=profile from user entry
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be modified
+ * : profile - profile to be deleted
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int delete_profile_from_user(const char *agentid, char *userid, const char *profile) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char msg[256];
+ char *profileid_values[2] = {(char *) profile, NULL};
+
+ if (PR_snprintf(dn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ a01.mod_op = LDAP_MOD_DELETE;
+ a01.mod_type = PROFILE_ID;
+ a01.mod_values = profileid_values;
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Deleted profile %s from user %s", profile, userid);
+ audit_log("delete_profile_from_user", agentid, msg);
+ }
+
+ return rc;
+}
+
+/**
+ * delete_all_profiles_from_user
+ * summary: removes all attributes profileID from user entry
+ * same as above, but passing NULL for mod_values
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be modified
+ * : profile - profile to be deleted
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int delete_all_profiles_from_user(const char *agentid, char *userid) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char msg[256];
+
+ if (PR_snprintf(dn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ a01.mod_op = LDAP_MOD_DELETE;
+ a01.mod_type = PROFILE_ID;
+ a01.mod_values = NULL; /* NULL will remove all values */
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Deleted all profiles from user %s", userid);
+ audit_log("delete_all_profiles_from_user", agentid, msg);
+ }
+
+ return rc;
+}
+
+
+/**
+ * add_profile_to_user
+ * summary: adds attribute profileID=profile to user entry
+ * params: agentid -user who is performing this change
+ * : userid - userid of user to be modified
+ * : profile - profile (tokenType) to be added
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int add_profile_to_user(const char *agentid, char *userid, const char *profile) {
+ LDAPMod a01;
+ LDAPMod *mods[2];
+ int rc = 0;
+ char dn[256];
+ char msg[256];
+ char *profileid_values[2] = {(char *) profile, NULL};
+
+ if (PR_snprintf(dn, 255, "uid=%s, ou=People, %s", userid, userBaseDN) < 0)
+ return -1;
+
+ a01.mod_op = LDAP_MOD_ADD;
+ a01.mod_type = PROFILE_ID;
+ a01.mod_values = profileid_values;
+ mods[0] = &a01;
+ mods[1] = NULL;
+
+ rc = update_tus_general_db_entry(agentid, dn, mods);
+ if (rc == LDAP_SUCCESS) {
+ PR_snprintf(msg, 256, "Added profile %s to user %s", profile, userid);
+ audit_log("add_profile_to_user", agentid, msg);
+ }
+
+ return rc;
+}
+
+int delete_tus_db_entry (char *userid, char *cn)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_delete_ext_s(ld, dn, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ /* audit log */
+ if (rc == LDAP_SUCCESS) {
+ audit_log("delete_token", userid, cn);
+ }
+
+ return rc;
+}
+
+int delete_tus_general_db_entry (char *dn)
+{
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_delete_ext_s(ld, dn, NULL, NULL)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * delete_user_db_entry
+ * Deletes user entry
+ * params: agentid - user performing this change
+ * uid - user to be deleted
+ * returns: LDAP return code
+ */
+TPS_PUBLIC int delete_user_db_entry(const char *agentid, char *uid)
+{
+ char dn[256];
+ int rc =0;
+ if (PR_snprintf(dn, 255, "uid=%s,ou=People,%s", uid, userBaseDN) < 0)
+ return -1;
+ rc = delete_tus_general_db_entry(dn);
+
+ if (rc == LDAP_SUCCESS) {
+ audit_log("delete user", agentid, uid);
+ }
+
+ return rc;
+}
+
+
+TPS_PUBLIC int find_tus_db_entry (char *cn, int max, LDAPMessage **result)
+{
+ char dn[256];
+ int rc = 0, tries = 0;
+
+ tus_check_conn();
+ if (ld == NULL)
+ return -1;
+
+ if (PR_snprintf(dn, 255, "cn=%s,%s", cn, baseDN) < 0)
+ return -1;
+
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: looking for :%s\n",dn);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: tries = %d\n",tries);
+ if ((rc = ldap_search_ext_s (ld, dn, LDAP_SCOPE_BASE, "(objectclass=*)",
+ NULL, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: found it\n");
+
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: server down or connect error\n");
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ } else {/* can't find?*/
+ if (debug_fd)
+ PR_fprintf(debug_fd, "find_tus_db_entry: can't find\n");
+ break;
+ }
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_db_entries (const char *filter, int max, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfModify");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_db_entries_pcontrol_1(const char *filter, int max, int time_limit, int size_limit, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ struct berval *cookie=NULL;
+ struct timeval timeout;
+
+ timeout.tv_sec = time_limit;
+ timeout.tv_usec = 0;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ rc = ldap_create_page_control(ld, max, cookie, 0, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfModify");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL,
+ time_limit >0 ? &timeout : NULL,
+ size_limit, result);
+ if ((rc == LDAP_SUCCESS) || (rc == LDAP_PARTIAL_RESULTS)) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (cookie != NULL) {
+ ber_bvfree(cookie);
+ cookie = NULL;
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+static int sort_cmp(const char *v1, const char *v2)
+{
+ return PL_strcasecmp(v1, v2);
+}
+
+static int reverse_sort_cmp(const char *v1, const char *v2)
+{
+ return PL_strcasecmp(v2, v1);
+}
+
+typedef int (LDAP_SORT_AD_CMP_PROC) (const char * left, const char *right);
+static LDAP_SORT_AD_CMP_PROC *et_cmp_fn;
+
+struct entrything {
+ char **et_vals;
+ LDAPMessage *et_msg;
+};
+
+static int et_cmp(const void *aa, const void *bb)
+{
+ int i, rc;
+
+ struct entrything *a = (struct entrything *)aa;
+ struct entrything *b = (struct entrything *)bb;
+
+ if ((a == NULL) && (b == NULL))
+ return 0;
+ if (a == NULL)
+ return -1;
+ if (b == NULL)
+ return 1;
+
+ if ((a->et_vals == NULL) && (b->et_vals == NULL))
+ return 0;
+ if (a->et_vals == NULL)
+ return -1;
+ if (b->et_vals == NULL)
+ return 1;
+
+ for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
+ if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] )) != 0) {
+ return rc;
+ }
+ }
+
+ if ((a->et_vals[i] == NULL) && (b->et_vals[i] == NULL))
+ return 0;
+ if (a->et_vals[i] == NULL)
+ return -1;
+ return 1;
+}
+
+
+static int ldap_multisort_entries(LDAP *ld, LDAPMessage **chain, char **attr, LDAP_SORT_AD_CMP_PROC *cmp)
+{
+ int i, count, c;
+ struct entrything *et;
+ LDAPMessage *e;
+
+ if ((chain == NULL) || (cmp == NULL) || (attr == NULL)) {
+ return LDAP_PARAM_ERROR;
+ }
+
+ count = ldap_count_entries( ld, *chain );
+
+ if (count < 0) { /* error, usually with bad ld or malloc */
+ return LDAP_PARAM_ERROR;
+ }
+
+ if (count < 2) { /* nothing to sort */
+ return 0;
+ }
+
+ if ((et = (struct entrything *)PR_Malloc( count * sizeof(struct entrything) )) == NULL ) {
+ //ldap_set_option(ld, LDAP_OPT_ERROR_NUMBER, LDAP_NO_MEMORY);
+ return -1;
+ }
+
+ for (i=0, e=get_first_entry(*chain); e != NULL; e = get_next_entry(e)) {
+ et[i].et_msg = e;
+ et[i].et_vals = NULL;
+ if (attr == NULL) {
+ /* if attr =NULL, sort by dn -- not yet implemented , fixme.
+ char *dn;
+ LDAPDN *ldapdn;
+ dn = ldap_get_dn(ld, e);
+ ldapstr2dn(dn, ldapdn, LDAP_DN_FORMAT_LDAPV3|LDAP_DN_P_NO_SPACES);
+ et[i].et_vals = ldap_explode_dn(dn, 1);
+ ldap_memfree(dn); */
+ } else {
+ int attrcnt;
+ struct berval **vals;
+
+ for (attrcnt = 0; attr[attrcnt] != NULL; attrcnt++ ) {
+ vals = ldap_get_values_len(ld, e, attr[attrcnt]);
+ if (vals == NULL) {
+ continue;
+ }
+ for (c=0; vals[c] != NULL; c++);
+ et[i].et_vals = (char **) PR_Malloc((c+1) * sizeof(char *));
+ for (c=0; vals[c] != NULL; c++) {
+ if (vals[c]->bv_val != NULL) {
+ et[i].et_vals[c] = (char *) PL_strdup(vals[c]->bv_val);
+ } else {
+ et[i].et_vals[c] = NULL;
+ }
+ }
+ et[i].et_vals[c] = NULL;
+
+ if (vals != NULL) {
+ ldap_value_free_len(vals );
+ vals = NULL;
+ }
+ }
+ }
+ i++;
+ }
+
+ et_cmp_fn = cmp;
+ qsort((void *) et, (size_t) count, (size_t) sizeof(struct entrything), et_cmp);
+
+ // reconstruct chain
+
+ for (i=0; i< count-1; i++)
+ ldap_delete_result_entry(chain, et[i].et_msg);
+
+ for (i=count -2; i >=0; i--)
+ ldap_add_result_entry(chain, et[i].et_msg);
+
+ // free et
+ for (i= 0; i < count; i++) {
+ for (c=0; et[i].et_vals[c] != NULL; c++) {
+ PL_strfree( et[i].et_vals[c]);
+ et[i].et_vals[c] = NULL;
+ }
+ }
+
+ PR_Free( (char *) et );
+
+ return 0;
+}
+
+/* this is not implemented in openldap and must be implemented in custom code.
+ * This code is adopted from mozldap sort.c
+ */
+static int ldap_sort_entries(LDAP *ld, LDAPMessage **result, const char* attr, LDAP_SORT_AD_CMP_PROC *cmp)
+{
+ char *attrs[2];
+ attrs[0] = (char *) attr;
+ attrs[1] = NULL;
+ return ldap_multisort_entries(ld, result, attr ? attrs : NULL, cmp);
+}
+
+TPS_PUBLIC int find_tus_token_entries_no_vlv(char *filter, LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ /* we do client-side sorting here */
+ if (order == 0) {
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ sort_cmp);
+ } else { /* order == 1 */
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ reverse_sort_cmp);
+ }
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * find_tus_user_entries_no_vlv
+ * params: filter - ldap search filter
+ * result - hash of LDAP Search results.
+ * order - 0 (order results increasing by uid), (!=0) order by decreasing uid
+ */
+TPS_PUBLIC int find_tus_user_entries_no_vlv(char *filter, LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ char peopleBaseDN[256];
+
+ PR_snprintf(peopleBaseDN, 256, "ou=People,%s", userBaseDN);
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, peopleBaseDN, LDAP_SCOPE_ONELEVEL, filter,
+ userAttributes, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ /* we do client-side sorting here */
+ if (order == 0) {
+ rc = ldap_sort_entries(ld, result, USER_ID, sort_cmp);
+ } else {
+ rc = ldap_sort_entries(ld, result, USER_ID, reverse_sort_cmp);
+ }
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * find_tus_user_role_entries
+ * summary: return the dns for the groups to which the user belongs
+ * (TUS Administrators, Agents, Operator)
+ * params: uid - userid
+ * result - hash of LDAPResults
+ */
+TPS_PUBLIC int find_tus_user_role_entries( const char*uid, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ char groupBaseDN[256];
+ char filter[256];
+ char *subgroup_attrs[] = {SUBGROUP_ID, NULL};
+
+ PR_snprintf(groupBaseDN, 256, "ou=Groups,%s", userBaseDN);
+ PR_snprintf(filter, 256, "member=uid=%s,ou=People,%s", uid, userBaseDN);
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, groupBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ subgroup_attrs, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_activity_entries_no_vlv(char *filter, LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, activityBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ /* we do client-side sorting here */
+ if (order == 0) {
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ sort_cmp);
+ } else { /* order == 1 */
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ reverse_sort_cmp);
+ }
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_token_entries(char *filter, int max, LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ (*sortKeyList)->reverseOrder = order;
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+TPS_PUBLIC int update_token_status_reason_userid(const char *userid, char *cuid,
+ const char *tokenStatus, const char *reason, int modifyDateOfCreate) {
+ LDAPMod **mods = NULL;
+ int status;
+ char **v = NULL;
+ int len = 0;
+
+ tus_check_conn();
+ if (modifyDateOfCreate)
+ mods = allocate_modifications(5);
+ else
+ mods = allocate_modifications(4);
+
+ if (mods == NULL) {
+ return -1;
+ } else {
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = get_modification_date_name();
+ mods[0]->mod_values = v;
+
+ /* for token status */
+ if (tokenStatus != NULL && PL_strlen(tokenStatus) > 0) {
+ len = PL_strlen(tokenStatus);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], tokenStatus);
+ mods[1]->mod_op = LDAP_MOD_REPLACE;
+ mods[1]->mod_type = get_token_status_name();
+ mods[1]->mod_values = v;
+ }
+
+ /* for token reason */
+ if (reason != NULL && PL_strlen(reason) > 0)
+ len = PL_strlen(reason);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[2]->mod_op = LDAP_MOD_REPLACE;
+ mods[2]->mod_type = tokenAttributes[13];
+ if (reason != NULL && PL_strlen(reason) > 0)
+ PL_strcpy(v[0], reason);
+ else
+ v[0] = "";
+ mods[2]->mod_values = v;
+
+ /* for userid */
+ if (userid != NULL && PL_strlen(userid) > 0)
+ len = PL_strlen(userid);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[3]->mod_op = LDAP_MOD_REPLACE;
+ mods[3]->mod_type = "tokenUserID";
+ if (userid != NULL && PL_strlen(userid) > 0)
+ PL_strcpy(v[0], userid);
+ else
+ v[0] = "";
+ mods[3]->mod_values = v;
+
+ if (modifyDateOfCreate) {
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+
+ mods[4]->mod_op = LDAP_MOD_REPLACE;
+ mods[4]->mod_type = "dateOfCreate";
+ mods[4]->mod_values = v;
+
+ }
+
+ status = update_tus_db_entry_with_mods(userid, cuid, mods);
+ return status;
+}
+
+TPS_PUBLIC int update_token_status_reason(char *userid, char *cuid, const char *tokenStatus, const char *reason) {
+ LDAPMod **mods = NULL;
+ int status;
+ char **v = NULL;
+ int len = 0;
+
+ tus_check_conn();
+ mods = allocate_modifications(3);
+
+ if (mods == NULL) {
+ return -1;
+ } else {
+ if ((v = create_modification_date_change()) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ }
+
+ mods[0]->mod_op = LDAP_MOD_REPLACE;
+ mods[0]->mod_type = get_modification_date_name();
+ mods[0]->mod_values = v;
+
+ /* for token status */
+ if (tokenStatus != NULL && PL_strlen(tokenStatus) > 0) {
+ len = PL_strlen(tokenStatus);
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ PL_strcpy(v[0], tokenStatus);
+ mods[1]->mod_op = LDAP_MOD_REPLACE;
+ mods[1]->mod_type = get_token_status_name();
+ mods[1]->mod_values = v;
+ }
+
+ /* for token reason */
+ if (reason != NULL && PL_strlen(reason) > 0)
+ len = PL_strlen(reason);
+ else
+ len = 0;
+ if ((v = allocate_values(1, len+1)) == NULL) {
+ if( mods != NULL ) {
+ free_modifications( mods, 0 );
+ mods = NULL;
+ }
+ return -1;
+ }
+ mods[2]->mod_op = LDAP_MOD_REPLACE;
+ mods[2]->mod_type = tokenAttributes[13];
+ if (reason != NULL && PL_strlen(reason) > 0)
+ PL_strcpy(v[0], reason);
+ else
+ v[0] = "";
+ mods[2]->mod_values = v;
+
+ status = update_tus_db_entry_with_mods(userid, cuid, mods);
+ return status;
+}
+
+TPS_PUBLIC int tus_has_active_tokens(char *userid)
+{
+ LDAPMessage *result;
+ char filter[256];
+ int n = 0;
+
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+ int max = 1000;
+
+ tus_check_conn();
+ PR_snprintf(filter, 256, "(&(tokenStatus=active)(tokenUserID=%s))", userid);
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, baseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, &result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((n = ldap_count_entries (ld, result)) >= 0) {
+ break;
+ } else {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ if (rc == LDAP_SUCCESS) {
+ if (n > 0)
+ return 0;
+ else
+ return -1;
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_certificate_entries_by_order_no_vlv (char *filter,
+ LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, certBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, NULL, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ /* we do client-side sorting here */
+ if (order == 0) {
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ sort_cmp);
+ } else {
+ rc = ldap_sort_entries(ld, result, "dateOfCreate",
+ reverse_sort_cmp);
+ }
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_certificate_entries_by_order (char *filter, int max,
+ LDAPMessage **result, int order)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ (*sortKeyList)->reverseOrder = order;
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, certBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+int find_tus_certificate_entries (char *filter, int max, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, certBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+int find_tus_activity_entries (char *filter, int max, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ LDAPVLVInfo vlv_data;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ vlv_data.ldvlv_before_count = 0;
+ vlv_data.ldvlv_after_count = max - 1;
+ vlv_data.ldvlv_attrvalue = NULL;
+ vlv_data.ldvlv_count = max;
+ vlv_data.ldvlv_offset = 0;
+ vlv_data.ldvlv_version = 1;
+ vlv_data.ldvlv_context = NULL;
+ vlv_data.ldvlv_extradata = NULL;
+ ldap_create_vlv_control(ld, &vlv_data, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((rc = ldap_search_ext_s (ld, activityBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL, NULL, 0, result)) == LDAP_SUCCESS) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+TPS_PUBLIC int find_tus_activity_entries_pcontrol_1(char *filter, int max, int time_limit, int size_limit, LDAPMessage **result)
+{
+ int rc = LDAP_OTHER, tries = 0;
+ LDAPSortKey **sortKeyList;
+ LDAPControl *controls[3];
+ struct berval *cookie=NULL;
+ struct timeval timeout;
+
+ timeout.tv_sec = time_limit;
+ timeout.tv_usec = 0;
+
+ tus_check_conn();
+ controls[0] = NULL;
+ controls[1] = NULL;
+ controls[2] = NULL;
+
+ rc = ldap_create_page_control(ld, max, cookie, 0, &controls[0]);
+
+ ldap_create_sort_keylist(&sortKeyList, "-dateOfCreate");
+ ldap_create_sort_control(ld, sortKeyList, 1 /* non-critical */,
+ &controls[1]);
+
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ rc = ldap_search_ext_s (ld, activityBaseDN, LDAP_SCOPE_SUBTREE, filter,
+ NULL, 0, controls, NULL,
+ time_limit >0 ? &timeout : NULL,
+ size_limit, result);
+ if ((rc == LDAP_SUCCESS) || (rc == LDAP_PARTIAL_RESULTS)) {
+ break;
+ } else if (rc == LDAP_SERVER_DOWN || rc == LDAP_CONNECT_ERROR) {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ if (cookie != NULL) {
+ ber_bvfree(cookie);
+ cookie = NULL;
+ }
+
+ ldap_free_sort_keylist(sortKeyList);
+
+ ldap_control_free(controls[0]);
+ ldap_control_free(controls[1]);
+
+ return rc;
+}
+
+int get_number_of_entries (LDAPMessage *result)
+{
+ int n = 0, rc = 0, tries = 0;
+
+ tus_check_conn();
+ for (tries = 0; tries < MAX_RETRIES; tries++) {
+ if ((n = ldap_count_entries (ld, result)) >= 0) {
+ break;
+ } else {
+ struct berval credential;
+ credential.bv_val = bindPass;
+ credential.bv_len= strlen(bindPass);
+ rc = ldap_sasl_bind_s(ld, bindDN, LDAP_SASL_SIMPLE, &credential, NULL, NULL, NULL);
+ if (rc != LDAP_SUCCESS) {
+ bindStatus = rc;
+ break;
+ }
+ }
+ }
+
+ return n;
+}
+
+int free_results (LDAPMessage *results)
+{
+ return ldap_msgfree (results);
+}
+
+LDAPMessage *get_first_entry (LDAPMessage *result)
+{
+ return ldap_first_entry (ld, result);
+}
+
+LDAPMessage *get_next_entry (LDAPMessage *entry)
+{
+ return ldap_next_entry (ld, entry);
+}
+
+TPS_PUBLIC char **get_token_states()
+{
+ return tokenStates;
+}
+
+TPS_PUBLIC char **get_certificate_attributes()
+{
+ return tokenCertificateAttributes;
+}
+
+TPS_PUBLIC char **get_activity_attributes()
+{
+ return tokenActivityAttributes;
+}
+
+TPS_PUBLIC char **get_token_attributes()
+{
+ return tokenAttributes;
+}
+
+TPS_PUBLIC char **get_user_attributes()
+{
+ return userAttributes;
+}
+
+TPS_PUBLIC char **get_view_user_attributes()
+{
+ return viewUserAttributes;
+}
+
+CERTCertificate **get_certificates(LDAPMessage *entry) {
+ int i;
+ struct berval **bvals;
+ CERTCertificate *cert;
+ int c = 0;
+ CERTCertificate **ret = NULL;
+
+ tus_check_conn();
+ bvals = ldap_get_values_len(ld, entry, "userCertificate");
+ if (bvals == NULL)
+ return NULL;
+
+ for (i = 0; bvals[i] != NULL; i++ )
+ c++;
+ ret = (CERTCertificate **) malloc ((sizeof (CERTCertificate *) * c) + 1);
+ c = 0;
+ for (i = 0; bvals[i] != NULL; i++ ) {
+ cert = CERT_DecodeCertFromPackage((char *) bvals[i]->bv_val, (int)
+ ( bvals[i]->bv_len ) );
+ ret[c] = cert;
+ c++;
+ }
+ ret[c] = NULL;
+ return ret;
+
+}
+
+struct berval **get_attribute_values(LDAPMessage *entry, const char *attribute)
+{
+ int i;
+ unsigned int j;
+ struct berval **bvals = NULL;
+ char buffer[2048];
+ int c = 0;
+ struct berval **ret = NULL;
+
+ tus_check_conn();
+ if (PL_strcasecmp(attribute, "userCertificate") == 0) {
+ bvals = ldap_get_values_len(ld, entry, attribute);
+ if (bvals == NULL)
+ return NULL;
+ for (i = 0; bvals[i] != NULL; i++ ) {
+ c++;
+ }
+ ret = (struct berval **) malloc ((sizeof (struct berval *) * c) + 1);
+ for (i=0; i< c; i++) {
+ ret[i] = (struct berval *) malloc(sizeof(struct berval));
+ }
+ ret[c] = NULL;
+ c = 0;
+ for (i = 0; bvals[i] != NULL; i++ ) {
+ char *tmp = BTOA_DataToAscii((unsigned char *)bvals[i]->bv_val,
+ (int)bvals[i]->bv_len);
+ snprintf(buffer, 2048, "%s", tmp);
+ PORT_Free(tmp);
+
+ /* remove \r\n that javascript does not like */
+ for (j = 0; j < strlen(buffer); j++) {
+ if (buffer[j] == '\r') {
+ buffer[j] = '.';
+ }
+ if (buffer[j] == '\n') {
+ buffer[j] = '.';
+ }
+ }
+ ret[c]->bv_val = PL_strdup(buffer);
+ ret[c]->bv_len = PL_strlen(buffer);
+ c++;
+ }
+ if (bvals != NULL) {
+ ldap_value_free_len(bvals);
+ bvals = NULL;
+ }
+
+ return ret;
+ } else {
+ return ldap_get_values_len(ld, entry, attribute);
+ }
+}
+
+void free_values(struct berval **values, int ldapValues)
+{
+ if (ldapValues != 0) {
+ if( values != NULL ) {
+ ldap_value_free_len( values );
+ values = NULL;
+ }
+ } else {
+ if( values != NULL ) {
+ PR_Free( values );
+ values = NULL;
+ }
+ }
+}
+
+TPS_PUBLIC char *get_token_users_name()
+{
+ return tokenAttributes[I_TOKEN_USER];
+}
+
+struct berval **get_token_users(LDAPMessage *entry)
+{
+ return ldap_get_values_len(ld, entry, TOKEN_USER);
+}
+
+char *get_token_id_name()
+{
+ return tokenAttributes[I_TOKEN_ID];
+}
+
+char *get_cert_attr_byname(LDAPMessage *entry, const char *name)
+{
+ struct berval **v = NULL;
+ char *value = NULL;
+
+ if (entry == NULL) return NULL;
+
+ v = ldap_get_values_len(ld, entry, name);
+ if (v == NULL) return NULL;
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ value = PL_strdup(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+
+ return value;
+}
+
+int get_cert_attr_byname_int(LDAPMessage *entry, const char *name)
+{
+ struct berval **v = NULL;
+ int n = 0;
+
+ if (entry == NULL) return 0;
+
+ v = ldap_get_values_len(ld, entry, name);
+ if (v == NULL) return 0;
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ n = atoi(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+
+ return n;
+}
+
+
+TPS_PUBLIC char *get_token_reason(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenReason");
+}
+
+char *get_token_id(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_ID);
+}
+
+char *get_cert_tokenType(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenType");
+}
+
+char *get_cert_serial(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenSerial");
+}
+
+char *get_cert_type(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenKeyType");
+}
+
+char *get_cert_status(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "tokenStatus");
+}
+
+char *get_cert_issuer(LDAPMessage *entry) {
+ return get_cert_attr_byname(entry, "tokenIssuer");
+}
+
+char *get_cert_cn(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, "cn");
+}
+
+char *get_token_status_name()
+{
+ return tokenAttributes[I_TOKEN_STATUS];
+}
+
+TPS_PUBLIC char *get_reason_name()
+{
+ return tokenAttributes[I_TOKEN_REASON];
+}
+
+TPS_PUBLIC char *get_policy_name()
+{
+ return tokenAttributes[I_TOKEN_POLICY];
+}
+
+char *get_token_status(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_STATUS);
+}
+
+char *get_applet_id_name()
+{
+ return tokenAttributes[I_TOKEN_APPLET];
+}
+
+char *get_applet_id(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_APPLET);
+}
+
+char *get_key_info_name()
+{
+ return tokenAttributes[I_TOKEN_KEY_INFO];
+}
+
+char *get_key_info(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_KEY_INFO);
+}
+
+char *get_creation_date_name()
+{
+ return tokenAttributes[I_TOKEN_C_DATE];
+}
+
+char *get_creation_date(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_C_DATE);
+}
+
+char *get_modification_date_name()
+{
+ return tokenAttributes[I_TOKEN_M_DATE];
+}
+
+char *get_modification_date(LDAPMessage *entry)
+{
+ return get_cert_attr_byname(entry, TOKEN_M_DATE);
+}
+
+char *get_number_of_modifications_name()
+{
+ return tokenAttributes[I_TOKEN_MODS];
+}
+
+int get_number_of_modifications(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_MODS);
+}
+
+TPS_PUBLIC char *get_dn(LDAPMessage *entry)
+{
+ char *ret = NULL;
+ char *dn = NULL;
+ if ((dn = ldap_get_dn( ld, entry )) != NULL) {
+ ret = PL_strdup(dn);
+ ldap_memfree(dn);
+ }
+ return ret;
+}
+
+char *get_number_of_resets_name()
+{
+ return tokenAttributes[I_TOKEN_RESETS];
+}
+
+int get_number_of_resets(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_RESETS);
+}
+
+char *get_number_of_enrollments_name()
+{
+ return tokenAttributes[I_TOKEN_ENROLLMENTS];
+}
+
+int get_number_of_enrollments(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_ENROLLMENTS);
+}
+
+char *get_number_of_renewals_name()
+{
+ return tokenAttributes[I_TOKEN_RENEWALS];
+}
+
+int get_number_of_renewals(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_RENEWALS);
+}
+
+char *get_number_of_recoveries_name()
+{
+ return tokenAttributes[I_TOKEN_RECOVERIES];
+}
+
+int get_number_of_recoveries(LDAPMessage *entry)
+{
+ return get_cert_attr_byname_int(entry, TOKEN_RECOVERIES);
+}
+
+TPS_PUBLIC char *get_token_userid(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ char *ret = NULL;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_USER)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ ret = PL_strdup(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return ret;
+}
+
+TPS_PUBLIC char *get_token_policy(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ char *ret = NULL;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry(cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_POLICY)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ ret = PL_strdup(v[0]->bv_val);
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return ret;
+}
+
+TPS_PUBLIC int allow_token_enroll_policy(char *cn, const char *policy)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ int can_reenroll = 0;
+ int token_is_uninitialized = 0;
+ int is_reenroll_attempt = 0;
+ int rc = -1;
+ char *token_status = NULL;
+
+ if(PL_strstr(policy,"RE_ENROLL"))
+ is_reenroll_attempt = 1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if(is_reenroll_attempt) {
+ token_status = get_token_status(e);
+
+ if(token_status && PL_strcmp(token_status,STATE_UNINITIALIZED) == 0)
+ token_is_uninitialized = 1;
+
+ if(token_status) {
+ PR_Free(token_status);
+ token_status = NULL;
+ }
+ }
+
+ if ((v = ldap_get_values_len(ld, e, TOKEN_POLICY)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ if (PL_strstr(v[0]->bv_val, policy)) {
+ can_reenroll = 1;
+ } else {
+ if( is_reenroll_attempt && token_is_uninitialized) {
+ can_reenroll = 1;
+ }
+ }
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return can_reenroll;
+}
+
+TPS_PUBLIC int allow_token_renew(char *cn)
+{
+ return allow_token_enroll_policy(cn, "RENEW=YES");
+}
+
+TPS_PUBLIC int allow_token_reenroll(char *cn)
+{
+ return allow_token_enroll_policy(cn, "RE_ENROLL=YES");
+}
+
+TPS_PUBLIC int force_token_format(char *cn)
+{
+ return allow_token_enroll_policy(cn,"FORCE_FORMAT=YES");
+}
+
+TPS_PUBLIC int is_token_present(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ int present = 0;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ present = 1;
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return present;
+}
+
+TPS_PUBLIC int is_token_pin_resetable(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ int resetable = 1;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_POLICY)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ if (PL_strstr(v[0]->bv_val, "PIN_RESET=NO")) {
+ resetable = 0;
+ }
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return resetable;
+}
+
+TPS_PUBLIC int is_update_pin_resetable_policy(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ int resetable = 0;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_POLICY)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ if (PL_strstr(v[0]->bv_val, "RESET_PIN_RESET_TO_NO=YES")) {
+ resetable = 1;
+ }
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return resetable;
+}
+
+TPS_PUBLIC int is_tus_db_entry_disabled(char *cn)
+{
+ LDAPMessage *result = NULL;
+ LDAPMessage *e = NULL;
+ struct berval **v = NULL;
+ int disabled = 0;
+ int rc = -1;
+
+ if (cn != NULL && PL_strlen(cn) > 0) {
+ if ((rc = find_tus_db_entry (cn, 0, &result)) == LDAP_SUCCESS) {
+ e = get_first_entry (result);
+ if (e != NULL) {
+ if ((v = ldap_get_values_len(ld, e, TOKEN_STATUS)) != NULL) {
+ if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) {
+ if (!PL_strcasecmp(v[0]->bv_val, STATE_DISABLED)) {
+ disabled = 1;
+ }
+ }
+ if( v != NULL ) {
+ ldap_value_free_len( v );
+ v = NULL;
+ }
+ }
+ }
+ if( result != NULL ) {
+ free_results( result );
+ result = NULL;
+ }
+ }
+ }
+ return disabled;
+}
+
+TPS_PUBLIC LDAPMod **allocate_modifications(int size)
+{
+ int i, n;
+ LDAPMod **mods = NULL;
+ char *s;
+
+ n = ((size + 1) * sizeof(LDAPMod *)) + (size * sizeof(LDAPMod));
+ s = (char *) PR_Malloc(n);
+ if (s == NULL)
+ return NULL;
+ memset(s, 0, n);
+
+ mods = (LDAPMod **)s;
+
+ s += ((size + 1) * sizeof(LDAPMod *));
+
+ for (i = 0; i < size; i++) {
+ mods[i] = (LDAPMod *)s;
+ s += sizeof(LDAPMod);
+ }
+
+ return mods;
+}
+
+void free_modifications(LDAPMod **mods, int ldapValues)
+{
+ int i;
+
+ if( mods == NULL ) {
+ return;
+ }
+
+ if (ldapValues) {
+ ldap_mods_free(mods, 0);
+ return;
+ }
+
+ for (i = 0; mods[i] != NULL; i++) {
+ if ((mods[i]->mod_op & LDAP_MOD_BVALUES) &&
+ (mods[i]->mod_bvalues != NULL)) {
+ if( ( mods[i] != NULL ) && ( mods[i]->mod_bvalues != NULL ) ) {
+ PR_Free( mods[i]->mod_bvalues );
+ mods[i]->mod_bvalues = NULL;
+ }
+ } else if (mods[i]->mod_values != NULL) {
+ if( ( mods[i] != NULL ) && ( mods[i]->mod_values != NULL ) ) {
+ PR_Free( mods[i]->mod_values );
+ mods[i]->mod_values = NULL;
+ }
+ }
+ }
+ if( mods != NULL ) {
+ PR_Free( mods );
+ mods = NULL;
+ }
+}
+
+TPS_PUBLIC char **allocate_values(int size, int extra)
+{
+ int n;
+ char **values = NULL;
+ char *s;
+
+ n = (size + 1) * sizeof(char *);
+ if (extra > 0) {
+ n += extra * sizeof(char);
+ }
+ s = (char *) PR_Malloc(n);
+ if (s == NULL)
+ return NULL;
+ memset(s, 0, n);
+
+ values = (char **)s;
+
+ if (extra > 0) {
+ s += ((size + 1) * sizeof(char *));
+ values[0] = s;
+ }
+
+ return values;
+}
+
+TPS_PUBLIC char **create_modification_date_change()
+{
+ PRExplodedTime time;
+ PRTime now;
+ char **v = NULL;
+
+ if ((v = allocate_values(1, 16)) == NULL) {
+ return NULL;
+ }
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+
+ PR_snprintf(v[0], 16, "%04d%02d%02d%02d%02d%02dZ",
+ time.tm_year, (time.tm_month + 1), time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+
+ return v;
+}
+
+/**
+ * Reads password.conf file
+ */
+static int ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return)
+{
+ char *cur = buf;
+ int sum = 0;
+ PRInt32 rc;
+
+ *removed_return = 0;
+ while (1) {
+ rc = PR_Read(f, cur, 1);
+ if (rc == -1 || rc == 0)
+ break;
+ if (*cur == '\r') {
+ continue;
+ }
+ if (*cur == '\n') {
+ *cur = '\0';
+ *removed_return = 1;
+ break;
+ }
+ sum++;
+ cur++;
+ }
+ return sum;
+}
+
+#define MAX_CFG_LINE_LEN 4096
+/*
+ * Search for password name "name" in the password file "filepath"
+ */
+char *get_pwd_from_conf(char *filepath, char *name)
+{
+ PRFileDesc *fd;
+ char line[MAX_CFG_LINE_LEN];
+ int removed_return;
+ char *val= NULL;
+
+ if (debug_fd)
+ PR_fprintf(debug_fd, "get_pwd_from_conf looking for %s\n", name);
+ fd= PR_Open(filepath, PR_RDONLY, 400);
+ if (fd == NULL) {
+ return NULL;
+ }
+ if (debug_fd)
+ PR_fprintf(debug_fd, "get_pwd_from_conf opened %s\n", filepath);
+
+ while (1) {
+ int n = ReadLine(fd, line, MAX_CFG_LINE_LEN, &removed_return);
+ if (n > 0) {
+ /* handle comment line */
+ if (line[0] == '#')
+ continue;
+ int c = 0;
+ while ((c < n) && (line[c] != ':')) {
+ c++;
+ }
+ if (c < n) {
+ line[c] = '\0';
+ } else {
+ continue; /* no ':', skip this line */
+ }
+ if (!PL_strcmp (line, name)) {
+ if (debug_fd)
+ PR_fprintf(debug_fd, "get_pwd_from_conf found %s is %s\n", line, &line[c+1]);
+ val = PL_strdup(&line[c+1]);
+ break;
+ }
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ if( fd != NULL ) {
+ PR_Close( fd );
+ fd = NULL;
+ }
+ return val;
+
+}
+
+void audit_log(const char *func_name, const char *userid, const char *msg)
+{
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRTime now;
+ PRExplodedTime time;
+ PRThread *ct;
+
+ if (audit_fd == NULL)
+ return;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+ ct = PR_GetCurrentThread();
+ PR_fprintf(audit_fd, "[%s] t=%x uid=%s op=%s - ",
+ datetime, ct, userid, func_name);
+ PR_fprintf(audit_fd, msg);
+ PR_fprintf(audit_fd, "\n");
+}
+
+int base64_decode( char *src, unsigned char *dst )
+{
+
+#define RIGHT2 0x03
+#define RIGHT4 0x0f
+
+ unsigned char b642nib[0x80] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
+ 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+ 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+ char *p, *stop;
+ unsigned char nib, *byte;
+ int i, len;
+
+ stop = strchr( src, '\0' );
+ byte = dst;
+ for ( p = src, len = 0; p < stop; p += 4, len += 3 ) {
+ for ( i = 0; i < 4; i++ ) {
+ if ( p[i] != '=' && (p[i] & 0x80 ||
+ b642nib[ p[i] & 0x7f ] > 0x3f) ) {
+ return( -1 );
+ }
+ }
+
+ /* first digit */
+ nib = b642nib[ p[0] & 0x7f ];
+ byte[0] = nib << 2;
+
+ /* second digit */
+ nib = b642nib[ p[1] & 0x7f ];
+ byte[0] |= nib >> 4;
+
+ /* third digit */
+ if ( p[2] == '=' ) {
+ len += 1;
+ break;
+ }
+ byte[1] = (nib & RIGHT4) << 4;
+ nib = b642nib[ p[2] & 0x7f ];
+ byte[1] |= nib >> 2;
+
+ /* fourth digit */
+ if ( p[3] == '=' ) {
+ len += 2;
+ break;
+ }
+ byte[2] = (nib & RIGHT2) << 6;
+ nib = b642nib[ p[3] & 0x7f ];
+ byte[2] |= nib;
+
+ byte += 3;
+ }
+
+ return( len );
+}
+