bluetoothengine/btui/btuidelegate/btdelegatedevsecurity.cpp
changeset 63 bcf742120177
parent 52 4545c04e61e1
equal deleted inserted replaced
52:4545c04e61e1 63:bcf742120177
    19 #include <QModelIndex>
    19 #include <QModelIndex>
    20 #include <btsettingmodel.h>
    20 #include <btsettingmodel.h>
    21 #include <btdevicemodel.h>
    21 #include <btdevicemodel.h>
    22 #include <btdelegatefactory.h>
    22 #include <btdelegatefactory.h>
    23 #include <hbnotificationdialog.h>
    23 #include <hbnotificationdialog.h>
       
    24 #include "btqtconstants.h"
       
    25 #include "btuiutil.h"
       
    26 #include <bluetoothuitrace.h>
       
    27 #include <btengconnman.h>
    24 
    28 
    25 BtDelegateDevSecurity::BtDelegateDevSecurity(            
    29 BtDelegateDevSecurity::BtDelegateDevSecurity(            
    26         BtSettingModel* settingModel, 
    30         BtSettingModel* settingModel, 
    27         BtDeviceModel* deviceModel, 
    31         BtDeviceModel* deviceModel, 
    28         QObject *parent) :
    32         QObject *parent) :
    29     BtAbstractDelegate(settingModel, deviceModel, parent), mBtEngDevMan(0), mBtengConnMan(0), mDisconnectDelegate(0)
    33     BtAbstractDelegate(settingModel, deviceModel, parent), mBtEngDevMan(0),
    30 {
    34     mDisconnectDelegate(0), mBtEngAddr(0), mRegDevArray(0), mOperation(0), 
    31     
    35     mDevice(0),mNewDev(0), mActiveHandling(false),mAddingBlockedDev(false)
       
    36 {
       
    37     BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); 
       
    38     mRegDevArray = new CBTDeviceArray(1);
       
    39     BTUI_ASSERT_X( mRegDevArray, "BtDelegateDevSecurity::BtDelegateDevSecurity()", 
       
    40             "can't allocate regdevarray");
       
    41     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
    32 }
    42 }
    33 
    43 
    34 BtDelegateDevSecurity::~BtDelegateDevSecurity()
    44 BtDelegateDevSecurity::~BtDelegateDevSecurity()
    35 {
    45 {
       
    46     BOstraceFunctionEntry1( DUMMY_DEVLIST, this );  
    36     delete mBtEngDevMan;
    47     delete mBtEngDevMan;
    37     delete mBtengConnMan;
       
    38     delete mDisconnectDelegate;
    48     delete mDisconnectDelegate;
    39 }
    49     delete mRegDevArray;
    40 
    50     delete mNewDev;
    41 
    51     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
    52 }
       
    53 
       
    54 
       
    55 /*!
       
    56     Returns the supported editor types.
       
    57     \return the sum of supported editor types
       
    58  */
       
    59 int BtDelegateDevSecurity::supportedEditorTypes() const
       
    60 {
       
    61     return BtDelegate::UnpairDevice 
       
    62            | BtDelegate::BlockDevice
       
    63            | BtDelegate::UnblockDevice
       
    64            | BtDelegate::TrustDevice
       
    65            | BtDelegate::UntrustDevice;
       
    66 }
       
    67 
       
    68 /*!
       
    69  * performs operations on remote device:  unpair, authorize/unauthorize, block/unblock
       
    70  * params of type QList<QVariant>: 
       
    71  *         1) remote device address (QString)
       
    72  *         2) DeviceSecurityService operation 
       
    73  */
    42 void BtDelegateDevSecurity::exec( const QVariant &params )
    74 void BtDelegateDevSecurity::exec( const QVariant &params )
    43 {
    75 {
       
    76     BOstraceFunctionEntry1( DUMMY_DEVLIST, this );
       
    77     // check if in use already
       
    78     if ( mActiveHandling ) {
       
    79         emit delegateCompleted(KErrInUse, this);
       
    80         BOstraceFunctionExitExt( DUMMY_DEVLIST, this, KErrInUse );
       
    81         return;
       
    82     }
       
    83     mActiveHandling = true;
       
    84     
       
    85     // check parameters
       
    86     QList<QVariant> paramList = params.value< QList<QVariant> >(); 
       
    87     if (paramList.count() != 2) {
       
    88         // wrong parameters
       
    89         emitCommandComplete( KErrArgument ); 
       
    90         BOstraceFunctionExitExt( DUMMY_DEVLIST, this, KErrArgument );
       
    91         return;
       
    92     }
       
    93     
       
    94     int error = 0;
       
    95     TRAP( error, {
       
    96         if( !mBtEngDevMan) {
       
    97             mBtEngDevMan = CBTEngDevMan::NewL( this );
       
    98         }
       
    99     });
       
   100     if (error) {
       
   101         emitCommandComplete( KErrNoMemory ); 
       
   102         BOstraceFunctionExitExt( DUMMY_DEVLIST, this, KErrNoMemory );
       
   103         return;
       
   104     }
       
   105     
       
   106     mStrBtAddr = paramList.at(0).value<QString>();  // device to operate on
       
   107     mOperation = paramList.at(1).toInt();                   // operation
       
   108     
       
   109     addrReadbleStringToSymbian( mStrBtAddr, mBtEngAddr );
       
   110     BtTraceBtAddr1( TRACE_DEBUG, DUMMY_DEVLIST, "device addr=", mBtEngAddr );
       
   111     
       
   112 
       
   113     // get device from registry since it is needed for all operations
       
   114     mSearchPattern.FindAddress( mBtEngAddr );
       
   115     mRegDevArray->ResetAndDestroy();
       
   116     mBtEngDevMan->GetDevices(mSearchPattern, mRegDevArray); // callback is HandleGetDevicesComplete()
       
   117     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   118 }
       
   119 
       
   120 
       
   121 void BtDelegateDevSecurity::unpair()
       
   122 {
       
   123     BOstraceFunctionEntry1( DUMMY_DEVLIST, this );  
    44     int error = KErrNone;
   124     int error = KErrNone;
    45     QModelIndex index = params.value<QModelIndex>();
   125     
    46     
   126     // unpair first since malicious device might try to connect/pair again 
    47     QString strBtAddr = getDeviceModel()->data(index,
   127     // immediately after disconnecting
    48             BtDeviceModel::ReadableBdaddrRole).toString();
   128     mDevice->SetPaired(EFalse);
    49     
   129     mDevice->DeleteLinkKey();
    50     mdeviceName = getDeviceModel()->data(index,BtDeviceModel::NameAliasRole).toString();
   130 
    51     
   131     // untrust the device also
    52     TBTDevAddr symaddr;
   132     TBTDeviceSecurity security = mDevice->GlobalSecurity();
    53     TBuf<KBTDevAddrSize * 2> buffer(strBtAddr.utf16());
   133     security.SetNoAuthorise( EFalse );
    54     symaddr.SetReadable( buffer );
   134     mDevice->SetGlobalSecurity( security );
    55     
   135 
    56     // Disconnect if paired device was connected 
   136     error = mBtEngDevMan->ModifyDevice( *mDevice );  // see callback for possible disconnect
    57     if ( ! mBtengConnMan ){
       
    58         TRAP( error, mBtengConnMan = CBTEngConnMan::NewL(this) );
       
    59     }
       
    60     TBTEngConnectionStatus connstatus;
       
    61     if ( !error && mBtengConnMan->IsConnected(symaddr, connstatus ) == KErrNone) {
       
    62         if ( connstatus == EBTEngConnected) {
       
    63             if (! mDisconnectDelegate){
       
    64                 mDisconnectDelegate = BtDelegateFactory::newDelegate(
       
    65                                         BtDelegate::Disconnect, getSettingModel(), getDeviceModel()); 
       
    66                 connect( mDisconnectDelegate, SIGNAL(commandCompleted(int)), this, SLOT(disconnectDelegateCompleted(int)) );
       
    67                 
       
    68             }
       
    69             QList<QVariant>list;
       
    70             QVariant paramFirst;
       
    71             paramFirst.setValue(index);            
       
    72             QVariant paramSecond;
       
    73             DisconnectOption discoOpt = ServiceLevel;
       
    74             paramSecond.setValue((int)discoOpt);
       
    75             list.append(paramFirst);
       
    76             list.append(paramSecond);
       
    77             QVariant paramsList;
       
    78             paramsList.setValue(list);
       
    79             mDisconnectDelegate->exec(paramsList);
       
    80         }
       
    81     }
       
    82 
       
    83     // Set device as unpaired
       
    84     CBTDevice *symBtDevice = 0;
       
    85     TRAP( error, {
       
    86             symBtDevice = CBTDevice::NewL( symaddr );
       
    87             if( !mBtEngDevMan) {
       
    88                 mBtEngDevMan = CBTEngDevMan::NewL( this );
       
    89             }
       
    90     });
       
    91     
       
    92     if ( !error ) {
       
    93         symBtDevice->SetPaired(EFalse);
       
    94         // deleting link key for executing unpair is safe as no 
       
    95         // link key shall exist if the device has been unpaired. 
       
    96         symBtDevice->DeleteLinkKey();
       
    97         error = mBtEngDevMan->ModifyDevice( *symBtDevice );
       
    98     }
       
    99     delete symBtDevice;
       
   100     
   137     
   101     if ( error ) {
   138     if ( error ) {
   102         emitCommandComplete(error);
   139         emitCommandComplete(error);
   103     }
   140     }
       
   141     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   142 }
       
   143 
       
   144 void BtDelegateDevSecurity::authorizeOrBlock()
       
   145 {
       
   146     BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); 
       
   147     BOstraceExt1( TRACE_NORMAL, DUMMY_DEVLIST, "operation (Unpair|Block|Unblock|Authorize|Unauthorize)=%d", 
       
   148             mOperation);
       
   149     int error = KErrNone;
       
   150     
       
   151     TBTDeviceSecurity security = mDevice->GlobalSecurity();
       
   152     switch ( mOperation ) {
       
   153     case BtAuthorize:
       
   154         security.SetNoAuthorise( ETrue ); // set trust status to true
       
   155         security.SetBanned( EFalse );
       
   156         break;
       
   157     case BtUnauthorize:
       
   158         security.SetNoAuthorise( EFalse );
       
   159         break;
       
   160     case BtUnblock:
       
   161         security.SetBanned( EFalse );
       
   162         break;
       
   163     case BtBlock:
       
   164         security.SetBanned( ETrue );
       
   165         security.SetNoAuthorise( EFalse ); // set trust status to false
       
   166         break;
       
   167     }
       
   168 
       
   169     mDevice->SetGlobalSecurity( security );
       
   170     if ( (mOperation == BtBlock) || (mOperation == BtUnblock) ) {
       
   171         // deleting link key for executing unblock is safe as no 
       
   172         // link key shall exist if the device has been blocked. 
       
   173         mDevice->DeleteLinkKey();
       
   174         if ( mOperation == BtBlock ) {
       
   175             mDevice->SetPaired(EFalse);
       
   176         }
       
   177     }
       
   178     error = mBtEngDevMan->ModifyDevice( *mDevice );
       
   179     
       
   180     if ( error ) {
       
   181         emitCommandComplete(error);
       
   182     }
       
   183     BOstraceFunctionExitExt( DUMMY_DEVLIST, this, error );
   104 }
   184 }
   105 
   185 
   106 void BtDelegateDevSecurity::cancel()
   186 void BtDelegateDevSecurity::cancel()
   107 {
   187 {
   108     
   188     BOstraceFunctionEntry1( DUMMY_DEVLIST, this ); 
       
   189     if ( mActiveHandling ) {
       
   190         mAddingBlockedDev = false;
       
   191         emitCommandComplete(KErrNone);
       
   192     }
       
   193     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
   109 }
   194 }
   110 
   195 
   111 void BtDelegateDevSecurity::disconnectDelegateCompleted( int err )
   196 void BtDelegateDevSecurity::disconnectDelegateCompleted( int err )
   112 {
   197 {
   113     Q_UNUSED(err);
   198     BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, err );  
   114 }
   199     if (mDisconnectDelegate) {
   115 
   200         delete mDisconnectDelegate;
   116 void BtDelegateDevSecurity::HandleDevManComplete( TInt aErr )
   201         mDisconnectDelegate = 0;
   117 {
   202     }
   118     emitCommandComplete(aErr);
   203     emitCommandComplete(err);
   119 }
   204     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
   120 
   205 }
   121 void BtDelegateDevSecurity::HandleGetDevicesComplete( TInt aErr, CBTDeviceArray* aDeviceArray )
   206 
   122 {
   207 void BtDelegateDevSecurity::HandleDevManComplete( TInt err )
   123     Q_UNUSED(aErr);
   208 {
   124     Q_UNUSED(aDeviceArray);
   209     BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, err );  
       
   210 
       
   211     if ( !mActiveHandling ) {
       
   212         BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   213         return;
       
   214     }
       
   215     if ( !err ) {
       
   216         if ( mAddingBlockedDev ) {
       
   217             // blocked a device which was not in the registry originally
       
   218             mAddingBlockedDev = false;
       
   219             delete mNewDev;
       
   220             mNewDev = 0;
       
   221         }
       
   222         else if ( mOperation == BtBlock || mOperation == BtUnpair) {  
       
   223             // disconnect after blocking/unpairing if device is connected;
       
   224             // disconnect done after block/unpair, instead of before, to prevent a malicious device 
       
   225             // from reconnecting/"re-pairing"
       
   226             CBTEngConnMan *connMan(0);
       
   227             TRAP( err, connMan = CBTEngConnMan::NewL() );
       
   228             TBTEngConnectionStatus connstatus(EBTEngNotConnected);
       
   229             if (!err) {
       
   230                 err = connMan->IsConnected(mBtEngAddr, connstatus );
       
   231                 delete connMan;
       
   232             }
       
   233             if ( !err && connstatus == EBTEngConnected ) {
       
   234                 if (! mDisconnectDelegate){
       
   235                     mDisconnectDelegate = BtDelegateFactory::newDelegate(
       
   236                                             BtDelegate::DisconnectService, settingModel(), deviceModel()); 
       
   237                     connect( mDisconnectDelegate, SIGNAL(delegateCompleted(int,BtAbstractDelegate*)), this, 
       
   238                             SLOT(disconnectDelegateCompleted(int)) );
       
   239                 }
       
   240                 QList<QVariant>list;
       
   241                 list.append(QVariant(ServiceLevel));
       
   242                 list.append(QVariant(mStrBtAddr));
       
   243                 mDisconnectDelegate->exec(QVariant(list)); // see callback for continuation
       
   244                 return;
       
   245             }
       
   246         }
       
   247     }
       
   248     emitCommandComplete(err);
       
   249     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
       
   250 }
       
   251 
       
   252 void BtDelegateDevSecurity::HandleGetDevicesComplete( TInt err, CBTDeviceArray* aDeviceArray )
       
   253 {
       
   254     BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, err );  
       
   255     
       
   256     if ( mActiveHandling ) {
       
   257         if ( !err && aDeviceArray->Count() ) { 
       
   258             mDevice = aDeviceArray->At( 0 );
       
   259             switch ( mOperation ) {
       
   260             case BtUnpair:
       
   261                 unpair();
       
   262                 break;
       
   263             case BtAuthorize:
       
   264             case BtUnauthorize:
       
   265             case BtUnblock:
       
   266             case BtBlock:
       
   267                 authorizeOrBlock();
       
   268                 break;
       
   269             default:
       
   270                 // wrong parameter
       
   271                 emitCommandComplete( KErrArgument );
       
   272             }
       
   273         }
       
   274         else if ( err == KErrNotFound && mOperation == BtBlock) {  // device not in registry, need to add it
       
   275             mAddingBlockedDev = true;
       
   276             TRAP( err, {
       
   277                     mNewDev = CBTDevice::NewL( mBtEngAddr );
       
   278             });
       
   279             if ( !err ) {
       
   280                 // get needed info about device from model, e.g. name, cod
       
   281                 QString btStringAddr;
       
   282                 addrSymbianToReadbleString(btStringAddr, mBtEngAddr);
       
   283                 QModelIndex start = deviceModel()->index(0,0);
       
   284                 QModelIndexList indexList = deviceModel()->match(start,
       
   285                         BtDeviceModel::ReadableBdaddrRole, btStringAddr);
       
   286                 // ToDo:  can we be sure that device will always be found in the model?
       
   287                 QModelIndex index = indexList.at(0);
       
   288                 QString devName = deviceModel()->data(index,BtDeviceModel::NameAliasRole).toString();
       
   289                 BtTraceQString1( TRACE_DEBUG, DUMMY_DEVLIST, "device name=", devName);
       
   290                 TBuf<KMaxBCBluetoothNameLen> buf( devName.utf16() );
       
   291                 TRAP( err, mNewDev->SetDeviceNameL( BTDeviceNameConverter::ToUTF8L( buf ) ));
       
   292                 if( !err ) {
       
   293                     int cod = (index.data(BtDeviceModel::CoDRole)).toInt();
       
   294                     mNewDev->SetDeviceClass(cod);
       
   295                     TBTDeviceSecurity security = mNewDev->GlobalSecurity();
       
   296                     security.SetBanned( ETrue );
       
   297                     security.SetNoAuthorise( EFalse ); // set trust status to false
       
   298                     mNewDev->SetGlobalSecurity( security );
       
   299                     mNewDev->DeleteLinkKey();
       
   300                     mNewDev->SetPaired(EFalse);
       
   301                     err = mBtEngDevMan->AddDevice( *mNewDev );  // see callback HandleDevManComplete()
       
   302                 }
       
   303             }
       
   304         }
       
   305         if (err) {
       
   306             mAddingBlockedDev = false;
       
   307             emitCommandComplete( err );
       
   308         }
       
   309     }
       
   310     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
   125 }
   311 }
   126 
   312 
   127 void BtDelegateDevSecurity::emitCommandComplete(int error)
   313 void BtDelegateDevSecurity::emitCommandComplete(int error)
   128 {
   314 {
       
   315     BOstraceFunctionEntryExt( DUMMY_DEVLIST, this, error );  
   129     // no dialogs here since stack provides "unpaired to %1" dialog
   316     // no dialogs here since stack provides "unpaired to %1" dialog
   130     // and failures are not reported
   317     // and failures are not reported
   131     
   318     mActiveHandling = false;
   132     emit commandCompleted(error);
   319     mAddingBlockedDev = false;
   133 }
   320     if ( mNewDev ) {
   134 
   321         delete mNewDev;
   135 void BtDelegateDevSecurity::ConnectComplete( TBTDevAddr& aAddr, TInt aErr, 
   322         mNewDev = 0;
   136                                    RBTDevAddrArray* aConflicts )
   323     }
   137 {
   324     emit delegateCompleted(error, this);
   138     Q_UNUSED(aAddr);
   325     BOstraceFunctionExit1( DUMMY_DEVLIST, this );
   139     Q_UNUSED(aErr);
   326 }
   140     Q_UNUSED(aConflicts);  
   327 
   141 }
   328 
   142 
   329 
   143 void BtDelegateDevSecurity::DisconnectComplete( TBTDevAddr& aAddr, TInt aErr )
   330 
   144 {
       
   145     Q_UNUSED(aAddr);
       
   146     Q_UNUSED(aErr);    
       
   147 }
       
   148 
       
   149 
       
   150 
       
   151