Notez que les intégrations ne sont pas incluses dans les packages de licence de base. Ils doivent être achetés séparément en tant qu'AddOns. Pour plus d'informations, veuillez visiter notre site Web : http://www.teamviewer.com/fr/integrations
Avec l'API REACH, TeamViewer offre une API pour une intégration dans les solutions RMM ou MDM, permettant d'initier des sessions de contrôle à distance surveillées et non surveillées.
L'objectif de ce document est d'expliquer les concepts fondamentaux de l'API REACH, ainsi que de fournir des instructions et des conseils pour intégrer l'API dans une solution de gestion.
À cette fin, le document est structuré en différentes sections qui offrent des informations sur chaque rubrique.
Le premier chapitre explique l'approche conceptuelle de base et offre une vue d'ensemble des raisons pour lesquelles certains mécanismes de sécurité ont été appliqués.
Ensuite, un exemple de mise en œuvre est décrit en fonction de l'exemple de code source d'un modèle d'intégration, également appelé VendorExampleApp, qui a été développé par TeamViewer.
Dans le chapitre final, les détails sur la mise en œuvre de l'intégration sur Android sont soulignés.
📌 Note : Tous les exemples de code dans cet article sont publiés sous la licence MIT :
Copyright (c) 2018 TeamViewer GmbH
La permission est accordée, par la présente et à titre gratuit, à toute personne qui obtient une copie de ce logiciel et des fichiers de documentation associés (le Logiciel), de gérer le Logiciel sans restrictions, y compris sans aucune limitation, les droits d'utiliser, de copier, de modifier, de fusionner, de publier, de distribuer, de concéder une sous-licence et/ou de vendre des copies du Logiciel, mais aussi de permettre aux personnes auxquelles le Logiciel est fourni d'effectuer ces opérations, sous réserve des conditions suivantes :
La notice de copyright et la présente mention d'autorisation doivent être incluses dans toutes les copies ou dans les parties importantes du Logiciel.
LE LOGICIEL EST FOURNI EN L'ÉTAT, SANS GARANTIE DE QUELQUE SORTE QUE CE SOIT, IMPLICITE OU EXPLICITE, Y COMPRIS, MAIS SANS S'Y LIMITER, LES GARANTIES DE QUALITÉ MARCHANDE, D'ADÉQUATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS, LES AUTEURS OU LES POSSESSEURS DU COPYRIGHT NE SAURAIENT ÊTRE TENUS RESPONSABLES DES RÉCLAMATIONS, DOMMAGES OU AUTRES RESPONSABILITÉS, Y COMPRIS DANS LE CADRE D'UN CONTRAT OU NON, OU EN LIEN DIRECT OU INDIRECT AVEC L'UTILISATION DU LOGICIEL OU D'AUTRES MANIPULATIONS DU LOGICIEL.
Lorsque vous réutilisez ou redistribuez le logiciel, veuillez respecter les licences des logiciels tiers inclus, le cas échéant.
Les concepts derrière l'API REACH sont finalement divisés en trois cas d'utilisation :
Le déploiement est utilisé pour échanger des clés de cryptage entre un appareil et la solution de gestion. Ces clés permettent de contrôler et d'annuler l'enregistrement. De plus, elles garantissent que toutes les communications avec un appareil sont sécurisées.
La figure ci-dessous explique le flux d'enregistrement :
Management Solution Agent (MSA) est un composant qui doit s'exécuter sur l'appareil. Cet agent doit disposer des droits d'administration sur l'appareil et récupère les données nécessaires à l'exécution correcte de la phase de déploiement.
Pour démarrer le déploiement, MSA lit un fichier spécial (étape 1) qui est écrit au démarrage du client TeamViewer et après chaque demande de déploiement réussie ou non sur ce client TeamViewer.
📌 Note : L'étape 1 peut être différente sur chaque plateforme. L'approche du fichier s'applique uniquement aux plateformes Windows et macOS. Cependant, les données fournies pour le déploiement sont identiques sur toutes les plateformes. Pour en savoir plus sur Android, veuillez consulter le chapitre Android.
Ce fichier contient RolloutKey (ROK est valable pour une demande et utilisé pour décrypter la réponse de l'API), un identificateur global unique (GUID), ainsi que RemotecontrolID de l'appareil (ID TeamViewer).
Avec RemotecontrolID et le GUID des données de déploiement et un jeu de permissions, un appel API (POST /oem/devices/createdevicekey) est effectué pour créer une nouvelle clé d'appareil (étape 3).
Cet appel API initie la communication de la solution TeamViewer principale vers le client TeamViewer cible.
Si les données sont correctes, le client TeamViewer crée une paire de clés pour les futures sessions de contrôle à distance.
Le client TeamViewer crypte la clé privée (=DeviceKey) de la paire de clés récemment créée avec RolloutKey et l'envoie avec un identifiant de cette paire de clés, ainsi qu'un jeton de retrait en réponse à l'appel API, en passant par la solution TeamViewer principale (étape 4).
La solution de gestion doit utiliser RolloutKey précédemment obtenu pour décrypter DeviceKey. Pour simplifier la procédure de décryptage, DeviceKey est crypté à l'aide du format PEM standard.
DeviceKey et DeviceKeyID sont utilisés lors de la phase de contrôle, tandis que le jeton de retrait est nécessaire pour annuler l'enregistrement de DeviceKey.
📌 Note : DeviceKey décrypté, DeviceKeyID et le jeton de retrait doivent être stockés de manière sécurisée côté solution de gestion.
Une fois la première étape terminée, il est maintenant possible d'initier des sessions de contrôle à distance sur l'appareil enregistré. Pour cela, la procédure suivante s'applique :
Le contrôle à distance est uniquement possible après avoir correctement enregistré un appareil, car DeviceKey et DeviceKeyID sont requis pour initier une session de contrôle à distance.
La première étape d'un appel WebAPI (POST /oem/devices/requestcontrol) avec les paramètres RemotecontrolID, DeviceKeyID et le type de contrôle. Ces paramètres sont transmis au client cible qui vérifie si DeviceKey possède les permissions de contrôle, qui sont requises dans l'appel API.
Après la vérification réussie de la demande, le client TeamViewer génère un secret temporaire pour une utilisation ponctuelle (un code d'authentification de message haché, HMAC), comparable à un mot de passe de session.
HMAC est calculé en fonction des données reçues via la demande de contrôle et d'autres données (valeur à usage unique cible, DeviceSecret) qui sont générées par le client TeamViewer.
Après avoir calculé HMAC, le client crypte DeviceSecret avec DeviceKey spécifié dans l'appel API via DeviceKeyID.
DeviceSecret est renvoyé en tant que paramètre de réponse d'appel API EncryptedDeviceSecret avec la valeur à usage unique cible et un modèle d'URL d'une URL de protocole TeamViewer (teamviewerapi://), incluant le caractère de substitution VOTRE_SECRET_PRINCIPAL.
La mise en œuvre de l'éditeur de logiciels indépendant doit décrypter EncryptedDeviceSecret avec DeviceKey et calculer HMAC en fonction du secret de l'appareil décrypté, la valeur à usage unique cible et les autres informations envoyées dans la demande de contrôle de l'appel API.
Une fois que HMAC est calculé, le caractère de substitution VOTRE_SECRET_PRINCIPAL doit être remplacé par HMAC pour concevoir une URL de protocole TeamViewer correcte.
L'URL complète contenant HMAC doit être présentée au client TeamViewer source pour initier une connexion.
Cela peut se produire via un navigateur ou en tant que paramètre de ligne de commande (le protocole TeamViewer est enregistré avec le système d'exploitation lorsque la solution TeamViewer est installée et associée à l'application TeamViewer).
Le client TeamViewer source utilise maintenant les informations contenues dans l'URL, notamment HMAC, pour établir une connexion sur le client cible.
Si DeviceKey n'est plus du tout utilisé, l'enregistrement de DeviceKey peut être annulé. La figure ci-dessous montre le principe de base :
Pour annuler l'enregistrement de DeviceKey, l'appel WebAPI DELETE /oem/devices/unregister est utilisé.
Pour une exécution réussie, il nécessite que DeviceKeyID identifie la clé correcte, RemotecontrolID de l'appareil, ainsi que la clé de retrait, qui a été également émise dans la réponse de l'appel API POST /oem/devices/createdevicekey lors de la phase de déploiement.
Ces informations sont alors traitées par le client TeamViewer sur l'appareil.
Si les informations dans l'API correspondent aux informations sur le client, la partie locale de la paire de clés créée dans la phase de déploiement est supprimée, et une confirmation est renvoyée via WbeAPI.
À partir de ce moment-là, plus aucune session de contrôle à distance ne peut être établie à l'aide de ce DeviceKey.
Pour suivre ce guide et effectuer réellement l'intégration, certaines informations sont requises pendant les différentes phases de l'intégration, à savoir :
L'ID du fournisseur a été fourni par un représentant TeamViewer à l'éditeur de logiciels indépendant.
Le compte du locataire peut alors être créé à l'aide d'un jeton de script du compte du fournisseur avec les autorisations de gestion du locataire.
Vous pouvez, par exemple, utiliser un outil comme Postman pour émettre les appels WebAPI.
Enfin, un jeton de script à partir du compte du locataire est nécessaire, disposant des autorisations de créer des clés d'appareils, de demander le contrôle et de supprimer les clés d'appareils.
Veuillez cliquer sur le lien Créer un script - Premiers pas pour obtenir des instructions sur la création d'un jeton de script.
Pour l'exemple d'intégration, les exemples de codes fournis utilisent les technologies et bibliothèques suivantes :
Pour Android, les informations suivantes sont également nécessaires :
AppKey est la signature de MSA sur l'appareil Android, AppKeyID est utilisé avec l'ID de compte sous forme d'index. Les deux valeurs sont renvoyées avec la réponse de l'appel WebAPI pour enregistrer AppKey dans la console Web.
💡 Astuce : Gardez à l'esprit que toutes les valeurs utilisées pendant l'explication doivent être remplacées par vos valeurs concrètes.
La figure suivante offre un aperçu des parties côté fournisseur, dans lesquelles l'intégration doit être effectuée.
L'appel API peut être effectué avec n'importe quelle classe client HTTP.
La précondition de cet appel WebAPI est de lire les informations à partir du fichier de déploiement écrit par le client TeamViewer.
Ce fichier est lisible sur les plateformes Windows et macOs avec des droits d'administration.
Sur les appareils Android, un enregistrement de l'application MSA est requis avant d'essayer d'accéder aux données de déploiement. Cela fait l'objet d'une description distincte dans le chapitre Intégration d'Android ci-dessous.
Pour notre exemple ici, nous nous référons au code, car il est également fourni dans VendorExampleApp disponible dans le code source. Vous devez d'abord créer le corps JSON, qui peut, par exemple, se produire à l'aide de la classe de données, comme l'exemple de création suivant d'une telle classe de données.
Gardez à l'esprit que les informations sur RemotecontrolID et RequestID proviennent du fichier de déploiement :
Création du corps de la demande
var createDeviceKeyRequest = new CreateDeviceKeyRequest { key_permissions = unattended, remotecontrol_id = r124124124, request_id = {8c4fa1a7-9d1c-41e9-be17-70e95c289080}, tenant_id = t0001 };
Avec cette classe de données créée et remplie avec les informations, l'appel WepAPI peut être émis en spécifiant l'URL et la méthode, en remplissant l'en-tête de la requête HTTP avec les informations d'authentification requises, puis en ajoutant le corps JSON contenant la classe de données sérialisées mentionnée ci-dessus.
Pour ajouter l'autorisation à l'en-tête HTTP, un jeton de script d'application doit être créé via TeamViewer (Classic) Management Console.
Vous devez vérifier que ce jeton de script dispose des permissions correctes pour exécuter les appels WebAPI.
Ces permissions peuvent uniquement être accordées pour ce jeton de script si le compte qui possède le jeton de script est un locataire.
Consultez un exemple de code dans la zone suivante émettant l'appel, analysant la réponse et renvoyant la classe de données sérialisées contenant les valeurs de réponses. Cet exemple de code provient de l'application du fournisseur.
Demander DeviceSecretKey
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(apiUrl + /api/v1/oem/devices/createdevicekey); webReq.Method = POST; webReq.ContentType = application/json; webReq.Headers.Add(Authorization, Bearer +accessToken); using (var streamWriter = new StreamWriter(webReq.GetRequestStream())) { var createSecretKeyRequestJson = JsonConvert.SerializeObject(createDeivceKeyRequest); streamWriter.Write(createDeviceKeyRequestJson); streamWriter.Flush(); streamWriter.Close(); } var httpResponse = (HttpWebResponse) await webReq.GetResponseAsync(); if (httpResponse == null) { throw new InvalidDataException(No response received); } var responseStream = httpResponse.GetResponseStream(); if (responseStream == null) { throw new InvalidDataException(No response stream received.); } using (var streamReader = new StreamReader(responseStream)) { var result = streamReader.ReadToEnd(); return JsonConvert.DeserializeObject<CreateDeviceKeyResponse>(result); }
Avec la réponse de l'API, vous êtes maintenant en possession du DeviceKey crypté.
Pour décoder le DeviceKey crypté qui est au format PEM, nous avons choisi BouncyCastle comme bibliothèque ici, car elle facilement considérablement les choses.
BouncyCastle est également disponible pour Java. Toutefois, il doit exister de nombreuses bibliothèques pour chaque langue en mesure de fonctionner avec des fichiers PEM.
L'algorithme de cryptage est indiqué directement dans le fichier PEM que vous obtenez de la demande d'API.
Exemple :
-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: AES-256-CBC,309AA16\n-----END RSA PRIVATE KEY-----\n
À cause des problèmes de sécurité, nous vous RECOMMANDONS FORTEMENT d'utiliser une bibliothèque pour gérer le travail, car les bibliothèques sont généralement fournies avec la capacité d'identifier automatiquement l'algorithme correct.
En cas de problèmes de sécurité avec l'algorithme lui-même, nous pouvons le changer et nous le ferons.
Aucune modification ne sera requise du côté de l'éditeur de logiciels indépendant si une bibliothèque appropriée est utilisée alors qu'une mise en œuvre manuelle ne serait jamais aussi flexible.
Avec Bouncy Castle, le décryptage de la clé PEM se réduit au code comme dans l'exemple suivant.
Pour des raisons de simplicité, nous stockons deviceKey sous forme de chaîne au format PEM décrypté, car il peut être parfaitement géré par la bibliothèque BouncyCastle et stocké comme une chaîne.
Décrypter la clé PEM
TextReader textReader = new StringReader(encryptedDeviceKey); PemReader pemReader = new PemReader(textReader, new PasswordFinder(password)); object deviceKeyObject = pemReader.ReadObject(); AsymmetricCipherKeyPair rsaPrivatekey = (AsymmetricCipherKeyPair)deviceKeyObject; TextWriter tw = new StringWriter(); var pemWriter = new PemWriter(tw); pemWriter.WriteObject(rsaPrivatekey.Private); pemWriter.Writer.Flush(); string deviceKey = tw.ToString(); return deviceKey;
Ce qui est important après cette étape, c'est que vous devez stocker DeviceKey avec DeviceKeyID et RemotecontrolID, renvoyé en réponse à l'appel WebAPI, dans le cadre de votre solution de gestion.
De plus, vous devez également conserver le jeton de retrait qui est finalement requis pour annuler à nouveau l'enregistrement de DeviceKey.
Avec les données de la phase précédente, DeviceKey et DeviceKeyID, une session de contrôle à distance peut être établie sur l'appareil enregistré.
Il est indispensable que pendant la demande de contrôle à distance, vous utilisiez le même type de contrôle pour lequel vous avez demandé les permissions lors de la phase de déploiement.
À nouveau au début, une instance de classe de données est d'abord remplie avec les informations requises pour l'appel WebAPI.
Demander le contrôle de la classe de données
var requestControlRequest = new RequestControlRequest() { control_type = attended, device_key_id = {114fa1a7-abab-41e9-be17-70e95c289080}, remotecontrol_id = r124124124, tenant_id = t0001, tenant_nonce = 243dd78d07324ab7befa41390d08d35f };
Avec cette instance de données en place, l'appel WebAPI peut être émis comme dans le code C# suivant.
Une nouvelle fois, l'URL est d'abord ajoutée, puis l'en-tête d'autorisation HTTP avec le jeton de script et enfin, l'instance de la classe de données sérialisées sous forme de corps JSON.
Une fois que la demande a été renvoyée avec une réponse, les données peuvent être désérialisées en une instance de classe de données, fournissant le modèle du lien TeamViewer.
Ce lien est ensuite complété avec le code d'authentification de message haché (HMAC, Hashed Method Authentication Message).
Appel de contrôle à distance
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(apiUrl + /api/v1/oem/devices/requestcontrol); webReq.Method = POST; webReq.ContentType = application/json; webReq.Headers.Add(Authorization, Bearer + accessToken); using (var streamWriter = new StreamWriter(webReq.GetRequestStream())) { var requestControlRequestJson = JsonConvert.SerializeObject(requestControlRequest); streamWriter.Write(requestControlRequestJson); streamWriter.Flush(); streamWriter.Close(); } var httpResponse = (HttpWebResponse)(await webReq.GetResponseAsync()); if (httpResponse == null) { throw new InvalidDataException(No response received); } var responseStream = httpResponse.GetResponseStream(); if (responseStream == null) { throw new InvalidDataException(No response stream received.); } using (var streamReader = new StreamReader(responseStream)) { var result = streamReader.ReadToEnd(); return JsonConvert.DeserializeObject<RequestControlResponse>(result); }
Comme la réponse de l'API renvoie uniquement un modèle de lien, le lien doit être complété avec HMAC.
Le secret pour créer HMAC est le renvoi crypté dans la réponse de l'API pour que la première étape consiste à décrypter le secret.
La clé du décryptage est DeviceKey, reçu avec la réponse de l'API lors de la phase de déploiement.
Comme DeviceKey est stocké sous forme de chaîne au format PEM, la première partie du code convertit cette chaîne en une structure adaptée à BouncyCastle (la variable de type AsymmetricCipherKeyPair).
Décrypter PreMasterSecret
using (var reader = new StringReader(DeviceKey)) { //Convert to right format var bytesToDecrypt = encryptedDeviceSecret.FromBase64SafeUrl(); //--------DECRYPT WITH PEM DEVICE KEY-------------// AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair) new PemReader(reader).ReadObject(); var decryptEngine = new OaepEncoding(new RsaEngine()); decryptEngine.Init(false, keyPair.Private); var decryptedDeviceSecret = decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length); }
Avec DeviceSecret, TenantID, RemotecontrolID de la cible et les valeurs à usage unique cibles et du locataire, HMAC peut être créé comme dans l'exemple suivant, qui est à nouveau mis en œuvre à l'aide de la bibliothèque de sécurité BouncyCastle.
Générer Mastersecret
//---------HMAC Values to be hashed, recombined in a string ------------// var hashVerifier = ${tenantNonce}{targetNonce}{tenantId.Substring(1)}{remotecontrolId.Substring(1)}; HMACSHA512 hmacsha512 = new HMACSHA512(decryptedDeviceSecret); byte[] hashmessage = hmacsha512.ComputeHash(Encoding.UTF8.GetBytes(hashVerifier)); var masterSecret = hashmessage.ToBase64SafeUrl();
Le résultat est placé dans le modèle du lien TeamViewer au lieu de la chaîne VOTRE_SECRET_PRINCIPAL.
Avec cette chaîne complétée, la session de contrôle à distance peut être établie en ouvrant le lien dans le navigateur Internet d'un système sur lequel un client d'entreprise TeamViewer est installé, ou en passant ce lien à la ligne de commande d'un appel vers TeamViewer.exe
L'annulation de l'enregistrement d'un appel d'appareil exige les paramètres suivants pour exécuter correctement l'annulation de l'enregistrement :
Comme dans les phases précédentes, une instance de classe de données pour cet appel spécifique doit être créée, remplie avec les données concrètes pour le prochain appel vers WebAPI :
Création de la structure de données
var unregisterDeviceRequest = new UnregisterDeviceRequest { tenant_id = t0001, remotecontrol_id = r124124124, device_key_id = {114fa1a7-abab-41e9-be17-70e95c289080}, decommission_token = _mState.LastDecommissionToken };
À nouveau, comme précédemment montré, le même modèle de mise en œuvre est suivi, ajoutant l'URL d'appel WebAPI, ajoutant la méthode, le jeton de script d'application sur l'en-tête d'autorisation HTTP et ajoutant enfin le contenu sérialisé de la classe de données précédemment créée au format JSON.
Annuler l'enregistrement
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(apiUrl + /api/v1/oem/devices); webReq.Method = DELETE; webReq.ContentType = application/json; webReq.Headers.Add(Authorization, Bearer + accessToken); using (var streamWriter = new StreamWriter(webReq.GetRequestStream())) { var unregisterDeviceRequestJson = JsonConvert.SerializeObject(unregisterDeviceRequest); streamWriter.Write(unregisterDeviceRequestJson); streamWriter.Flush(); streamWriter.Close(); } var httpResponse = (HttpWebResponse)await webReq.GetResponseAsync(); if (httpResponse == null) { throw new InvalidDataException(No response received); } var responseStream = httpResponse.GetResponseStream(); if (responseStream == null) { throw new InvalidDataException(No response stream received.); } using (var streamReader = new StreamReader(responseStream)) { var result = streamReader.ReadToEnd(); return; }
Dans ce cas, le résultat renvoyé ne contient aucune donnée.
La réussite de l'opération peut uniquement être vérifiée en contrôlant la valeur de retour, qui doit être 204 (voir aussi Valeurs de retour communes HTTP).
À cause des restrictions de plateforme sur Android (ne disposant pas de la séparation correcte des privilèges d'administration), le déploiement diffère des autres plateformes. Une vérification de MSA doit être effectuée avant de pouvoir communiquer avec l'application Android TeamViewer, et RolloutKey est obtenu de manière différente.
Le hachage SHA-256 de la clé de signature de MSA (appelée AppKey à partir de maintenant) doit être enregistré avec TeamViewer sous forme de chaîne hexadécimale à l'aide de l'appel WebAPI POST /oem/appregistrations.
Cette étape d'enregistrement est uniquement requise une fois par AppKey et peut être réalisée avec tout client REST, comme Postman.
La communication entre l'application TeamViewer et MSA utilise l'interface Android Binder native (https://developer.android.com/reference/android/os/Binder.html) comme décrit par les fichiers AIDL que vous avez reçus lors de l'enregistrement pour l'API REACH.
Avant n'importe quel appel, la méthode de vérification doit être appelée. La méthode de vérification nécessite AccountID du compte qui a été utilisé pour enregistrer MSA AppKey et KeyID qui a été renvoyé lors de l'enregistrement. Si la vérification réussit, vous pouvez appeler l'une des méthodes du service Binder, sinon SecurityException est levé.
La principale différence sur Android, à l'exception de l'enregistrement d'application, c'est la façon dont RolloutKey est obtenu. Le fichier contenant les données de déploiement est écrit dans le stockage d'application privé de l'application TeamViewer. Il est uniquement possible de lire ces informations pour l'application TeamViewer. C'est pour cette raison que l'application MSA doit demander les données de déploiement via l'interface Binder. Après avoir correctement obtenu les données de déploiement, à l'aide de la méthode requestPreKeyData sur l'interface Binder, vous pouvez alors procéder de la même manière que celle qui est décrite dans le chapitre Déploiement d'un appareil pour l'API REACH.