xref: /freebsd/crypto/krb5/src/ccapi/common/win/OldCC/secure.cxx (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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     }