Cette documentation est archivée et n’est pas conservée.

Exemple : création de logiciels de protection IRM personnalisés

Windows SharePoint Services 3

Vous pouvez créer des logiciels personnalisés de protection de la gestion des droits, qui convertissent aux formats de gestion des droits les fichiers que l'utilisateur télécharge via l'architecture extensible de la Gestion des droits relatifs à l'information (IRM, Information Rights Management) dans Windows SharePoint Services. Vous pouvez reconvertir ces fichiers vers des formats de fichiers non chiffrés à l'aide des mêmes logiciels de protection lorsque l'utilisateur télécharge les fichiers pour les stocker dans la bibliothèque de documents SharePoint.

Les développeurs peuvent contrôler l'emplacement du contenu protégé, de la licence d'émission et de la licence utilisateur final dans la version protégée du fichier ; en outre, ils peuvent faire varier le format du document protégé selon le type de fichier, à l'aide d'un logiciel de protection IRM personnalisé. Les développeurs peuvent également supprimer et remplacer le type de protection par une autre plateforme de gestion des droits.

Cet exemple de code (projet SampleDocProtector) montre comment utiliser les logiciels de protection IRM pour des fichiers texte. L'exemple de logiciel de protection IRM protège les fichiers texte à l'aide de l'infrastructure des services RMS (Rights Management Services) Microsoft Windows dans Windows SharePoint Services. Il permet également de chiffrer les fichiers texte, à l'aide de la méthode de chiffrement de votre choix.

Remarque Remarque :

Cette rubrique suppose que vous connaissez bien la Gestion des droits relatifs à l'information (IRM) dans Windows SharePoint Services, les services RMS, les interfaces IRM et les classes IRM. Pour plus d'informations, voir Vue d'ensemble du service Gestion des droits relatifs à l'information dans Windows SharePoint Services, I_IrmProtector, interface et Logiciels de protection IRM personnalisés.

Vous pouvez créer deux types de logiciels de protection IRM qui utilisent l'infrastructure IRM de Windows SharePoint Services : les logiciels de protection intégrés et les logiciels de protection autonomes.

Remarque Remarque :

Pour plus d'informations sur les logiciels de protection intégrés et autonomes, voir Logiciels de protection IRM personnalisés.

L'exemple de code SampleDocProtector vous montre comment utiliser les logiciels de protection intégrés et les logiciels de protection autonomes. Les logiciels de protection intégrés reposent sur Windows SharePoint Services pour l'accès à la plateforme des services RMS Microsoft Windows, la génération des versions protégées des fichiers et la suppression de la protection des fichiers gérés par des droits. En revanche, les logiciels de protection autonomes doivent configurer et exécuter eux-mêmes l'ensemble du processus de gestion des droits. Les logiciels de protection autonomes peuvent accéder directement à la plateforme des services RMS Microsoft Windows, ou recourir à une autre plateforme de gestion des droits.

Remarque Remarque :

Dans une implémentation réelle, vous utilisez soit les logiciels de protection intégrés, soit les logiciels de protection autonomes, mais pas les deux à la fois. Cet exemple n'est qu'une démonstration de l'utilisation des logiciels de protection IRM.

Bb802693.important(fr-fr,office.12).gif Important :

Ne vous servez pas de l'exemple en l'état. Il s'agit d'une simple démonstration de l'utilisation de logiciels de protection IRM personnalisés. Aucune application côté client, telle que le Bloc-notes, ne peut utiliser le format de fichier chiffré spécifié dans l'exemple. Le Bloc-notes ne peut pas ouvrir et déchiffrer le fichier texte.

Emplacement de l'exemple de code

Vous trouverez le projet SampleDocProtector dans le dossier de l'exemple de code SampleDocProtector, à l'intérieur du dossier ECM Starter Kit du téléchargement de Windows SharePoint Services 3.0 SDK .

Fichiers de l'exemple de projet

Pour plus d'informations sur les divers fichiers de l'exemple de projet et leurs finalités, voir le fichier ReadMe.txt inclus dans le dossier du projet SampleDocProtector.

Procédure pas à pas de l'exemple de code

