uiacceltk/hitchcock/TokenServer/SrvSrc/ftokenserver.cpp
changeset 0 15bf7259bb7c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/TokenServer/SrvSrc/ftokenserver.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,288 @@
+/*
+* Copyright (c) 2006 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:   Server implementation fo share files in application private gage 
+*                with controlled way
+*
+*/
+
+
+
+#include <e32std.h>
+#include <f32file.h>
+#include <e32math.h>
+#include "ftokenserver.h"
+#include "ftokenconsts.h"
+
+void CFsTokenServer::NewLC()
+    {
+    CFsTokenServer* pS = new (ELeave) CFsTokenServer;
+    CleanupStack::PushL(pS);
+    pS->ConstructL();
+    }
+
+void CFsTokenServer::ConstructL()
+    {
+    User::LeaveIfError( iFs.Connect() );
+    User::LeaveIfError( iFs.ShareProtected() );
+    StartL(FTOKEN_SERVER_NAME);
+    }
+
+CSession2* CFsTokenServer::NewSessionL(const TVersion& /*aVersion*/,const RMessage2& /*aMessage*/) const
+    {
+	return new(ELeave) CFsTokenServerSession();   
+    }
+
+void CFsTokenServer::HandleClientExit(const CSession2* aClient)
+    { // Todo: We could invent somekind notify here to notify 
+      // possible user of a file to release its handle as well..
+    for(TInt index = iTokens.Find(*aClient, TToken::CompareOwner); 
+        index != KErrNotFound; 
+        index = iTokens.Find(*aClient, TToken::CompareOwner) )
+        {
+        if (iTokens[index].iHasSubToken == 0)
+            {
+            delete iTokens[index].iFileName;
+            }
+        iTokens.Remove(index);
+        }
+    }
+
+CFsTokenServer::~CFsTokenServer()
+    {
+    for(TInt count = iTokens.Count(); count > 0; count-- )
+        {
+        if (iTokens[0].iHasSubToken == 0)
+            {
+            delete iTokens[0].iFileName;
+            }
+        iTokens.Remove(0);
+        }
+        
+    iFs.Close();
+	iTokens.Close();
+    }
+	    
+void CFsTokenServer::AddTokenL(const RMessage2& aMessage)
+    {
+	HBufC* fileName = 0;
+    TKeyArrayFix tokenKey(_FOFF(TToken, iToken), ECmpTInt64);	  	    
+	
+	TInt function = aMessage.Function();
+	switch(aMessage.Function())
+        {
+        case EGenerateTokenBasedOnName:
+        //==================================================
+        // 1) filename
+        //===================================================
+           {
+           User::Leave(KErrNotSupported);
+/*                TInt msgLenght = aMessage.GetDesLength(1);
+                if (length > 0)
+                    {
+                    fileName = HBufC::NewLC(length);
+                    TPtr ptr = fileName->Des();
+                    aMessage.Read(1,ptr);
+                    if (iFs.IsValidName(ptr))
+                        {
+
+                        }
+                    else
+                        {
+                        User::Leave(KErrArgument);
+                        }
+                    }
+                else 
+                    {
+                    User::Leave(KErrArgument);
+                    }    
+*/	    
+            break;
+            }
+        case EGenerateTokenBasedOnOpenHandle:
+        //===================================================
+        // 2) handle
+        //===================================================
+            {
+            // 2.1) check that we are able to open the file	
+            RFile file;
+            User::LeaveIfError(file.AdoptFromClient(aMessage,2,3));
+            // 2.2) resolve full filename
+            TFileName fn;
+            file.FullName(fn);
+            file.Close();
+               
+            fileName = fn.AllocLC();
+            break;
+            }
+        case EGenerateTokenBasedOnAnotherToken:
+        // ==================================================        
+        // 3) token
+        //===================================================
+            {
+            TInt64 token = 0;
+            TPckg<TInt64> buf(token); 
+    
+            // 3.1) just check that client uid and token match     
+            aMessage.ReadL(1,buf);
+            TInt index = iTokens.Find(token, TToken::CompareToken);
+            User::LeaveIfError( index );
+    
+	        if (iTokens[index].iPolicy.CheckPolicy(aMessage))
+	            {
+	            // set a pointer to existing buffer, when deleting
+	            // this must be handled slightly different way
+                // but theres no need to spend lots of mem 
+                // for duplicate filenames
+                fileName = iTokens[index].iFileName;
+                
+                // there shouldn't be more than one subtoken per token ever 
+                ASSERT(iTokens[index].iHasSubToken==EFalse);
+                iTokens[index].iHasSubToken = ETrue;
+                }
+            else 
+                {
+                User::Leave(KErrPermissionDenied);
+                }    
+ 
+            break;
+            }
+        default:
+            break;
+        }
+    // add token to array
+    TInt64 newToken = User::NTickCount();
+
+    for(newToken = Math::FRand(newToken);
+        iTokens.Find(newToken, TToken::CompareToken) != KErrNotFound;
+        newToken = User::NTickCount())
+        {
+        newToken = Math::FRand(newToken);
+        }
+    
+    TToken entry;
+    entry.iToken = newToken; 
+    entry.iFileName = fileName;
+    entry.iOwner = aMessage.Session();
+
+    TPckg<TSecurityPolicy> policyBuf(entry.iPolicy);
+    aMessage.ReadL(0, policyBuf);
+
+    User::LeaveIfError(iTokens.Append(entry));
+    if (function == EGenerateTokenBasedOnOpenHandle)
+        {
+        CleanupStack::Pop(); // filename
+        }
+    }
+	
+void CFsTokenServer::OpenFileL(const RMessage2& aMessage)
+    {
+	// find token based on client uid and given token 
+    TInt64 token = 0;
+    TPckg<TInt64> buf(token); 
+    aMessage.ReadL(1,buf);
+    
+    TInt index = iTokens.Find(token, TToken::CompareToken);
+	User::LeaveIfError(index);
+	
+	if (iTokens[index].iPolicy.CheckPolicy(aMessage))        
+	    { // authorized client requests file 
+        RFile file;
+	    // Todo: what should the mode be ??
+	    User::LeaveIfError(file.Open(iFs, *(iTokens[index].iFileName), EFileShareReadersOnly)); 
+        CleanupClosePushL(file);
+        User::LeaveIfError(file.TransferToClient(aMessage, 0));
+        CleanupStack::PopAndDestroy(); //file
+        }
+    else 
+        {
+        User::Leave(KErrPermissionDenied);    
+        } 
+    }
+
+
+CFsTokenServerSession::CFsTokenServerSession()
+    {
+    }
+
+CFsTokenServerSession::~CFsTokenServerSession()
+    {
+    ((CFsTokenServer*)(Server()))->HandleClientExit(this);
+    }
+
+void CFsTokenServerSession::ServiceL(const RMessage2& aMessage)
+    {
+    CFsTokenServer* server = (CFsTokenServer*)( Server() );
+    switch(aMessage.Function())
+        {
+        case EGenerateTokenBasedOnName:
+        case EGenerateTokenBasedOnOpenHandle:
+        case EGenerateTokenBasedOnAnotherToken:
+            {
+            server->AddTokenL(aMessage);
+            break;
+            }
+        case EOpenHandleForToken:
+            {
+            server->OpenFileL(aMessage);
+            // Todo: We could set somekind penalty to client that continuously
+            // passes wrong tokens (i.e. seems to be guessing), e.g. panic it...
+            break;
+            }
+
+        default:
+            aMessage.Complete(KErrNotSupported);
+            break;
+        }
+    if (!aMessage.IsNull())
+        {
+        aMessage.Complete(KErrNone);
+        }
+    }
+
+static void RunServerL()
+	{
+    // Create Scheduler, obsolete nowdays ?
+    CActiveScheduler* s=new(ELeave) CActiveScheduler;
+    CleanupStack::PushL(s);
+    CActiveScheduler::Install(s);
+
+    CFsTokenServer::NewLC(); 
+ 
+    RProcess::Rendezvous(KErrNone);
+    
+	CActiveScheduler::Start();
+	
+	CleanupStack::PopAndDestroy(2);	
+	}
+
+
+TInt E32Main()
+	{
+	TInt err = User::RenameThread(FTOKEN_SERVER_NAME);
+    if ( err != KErrNone )
+        {
+        return err;
+        }
+    
+    // create CCleanup
+    CTrapCleanup * cleanup = CTrapCleanup::New();
+    if (cleanup)
+        {
+        TRAP(err, RunServerL());
+        delete cleanup;
+        }
+
+	return err;
+	}
+