00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "gm/xml_manager.h"
00024
#include "gm/contact_manager.h"
00025
#include "gm/settings_manager.h"
00026
#include "gm/cryptography.h"
00027
00033
#include "sys/stat.h"
00034
00035
namespace GNUMessenger {
00036
00037 string XMLManager::m_directory =
"";
00038
00039 XMLManager::XMLManager(
const string& directory)
00040 : m_isOnline(false)
00041 {
00042
00043 setDirectory(directory);
00044 }
00045
00046 XMLManager::~XMLManager()
00047 {
00048 }
00049
00050 bool XMLManager::logout()
00051 {
00052
if (!m_isOnline)
00053
return false;
00054
00055
00056
commit();
00057
00058
00059 m_isOnline =
false;
00060
00061
00062
XMLNode empty;
00063 m_xml = empty;
00064
00065
00066 m_diskPass.
wipe();
00067
00068
00069 m_filename.clear();
00070
00071
return true;
00072
00073 }
00074
00075 bool XMLManager::setDirectory(
const string& dir)
00076 {
00077
if (dir.empty()) {
00078 LOG_DEBUG(
"Dir is empty.");
00079 m_directory.clear();
00080
return true;
00081 }
00082
00083
if (!isDirectory(dir)) {
00084 LOG_DEBUG(
"Dir is not a directory.");
00085
return false;
00086 }
00087
00088 m_directory = dir;
00089
00090
if ( (dir[dir.length() - 1] !=
'\\') &&
00091 (dir[dir.length() -1] !=
'/')) {
00092 m_directory +=
'/';
00093 }
00094
00095
return true;
00096 }
00097
00098 bool XMLManager::createNew(
const string& username,
const VBuffer &password)
00099 {
00100
00101
if (
exists(username))
00102
return false;
00103
00104
if (m_isOnline)
00105
logout();
00106
00107
00108 m_filename =
getFileName(username);
00109
00110
00111 m_diskPass = CryptoManager::hash(password, CryptDefines::SHA_384);
00112
00113
00114 m_xml.
setName(
"config").
setProperty(
"username", username);
00115
00116 m_settingsManager.reset(
new SettingsManager(m_xml));
00117 m_contactManager.reset(
new ContactManager(m_xml));
00118
00119
00120 m_isOnline =
true;
00121
00122
00123
commit();
00124
00125
return true;
00126
00127 }
00128
00129 bool XMLManager::login(
const string & username,
const VBuffer &password)
00130 {
00131
00132
if (!
exists(username))
00133
return false;
00134
00135
if (m_isOnline)
00136
logout();
00137
00138 m_filename =
getFileName(username);
00139
00140 m_diskPass = CryptoManager::hash(password, CryptDefines::SHA_384);
00141
00142
#if 0
00143
00144 ifstream in;
00145 string tmp, inbound;
00146 in.open(
"test.xml");
00147
while (getline(in, tmp))
00148 inbound += tmp;
00149
00150 *m_config << inbound;
00151
#endif
00152
00153
try {
00154
00155 m_xml << CryptoManager::decryptFile(m_directory + m_filename, m_diskPass);
00156 }
catch(
CryptoManager::InvalidPassword &e)
00157 {
00158 LOG_THROW(e.what(),
PasswordError);
00159 }
catch(
CryptoManager::AuthFailed &e)
00160 {
00161 LOG_THROW(e.what(),
AuthError);
00162 }
catch(
CryptoManager::IOError &e)
00163 {
00164 LOG_THROW(e.what(),
DiskError);
00165 }
00166
00167 m_settingsManager.reset(
new SettingsManager(m_xml));
00168 m_contactManager.reset(
new ContactManager(m_xml));
00169
00170 m_isOnline =
true;
00171
00172
return true;
00173
00174 }
00175
00176
bool
00177 XMLManager::search(
const string& toFind,
const string& findType,
XMLNode& parentNode,
XMLNode& returnNode)
00178 {
00179
unsigned int iter;
00180
for (iter = 1; iter <= parentNode.
numChildren(findType); iter++)
00181 {
00182
if (parentNode.
child(findType, iter).
property(
"name") == toFind)
00183 {
00184 returnNode = parentNode.
child(findType, iter);
00185
return true;
00186 }
00187 }
00188
00189
00190
for (iter = 0; iter < parentNode.
children().size(); iter++)
00191 {
00192
if (
search(toFind, findType, parentNode.
children()[iter], returnNode))
00193
return true;
00194 }
00195
00196
return false;
00197 }
00198
00199
bool
00200 XMLManager::baseSearch(
const string& toFind,
const string& findType,
XMLNode& parentNode,
XMLNode& returnNode,
unsigned int& num)
00201 {
00202
00203
00204
for (
unsigned int iter2 = 1; iter2 <= parentNode.
numChildren(findType); iter2++)
00205 {
00206
if (parentNode.
child(findType, iter2).
property(
"name") == toFind)
00207 {
00208 num = iter2;
00209 returnNode = parentNode;
00210
return true;
00211 }
00212 }
00213
00214
00215
for (
unsigned int iter = 0; iter < parentNode.
children().size(); iter++)
00216 {
00217
if (
baseSearch(toFind, findType, parentNode.
children()[iter], returnNode, num))
00218
00219
return true;
00220 }
00221
00222
return false;
00223 }
00224
00225
unsigned int
00226 XMLManager::tagCount(
const string& findType,
const XMLNode& parentNode)
00227 {
00228
00229
00230
unsigned int levelCount(parentNode.
numChildren(findType));
00231
00232
00233
for (
unsigned int iter = 0; iter < parentNode.
const_children().size(); iter++)
00234 {
00235 levelCount +=
tagCount(findType, parentNode.
const_children()[iter]);
00236 }
00237
00238
return levelCount;
00239 }
00240
00241 void XMLManager::getAllTags(
const string& findType,
XMLNode& parentNode, vector<XMLNode> &result_vector)
00242 {
00243
for (
unsigned int iter2 = 1; iter2 <= parentNode.
numChildren(findType); iter2++)
00244 {
00245 result_vector.push_back(parentNode.
child(findType, iter2));
00246 }
00247
00248
00249
for (
unsigned int iter = 0; iter < parentNode.
children().size(); iter++)
00250 {
00251
getAllTags(findType, parentNode.
children()[iter], result_vector);
00252
00253 }
00254 }
00255
00256 string XMLManager::printTree(
const XMLNode& base)
00257 {
00258
return base;
00259 }
00260
00261 bool XMLManager::commit()
00262 {
00263
00264
if (!m_isOnline)
00265 {
00266 LOG_ERROR(
"Cannot Commit to file while not logged in.");
00267
return false;
00268 }
00269
00270
00271 string data(
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n");
00272
00273
00274 data += string(m_xml);
00275
00276
00277
try
00278 {
00279 CryptoManager::encryptFile(m_directory + m_filename, m_diskPass, data.c_str());
00280 }
00281
catch (
CryptoManager::IOError &e)
00282 {
00283 LOG_THROW(e.what(),
DiskError);
00284
return false;
00285 }
00286
00287
00288
00289 ofstream out;
00290 string dir = m_directory + string(
"test.xml");
00291 out.open(dir.c_str());
00292 out << data;
00293
00294
00295
return true;
00296 }
00297
00298 string XMLManager::encode(
const string & inbound)
00299 {
00300
00301 string outbound;
00302
unsigned int i(0);
00303
00304
00305
for (i = 0; i < inbound.size(); i++)
00306 {
00307
switch (inbound[i])
00308 {
00309
case(
'#'): outbound +=
"#";
break;
00310
case(
'&'): outbound +=
"&";
break;
00311
case(
';'): outbound +=
";";
break;
00312
case(
'\''): outbound +=
"'";
break;
00313
case(
'\"'): outbound +=
""";
break;
00314
default: outbound += inbound[i];
00315 }
00316 }
00317
00318
return outbound;
00319 }
00320
00321 string XMLManager::decode(
const string & inbound)
00322 {
00323
00324 string outbound;
00325 string code;
00326
00327
int STATE(0);
00328
unsigned int i(0);
00329
00330
00331
00332
00333
00334
00335
for (i = 0; i < inbound.size(); i++)
00336 {
00337
switch (inbound[i])
00338 {
00339
case(
'&'): STATE = 1; code =
'&';
break;
00340
case(
';'): STATE = 2; code +=
';';
break;
00341
default:
00342 {
00343
if ( STATE > 0 )
00344 code += inbound[i];
00345
else
00346 outbound += inbound[i];
00347 }
00348 }
00349
if (STATE == 2)
00350 {
00351 STATE = 0;
00352
if (code ==
"#")
00353 outbound +=
'#';
00354
if (code ==
"&")
00355 outbound +=
'&';
00356
if (code ==
";")
00357 outbound +=
';';
00358
if (code ==
"'")
00359 outbound +=
'\'';
00360
if (code ==
""")
00361 outbound +=
'\"';
00362 }
00363 }
00364
00365
return outbound;
00366
00367
00368 }
00369
00370
bool
00371 XMLManager::exists(
const string& username)
00372 {
00373 string toOpen;
00374 toOpen += m_directory;
00375 toOpen += CryptoManager::encode(username, CryptDefines::Base32);
00376 toOpen +=
".gm";
00377
00378
struct stat my_stat;
00379
return (stat(toOpen.c_str(), &my_stat) == 0);
00380
00381
#if 0
00382
ifstream in;
00383 in.open(toOpen.c_str());
00384
00385
if (in.fail() || in.bad())
00386 {
00387
return false;
00388 }
00389
return true;
00390
#endif
00391
}
00392
00393
00394
bool XMLManager::isDirectory(
const string& dirname)
00395 {
00396
struct stat my_stat;
00397
if (stat(dirname.c_str(), &my_stat) != 0)
00398
return false;
00399
return ((my_stat.st_mode & S_IFDIR) != 0);
00400 }
00401
00402 string XMLManager::getFileName(
const string& username)
const
00403
{
00404
return CryptoManager::encode(username, CryptDefines::Base32) + string(
".gm");
00405 }
00406
00407
bool
00408 XMLManager::setPassword(
const VBuffer& password)
00409 {
00410
00411
if (!m_isOnline)
00412
return false;
00413
00414
00415 m_diskPass = CryptoManager::hash(password, CryptDefines::SHA_384);
00416
00417
00418
commit();
00419
00420
return true;
00421
00422 }
00423
00424 string
00425 XMLManager::getLogin()
const
00426
{
00427
if (!m_isOnline)
00428
return "";
00429
00430
return m_xml.
property(
"username");
00431 }
00432
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454