-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathHorizonDlg.h
318 lines (227 loc) · 9.24 KB
/
HorizonDlg.h
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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
// HorizonDlg.h : header file
//
#pragma once
#include <netlink/socket.h>
#include <netlink/socket_group.h>
#include <Psapi.h>
#include <vector>
#include "..\\CommonData.h"
#define inherits_nl_sockets public NL::SocketGroupCmd
#define inherits_instantiate_class public InstantiateBaseClass
// HorizonDlg dialog
class HorizonDlg : public CDialogEx {
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_HORIZONSECUREFOLDER_DIALOG };
#endif
protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg void OnOK();
afx_msg void OnCancel();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
// Stable formatted local logger.
void DbgPrint(PTCHAR lpOutputString, ...);
// Setup server socket
NL::Socket *socketServer = nullptr;
// Create socket container
NL::SocketGroup *group = nullptr;
// Setup a thread - alive flag.
static BOOL KzThreadFlag;
// Obtain a resource handle for the thread.
HANDLE KzThreadHandle = nullptr;
// Create specific thread argument type.
struct KzLocalNewtworkThreadArg {
// Dlg context
HorizonDlg* mCtx;
// Setup server socket
NL::Socket* sSrv;
// Create socket container
NL::SocketGroup* sGrp;
};
// Declare a thread argument
KzLocalNewtworkThreadArg kzArg;
HANDLE MtxMutexGroupOfSockets = nullptr;
HANDLE MtxMutexPathList = nullptr;
HANDLE MtxMutexSecurityGroupPolicy = nullptr;
HANDLE MtxMutexKzThreadFlag = nullptr;
enum MpSharedMemAction {
full_update = 0x00000000U,
insert_element = 0x00000001U, /* TODO : in future releases */
remove_element = 0x00000002U /* TODO : in future releases */
/* This data can be saved on one byte
* Therefore, in case of DWORD conversion
* There are 3 bytes left intact which aproximate
* in unsigned context abt. 0 - 2^24 - 1
*/
};
HANDLE mHandleMapFile;
LPTSTR mViewPtr;
/* The following class specializez in holding details about processes
* which have been granted access to hidden data on the filesystem.
* The data is not temporary. Each time this interface is closed, the
* data is backed up in a local, hidden config file.s
*/
class SecurityGroupPolicy {
private: std::vector < CString > mProcFullPathList;
public:
void insert(CString mProcPath) {
if (!exists(mProcPath)) mProcFullPathList.push_back(mProcPath);
}
std::vector < CString>::iterator find(CString mProcPath) {
return std::find(mProcFullPathList.begin(), mProcFullPathList.end(), mProcPath);
}
void remove(CString mProcPath) {
std::vector < CString>::iterator mFoundIt = find(mProcPath);
if (find(mProcPath) != mProcFullPathList.end()) mProcFullPathList.erase(mFoundIt);
}
bool exists(CString mProcPath) {
if (find(mProcPath) != mProcFullPathList.end()) return true;
return false;
}
} ;
// Create an instance of the security class.
SecurityGroupPolicy mSecurityGroupPolicy;
// Socket callback declarations
class InstantiateBaseClass {
protected: HorizonDlg* mContext = nullptr;
public: InstantiateBaseClass(HorizonDlg* mContext) {
this->mContext = mContext;
}
};
class OnAccept : inherits_nl_sockets , inherits_instantiate_class {
public: void exec(NL::Socket* socket, NL::SocketGroup* group, void* reference) {
// Create instance for the new connection
NL::Socket* newConnection = socket->accept();
// Add the instance to the collection
ENTER_MUTEX_SCOPE(mContext->MtxMutexGroupOfSockets);
group->add(newConnection);
EXIT_MUTEX_SCOPE(mContext->MtxMutexGroupOfSockets);
// Show debug message
mContext->DbgPrint(_T("OnAccept: Accepted new client!\n"));
}
OnAccept(HorizonDlg* mContext) : InstantiateBaseClass(mContext) {}
};
class OnRead : inherits_nl_sockets, inherits_instantiate_class {
public: void exec(NL::Socket* socket, NL::SocketGroup* group, void* reference) {
DWORD mRecvCommand;
DWORD mData;
// Read and parse receved data.
ENTER_MUTEX_SCOPE(mContext->MtxMutexGroupOfSockets);
socket->readCommand(mRecvCommand, mData);
switch (mRecvCommand) {
case mCommand_pid: {
// This array holds the full path of a process.
TCHAR mFullProcessPath[MAX_PATH];
// Save the PID and asociate it with this socket.
socket->setPid(mData);
// Write some safe data in the array.
wcscpy_s(mFullProcessPath, _T("EMPTY"));
// Transform the PID into a valid process image name.
HANDLE mProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, mData);
if (mProcHandle) {
// Get the full process path and write it into the buffer.
::GetModuleFileNameEx(mProcHandle, 0, mFullProcessPath, MAX_PATH);
// Make sure there is no chance of overwritting the \0
mFullProcessPath[MAX_PATH - 1] = 0;
// Release the handle.
CloseHandle(mProcHandle);
}
// Copy the full process path into the client asociated to this socket.
wcscpy_s(socket->getPathPtr(), MAX_PATH, mFullProcessPath);
// Show debug message
mContext->DbgPrint(_T("OnRead: Received PID %u from process %s!\n"), mData, mFullProcessPath);
// Is this process in the security group?
ENTER_MUTEX_SCOPE(mContext->MtxMutexSecurityGroupPolicy);
BOOL mSecurityStatus = mContext->mSecurityGroupPolicy.exists(mFullProcessPath);
EXIT_MUTEX_SCOPE(mContext->MtxMutexSecurityGroupPolicy);
// Create a new entry in the list for the new pocess.
mContext->LbCreateProcessEntry(mFullProcessPath, mSecurityStatus, mData);
// If it is in the security group then notify the process.
if (mSecurityStatus) {
mContext->DbgPrint(_T("OnRead: The process '%s' is in the security policy group! Sending client the new security status!\n"), mFullProcessPath);
socket->sendCommand(mCommand_security_status, 1);
}
break;
}
case mCommand_security_status: {
// Receive security status. This is a confirmation of aproval
// after having received the command from the server.
INT nItem = mContext->LbFindProcessItemByPid(socket->getPid());
// Check existance of a row containing the process pid.
if (nItem == -1) break;
// Update the process status in the UI.
mContext->mProcessList.SetItemText(nItem, 1, mData == 1 ? _T("true") : _T("false"));
// Show debug message
mContext->DbgPrint(_T("OnRead: Updated UI after security status changed to %s!\n"), mData == 1 ? _T("true") : _T("false"));
break;
}
}
EXIT_MUTEX_SCOPE(mContext->MtxMutexGroupOfSockets);
}
OnRead(HorizonDlg* mContext) : InstantiateBaseClass(mContext) {}
};
class OnDisconnect : inherits_nl_sockets, inherits_instantiate_class {
public: void exec(NL::Socket* socket, NL::SocketGroup* group, void* reference) {
ENTER_MUTEX_SCOPE(mContext->MtxMutexGroupOfSockets);
// Show debug message
mContext->DbgPrint(_T("OnDisconnect: Process %s disconnected!\n"), socket->getPathPtr());
// Remove socket from group container
group->remove(socket);
// Remove entry from process lsit
mContext->LbRemoveProcessItemByPid(socket->getPid());
// Delete socket instance
delete socket;
EXIT_MUTEX_SCOPE(mContext->MtxMutexGroupOfSockets);
}
OnDisconnect(HorizonDlg* mContext) : InstantiateBaseClass(mContext) {}
};
// Instantiate socket handlers
OnDisconnect onDisconnect;
OnAccept onAccept;
OnRead onRead;
// Socket communication thread.
static DWORD WINAPI KzLocalNetworkTransactionThread(LPVOID lpParam) {
KzLocalNewtworkThreadArg* kzArg = (KzLocalNewtworkThreadArg*)lpParam;
// Show debug message
kzArg->mCtx->DbgPrint(_T("KzLocalNetworkTransactionThread: Entered Thread!\n"));
// Show debug message
kzArg->mCtx->DbgPrint(_T("KzLocalNetworkTransactionThread: Starting listening session!\n"));
while (true) {
ENTER_MUTEX_SCOPE(kzArg->mCtx->MtxMutexKzThreadFlag);
if (!kzArg->mCtx->KzThreadFlag) break;
kzArg->sGrp->listen(1000);
EXIT_MUTEX_SCOPE(kzArg->mCtx->MtxMutexKzThreadFlag);
}
// Show debug message
kzArg->mCtx->DbgPrint(_T("KzLocalNetworkTransactionThread: Service thread received kill signal!\n"));
return 0;
}
public:
HorizonDlg(CWnd* pParent = nullptr); // standard constructor
public:
// Creates new entry in the process list.
VOID LbCreateProcessEntry(PTCHAR FULL_PATH, BOOL SECURITY, DWORD PID);
INT LbFindProcessItemByPid(DWORD PID);
VOID LbRemoveProcessItemByPid(DWORD PID);
BOOL MpInitializeSharedMemoryMap();
VOID MpNotifyClientsOnSharedMemUpdate(MpSharedMemAction mAction);
template < typename LambdaFunctor >
VOID MtIterateThroughClients( LambdaFunctor );
// Holds the list of process along with details
CListCtrl mProcessList;
CButton cbxSetClearSecurityToken;
CListBox mPathList;
CEdit mLogCtrl;
afx_msg void OnBnClickedButtonSigKill();
afx_msg void OnNMClickListProcessList(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnBnClickedCheckcbxsetclearsecuritytoken();
afx_msg void OnBnClickBrowseFolder();
afx_msg void OnBnClickedRemoveFolder();
};