Chaque logiciel de protection IRM doit être un composant COM qui implémente l'interface I_IrmProtector. Bien que les logiciels de protection intégrés et autonomes soient obligés d'implémenter l'interface I_IrmProtector, chaque type de logiciel de protection implémente l'interface de manière différente, car Windows SharePoint Services appelle ces deux types à l'aide de méthodes distinctes de l'interface. Windows SharePoint Services appelle les logiciels de protection intégrés à l'aide des méthodes HrProtectRMS et HrUnprotectRMS ; il appelle les logiciels de protection autonomes à l'aide des méthodes HrProtect et HrUnprotect.

La fonction HrProtectRMS du projet SampleDocProtector comporte un paramètre nommé piid. Le paramètre piid est un lien vers les fonctions et les données d'assistance du processus de chiffrement et de déchiffrement. L'argument piid, qui est un objet I_IrmPolicyInfoRMS, contient plusieurs fonctions d'assistance.

Notez que l'exemple de fonction HrProtectRMS n'appelle pas les API des services RMS Microsoft Windows. Cela est dû au fait que tous les appels à l'API RMS, y compris les appels au serveur RMS, sont gérés automatiquement par Windows SharePoint Services. À la place, la fonction HrProtectRMS accède aux objets RMS, par exemple la licence d'émission et les licences utilisateur final, via l'argument piid, puis les enregistre dans un flux.

La méthode StgIsStorageILockBytes est un moyen simple de stocker des données binaires. L'extrait de code de la fonction HrProtectRMS est illustré dans le code suivant.

Remarque Remarque :

Vous pourrez trouver l'extrait de code suivant dans le fichier SampleProtector.cpp du projet SampleDocProtector.

