1*7f2fe78bSCy Schubert /*
2*7f2fe78bSCy Schubert * $Header$
3*7f2fe78bSCy Schubert *
4*7f2fe78bSCy Schubert * Copyright 2008 Massachusetts Institute of Technology.
5*7f2fe78bSCy Schubert * All Rights Reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Export of this software from the United States of America may
8*7f2fe78bSCy Schubert * require a specific license from the United States Government.
9*7f2fe78bSCy Schubert * It is the responsibility of any person or organization contemplating
10*7f2fe78bSCy Schubert * export to obtain such a license before exporting.
11*7f2fe78bSCy Schubert *
12*7f2fe78bSCy Schubert * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13*7f2fe78bSCy Schubert * distribute this software and its documentation for any purpose and
14*7f2fe78bSCy Schubert * without fee is hereby granted, provided that the above copyright
15*7f2fe78bSCy Schubert * notice appear in all copies and that both that copyright notice and
16*7f2fe78bSCy Schubert * this permission notice appear in supporting documentation, and that
17*7f2fe78bSCy Schubert * the name of M.I.T. not be used in advertising or publicity pertaining
18*7f2fe78bSCy Schubert * to distribution of the software without specific, written prior
19*7f2fe78bSCy Schubert * permission. Furthermore if you modify this software you must label
20*7f2fe78bSCy Schubert * your software as modified software and not distribute it in such a
21*7f2fe78bSCy Schubert * fashion that it might be confused with the original M.I.T. software.
22*7f2fe78bSCy Schubert * M.I.T. makes no representations about the suitability of
23*7f2fe78bSCy Schubert * this software for any purpose. It is provided "as is" without express
24*7f2fe78bSCy Schubert * or implied warranty.
25*7f2fe78bSCy Schubert */
26*7f2fe78bSCy Schubert
27*7f2fe78bSCy Schubert #include <windows.h>
28*7f2fe78bSCy Schubert #include "secure.hxx"
29*7f2fe78bSCy Schubert
30*7f2fe78bSCy Schubert extern "C" {
31*7f2fe78bSCy Schubert #include "cci_debugging.h"
32*7f2fe78bSCy Schubert }
33*7f2fe78bSCy Schubert
34*7f2fe78bSCy Schubert CcOsLock SecureClient::s_lock;
35*7f2fe78bSCy Schubert DWORD SecureClient::s_refcount = 0;
36*7f2fe78bSCy Schubert DWORD SecureClient::s_error = 0;
37*7f2fe78bSCy Schubert HANDLE SecureClient::s_hToken = 0;
38*7f2fe78bSCy Schubert
39*7f2fe78bSCy Schubert #include "util.h"
40*7f2fe78bSCy Schubert
41*7f2fe78bSCy Schubert #define SC "SecureClient::"
42*7f2fe78bSCy Schubert
43*7f2fe78bSCy Schubert DWORD
Attach()44*7f2fe78bSCy Schubert SecureClient::Attach(
45*7f2fe78bSCy Schubert )
46*7f2fe78bSCy Schubert {
47*7f2fe78bSCy Schubert CcAutoLock AL(s_lock);
48*7f2fe78bSCy Schubert if (s_hToken) {
49*7f2fe78bSCy Schubert s_refcount++;
50*7f2fe78bSCy Schubert return 0;
51*7f2fe78bSCy Schubert }
52*7f2fe78bSCy Schubert if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
53*7f2fe78bSCy Schubert &s_hToken)) {
54*7f2fe78bSCy Schubert s_refcount++;
55*7f2fe78bSCy Schubert s_error = 0;
56*7f2fe78bSCy Schubert } else {
57*7f2fe78bSCy Schubert s_hToken = 0;
58*7f2fe78bSCy Schubert s_error = GetLastError();
59*7f2fe78bSCy Schubert }
60*7f2fe78bSCy Schubert return s_error;
61*7f2fe78bSCy Schubert }
62*7f2fe78bSCy Schubert
63*7f2fe78bSCy Schubert DWORD
Detach()64*7f2fe78bSCy Schubert SecureClient::Detach(
65*7f2fe78bSCy Schubert )
66*7f2fe78bSCy Schubert {
67*7f2fe78bSCy Schubert CcAutoLock AL(s_lock);
68*7f2fe78bSCy Schubert s_refcount--;
69*7f2fe78bSCy Schubert if (s_refcount) return 0;
70*7f2fe78bSCy Schubert if (!s_hToken) return 0;
71*7f2fe78bSCy Schubert DWORD error = 0;
72*7f2fe78bSCy Schubert if (!CloseHandle(s_hToken))
73*7f2fe78bSCy Schubert error = GetLastError();
74*7f2fe78bSCy Schubert s_hToken = 0;
75*7f2fe78bSCy Schubert s_error = 0;
76*7f2fe78bSCy Schubert return error;
77*7f2fe78bSCy Schubert }
78*7f2fe78bSCy Schubert
Token(HANDLE & hToken)79*7f2fe78bSCy Schubert DWORD SecureClient::Token(HANDLE& hToken) {
80*7f2fe78bSCy Schubert // This function will not do automatic initialization.
81*7f2fe78bSCy Schubert CcAutoLock AL(s_lock);
82*7f2fe78bSCy Schubert hToken = 0;
83*7f2fe78bSCy Schubert if (!s_hToken) {
84*7f2fe78bSCy Schubert cci_debug_printf("%s no process token initialized (%u)", __FUNCTION__, s_error);
85*7f2fe78bSCy Schubert return s_error ? s_error : ERROR_INVALID_HANDLE;
86*7f2fe78bSCy Schubert }
87*7f2fe78bSCy Schubert else {
88*7f2fe78bSCy Schubert DWORD status = 0;
89*7f2fe78bSCy Schubert if (!DuplicateHandle(GetCurrentProcess(), s_hToken,
90*7f2fe78bSCy Schubert GetCurrentProcess(), &hToken, 0, FALSE,
91*7f2fe78bSCy Schubert DUPLICATE_SAME_ACCESS)) {
92*7f2fe78bSCy Schubert status = GetLastError();
93*7f2fe78bSCy Schubert cci_debug_printf(" Could not duplicate handle (%u)", status);
94*7f2fe78bSCy Schubert }
95*7f2fe78bSCy Schubert return status;
96*7f2fe78bSCy Schubert }
97*7f2fe78bSCy Schubert }
98*7f2fe78bSCy Schubert
99*7f2fe78bSCy Schubert void
Start(SecureClient * & s)100*7f2fe78bSCy Schubert SecureClient::Start(SecureClient*& s) {
101*7f2fe78bSCy Schubert s = new SecureClient;
102*7f2fe78bSCy Schubert }
103*7f2fe78bSCy Schubert
104*7f2fe78bSCy Schubert void
Stop(SecureClient * & s)105*7f2fe78bSCy Schubert SecureClient::Stop(SecureClient*& s) {
106*7f2fe78bSCy Schubert delete s;
107*7f2fe78bSCy Schubert s = 0;
108*7f2fe78bSCy Schubert }
109*7f2fe78bSCy Schubert
110*7f2fe78bSCy Schubert ///////////////////////////////////////////////////////////////////////////////
111*7f2fe78bSCy Schubert
112*7f2fe78bSCy Schubert /* This constructor turns off impersonation.
113*7f2fe78bSCy Schubert * It is OK for OpenThreadToken to return an error -- that just means impersonation
114*7f2fe78bSCy Schubert * is off.
115*7f2fe78bSCy Schubert */
SecureClient()116*7f2fe78bSCy Schubert SecureClient::SecureClient():
117*7f2fe78bSCy Schubert m_Error(0),
118*7f2fe78bSCy Schubert m_hToken(0),
119*7f2fe78bSCy Schubert m_NeedRestore(false) {
120*7f2fe78bSCy Schubert
121*7f2fe78bSCy Schubert HANDLE hThread = GetCurrentThread();
122*7f2fe78bSCy Schubert HANDLE hThDuplicate;
123*7f2fe78bSCy Schubert
124*7f2fe78bSCy Schubert int status = DuplicateHandle( GetCurrentProcess(),
125*7f2fe78bSCy Schubert hThread,
126*7f2fe78bSCy Schubert GetCurrentProcess(),
127*7f2fe78bSCy Schubert &hThDuplicate,
128*7f2fe78bSCy Schubert TOKEN_ALL_ACCESS,
129*7f2fe78bSCy Schubert FALSE,
130*7f2fe78bSCy Schubert 0);
131*7f2fe78bSCy Schubert if (!status) return;
132*7f2fe78bSCy Schubert
133*7f2fe78bSCy Schubert if (!OpenThreadToken(hThDuplicate, TOKEN_ALL_ACCESS, FALSE, &m_hToken)) {
134*7f2fe78bSCy Schubert m_Error = GetLastError();
135*7f2fe78bSCy Schubert return;
136*7f2fe78bSCy Schubert }
137*7f2fe78bSCy Schubert if (SetThreadToken(&hThDuplicate, NULL)) {
138*7f2fe78bSCy Schubert m_NeedRestore = true;
139*7f2fe78bSCy Schubert } else {
140*7f2fe78bSCy Schubert m_Error = GetLastError();
141*7f2fe78bSCy Schubert }
142*7f2fe78bSCy Schubert CloseHandle(hThDuplicate);
143*7f2fe78bSCy Schubert }
144*7f2fe78bSCy Schubert
~SecureClient()145*7f2fe78bSCy Schubert SecureClient::~SecureClient() {
146*7f2fe78bSCy Schubert if (m_NeedRestore) {
147*7f2fe78bSCy Schubert HANDLE hThread = GetCurrentThread();
148*7f2fe78bSCy Schubert if (!SetThreadToken(&hThread, m_hToken)) {
149*7f2fe78bSCy Schubert m_Error = cci_check_error(GetLastError());
150*7f2fe78bSCy Schubert }
151*7f2fe78bSCy Schubert }
152*7f2fe78bSCy Schubert if (m_hToken) {
153*7f2fe78bSCy Schubert if (!CloseHandle(m_hToken)) {
154*7f2fe78bSCy Schubert m_Error = cci_check_error(GetLastError());
155*7f2fe78bSCy Schubert }
156*7f2fe78bSCy Schubert }
157*7f2fe78bSCy Schubert }
158*7f2fe78bSCy Schubert
Error()159*7f2fe78bSCy Schubert DWORD SecureClient::Error() {
160*7f2fe78bSCy Schubert return m_Error;
161*7f2fe78bSCy Schubert }