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