-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsetLabelsAndKeychains.swift
More file actions
executable file
·177 lines (157 loc) · 5.57 KB
/
Copy pathsetLabelsAndKeychains.swift
File metadata and controls
executable file
·177 lines (157 loc) · 5.57 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#!/usr/bin/env swift
// Set human-readable labels, keychains for remote desktop
// Usage: ./setRemoteDesktopsName.swift
// http://apple.stackexchange.com/questions/182209/where-does-microsoft-rdp-8-for-mac-store-its-configuration
// /Users/${USER}/Library/Containers/com.microsoft.rdc.mac/Data/Library/Preferences/com.microsoft.rdc.mac.plist
import Foundation
extension String {
func appendPath(path: String) -> String {
let nsString = self as NSString
return nsString.stringByAppendingPathComponent(path)
}
}
// execute shell
func shell(cmd: String, args: [String]) -> String {
let task = NSTask()
task.launchPath = cmd
let pipe = NSPipe()
task.arguments = args
task.standardOutput = pipe
task.launch()
task.waitUntilExit()
guard task.terminationStatus == 0 else {
print("ERROR: shell terminationStatus: \(task.terminationStatus)")
exit(1)
}
let output = pipe.fileHandleForReading.readDataToEndOfFile()
guard let result = String(data: output, encoding: NSUTF8StringEncoding) else {
print("ERROR: encoding data")
exit(1)
}
return result
}
let fileManager = NSFileManager.defaultManager()
let currentDirectoryPath = fileManager.currentDirectoryPath
let osUserName = NSUserName()
let fileName = "com.microsoft.rdc.mac.plist"
let directoryPath = "/Users/\(osUserName)/Library/Containers/com.microsoft.rdc.mac/Data/Library/Preferences/"
let preferenceFilePath = directoryPath.appendPath(fileName)
let datasourcePath: String = {
return currentDirectoryPath.appendPath("datasource.csv")
}()
func read(path filePath: String) -> String {
return try! String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding)
}
guard var preferences = NSMutableDictionary(contentsOfFile: preferenceFilePath) else {
print("ERROR: not found file")
exit(1)
}
guard let bookmarkOrderIds = preferences["bookmarkorder.ids"] as? [String] else {
print("ERROR: downcasting bookmarkorder.ids")
exit(1)
}
struct Content {
var name: String?
var ipAddress: String?
var userName: String?
var password: String?
var redirectionPath: String?
}
func getContents() -> [Content] {
let data = read(path: datasourcePath)
var contents = [Content]()
data.enumerateLines { (line, stop) -> () in
let components = line.componentsSeparatedByString(",")
var content = Content()
content.name = components[0]
content.ipAddress = components[1]
content.userName = components[2]
content.password = components[3]
// content.redirectionPath = components[4]
contents.append(content)
}
return contents
}
let contents = getContents()
// set keychains
let setKeychain = { (bookmarkOrderId: String, content: Content) in
let prefixId = "bookmarks.bookmark.\(bookmarkOrderId)"
let label = content.name!
let userName = content.userName!
let hostName = content.ipAddress!
let password = content.password!
print("Deleting internet keychain. \(bookmarkOrderId)")
_ = {
let args = [
userName,
bookmarkOrderId
]
let executeFile = "deleteKeychain"
shell(executeFile, args: args)
}()
print("Adding keychain. \(bookmarkOrderId):\(label)")
_ = {
let args = [
userName,
label,
hostName,
bookmarkOrderId,
password
]
let executeFile = "addKeychain"
shell(executeFile, args: args)
}()
}
// set label, password, redirection file path
for bookmarkOrderId in bookmarkOrderIds {
let prefixId = "bookmarks.bookmark.\(bookmarkOrderId)"
// get ipAddress
guard let hostName = preferences["\(prefixId).hostname"] as? String else {
print("ERROR: failed get hostName")
continue
}
guard let content = contents.filter({$0.ipAddress == hostName}).first else {
continue
}
if hostName == content.ipAddress {
preferences.setObject(content.name!, forKey: "\(prefixId).label")
setKeychain(bookmarkOrderId, content)
} else {
print("WARNING: invalid same hostName: \(hostName)")
}
// set redirection file path
guard let redirectionPath = content.redirectionPath else {
continue
}
let redirectionName = redirectionPath.componentsSeparatedByString("/").last!
print(redirectionPath)
print(redirectionName)
let folderForwards: [String] = [
"@Variant(\0\0\0\u{7F}\0\0\0\u{0E}FolderForward\0\0\0\0\u{04}\(redirectionName)\0\0\0\0\u{1B}\(redirectionPath)\0\0)"
]
// NOTE: Crash RDP.app If you specify redirection file path.
// ascii code is changed by the path.
// How to use? It is necessary to specify the ascii code that matches the path.
//
// key: secureFilePaths.{directory.redirection.file.path}
// I cann't understand this data format.
preferences.setObject(folderForwards, forKey: "\(prefixId).folderForwards")
}
print("Set human-readable labels, keychains for password.")
// sort by label
let sortedBookmarkOrderIds = bookmarkOrderIds.sort { (lhs, rhs) in
let labelClosure = { (id: String) -> String in
guard let label = preferences["bookmarks.bookmark.\(id).label"] as? String else {
return ""
}
return label
}
let lhsLabel = labelClosure(lhs)
let rhsLabel = labelClosure(rhs)
return lhsLabel < rhsLabel
}
print("sorted by label.")
preferences.setObject(sortedBookmarkOrderIds, forKey: "bookmarkorder.ids")
// save
preferences.writeToFile(preferenceFilePath, atomically: true)
print("Please restart Mircrosoft Remtoe Desktop.app.")