-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathevernote_new.go
123 lines (90 loc) · 2.84 KB
/
evernote_new.go
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
package main
import (
"database/sql"
"encoding/base64"
"encoding/json"
"io/ioutil"
"path/filepath"
"strings"
"github.com/kirsle/configdir"
"golang.org/x/text/encoding/charmap"
_ "modernc.org/sqlite"
)
func newGetUsers() (users []User) {
confDir := configdir.LocalConfig("Evernote")
for _, user := range newListUsers() {
storagePath := filepath.Join(confDir, "secure-storage", "authtoken_user_"+user.ID)
encData, iv := newGetSecureStorageData(storagePath)
key := newGetSecureStorageKey(user.ID)
decryptedData := aesDecrypt(encData, key, iv)
token := newGetToken(decryptedData)
users = append(users, User{
path: storagePath,
id: user.ID,
username: user.Username,
email: user.Email,
token: token,
})
}
return
}
func newListUsers() (users []UserData) {
confDir := configdir.LocalConfig("Evernote")
dbFile := filepath.Join(confDir, "conduit-storage", "https%3A%2F%2Fwww.evernote.com", "_ConduitMultiUserDB.sql")
db, err := sql.Open("sqlite", dbFile)
panicFail(err)
rows, err := db.Query("SELECT Tkey, TValue FROM MultiUsers")
panicFail(err)
defer func(rows *sql.Rows) {
err := rows.Close()
panicFail(err)
}(rows)
for rows.Next() {
var userID string
var userInfoS string
err = rows.Scan(&userID, &userInfoS)
panicFail(err)
var userInfo map[string]interface{}
err = json.Unmarshal([]byte(userInfoS), &userInfo)
panicFail(err)
users = append(users, UserData{
ID: strings.Split(userID, ":")[1],
Username: userInfo["username"].(string),
Email: userInfo["email"].(string),
})
}
return users
}
func newGetSecureStorageData(storagePath string) ([]byte, []byte) {
dat, err := ioutil.ReadFile(storagePath)
panicFail(err)
var storageData map[string]interface{}
err = json.Unmarshal(dat, &storageData)
panicFail(err)
// authtoken_user encrypted data saved as js "binary string" by Evernote
// without properly encoding it to base64
// emulating this behaviour by encoding string with ISO8859_1
encryptedData, err := charmap.ISO8859_1.NewEncoder().String(storageData["encrypted"].(string))
panicFail(err)
iv, err := base64.StdEncoding.DecodeString(storageData["iv"].(string))
panicFail(err)
return []byte(encryptedData), iv
}
func newGetSecureStorageKey(userId string) []byte {
var keyData string
const keyPrefix = "enote-encr-key"
service := "Evernote"
accountID := "AuthToken:User:" + userId
keyData = string(getSecureStorageData(service, accountID))
key, err := base64.StdEncoding.DecodeString(strings.Replace(keyData, keyPrefix, "", 1))
panicFail(err)
return key
}
func newGetToken(storagedataBytes []byte) string {
storagedataRaw, err := base64.StdEncoding.DecodeString(string(storagedataBytes))
panicFail(err)
var storageData map[string]interface{}
err = json.Unmarshal(storagedataRaw, &storageData)
panicFail(err)
return storageData["t"].(string)
}