Mercurial > dropbear
comparison cli-agentfwd.c @ 550:61c3513825b0 agent-client
Talking to the agent works now. Can't interpret the pubkeys.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 01 Jul 2009 06:27:27 +0000 |
parents | cf376c696dfc |
children | c3f2ec71e3d4 |
comparison
equal
deleted
inserted
replaced
547:cf376c696dfc | 550:61c3513825b0 |
---|---|
92 return 0; | 92 return 0; |
93 } | 93 } |
94 | 94 |
95 /* Sends a request to the agent, returning a newly allocated buffer | 95 /* Sends a request to the agent, returning a newly allocated buffer |
96 * with the response */ | 96 * with the response */ |
97 /* This function will block waiting for a response - it will | |
98 * only be used by client authentication (not for forwarded requests) | |
99 * won't cause problems for interactivity. */ | |
97 /* Packet format (from draft-ylonen) | 100 /* Packet format (from draft-ylonen) |
98 4 bytes Length, msb first. Does not include length itself. | 101 4 bytes Length, msb first. Does not include length itself. |
99 1 byte Packet type. The value 255 is reserved for future extensions. | 102 1 byte Packet type. The value 255 is reserved for future extensions. |
100 data Any data, depending on packet type. Encoding as in the ssh packet | 103 data Any data, depending on packet type. Encoding as in the ssh packet |
101 protocol. | 104 protocol. |
102 | |
103 In this case, data is always empty | |
104 */ | 105 */ |
105 static buffer * agent_request(int fd, unsigned char type) { | 106 static buffer * agent_request(int fd, unsigned char type) { |
106 | 107 |
107 buffer * payload = NULL; | 108 buffer * payload = NULL; |
108 buffer * inbuf = NULL; | 109 buffer * inbuf = NULL; |
111 | 112 |
112 payload = buf_new(4 + 1); | 113 payload = buf_new(4 + 1); |
113 | 114 |
114 buf_putint(payload, 1); | 115 buf_putint(payload, 1); |
115 buf_putbyte(payload, type); | 116 buf_putbyte(payload, type); |
117 buf_setpos(payload, 0); | |
116 | 118 |
117 ret = atomicio(write, fd, buf_getptr(payload, payload->len), payload->len); | 119 ret = atomicio(write, fd, buf_getptr(payload, payload->len), payload->len); |
118 if ((size_t)ret != payload->len) { | 120 if ((size_t)ret != payload->len) { |
119 TRACE(("write failed for agent_request")) | 121 TRACE(("write failed fd %d for agent_request, %s", fd, strerror(errno))) |
120 goto out; | 122 goto out; |
121 } | 123 } |
122 | 124 |
123 buf_free(payload); | 125 buf_free(payload); |
124 payload = NULL; | 126 payload = NULL; |
125 | 127 TRACE(("Wrote out bytes for agent_request")) |
126 /* Now we read the response */ | 128 /* Now we read the response */ |
127 inbuf = buf_new(4); | 129 inbuf = buf_new(4); |
128 ret = atomicio(read, fd, buf_getwriteptr(inbuf, 4), 4); | 130 ret = atomicio(read, fd, buf_getwriteptr(inbuf, 4), 4); |
129 if (ret != 4) { | 131 if (ret != 4) { |
130 TRACE(("read of length failed for agent_request")) | 132 TRACE(("read of length failed for agent_request")) |
131 goto out; | 133 goto out; |
132 } | 134 } |
135 buf_setpos(inbuf, 0); | |
136 buf_setlen(inbuf, ret); | |
133 | 137 |
134 readlen = buf_getint(inbuf); | 138 readlen = buf_getint(inbuf); |
135 if (readlen > MAX_AGENT_REPLY) { | 139 if (readlen > MAX_AGENT_REPLY) { |
136 TRACE(("agent reply is too big")); | 140 TRACE(("agent reply is too big")); |
137 goto out; | 141 goto out; |
138 } | 142 } |
143 | |
144 TRACE(("agent_request readlen is %d", readlen)) | |
139 | 145 |
140 buf_resize(inbuf, readlen); | 146 buf_resize(inbuf, readlen); |
147 buf_setpos(inbuf, 0); | |
141 ret = atomicio(read, fd, buf_getwriteptr(inbuf, readlen), readlen); | 148 ret = atomicio(read, fd, buf_getwriteptr(inbuf, readlen), readlen); |
142 if ((size_t)ret != readlen) { | 149 if ((size_t)ret != readlen) { |
143 TRACE(("read of data failed for agent_request")) | 150 TRACE(("read of data failed for agent_request")) |
144 goto out; | 151 goto out; |
145 } | 152 } |
153 buf_incrwritepos(inbuf, readlen); | |
154 buf_setpos(inbuf, 0); | |
155 TRACE(("agent_request success, length %d", readlen)) | |
146 | 156 |
147 out: | 157 out: |
148 if (payload) | 158 if (payload) |
149 buf_free(payload); | 159 buf_free(payload); |
150 | 160 |
151 return inbuf; | 161 return inbuf; |
152 } | 162 } |
153 | 163 |
154 static struct SignKeyList * agent_get_key_list(int fd) | 164 static void agent_get_key_list(int fd, struct SignKeyList * ret_list) |
155 { | 165 { |
156 buffer * inbuf = NULL; | 166 buffer * inbuf = NULL; |
157 unsigned int num = 0; | 167 unsigned int num = 0; |
158 unsigned char packet_type; | 168 unsigned char packet_type; |
159 unsigned int i; | 169 unsigned int i; |
160 struct SignKeyList *retkey = NULL, *key = NULL; | 170 struct SignKeyList *key = NULL; |
161 int ret; | 171 int ret; |
162 | 172 |
163 inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES); | 173 inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES); |
164 if (!inbuf) { | 174 if (!inbuf) { |
175 TRACE(("agent_request returned no identities")) | |
165 goto out; | 176 goto out; |
166 } | 177 } |
167 | 178 |
168 /* The reply has a format of: | 179 /* The reply has a format of: |
169 * byte packet_type | 180 * byte packet_type |
185 sign_key * pubkey = NULL; | 196 sign_key * pubkey = NULL; |
186 int key_type = DROPBEAR_SIGNKEY_ANY; | 197 int key_type = DROPBEAR_SIGNKEY_ANY; |
187 struct SignKeyList *nextkey = NULL; | 198 struct SignKeyList *nextkey = NULL; |
188 | 199 |
189 nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList)); | 200 nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList)); |
190 if (key) | 201 ret_list->next = nextkey; |
191 key->next = nextkey; | 202 ret_list = nextkey; |
192 else | |
193 retkey = nextkey; | |
194 key = nextkey; | |
195 | 203 |
196 pubkey = new_sign_key(); | 204 pubkey = new_sign_key(); |
197 ret = buf_get_pub_key(inbuf, pubkey, &key_type); | 205 ret = buf_get_pub_key(inbuf, pubkey, &key_type); |
198 if (ret != DROPBEAR_SUCCESS) { | 206 if (ret != DROPBEAR_SUCCESS) { |
199 /* This is slack, properly would cleanup vars etc */ | 207 /* This is slack, properly would cleanup vars etc */ |
212 out: | 220 out: |
213 if (inbuf) { | 221 if (inbuf) { |
214 buf_free(inbuf); | 222 buf_free(inbuf); |
215 inbuf = NULL; | 223 inbuf = NULL; |
216 } | 224 } |
217 | 225 } |
218 return retkey; | 226 |
219 } | 227 /* Returned keys are appended to ret_list */ |
220 | 228 void load_agent_keys(struct SignKeyList * ret_list) |
221 void load_agent_keys() | |
222 { | 229 { |
223 | |
224 struct SignKeyList * ret_list; | |
225 int fd; | 230 int fd; |
226 fd = connect_agent(); | 231 fd = connect_agent(); |
227 if (fd < 0) { | 232 if (fd < 0) { |
228 dropbear_log(LOG_INFO, "Failed to connect to agent"); | 233 dropbear_log(LOG_INFO, "Failed to connect to agent"); |
229 return; | 234 return; |
230 } | 235 } |
231 | 236 |
232 ret_list = agent_get_key_list(fd); | 237 agent_get_key_list(fd, ret_list); |
233 close(fd); | 238 close(fd); |
234 } | 239 } |
235 | 240 |
236 // general procedure: | 241 // general procedure: |
237 // - get the list of keys from the agent | 242 // - get the list of keys from the agent |