Libgourou

Libgourou Git Source Tree

Root/src/user.cpp

1/*
2 Copyright 2021 Grégory Soutadé
3
4 This file is part of libgourou.
5
6 libgourou is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 libgourou is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with libgourou. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include <libgourou.h>
21#include <libgourou_common.h>
22#include <libgourou_log.h>
23#include <user.h>
24
25namespace gourou {
26 User::User(DRMProcessor* processor):processor(processor) {}
27
28 User::User(DRMProcessor* processor, const std::string& activationFile):
29processor(processor), activationFile(activationFile)
30 {
31parseActivationFile();
32 }
33
34 void User::parseActivationFile(bool throwOnNull)
35 {
36GOUROU_LOG(DEBUG, "Parse activation file " << activationFile);
37
38if (!activationDoc.load_file(activationFile.c_str()))
39{
40 if (throwOnNull)
41EXCEPTION(USER_INVALID_ACTIVATION_FILE, "Invalid activation file");
42 return;
43}
44
45try
46{
47 pkcs12 = gourou::extractTextElem(activationDoc, "//adept:pkcs12", throwOnNull);
48 uuid = gourou::extractTextElem(activationDoc, "//adept:user", throwOnNull);
49 deviceUUID = gourou::extractTextElem(activationDoc, "//device", throwOnNull);
50 deviceFingerprint = gourou::extractTextElem(activationDoc, "//fingerprint", throwOnNull);
51 authenticationCertificate = gourou::extractTextElem(activationDoc, "//adept:authenticationCertificate", throwOnNull);
52 privateLicenseKey = gourou::extractTextElem(activationDoc, "//adept:privateLicenseKey", throwOnNull);
53
54 pugi::xpath_node xpath_node = activationDoc.select_node("//adept:username");
55 if (xpath_node)
56loginMethod = xpath_node.node().attribute("method").value();
57 else
58 {
59if (throwOnNull)
60 EXCEPTION(USER_INVALID_ACTIVATION_FILE, "Invalid activation file");
61 }
62
63 if (loginMethod == "anonymous")
64username = "anonymous";
65 else
66username = gourou::extractTextElem(activationDoc, "//adept:username", throwOnNull);
67
68 pugi::xpath_node_set nodeSet = activationDoc.select_nodes("//adept:licenseServices/adept:licenseServiceInfo");
69 for (pugi::xpath_node_set::const_iterator it = nodeSet.begin();
70 it != nodeSet.end(); ++it)
71 {
72std::string url = gourou::extractTextElem(it->node(), "adept:licenseURL");
73std::string certificate = gourou::extractTextElem(it->node(), "adept:certificate");
74licenseServiceCertificates[url] = certificate;
75 }
76}
77catch(gourou::Exception& e)
78{
79 EXCEPTION(USER_INVALID_ACTIVATION_FILE, "Invalid activation file");
80}
81 }
82
83 std::string& User::getUUID() { return uuid; }
84 std::string& User::getPKCS12() { return pkcs12; }
85 std::string& User::getDeviceUUID() { return deviceUUID; }
86 std::string& User::getDeviceFingerprint() { return deviceFingerprint; }
87 std::string& User::getUsername() { return username; }
88 std::string& User::getLoginMethod() { return loginMethod; }
89 std::string& User::getAuthenticationCertificate() { return authenticationCertificate; }
90 std::string& User::getPrivateLicenseKey() { return privateLicenseKey; }
91
92 void User::readActivation(pugi::xml_document& doc)
93 {
94if (!doc.load_file(activationFile.c_str()))
95 EXCEPTION(USER_INVALID_ACTIVATION_FILE, "Invalid activation file");
96 }
97
98 void User::updateActivationFile(const char* data)
99 {
100GOUROU_LOG(INFO, "Update Activation file : " << std::endl << data);
101
102writeFile(activationFile, (unsigned char*)data, strlen(data));
103
104parseActivationFile(false);
105 }
106
107 void User::updateActivationFile(const pugi::xml_document& doc)
108 {
109StringXMLWriter xmlWriter;
110doc.save(xmlWriter, " ");
111updateActivationFile(xmlWriter.getResult().c_str());
112 }
113
114 std::string User::getProperty(const std::string property)
115 {
116pugi::xpath_node xpathRes = activationDoc.select_node(property.c_str());
117if (!xpathRes)
118 EXCEPTION(USER_NO_PROPERTY, "Property " << property << " not found in activation.xml");
119
120std::string res = xpathRes.node().first_child().value();
121return trim(res);
122 }
123
124 pugi::xpath_node_set User::getProperties(const std::string property)
125 {
126return activationDoc.select_nodes(property.c_str());
127 }
128
129 User* User::createUser(DRMProcessor* processor, const std::string& dirName, const std::string& ACSServer)
130 {
131struct stat _stat;
132
133if (stat(dirName.c_str(), &_stat) != 0)
134{
135 if (mkdir_p(dirName.c_str(), S_IRWXU))
136EXCEPTION(USER_MKPATH, "Unable to create " << dirName)
137}
138
139User* user = new User(processor);
140bool doUpdate = false;
141
142user->activationFile = dirName + "/activation.xml";
143user->parseActivationFile(false);
144
145pugi::xpath_node nodeActivationInfo = user->activationDoc.select_node("activation_info");
146pugi::xpath_node nodeActivationServiceInfo = nodeActivationInfo.node().select_node("adept:activationServiceInfo");
147pugi::xml_node activationInfo;
148pugi::xml_node activationServiceInfo;
149
150if (nodeActivationInfo && nodeActivationServiceInfo)
151{
152 GOUROU_LOG(DEBUG, "Read previous activation configuration");
153 activationInfo = nodeActivationInfo.node();
154 activationServiceInfo = nodeActivationServiceInfo.node();
155}
156else
157{
158 GOUROU_LOG(DEBUG, "Create new activation");
159
160 user->activationDoc.reset();
161
162 pugi::xml_node decl = user->activationDoc.append_child(pugi::node_declaration);
163 decl.append_attribute("version") = "1.0";
164 activationInfo = user->activationDoc.append_child("activationInfo");
165 activationInfo.append_attribute("xmlns") = ADOBE_ADEPT_NS;
166 activationServiceInfo = activationInfo.append_child("adept:activationServiceInfo");
167 activationServiceInfo.append_attribute("xmlns:adept") = ADOBE_ADEPT_NS;
168
169 // Go to activation Service Info
170 std::string activationURL = ACSServer + "/ActivationServiceInfo";
171 ByteArray activationServiceInfoReply = processor->sendRequest(activationURL);
172 pugi::xml_document docActivationServiceInfo;
173 docActivationServiceInfo.load_buffer(activationServiceInfoReply.data(),
174 activationServiceInfoReply.length());
175
176 pugi::xpath_node path = docActivationServiceInfo.select_node("//authURL");
177 appendTextElem(activationServiceInfo, "adept:authURL", path.node().first_child().value());
178 path = docActivationServiceInfo.select_node("//userInfoURL");
179 appendTextElem(activationServiceInfo, "adept:userInfoURL", path.node().first_child().value());
180 appendTextElem(activationServiceInfo, "adept:activationURL", ACSServer);
181 path = docActivationServiceInfo.select_node("//certificate");
182 appendTextElem(activationServiceInfo, "adept:certificate", path.node().first_child().value());
183 doUpdate = true;
184}
185
186pugi::xpath_node nodeAuthenticationCertificate = activationServiceInfo.select_node("adept:authenticationCertificate");
187
188if (!nodeAuthenticationCertificate)
189{
190 GOUROU_LOG(DEBUG, "Create new activation, authentication part");
191
192 pugi::xpath_node xpathRes = activationServiceInfo.select_node("adept:authURL");
193 if (!xpathRes)
194EXCEPTION(USER_NO_AUTHENTICATION_URL, "No authentication URL");
195
196 std::string authenticationURL = xpathRes.node().first_child().value();
197 authenticationURL = trim(authenticationURL) + "/AuthenticationServiceInfo";
198
199 // Go to authentication Service Info
200 ByteArray authenticationServiceInfo = processor->sendRequest(authenticationURL);
201 pugi::xml_document docAuthenticationServiceInfo;
202 docAuthenticationServiceInfo.load_buffer(authenticationServiceInfo.data(), authenticationServiceInfo.length());
203 pugi::xpath_node path = docAuthenticationServiceInfo.select_node("//certificate");
204 appendTextElem(activationServiceInfo, "adept:authenticationCertificate", path.node().first_child().value());
205 doUpdate = true;
206}
207
208if (doUpdate)
209 user->updateActivationFile(user->activationDoc);
210
211
212return user;
213 }
214
215 std::string User::getLicenseServiceCertificate(std::string url)
216 {
217if (licenseServiceCertificates.count(trim(url)))
218 return licenseServiceCertificates[trim(url)];
219
220return "";
221 }
222
223}

Archive Download this file