Mercurial > dropbear
comparison cli-agentfwd.c @ 551:c3f2ec71e3d4 agent-client
New standard linked list to use, rather than adhoc SignKeyList or TCPFwdList
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 06 Jul 2009 12:59:13 +0000 |
parents | 61c3513825b0 |
children | de3653483ac0 |
comparison
equal
deleted
inserted
replaced
550:61c3513825b0 | 551:c3f2ec71e3d4 |
---|---|
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 * SOFTWARE. */ | 23 * SOFTWARE. */ |
24 | |
25 /* The basic protocol use to communicate with the agent is defined in | |
26 * draft-ylonen-ssh-protocol-00.txt, with the ssh2 extensions defined through | |
27 * openssh's implementation. */ | |
28 | 24 |
29 #include "includes.h" | 25 #include "includes.h" |
30 | 26 |
31 #ifdef ENABLE_CLI_AGENTFWD | 27 #ifdef ENABLE_CLI_AGENTFWD |
32 | 28 |
43 #include "runopts.h" | 39 #include "runopts.h" |
44 #include "atomicio.h" | 40 #include "atomicio.h" |
45 #include "signkey.h" | 41 #include "signkey.h" |
46 #include "auth.h" | 42 #include "auth.h" |
47 | 43 |
44 /* The protocol implemented to talk to OpenSSH's SSH2 agent is documented in | |
45 PROTOCOL.agent in recent OpenSSH source distributions (5.1p1 has it). */ | |
46 | |
48 static int new_agent_chan(struct Channel * channel); | 47 static int new_agent_chan(struct Channel * channel); |
49 | 48 |
50 const struct ChanType cli_chan_agent = { | 49 const struct ChanType cli_chan_agent = { |
51 0, /* sepfds */ | 50 0, /* sepfds */ |
52 "[email protected]", | 51 "[email protected]", |
159 buf_free(payload); | 158 buf_free(payload); |
160 | 159 |
161 return inbuf; | 160 return inbuf; |
162 } | 161 } |
163 | 162 |
164 static void agent_get_key_list(int fd, struct SignKeyList * ret_list) | 163 static void agent_get_key_list(int fd, m_list * ret_list) |
165 { | 164 { |
166 buffer * inbuf = NULL; | 165 buffer * inbuf = NULL; |
167 unsigned int num = 0; | 166 unsigned int num = 0; |
168 unsigned char packet_type; | 167 unsigned char packet_type; |
169 unsigned int i; | 168 unsigned int i; |
170 struct SignKeyList *key = NULL; | |
171 int ret; | 169 int ret; |
172 | 170 |
173 inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES); | 171 inbuf = agent_request(fd, SSH2_AGENTC_REQUEST_IDENTITIES); |
174 if (!inbuf) { | 172 if (!inbuf) { |
175 TRACE(("agent_request returned no identities")) | 173 TRACE(("agent_request returned no identities")) |
176 goto out; | 174 goto out; |
177 } | 175 } |
178 | 176 |
179 /* The reply has a format of: | 177 /* The reply has a format of: |
180 * byte packet_type | 178 byte SSH2_AGENT_IDENTITIES_ANSWER |
181 * int num_keys | 179 uint32 num_keys |
182 * | 180 Followed by zero or more consecutive keys, encoded as: |
183 * string keyblob1 | 181 string key_blob |
184 * string comment1 | 182 string key_comment |
185 * ... | |
186 * string keyblob(n) | |
187 * string comment(n) | |
188 */ | 183 */ |
189 packet_type = buf_getbyte(inbuf); | 184 packet_type = buf_getbyte(inbuf); |
190 if (packet_type != SSH2_AGENT_IDENTITIES_ANSWER) { | 185 if (packet_type != SSH2_AGENT_IDENTITIES_ANSWER) { |
191 goto out; | 186 goto out; |
192 } | 187 } |
193 | 188 |
194 num = buf_getint(inbuf); | 189 num = buf_getint(inbuf); |
195 for (i = 0; i < num; i++) { | 190 for (i = 0; i < num; i++) { |
196 sign_key * pubkey = NULL; | 191 sign_key * pubkey = NULL; |
197 int key_type = DROPBEAR_SIGNKEY_ANY; | 192 int key_type = DROPBEAR_SIGNKEY_ANY; |
193 buffer * key_buf; | |
198 struct SignKeyList *nextkey = NULL; | 194 struct SignKeyList *nextkey = NULL; |
199 | 195 |
200 nextkey = (struct SignKeyList*)m_malloc(sizeof(struct SignKeyList)); | 196 /* each public key is encoded as a string */ |
201 ret_list->next = nextkey; | 197 key_buf = buf_getstringbuf(inbuf); |
202 ret_list = nextkey; | |
203 | |
204 pubkey = new_sign_key(); | 198 pubkey = new_sign_key(); |
205 ret = buf_get_pub_key(inbuf, pubkey, &key_type); | 199 ret = buf_get_pub_key(key_buf, pubkey, &key_type); |
200 buf_free(key_buf); | |
206 if (ret != DROPBEAR_SUCCESS) { | 201 if (ret != DROPBEAR_SUCCESS) { |
207 /* This is slack, properly would cleanup vars etc */ | 202 /* This is slack, properly would cleanup vars etc */ |
208 dropbear_exit("Bad pubkey received from agent"); | 203 dropbear_exit("Bad pubkey received from agent"); |
209 } | 204 } |
210 | 205 pubkey->type = key_type; |
211 key->key = pubkey; | 206 pubkey->source = SIGNKEY_SOURCE_AGENT; |
212 key->next = NULL; | 207 |
213 key->type = key_type; | 208 list_append(ret_list, pubkey); |
214 key->source = SIGNKEY_SOURCE_AGENT; | 209 |
215 | 210 /* We'll ignore the comment for now. might want it later.*/ |
216 /* We'll ignore the comment */ | |
217 buf_eatstring(inbuf); | 211 buf_eatstring(inbuf); |
218 } | 212 } |
219 | 213 |
220 out: | 214 out: |
221 if (inbuf) { | 215 if (inbuf) { |
222 buf_free(inbuf); | 216 buf_free(inbuf); |
223 inbuf = NULL; | 217 inbuf = NULL; |
224 } | 218 } |
225 } | 219 } |
226 | 220 |
227 /* Returned keys are appended to ret_list */ | 221 /* Returned keys are prepended to ret_list, which will |
228 void load_agent_keys(struct SignKeyList * ret_list) | 222 be updated. */ |
223 void load_agent_keys(m_list *ret_list) | |
229 { | 224 { |
230 int fd; | 225 int fd; |
231 fd = connect_agent(); | 226 fd = connect_agent(); |
232 if (fd < 0) { | 227 if (fd < 0) { |
233 dropbear_log(LOG_INFO, "Failed to connect to agent"); | 228 dropbear_log(LOG_INFO, "Failed to connect to agent"); |
235 } | 230 } |
236 | 231 |
237 agent_get_key_list(fd, ret_list); | 232 agent_get_key_list(fd, ret_list); |
238 close(fd); | 233 close(fd); |
239 } | 234 } |
240 | 235 |
241 // general procedure: | 236 void agent_buf_sign(buffer *sigblob, sign_key *key, |
242 // - get the list of keys from the agent | 237 const unsigned char *data, unsigned int len) { |
243 // - foreach, send a dummy userauth_pubkey message to the server and see | 238 } |
244 // if it lets us in | |
245 // - if it does, sign and auth | |
246 // - if not, repeat. | |
247 // | |
248 | 239 |
249 #endif | 240 #endif |