31
31
32
32
#include "agent.h"
33
33
#include "agent-request.h"
34
+ #include <sddl.h>
34
35
35
36
#define MAX_KEY_LENGTH 255
36
37
#define MAX_VALUE_NAME 16383
@@ -47,31 +48,84 @@ get_user_root(struct agent_connection* con, HKEY *root){
47
48
return r ;
48
49
}
49
50
51
+ static int
52
+ convert_blob (struct agent_connection * con , char * blob , DWORD blen , char * * eblob , DWORD * eblen , int encrypt ) {
53
+ int r = 0 ;
54
+ DATA_BLOB in , out ;
55
+ if (ImpersonateNamedPipeClient (con -> connection ) == FALSE)
56
+ return ERROR_INTERNAL_ERROR ;
57
+
58
+ in .cbData = blen ;
59
+ in .pbData = blob ;
60
+ out .cbData = 0 ;
61
+ out .pbData = NULL ;
62
+
63
+ if (encrypt ) {
64
+ if (!CryptProtectData (& in , NULL , NULL , 0 , NULL , 0 , & out )) {
65
+ r = GetLastError ();
66
+ goto done ;
67
+ }
68
+ }
69
+ else {
70
+ if (!CryptUnprotectData (& in , NULL , NULL , 0 , NULL , 0 , & out )) {
71
+ r = GetLastError ();
72
+ goto done ;
73
+ }
74
+ }
75
+
76
+
77
+
78
+
79
+ * eblob = malloc (out .cbData );
80
+ if (* eblob == NULL ) {
81
+ r = ERROR_OUTOFMEMORY ;
82
+ goto done ;
83
+ }
84
+
85
+ memcpy (* eblob , out .pbData , out .cbData );
86
+ * eblen = out .cbData ;
87
+ done :
88
+ if (out .cbData )
89
+ LocalFree (out .cbData );
90
+ RevertToSelf ();
91
+ return r ;
92
+ }
93
+
50
94
int
51
95
process_add_identity (struct sshbuf * request , struct sshbuf * response , struct agent_connection * con ) {
52
96
struct sshkey * key = NULL ;
53
- int r = 0 , r1 = 0 , blob_len ;
97
+ int r = 0 , r1 = 0 , blob_len , eblob_len ;
54
98
size_t comment_len , pubkey_blob_len ;
55
99
u_char * pubkey_blob = NULL ;
56
100
char * thumbprint = NULL , * comment ;
57
101
const char * blob ;
102
+ char * eblob = NULL ;
58
103
HKEY reg = 0 , sub = 0 , user_root = 0 ;
104
+ PSECURITY_DESCRIPTOR sd = NULL ;
105
+ wchar_t * str = L"O:SYG:BAD:P(A;;GA;;;SY)" ;
106
+ SECURITY_ATTRIBUTES sa ;
107
+ ConvertStringSecurityDescriptorToSecurityDescriptorW (str , SDDL_REVISION_1 , & sd , NULL );
108
+ sa .nLength = sizeof (sa );
109
+ sa .lpSecurityDescriptor = sd ;
110
+ sa .bInheritHandle = FALSE;
59
111
60
112
blob = sshbuf_ptr (request );
61
113
if ((r = sshkey_private_deserialize (request , & key )) != 0 )
62
114
goto done ;
63
115
blob_len = (sshbuf_ptr (request ) - blob ) & 0xffffffff ;
64
116
65
- if ((r = sshkey_to_blob (key , & pubkey_blob , & pubkey_blob_len )) != 0 ) {
117
+ if ((r = sshkey_to_blob (key , & pubkey_blob , & pubkey_blob_len )) != 0 )
118
+ goto done ;
119
+
120
+ if ((r = convert_blob (con , blob , blob_len , & eblob , & eblob_len , 1 )) != 0 )
66
121
goto done ;
67
- }
68
122
69
123
if (((r = sshbuf_peek_string_direct (request , & comment , & comment_len )) != 0 ) ||
70
124
((thumbprint = sshkey_fingerprint (key , SSH_FP_HASH_DEFAULT , SSH_FP_DEFAULT )) == NULL ) ||
71
125
((r = get_user_root (con , & user_root )) != 0 ) ||
72
126
((r = RegCreateKeyExW (user_root , SSHD_KEYS_ROOT , 0 , 0 , 0 , KEY_WRITE , NULL , & reg , NULL )) != 0 ) ||
73
127
((r = RegCreateKeyExA (reg , thumbprint , 0 , 0 , 0 , KEY_WRITE , NULL , & sub , NULL )) != 0 ) ||
74
- ((r = RegSetValueExW (sub , NULL , 0 , REG_BINARY , blob , blob_len )) != 0 ) ||
128
+ ((r = RegSetValueExW (sub , NULL , 0 , REG_BINARY , eblob , eblob_len )) != 0 ) ||
75
129
((r = RegSetValueExW (sub , L"pub" , 0 , REG_BINARY , pubkey_blob , pubkey_blob_len )) != 0 ) ||
76
130
((r = RegSetValueExW (sub , L"type" , 0 , REG_DWORD , (BYTE * )& key -> type , 4 )) != 0 ) ||
77
131
((r = RegSetValueExW (sub , L"comment" , 0 , REG_BINARY , comment , comment_len )) != 0 ) )
@@ -83,6 +137,10 @@ process_add_identity(struct sshbuf* request, struct sshbuf* response, struct age
83
137
84
138
r1 = sshbuf_put_u8 (response , (r == 0 ) ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE );
85
139
140
+ if (eblob )
141
+ free (eblob );
142
+ if (sd )
143
+ LocalFree (sd );
86
144
if (key )
87
145
sshkey_free (key );
88
146
if (thumbprint )
@@ -104,8 +162,9 @@ static int sign_blob(const struct sshkey *pubkey, u_char ** sig, size_t *siglen,
104
162
int r = 0 ;
105
163
struct sshkey * prikey = NULL ;
106
164
char * thumbprint = NULL , * regdata = NULL ;
107
- DWORD regdatalen = 0 ;
108
- struct sshbuf * tmpbuf ;
165
+ DWORD regdatalen = 0 , keyblob_len = 0 ;;
166
+ struct sshbuf * tmpbuf = NULL ;
167
+ char * keyblob = NULL ;
109
168
110
169
regdata = malloc (4 );
111
170
regdatalen = 4 ;
@@ -140,7 +199,10 @@ static int sign_blob(const struct sshkey *pubkey, u_char ** sig, size_t *siglen,
140
199
if ((r = RegQueryValueExW (sub , NULL , 0 , NULL , regdata , & regdatalen )) != 0 )
141
200
goto done ;
142
201
143
- if ((tmpbuf = sshbuf_from (regdata , regdatalen )) == NULL ) {
202
+ if ((r = convert_blob (con , regdata , regdatalen , & keyblob , & keyblob_len , FALSE)) != 0 )
203
+ goto done ;
204
+
205
+ if ((tmpbuf = sshbuf_from (keyblob , keyblob_len )) == NULL ) {
144
206
r = ENOMEM ;
145
207
goto done ;
146
208
}
@@ -150,6 +212,8 @@ static int sign_blob(const struct sshkey *pubkey, u_char ** sig, size_t *siglen,
150
212
goto done ;
151
213
152
214
done :
215
+ if (keyblob )
216
+ free (keyblob );
153
217
if (regdata )
154
218
free (regdata );
155
219
if (tmpbuf )
0 commit comments