Mercurial > dropbear
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 } |