omadrm/drmengine/roapstorage/src/RoapStorageServer.cpp
changeset 0 95b198f216e5
child 12 8a03a285ab14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omadrm/drmengine/roapstorage/src/RoapStorageServer.cpp	Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,431 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <e32std.h>
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <DriveInfo.h>
+#endif
+
+#include "RoapStorageServer.h"
+#include "DRMContextDB.h"
+#include "RoapLog.h"
+#include "drmroapclientserver.h"
+#include "drmcommonclientserver.h"
+#include "drmkeystorage.h"
+
+// EXTERNAL DATA STRUCTURES
+// EXTERNAL FUNCTION PROTOTYPES  
+// CONSTANTS
+// MACROS
+
+
+// LOCAL CONSTANTS AND MACROS
+const TUint8 KMaxStartTries = 5;
+const TInt KWaitingTime = 1000000; // 10 secs
+
+_LIT( KRoapStorageThread, "RoapStorageServer" );
+
+#ifdef RD_MULTIPLE_DRIVE
+_LIT( KRIContextFileName, "%c:\\private\\101F51F2\\ricontexts.dat" );
+_LIT( KDomainContextFileName, "%c:\\private\\101F51F2\\domaincontexts.dat" );
+// File names and paths for importing keys
+_LIT( KImportDir, "%c:\\private\\101F51F2\\import\\" );
+_LIT( KInputFilePattern, "%c:\\private\\101F51F2\\import\\SigningCert*" );
+_LIT( KDeviceKeyFileName, "%c:\\private\\101F51F2\\import\\DevicePrivateKey.der" );
+_LIT( KDeviceCertFileName, "%c:\\private\\101F51F2\\import\\DeviceCert.der" );
+#else
+// File names and paths for importing keys
+_LIT( KImportDir, "c:\\private\\101F51F2\\import\\" );
+_LIT( KInputFilePattern, "c:\\private\\101F51F2\\import\\SigningCert*" );
+_LIT( KDeviceKeyFileName, "c:\\private\\101F51F2\\import\\DevicePrivateKey.der" );
+_LIT( KDeviceCertFileName, "c:\\private\\101F51F2\\import\\DeviceCert.der" );
+#endif
+
+// MODULE DATA STRUCTURES
+using Roap::KServerMajorVersion;
+using Roap::KServerMinorVersion;
+using Roap::KServerBuildVersion;
+
+// LOCAL FUNCTION PROTOTYPES
+LOCAL_C TInt StartRoapServer( RSemaphore& aClientSem );
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// Function StartRoapServer().
+// This function starts the actual server under TRAP harness and starts
+// waiting for connections. This function returns only if there has been
+// errors during server startup or the server is stopped for some reason.
+// 
+// Returns: TInt: Symbian OS error code.
+// -----------------------------------------------------------------------------
+LOCAL_C TInt StartRoapServer( RSemaphore& aClientSem ) 
+
+    {
+    TInt error = KErrNone;
+    CRoapStorageServer* server = NULL;
+    TUint8 count = 0;
+
+    do 
+        {
+        ++count;
+        TRAP( error, ( server = CRoapStorageServer::NewL() ) );
+        if ( error ) 
+           {
+           User::After( TTimeIntervalMicroSeconds32(KWaitingTime) );
+           }
+       
+        } while( error && ( count <= KMaxStartTries ) );
+    
+    if( error ) 
+        {
+        return error;
+        }
+        
+    // Release the semaphore...
+    aClientSem.Signal();
+    aClientSem.Close();
+    
+    // Start waiting for connections
+    CActiveScheduler::Start();
+    
+    // Delete CRoapStorageServer
+    delete server;
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// Function ReadFileL().
+// Read a file into a buffer
+// -----------------------------------------------------------------------------
+LOCAL_C void ReadFileL( RFs& aFs, HBufC8*& aContent, const TDesC& aName )
+	{	
+	TInt size = 0;
+	RFile file;
+	
+	User::LeaveIfError( file.Open( aFs, aName, EFileRead ) );
+	CleanupClosePushL( file );
+    User::LeaveIfError( file.Size( size ) );
+    aContent = HBufC8::NewLC( size );
+    TPtr8 ptr( aContent->Des() );
+    User::LeaveIfError( file.Read( ptr, size) );
+    CleanupStack::Pop(); // aContent
+	CleanupStack::PopAndDestroy(); // file
+	}
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CRoapStorageServer::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CRoapStorageServer* CRoapStorageServer::NewL()
+    {
+    CRoapStorageServer* self = new( ELeave ) CRoapStorageServer();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self ); 
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+CRoapStorageServer::~CRoapStorageServer() 
+    {
+    iRFs.Close();
+    delete iRoapStorage;
+    }
+
+// -----------------------------------------------------------------------------
+// CRoapStorageServer::RunErrorL
+// From CActive. Complete the request and restart the scheduler.
+// -----------------------------------------------------------------------------
+//
+TInt CRoapStorageServer::RunError( TInt aError ) 
+    {
+    // Inform the client.
+    Message().Complete( aError );
+    // Restart the scheduler.
+    ReStart();
+    // Error handled.
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CRoapStorageServer::NewSessionL
+// Called when a client requires a new instance.
+// -----------------------------------------------------------------------------
+CSession2* CRoapStorageServer::NewSessionL(
+    const TVersion& aVersion,
+    const RMessage2& /*aMessage*/) const
+    {
+    RThread client;
+    // Check that the versions are compatible.
+    if ( ! User::QueryVersionSupported( TVersion( KServerMajorVersion,
+                                                  KServerMinorVersion,
+                                                  KServerBuildVersion ), 
+                                        aVersion ) ) 
+        {
+        // Sorry, no can do.
+        User::Leave( KErrNotSupported );
+        }
+    return CRoapStorageSession::NewL();
+    }
+
+// -----------------------------------------------------------------------------
+// CRoapStorageServer::CRoapStorageServer
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CRoapStorageServer::CRoapStorageServer() : 
+    CServer2( EPriorityStandard ),
+    iRoapStorage( NULL )
+    {
+    // Nothing
+    }
+    
+// -----------------------------------------------------------------------------
+// CRoapStorageServer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CRoapStorageServer::ConstructL() 
+    {
+    TInt err = KErrNone;
+    
+    User::RenameThread( KRoapStorageThread );
+    StartL( Roap::KServerName );
+    User::LeaveIfError(iRFs.Connect());
+    
+#ifndef RD_MULTIPLE_DRIVE
+    
+    iRoapStorage = CDRMContextDB::NewL( KRIContextFile(), 
+                                        KDomainContextFile(),
+                                        iRFs );
+    
+#else //RD_MULTIPLE_DRIVE
+    
+    TInt driveNumber( -1 );
+    TChar driveLetter;
+    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+	iRFs.DriveToChar( driveNumber, driveLetter );
+	
+	TFileName riContextFile;
+	riContextFile.Format( KRIContextFileName, (TUint)driveLetter );
+    
+    TFileName domainContextFile;
+	domainContextFile.Format( KDomainContextFileName, (TUint)driveLetter );
+    
+    iRoapStorage = CDRMContextDB::NewL( riContextFile, 
+                                        domainContextFile,
+                                        iRFs );
+    
+#endif
+    
+    TRAP( err, ImportKeysL() );
+    }
+    
+// -----------------------------------------------------------------------------
+// CRoapStorageServer::ContextDB
+// Return the internal ROAP storage object
+// -----------------------------------------------------------------------------
+//       
+CDRMContextDB* CRoapStorageServer::ContextDB()
+    {
+    return iRoapStorage;
+    }
+
+// -----------------------------------------------------------------------------
+// CRoapStorageServer::ImportKeys
+// Import keys which are stored in the import directory into the private
+// directory. Only one key pair plus assocated certificates can be imported
+// at a time. The file names are DevicePrivateKey.der, DeviceCert.der and
+// SigningCertXX.der.
+// -----------------------------------------------------------------------------
+//       
+void CRoapStorageServer::ImportKeysL()
+    {
+    MDrmKeyStorage* storage = NULL; 
+    HBufC8* privateKey = NULL;
+    HBufC8* cert = NULL;
+    RArray<TPtrC8> certChain;
+    RPointerArray<HBufC8> buffers;
+    TFileName fileName;
+    RFile file;
+    TInt i;
+    CDir* dir = NULL;
+    TInt err = KErrNone;
+    
+    __UHEAP_MARK;
+    LOG( _L( "CRoapStorageServer::ImportKeysL" ) );
+    CleanupClosePushL( buffers );
+    CleanupClosePushL( certChain );
+    
+#ifndef RD_MULTIPLE_DRIVE
+    
+    ReadFileL( iRFs, privateKey, KDeviceKeyFileName );
+    
+#else //RD_MULTIPLE_DRIVE
+    
+    TFileName tempPath;
+    TFileName tempPath2;
+    TInt driveNumber( -1 );
+    TChar driveLetter;
+    DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
+	iRFs.DriveToChar( driveNumber, driveLetter );
+	
+	tempPath.Format( KDeviceKeyFileName, (TUint)driveLetter );
+    
+    ReadFileL( iRFs, privateKey, tempPath );
+    
+#endif
+    
+    CleanupStack::PushL( privateKey );
+    
+#ifndef RD_MULTIPLE_DRIVE
+    
+    ReadFileL( iRFs, cert, KDeviceCertFileName );
+    
+#else //RD_MULTIPLE_DRIVE
+    
+	tempPath2.Format( KDeviceCertFileName, (TUint)driveLetter );
+    
+    ReadFileL( iRFs, cert, tempPath2 );
+    
+#endif
+    
+    CleanupStack::PushL( cert );
+    buffers.AppendL( cert );
+    
+#ifndef RD_MULTIPLE_DRIVE
+    
+    iRFs.Delete( KDeviceKeyFileName );
+    iRFs.Delete( KDeviceCertFileName );
+    
+#else //RD_MULTIPLE_DRIVE
+    
+	iRFs.Delete( tempPath );
+    iRFs.Delete( tempPath2 );
+    
+#endif
+    
+#ifndef RD_MULTIPLE_DRIVE
+    
+    User::LeaveIfError( iRFs.GetDir( KInputFilePattern, KEntryAttNormal,
+        ESortByName, dir ) );
+    
+#else //RD_MULTIPLE_DRIVE
+    
+	tempPath.Format( KInputFilePattern, (TUint)driveLetter );
+    
+    User::LeaveIfError( iRFs.GetDir( tempPath, KEntryAttNormal,
+        ESortByName, dir ) );
+    
+#endif
+    
+    CleanupStack::PushL( dir );
+    
+    for ( i = 0; i < dir->Count(); i++ )
+        {
+        
+#ifndef RD_MULTIPLE_DRIVE
+    
+        fileName.Copy( KImportDir );
+    
+#else //RD_MULTIPLE_DRIVE
+    
+	    tempPath.Format( KImportDir, (TUint)driveLetter );
+        
+        fileName.Copy( tempPath );
+    
+#endif
+        
+        fileName.Append( (*dir)[i].iName );
+        ReadFileL( iRFs, cert, fileName );
+        CleanupStack::PushL( cert );
+        buffers.AppendL( cert );
+        
+        iRFs.Delete( fileName );
+        }
+    for ( i = 0; i < buffers.Count(); i++ )
+        {
+        certChain.AppendL( *( buffers[i] ) );
+        }
+    storage = DrmKeyStorageNewL();
+    TRAP( err, storage->ImportDataL( *privateKey, certChain ) );
+    delete storage;
+    CleanupStack::PopAndDestroy( i + 1 ); // certs & dir
+    CleanupStack::PopAndDestroy( 3 ); // privateKey, certChain, buffers
+    LOG( _L( "CRoapStorageServer::ImportKeysL done" ) );
+    __UHEAP_MARKEND;
+    }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+// -----------------------------------------------------------------------------
+// Function StartupRoapStorage().
+// This function starts the actual Roap Storage
+// the cleanup stack and active scheduler.
+// Returns: TInt: Symbian OS error code.
+// -----------------------------------------------------------------------------
+//
+
+TInt StartupRoapStorage( TAny* ) 
+    {    
+    TInt error = KErrNone;
+    CTrapCleanup* trap = CTrapCleanup::New();
+    __ASSERT_ALWAYS( trap, User::Invariant() );
+    
+    CActiveScheduler* scheduler = new CActiveScheduler();
+    __ASSERT_ALWAYS( scheduler, User::Invariant() );
+    
+    CActiveScheduler::Install( scheduler );
+    RSemaphore clientSem;
+    __ASSERT_ALWAYS( clientSem.OpenGlobal( KDRMEngCommonSemaphore ) == 0, User::Invariant() );
+    
+    error = StartRoapServer( clientSem );
+    
+    if ( error ) {
+        // Server creation failed. Release the semaphore.
+        // In case of successful startup, CRoapStorageServer
+        // releases the semaphore.
+        clientSem.Signal();
+        clientSem.Close();
+        }
+    
+    delete scheduler; 
+    scheduler = NULL;
+    
+    delete trap;
+    trap = NULL;
+    
+    // __ASSERT_ALWAYS( !error, User::Invariant() );
+    
+    return KErrNone;
+    }
+
+//  End of File