HRESULT CSampleProtector::HrProtectRMS(ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfoRMS *piid, DWORD *pdwStatus)
{
    HRESULT hr = S_OK;
    IStorage *pistgOutput = NULL;
        IStorage *pistgLicenses = NULL;
        IStream *pistmT = NULL;
        BSTR bstr = NULL;
    UINT cEULs = 0;
    BSTR *rgbstrEUL = NULL;
    BSTR *rgbstrId = NULL;
    I_IrmCrypt *piic = NULL;
    BYTE rgbBuffer[STACK_RW_BUF_SIZE];
          = 16;
    ULARGE_INTEGER ulOffset = { 0 };

    if (pilbInput == NULL || pilbOutput == NULL || piid == NULL || pdwStatus == NULL)
    {
        hr = E_INVALIDARG;
        goto LExit;
    }

    *pdwStatus = MSOIPI_STATUS_UNKNOWN;

    hr = StgIsStorageILockBytes(pilbOutput);
    if (FAILED(hr))
        goto LExit;

    if (hr != S_FALSE)
    {
        hr = StgOpenStorageOnILockBytes(pilbOutput, NULL, 
        STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &pistgOutput);
        if (hr == STG_E_FILEALREADYEXISTS)
            goto LCreateStorage;
    }
    else
    {
LCreateStorage:
        hr = StgCreateDocfileOnILockBytes(pilbOutput, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, &pistgOutput);
    }
    if (FAILED(hr))
        goto LExit;

        // Write out the key.
        BSTR key = SysAllocString(wzKey);
        hr = HrWriteSubStream(pistgOutput, wzKey, &key);

        // Write out the signed IL.
    hr = piid->HrGetSignedIL(&bstr);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
        hr = HrWriteSubStream(pistgOutput, wzSignedIL, &bstr);

        // Write out the server Id.
    hr = piid->HrGetServerId(&bstr);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
        hr = HrWriteSubStream(pistgOutput, wzServerID, &bstr);
        if (FAILED(hr))
            goto LExit;

        // Write out the licenses.
        hr = HrEnsureStg(pistgOutput, wzLicenses, true /*fReadWrite*/, &pistgLicenses);
        if (FAILED(hr))
            goto LExit;
    hr = piid->HrGetEULs(NULL, NULL, &cEULs);
        // printf("Got %d EULS", cEULs);
    if (FAILED(hr))
        goto LExit;
    rgbstrEUL = (BSTR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cEULs * sizeof(BSTR));
    if (rgbstrEUL == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto LExit;
    }
    rgbstrId = (BSTR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cEULs * sizeof(BSTR));
    if (rgbstrId == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto LExit;
    }
    hr = piid->HrGetEULs(rgbstrEUL, rgbstrId, &cEULs);

    if (FAILED(hr))
        goto LExit;
        WCHAR    streamId[STREAM_MAX];
    for (UINT iEUL = 0; iEUL < cEULs; iEUL++)
    {
        if (rgbstrEUL[iEUL] != NULL && rgbstrId[iEUL] != NULL)
            {
            hr = StringCchCopy(streamId, cElements(streamId), wzEULPrefix);
            WCHAR   *pwz         = streamId + wcslen(streamId);
            *pwz++ = (WCHAR) iEUL;
            *pwz = NULL;
            hr = HrWriteSubStream(pistgLicenses, streamId, &rgbstrEUL[iEUL]);
            if (FAILED(hr))
                goto LExit;
        }
        if (rgbstrEUL[iEUL] != NULL)
            SysFreeString(rgbstrEUL[iEUL]);
        if (rgbstrId[iEUL] != NULL)
            SysFreeString(rgbstrId[iEUL]);
    }
    HeapFree(GetProcessHeap(), 0, rgbstrId);
    rgbstrId = NULL;
    HeapFree(GetProcessHeap(), 0, rgbstrEUL);
    rgbstrEUL = NULL;
    pistgLicenses->Release();
    pistgLicenses = NULL;

    // Write out the rights template.
    hr = piid->HrGetRightsTemplate(&bstr);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzRightsTemplate, &bstr);
    if (FAILED(hr))
        goto LExit;

    // Write out the list GUID.
    hr = piid->HrGetListGuid(&bstr);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzListGuid, &bstr);
    if (FAILED(hr))
        goto LExit;

    // Write out the content.
    hr = HrEnsureStm(pistgOutput, wzContent, true /*fReadWrite*/, &pistmT);
    if (FAILED(hr))
        goto LExit;
    hr = piid->HrGetICrypt(&piic);
    if (FAILED(hr) || piic == NULL)
        goto LExit;
    ulOffset.QuadPart = 0;
    while (true)
    {
        ULONG cbRead = cElements(rgbBuffer);
        ULONG cbWritten = 0;
        hr = pilbInput->ReadAt(ulOffset, rgbBuffer, cbRead, &cbRead);
        if (FAILED(hr))
            goto LExit;
        if (cbRead == 0)
            goto LFinished;
        // cbRead needs to be a multiple of 16 for RMS.
        // If it is not, pad it for encryption.
        if(cbRead % BLOCK_SIZE)
        {
            ULONG nCbRead = ((cbRead /BLOCK_SIZE)+1)*BLOCK_SIZE;
            for(ULONG pad = 0; pad < (nCbRead - cbRead);pad++)
            {
                rgbBuffer[cbRead + pad] = '0';
            }
            cbRead = nCbRead;
        }
        hr = piic->HrEncrypt(0, rgbBuffer, cbRead, 0);
        if (FAILED(hr))
            goto LExit;
        hr = pistmT->Write(rgbBuffer, cbRead, &cbWritten);
        if (FAILED(hr))
            goto LExit;
        if (cbRead != cbWritten)
        {
            hr = STG_E_CANTSAVE;
            goto LExit;
        }

        ulOffset.QuadPart += cbRead;
    }

LFinished:
    piic->Release();
    piic = NULL;
    hr = pistmT->Commit(STGC_DEFAULT);

LExit:
    *pdwStatus = SUCCEEDED(hr) ? MSOIPI_STATUS_PROTECT_SUCCESS : MSOIPI_STATUS_CANT_PROTECT;
    if (piic != NULL)
        piic->Release();
    if (rgbstrId != NULL)
        HeapFree(GetProcessHeap(), 0, rgbstrId);
    if (rgbstrEUL != NULL)
        HeapFree(GetProcessHeap(), 0, rgbstrEUL);
    if (bstr != NULL)
        SysFreeString(bstr);
    if (pistmT != NULL)
    {
        pistmT->Release();
        pistmT = NULL;
    }
    if (pistgLicenses != NULL)
        pistgLicenses->Release();
    if (pistgOutput != NULL)
        pistgOutput->Release();

    return hr;
}

