forked from lastpass/lastpass-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxml.c
More file actions
129 lines (116 loc) · 3.46 KB
/
xml.c
File metadata and controls
129 lines (116 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* Copyright (c) 2014 LastPass. All Rights Reserved.
*
*
*/
#include "xml.h"
#include "util.h"
#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
struct session *xml_ok_session(const char *buf, unsigned const char key[KDF_HASH_LEN])
{
struct session *session = NULL;
xmlDoc *doc = NULL;
xmlNode *root;
doc = xmlParseMemory(buf, strlen(buf));
if (!doc)
goto out;
root = xmlDocGetRootElement(doc);
if (root && !xmlStrcmp(root->name, BAD_CAST "response")) {
for (root = root->children; root; root = root->next) {
if (!xmlStrcmp(root->name, BAD_CAST "ok"))
break;
}
}
if (root && !xmlStrcmp(root->name, BAD_CAST "ok")) {
session = session_new();
for (xmlAttrPtr attr = root->properties; attr; attr = attr->next) {
if (!xmlStrcmp(attr->name, BAD_CAST "uid"))
session->uid = (char *)xmlNodeListGetString(doc, attr->children, 1);
if (!xmlStrcmp(attr->name, BAD_CAST "sessionid"))
session->sessionid = (char *)xmlNodeListGetString(doc, attr->children, 1);
if (!xmlStrcmp(attr->name, BAD_CAST "token"))
session->token = (char *)xmlNodeListGetString(doc, attr->children, 1);
if (!xmlStrcmp(attr->name, BAD_CAST "privatekeyenc")) {
_cleanup_free_ char *private_key = (char *)xmlNodeListGetString(doc, attr->children, 1);
session_set_private_key(session, key, private_key);
}
}
}
out:
if (doc)
xmlFreeDoc(doc);
if (!session_is_valid(session)) {
session_free(session);
return NULL;
}
return session;
}
unsigned long long xml_login_check(const char *buf, struct session *session)
{
_cleanup_free_ char *versionstr = NULL;
unsigned long long version = 0;
xmlDoc *doc = NULL;
xmlNode *root, *child = NULL;
doc = xmlParseMemory(buf, strlen(buf));
if (!doc)
goto out;
root = xmlDocGetRootElement(doc);
if (root && !xmlStrcmp(root->name, BAD_CAST "response")) {
for (child = root->children; child; child = child->next) {
if (!xmlStrcmp(child->name, BAD_CAST "ok"))
break;
}
}
if (child) {
for (xmlAttrPtr attr = child->properties; attr; attr = attr->next) {
if (!xmlStrcmp(attr->name, BAD_CAST "uid")) {
free(session->uid);
session->uid = (char *)xmlNodeListGetString(doc, attr->children, 1);
} else if (!xmlStrcmp(attr->name, BAD_CAST "sessionid")) {
free(session->sessionid);
session->sessionid = (char *)xmlNodeListGetString(doc, attr->children, 1);
} else if (!xmlStrcmp(attr->name, BAD_CAST "token")) {
free(session->token);
session->token = (char *)xmlNodeListGetString(doc, attr->children, 1);
} else if (!xmlStrcmp(attr->name, BAD_CAST "accts_version")) {
versionstr = (char *)xmlNodeListGetString(doc, attr->children, 1);
version = strtoull(versionstr, NULL, 10);
}
}
}
out:
if (doc)
xmlFreeDoc(doc);
return version;
}
char *xml_error_cause(const char *buf, const char *what)
{
char *result = NULL;
xmlDoc *doc = NULL;
xmlNode *root;
doc = xmlParseMemory(buf, strlen(buf));
if (!doc)
goto out;
root = xmlDocGetRootElement(doc);
if (root && !xmlStrcmp(root->name, BAD_CAST "response")) {
for (xmlNode *child = root->children; child; child = child->next) {
if (!xmlStrcmp(child->name, BAD_CAST "error")) {
for (xmlAttrPtr attr = child->properties; attr; attr = attr->next) {
if (!xmlStrcmp(attr->name, BAD_CAST what)) {
result = (char *)xmlNodeListGetString(doc, attr->children, 1);
goto out;
}
}
break;
}
}
}
out:
if (doc)
xmlFreeDoc(doc);
if (!result)
result = xstrdup("unknown");
return result;
}