29
29
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
*/
31
31
32
+ #define WIN32_NO_STATUS
32
33
#include <Windows.h>
34
+ #undef WIN32_NO_STATUS
33
35
#include <Ntsecapi.h>
34
- // #include <ntstatus.h>
36
+ #include <ntstatus.h>
35
37
#include "agent.h"
36
38
#include "agent-request.h"
37
39
40
+ static void
41
+ InitLsaString (LSA_STRING * lsa_string , const char * str )
42
+ {
43
+ if (str == NULL )
44
+ memset (lsa_string , 0 , sizeof (LSA_STRING ));
45
+ else {
46
+ lsa_string -> Buffer = str ;
47
+ lsa_string -> Length = strlen (str );
48
+ lsa_string -> MaximumLength = lsa_string -> Length + 1 ;
49
+ }
50
+ }
38
51
39
- int process_authagent_request (struct sshbuf * request , struct sshbuf * response , struct agent_connection * con ) {
40
- while (1 )
41
- {
42
- HANDLE lsa_handle ;
43
- PLSA_OPERATIONAL_MODE mode ;
44
- ULONG auth_package_id ;
45
- NTSTATUS ret ;
46
- KERB_S4U_LOGON * s4u_logon ;
47
- size_t logon_info_size ;
48
- LSA_STRING logon_process_name , auth_package_name , originName ;
49
- InitLsaString (& logon_process_name , "ssh-agent" );
50
- //InitLsaString(&auth_package_name, MICROSOFT_KERBEROS_NAME_A);
51
- InitLsaString (& auth_package_name , "Negotiate" );
52
- InitLsaString (& originName , "sshd" );
53
- if (ret = LsaRegisterLogonProcess (& logon_process_name , & lsa_handle , & mode ) != STATUS_SUCCESS )
54
- break ;
55
-
56
- if (ret = LsaLookupAuthenticationPackage (lsa_handle , & auth_package_name , & auth_package_id ) != STATUS_SUCCESS )
57
- break ;
58
- #define USER_NAME L"user@domain"
59
- logon_info_size = sizeof (KERB_S4U_LOGON );
60
- logon_info_size += (wcslen (USER_NAME ) * 2 + 2 );
61
- s4u_logon = malloc (logon_info_size );
62
- s4u_logon -> MessageType = KerbS4ULogon ;
63
- s4u_logon -> Flags = 0 ;
64
- s4u_logon -> ClientUpn .Length = wcslen (USER_NAME ) * 2 ;
65
- s4u_logon -> ClientUpn .MaximumLength = s4u_logon -> ClientUpn .Length ;
66
- s4u_logon -> ClientUpn .Buffer = (WCHAR * )(s4u_logon + 1 );
67
- memcpy (s4u_logon -> ClientUpn .Buffer , USER_NAME , s4u_logon -> ClientUpn .Length + 2 );
68
- s4u_logon -> ClientRealm .Length = 0 ;
69
- s4u_logon -> ClientRealm .MaximumLength = 0 ;
70
- s4u_logon -> ClientRealm .Buffer = 0 ;
71
-
72
- TOKEN_SOURCE sourceContext ;
73
- RtlCopyMemory (
74
- sourceContext .SourceName ,
75
- ".Jobs " ,
76
- sizeof (sourceContext .SourceName )
77
- );
78
-
79
- if (AllocateLocallyUniqueId (& sourceContext .SourceIdentifier ) != TRUE)
80
- break ;
81
-
82
- PKERB_INTERACTIVE_PROFILE pProfile = NULL ;
83
- LUID logonId ;
84
- QUOTA_LIMITS quotas ;
85
- NTSTATUS subStatus ;
86
- DWORD cbProfile ;
87
- HANDLE hToken = INVALID_HANDLE_VALUE ;
88
- if (ret = LsaLogonUser (lsa_handle , & originName , Network , auth_package_id , s4u_logon , logon_info_size , NULL , & sourceContext ,
89
- (PVOID * )& pProfile ,
90
- & cbProfile ,
91
- & logonId ,
92
- & hToken ,
93
- & quotas ,
94
- & subStatus ) != STATUS_SUCCESS )
95
- break ;
96
-
97
- CloseHandle (hToken );
52
+ static HANDLE
53
+ generate_user_token (wchar_t * user ) {
54
+ HANDLE lsa_handle = 0 , token = 0 ;;
55
+ LSA_OPERATIONAL_MODE mode ;
56
+ ULONG auth_package_id ;
57
+ NTSTATUS ret , subStatus ;
58
+ KERB_S4U_LOGON * s4u_logon = NULL ;
59
+ size_t logon_info_size ;
60
+ LSA_STRING logon_process_name , auth_package_name , originName ;
61
+ TOKEN_SOURCE sourceContext ;
62
+ PKERB_INTERACTIVE_PROFILE pProfile = NULL ;
63
+ LUID logonId ;
64
+ QUOTA_LIMITS quotas ;
65
+ DWORD cbProfile ;
66
+
67
+ InitLsaString (& logon_process_name , "ssh-agent" );
68
+ InitLsaString (& auth_package_name , MICROSOFT_KERBEROS_NAME_A );
69
+ //InitLsaString(&auth_package_name, "Negotiate");
70
+ InitLsaString (& originName , "sshd" );
71
+ if (ret = LsaRegisterLogonProcess (& logon_process_name , & lsa_handle , & mode ) != STATUS_SUCCESS )
72
+ goto done ;
73
+
74
+ if (ret = LsaLookupAuthenticationPackage (lsa_handle , & auth_package_name , & auth_package_id ) != STATUS_SUCCESS )
75
+ goto done ;
76
+
77
+ logon_info_size = sizeof (KERB_S4U_LOGON );
78
+ logon_info_size += (wcslen (user ) * 2 + 2 );
79
+ s4u_logon = malloc (logon_info_size );
80
+ if (s4u_logon == NULL )
81
+ goto done ;
82
+
83
+ s4u_logon -> MessageType = KerbS4ULogon ;
84
+ s4u_logon -> Flags = 0 ;
85
+ s4u_logon -> ClientUpn .Length = wcslen (user ) * 2 ;
86
+ s4u_logon -> ClientUpn .MaximumLength = s4u_logon -> ClientUpn .Length ;
87
+ s4u_logon -> ClientUpn .Buffer = (WCHAR * )(s4u_logon + 1 );
88
+ memcpy (s4u_logon -> ClientUpn .Buffer , user , s4u_logon -> ClientUpn .Length + 2 );
89
+ s4u_logon -> ClientRealm .Length = 0 ;
90
+ s4u_logon -> ClientRealm .MaximumLength = 0 ;
91
+ s4u_logon -> ClientRealm .Buffer = 0 ;
92
+
93
+ memcpy (sourceContext .SourceName ,".Jobs " , sizeof (sourceContext .SourceName ));
94
+
95
+ if (AllocateLocallyUniqueId (& sourceContext .SourceIdentifier ) != TRUE)
96
+ goto done ;
97
+
98
+ if (ret = LsaLogonUser (lsa_handle ,
99
+ & originName ,
100
+ Network ,
101
+ auth_package_id ,
102
+ s4u_logon ,
103
+ logon_info_size ,
104
+ NULL ,
105
+ & sourceContext ,
106
+ (PVOID * )& pProfile ,
107
+ & cbProfile ,
108
+ & logonId ,
109
+ & token ,
110
+ & quotas ,
111
+ & subStatus ) != STATUS_SUCCESS )
112
+ goto done ;
113
+
114
+ done :
115
+ if (lsa_handle )
98
116
LsaDeregisterLogonProcess (lsa_handle );
99
- break ;
117
+ if (s4u_logon )
118
+ free (s4u_logon );
119
+ if (pProfile )
120
+ LsaFreeReturnBuffer (pProfile );
121
+
122
+ return token ;
123
+ }
124
+
125
+ #define AUTH_REQUEST "keyauthenticate"
126
+ #define MAX_USER_NAME_LEN 255 + 255
127
+
128
+ int process_authagent_request (struct sshbuf * request , struct sshbuf * response , struct agent_connection * con ) {
129
+ int r = 0 ;
130
+ char * opn , key_blob , user , sig , blob ;
131
+ size_t opn_len , key_blob_len , user_len , sig_len , blob_len ;
132
+ struct sshkey * key = NULL ;
133
+ HANDLE token = NULL , dup_token = NULL ;
134
+ wchar_t wuser [MAX_USER_NAME_LEN ];
135
+ PWSTR wuser_home = NULL ;
136
+
137
+ user = NULL ;
138
+ if ((r = sshbuf_get_string_direct (request , & opn , & opn_len )) != 0 ||
139
+ (r = sshbuf_get_string_direct (request , & key_blob , & key_blob_len )) != 0 ||
140
+ (r = sshbuf_get_cstring (request , & user , & user_len )) != 0 ||
141
+ (r = sshbuf_get_string_direct (request , & sig , & sig_len )) != 0 ||
142
+ (r = sshbuf_get_string_direct (request , & blob , & blob_len )) != 0 ||
143
+ (r = sshkey_from_blob (key_blob , key_blob_len , & key )) != 0 )
144
+ goto done ;
145
+
146
+ if ((opn_len != strlen (AUTH_REQUEST )) || (memcmp (opn , AUTH_REQUEST , opn_len ) != 0 )) {
147
+ r = EINVAL ;
148
+ goto done ;
149
+ }
150
+
151
+ if (0 == MultiByteToWideChar (CP_UTF8 , 0 , user , user_len + 1 , wuser , MAX_USER_NAME_LEN ) {
152
+ r = GetLastError ();
153
+ goto done ;
154
+ }
155
+
156
+ if ((token = generate_user_token (wuser )) == 0 ) {
157
+ r = EINVAL ;
158
+ goto done ;
100
159
}
101
- return -1 ;
160
+
161
+ done :
162
+ if (user )
163
+ free (user );
164
+ if (key )
165
+ sshkey_free (key );
166
+ if (token )
167
+ CloseHandle (token );
168
+ if (wuser_home )
169
+ CoTaskMemFree (wuser_home );
170
+ return r ;
102
171
}
0 commit comments