comparison cli-kex.c @ 59:bdc97a5719f4

add new entries to known_hosts
author Matt Johnston <matt@ucc.asn.au>
date Mon, 09 Aug 2004 08:06:57 +0000
parents 095d689fed16
children e3adf4cf5465
comparison
equal deleted inserted replaced
56:6f091656c100 59:bdc97a5719f4
123 123
124 static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) { 124 static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen) {
125 125
126 char * filename = NULL; 126 char * filename = NULL;
127 FILE *hostsfile = NULL; 127 FILE *hostsfile = NULL;
128 int readonly = 0;
128 struct passwd *pw = NULL; 129 struct passwd *pw = NULL;
129 unsigned int len, hostlen; 130 unsigned int hostlen, algolen;
131 unsigned long len;
130 const char *algoname = NULL; 132 const char *algoname = NULL;
131 buffer * line = NULL; 133 buffer * line = NULL;
132 int ret; 134 int ret;
133 135
134 pw = getpwuid(getuid()); 136 pw = getpwuid(getuid());
149 } 151 }
150 } 152 }
151 153
152 snprintf(filename, len+18, "%s/.ssh/known_hosts", pw->pw_dir); 154 snprintf(filename, len+18, "%s/.ssh/known_hosts", pw->pw_dir);
153 hostsfile = fopen(filename, "r+"); 155 hostsfile = fopen(filename, "r+");
156
157 /* We mightn't have been able to open it if it was read-only */
158 if (hostsfile == NULL && (errno == EACCES || errno == EROFS)) {
159 readonly = 1;
160 hostsfile = fopen(filename, "r");
161 }
162
154 if (hostsfile == NULL) { 163 if (hostsfile == NULL) {
155 ask_to_confirm(keyblob, keybloblen); 164 ask_to_confirm(keyblob, keybloblen);
156 goto out; /* We only get here on success */ 165 goto out; /* We only get here on success */
157 } 166 }
158 167
159 line = buf_new(MAX_KNOWNHOSTS_LINE); 168 line = buf_new(MAX_KNOWNHOSTS_LINE);
160 hostlen = strlen(cli_opts.remotehost); 169 hostlen = strlen(cli_opts.remotehost);
170 algoname = signkey_name_from_type(ses.newkeys->algo_hostkey, &algolen);
161 171
162 do { 172 do {
163 if (buf_getline(line, hostsfile) == DROPBEAR_FAILURE) { 173 if (buf_getline(line, hostsfile) == DROPBEAR_FAILURE) {
164 TRACE(("failed reading line: prob EOF")); 174 TRACE(("failed reading line: prob EOF"));
165 break; 175 break;
186 /* there wasn't a space after the hostname, something dodgy */ 196 /* there wasn't a space after the hostname, something dodgy */
187 TRACE(("missing space afte matching hostname")); 197 TRACE(("missing space afte matching hostname"));
188 continue; 198 continue;
189 } 199 }
190 200
191 algoname = signkey_name_from_type(ses.newkeys->algo_hostkey, &len); 201 if ( strncmp(buf_getptr(line, algolen), algoname, algolen) != 0) {
192 if ( strncmp(buf_getptr(line, len), algoname, len) != 0) {
193 TRACE(("algo doesn't match")); 202 TRACE(("algo doesn't match"));
194 continue; 203 continue;
195 } 204 }
196 205
197 buf_incrpos(line, len); 206 buf_incrpos(line, algolen);
198 if (buf_getbyte(line) != ' ') { 207 if (buf_getbyte(line) != ' ') {
199 TRACE(("missing space after algo")); 208 TRACE(("missing space after algo"));
200 continue; 209 continue;
201 } 210 }
202 211
203 /* Now we're at the interesting hostkey */ 212 /* Now we're at the interesting hostkey */
204 ret = cmp_base64_key(keyblob, keybloblen, algoname, len, line); 213 ret = cmp_base64_key(keyblob, keybloblen, algoname, algolen, line);
205 214
206 if (ret == DROPBEAR_SUCCESS) { 215 if (ret == DROPBEAR_SUCCESS) {
207 /* Good matching key */ 216 /* Good matching key */
208 TRACE(("good matching key")); 217 TRACE(("good matching key"));
209 goto out; 218 goto out;
212 /* The keys didn't match. eep. */ 221 /* The keys didn't match. eep. */
213 } while (1); /* keep going 'til something happens */ 222 } while (1); /* keep going 'til something happens */
214 223
215 /* Key doesn't exist yet */ 224 /* Key doesn't exist yet */
216 ask_to_confirm(keyblob, keybloblen); 225 ask_to_confirm(keyblob, keybloblen);
226
217 /* If we get here, they said yes */ 227 /* If we get here, they said yes */
228
229 if (readonly) {
230 goto out;
231 }
232
233 /* put the new entry in the file */
234 fseek(hostsfile, 0, SEEK_END);
235 buf_setpos(line, 0);
236 buf_setlen(line, 0);
237 buf_putbytes(line, ses.remotehost, hostlen);
238 buf_putbyte(line, ' ');
239 buf_putbytes(line, algoname, algolen);
240 buf_putbyte(line, ' ');
241 len = line->size - line->pos;
242 TRACE(("keybloblen %d, len %d", keybloblen, len));
243 /* The only failure with base64 is buffer_overflow, but buf_getwriteptr
244 * will die horribly in the case anyway */
245 base64_encode(keyblob, keybloblen, buf_getwriteptr(line, len), &len);
246 buf_incrwritepos(line, len);
247 buf_putbyte(line, '\n');
248 buf_setpos(line, 0);
249 fwrite(buf_getptr(line, line->len), line->len, 1, hostsfile);
250 /* We ignore errors, since there's not much we can do about them */
218 251
219 out: 252 out:
220 if (hostsfile != NULL) { 253 if (hostsfile != NULL) {
221 fclose(hostsfile); 254 fclose(hostsfile);
222 } 255 }