La fonction HrInit initialise le logiciel de protection IRM. Dans la fonction HrInit, le paramètre pfUseRMS a la valeur true afin de permettre l'utilisation d'un logiciel de protection intégré. Pour permettre l'utilisation d'un logiciel de protection autonome, affectez au paramètre la valeur false. Il contacte ensuite le serveur RMS directement pour demander la licence utilisateur final du document. N'effectuez pas une telle implémentation dans une application réelle. Vous devez implémenter soit un logiciel de protection intégré, soit un logiciel de protection autonome, mais pas les deux à la fois dans votre code.

L'extrait de code de la fonction HrInit est le suivant :

/*-----------------------------------------------------------------------------
    CSampleProtector::HrInit
------------------------------------------------------------------------------*/
STDMETHODIMP CSampleProtector::HrInit(BSTR *pbstrProduct, DWORD *pdwVersion, BSTR *pbstrExtensions, BOOL *pfUseRMS)
{
    if ( pbstrExtensions == NULL || pfUseRMS == NULL)
        return E_INVALIDARG;
    *pfUseRMS        = true; //set to "false" to use the non-RMS infrastructure
    *pbstrProduct    = SysAllocString(L"SampleIrmProtector");
    *pdwVersion      = 1;
    *pbstrExtensions = SysAllocString(L"txt");
    return S_OK;

La fonction HrProtect gère le chiffrement. Cet exemple utilise une méthode de chiffrement simple. Pour l'implémenter, vous pouvez utiliser la méthode de chiffrement en vigueur dans votre organisation.

L'extrait de code de la fonction HrProtect est le suivant :

/*---------------------------------------------------------------------
    CSampleProtector::HrProtect
---------------------------------------------------------------------*/
HRESULT CSampleProtector::HrProtect(ILockBytes *pilbInput, ILockBytes *pilbOutput, I_IrmPolicyInfo *piid, DWORD *pdwStatus)
{
    HRESULT hr = S_OK;
    IStorage *pistgOutput = NULL;
    IStream *pistmT = NULL;
    BSTR bstr = NULL;
    DWORD dw = 0;
    BOOL bRequestingUserIsSystem = false;
    BYTE rgbBuffer[STACK_RW_BUF_SIZE];
    ULARGE_INTEGER ulOffset = { 0 };
    if (pilbInput == NULL || pilbOutput == NULL || piid == NULL || pdwStatus == NULL)
    {
        hr = E_INVALIDARG;
        goto LExit;
    }
    *pdwStatus = MSOIPI_STATUS_UNKNOWN;
    hr = StgIsStorageILockBytes(pilbOutput);
    if (FAILED(hr))
        goto LExit;
    if (hr != S_FALSE)
    {
        hr = StgOpenStorageOnILockBytes(pilbOutput, NULL, STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, NULL, &pistgOutput);
        if (hr == STG_E_FILEALREADYEXISTS)
            goto LCreateStorage;
    }
    else
    {
LCreateStorage:
        hr = StgCreateDocfileOnILockBytes(pilbOutput, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, &pistgOutput);
    }
    if (FAILED(hr))
        goto LExit;
    // Write out the key.
    BSTR key = SysAllocString(wzKey);
    hr = HrWriteSubStream(pistgOutput, wzKey, &key);
    // Write out the list GUID.
    hr = piid->HrGetListGuid(&bstr);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzListGuid, &bstr);
    if (FAILED(hr))
        goto LExit;
    // Write out the rights mask.
    hr = piid->HrGetRightsMask(&dw);
    if (FAILED(hr))
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzRightsMask, &bstr);
    if (FAILED(hr))
        goto LExit;
    // Write out the requesting user.
    hr = piid->HrGetRequestingUser(&bstr, &bRequestingUserIsSystem);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzRequestingUser, &bstr);
    if (FAILED(hr))
        goto LExit;
    // Write out the URL.
    hr = piid->HrGetURL(&bstr);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzURL, &bstr);
    if (FAILED(hr))
        goto LExit;
    // Write out the title.
    hr = piid->HrGetPolicyTitle(&bstr);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzPolicyTitle, &bstr);
    if (FAILED(hr))
        goto LExit;
    // Write out the description.
    hr = piid->HrGetPolicyTitle(&bstr);
    if (FAILED(hr) || bstr == NULL)
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzPolicyDescription, &bstr);
    if (FAILED(hr))
        goto LExit;
    // Write out the offline days.
    hr = piid->HrGetOfflineDays(&dw);
    if (FAILED(hr))
        goto LExit;
    hr = HrWriteSubStream(pistgOutput, wzOfflineDays, &bstr);
    if (FAILED(hr))
        goto LExit;
    // Write out the content.
    hr = HrEnsureStm(pistgOutput, wzContent, true /*fReadWrite*/, &pistmT);
    if (FAILED(hr))
        goto LExit;
    ulOffset.QuadPart = 0;
    while (true)
    {
        ULONG cbRead = cElements(rgbBuffer);
        ULONG cbWritten = 0;
        hr = pilbInput->ReadAt(ulOffset, rgbBuffer, cbRead, &cbRead);
        if (FAILED(hr))
            goto LExit;
        if (cbRead == 0)
            goto LFinished;
        for (ULONG i = 0; i < cbRead; i++)
            //Simple encryption: flip bits
            rgbBuffer[i] ^= 1;
        hr = pistmT->Write(rgbBuffer, cbRead, &cbWritten);
        if (FAILED(hr))
            goto LExit;
        if (cbRead != cbWritten)
        {
            hr = STG_E_CANTSAVE;
            goto LExit;
        }
        ulOffset.QuadPart += cbRead;
    }
