-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtemplate.cs
172 lines (148 loc) · 4.96 KB
/
template.cs
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
using System;
using System.IO;
using System.Text;
using System.Security;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Security.Principal;
public class Module_template
{
public const string SUCC_CODE = "0";
public const string ERR_CODE = "1";
public const string NON_TOKEN_VALUE = "0";
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool RevertToSelf();
private void ImpersonateWithToken(string token)
{
int token_int = Int32.Parse(token);
IntPtr targetToken = new IntPtr(token_int);
string current_username = "";
using (WindowsIdentity wid = WindowsIdentity.GetCurrent())
{
current_username = wid.Name;
}
if (!ImpersonateLoggedOnUser(targetToken))
{
int errorCode = Marshal.GetLastWin32Error();
throw new Exception("ImpersonateLoggedOnUser failed with the following error: " + errorCode);
}
string impersonate_username = "";
using (WindowsIdentity wid = WindowsIdentity.GetCurrent())
{
impersonate_username = wid.Name;
}
if (current_username == impersonate_username)
throw new Exception("ImpersonateLoggedOnUser worked, but thread running as user " + current_username);
}
private string hex2Str(string hex)
{
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return Encoding.ASCII.GetString(raw);
}
private string normalizePath(string currPath)
{
currPath = currPath.Replace("\"", "");
currPath = currPath.Replace("'", "");
currPath = currPath.Replace(@"\", "/");
return currPath;
}
private string changeCWD(string cwd)
{
try
{
Directory.SetCurrentDirectory(cwd);
return normalizePath(Directory.GetCurrentDirectory());
}
catch (Exception ex)
{
if (ex is IOException)
throw new Exception("Path '" + cwd + "' is not a directory");
else if (ex is DirectoryNotFoundException)
throw new Exception("Directory '" + cwd + "' does not exist");
else if (ex is SecurityException)
throw new Exception("Directory '" + cwd + "' permission denied");
else if (ex is PathTooLongException)
throw new Exception("Path '" + cwd + "' exceed the maximum length defined by the system");
else
throw new Exception("Move to path '" + cwd + "' failed");
}
}
private string[] parseArguments(string args)
{
List<string> arguments_parsed = new List<string>();
string pattern = @"""[^""]+""|'[^']+'|\S+";
foreach (Match m in Regex.Matches(args, pattern))
{
arguments_parsed.Add(m.Value);
}
return arguments_parsed.ToArray();
}
private string[] doEcho(string[] str_params)
{
string result = "";
try
{
foreach (string p in str_params)
{
result += p + Environment.NewLine;
}
}
catch(Exception ex)
{
result += ex.ToString() + Environment.NewLine;
return new string[]{ERR_CODE, result};
}
return new string[]{SUCC_CODE, result};
}
public string[] execute(string[] args)
{
string result = "";
List<string> nargs = new List<string>(args);
if (nargs.Count == 0)
{
result = "Invalid arguments provided. Specify one or multiple strings to echo.";
return new string[]{ERR_CODE, result};
}
return doEcho(nargs.ToArray());
}
public string[] go(string cwd, string args, string token)
{
string[] results = new string[]{SUCC_CODE, ""};
string pwd = Directory.GetCurrentDirectory();
try
{
if (token != NON_TOKEN_VALUE)
ImpersonateWithToken(token);
string new_cwd = changeCWD(cwd);
string[] arguments_parsed = parseArguments(hex2Str(args));
results = execute(arguments_parsed);
}
catch (Exception ex)
{
results[0] = ERR_CODE;
results[1] = ex.ToString();
}
finally
{
changeCWD(pwd);
if (token != NON_TOKEN_VALUE)
RevertToSelf();
}
return results;
}
public static void Main(string[] args)
{
Module_template m = new Module_template();
String[] results = m.execute(args);
Console.WriteLine(results[0]);
Console.WriteLine(results[1]);
return;
}
}