LFinished:
    hr = pistmT->Commit(STGC_DEFAULT);
LExit:
    *pdwStatus = SUCCEEDED(hr) ? MSOIPI_STATUS_PROTECT_SUCCESS : MSOIPI_STATUS_CANT_PROTECT;
    if (bstr != NULL)
        SysFreeString(bstr);
    if (pistmT != NULL)
        pistmT->Release();
    if (pistgOutput != NULL)
        pistgOutput->Release();
    return hr;
}

Inscription d'un logiciel de protection IRM

Après avoir compilé votre logiciel de protection IRM personnalisé, vous devez l'inscrire auprès de Windows SharePoint Services afin de le rendre accessible aux bibliothèques de documents. Vous inscrivez le logiciel de protection IRM, qui est un composant COM, de la même façon qu'un composant COM.

Pour cet exemple, la syntaxe d'inscription est la suivante :

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\IrmProtectors]
"{6EC4BB1F-3F73-4799-BC98-A3DF9AE23A0B}"="SampleDocProtector"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\SampleDocProtector]
"Extensions"="doc"
"Product"="SampleIrmProtector"
"Version"="1"

Vous trouverez les informations d'inscription dans le fichier IrmProtectors.reg du projet SampleDocProtector.

Définition et activation de la propriété du module complémentaire Gestion des droits relatifs à l'information (IRM, Information Rights Management)

Pour utiliser un logiciel de protection intégré ou des logiciels de protection IRM inclus dans Windows SharePoint Services, vous activez la gestion des droits relatifs à l'information en spécifiant un emplacement pour votre serveur RMS Windows à l'aide des paramètres de la page Paramètres de la Gestion des droits relatifs à l'information dans l'Administration centrale.

Toutefois, si vous utilisez des logiciels de protection autonomes, vous devez activer le module complément IRM à l'aide de stsadm.exe. Vous effectuez cette opération en affectant à la propriété irmaddinsenabled la valeur true. Si le module complémentaire IRM n'est pas activé, les logiciels de protection autonomes ne chiffrent pas le contenu téléchargé.

La commande suivante montre comment vous pouvez activer la propriété du module complémentaire IRM à l'aide de stdsadm.exe :

stsadm -o setproperty -propertyname irmaddinsenabled -propertyvalue TRUE

Voir aussi

Afficher: