]> andersk Git - openssh.git/blame - ssh-add.c
Clarify mailing list details
[openssh.git] / ssh-add.c
CommitLineData
8efc0c15 1/*
2
3ssh-add.c
4
5Author: Tatu Ylonen <ylo@cs.hut.fi>
6
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved
9
10Created: Thu Apr 6 00:52:24 1995 ylo
11
12Adds an identity to the authentication server, or removes an identity.
13
14*/
15
16#include "includes.h"
17RCSID("$Id$");
18
19#include "rsa.h"
20#include "ssh.h"
21#include "xmalloc.h"
22#include "authfd.h"
23
dad9a31e 24#ifdef USE_EXTERNAL_ASKPASS
25int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment);
26#endif /* USE_EXTERNAL_ASKPASS */
27
f601d847 28#ifdef HAVE___PROGNAME
29extern char *__progname;
30#else /* HAVE___PROGNAME */
31const char *__progname = "ssh-add";
32#endif /* HAVE___PROGNAME */
33
8efc0c15 34void
5068f573 35delete_file(AuthenticationConnection *ac, const char *filename)
8efc0c15 36{
37 RSA *key;
38 char *comment;
8efc0c15 39
40 key = RSA_new();
41 if (!load_public_key(filename, key, &comment))
42 {
43 printf("Bad key file %s: %s\n", filename, strerror(errno));
44 return;
45 }
46
8efc0c15 47 if (ssh_remove_identity(ac, key))
48 fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment);
49 else
50 fprintf(stderr, "Could not remove identity: %s\n", filename);
51 RSA_free(key);
52 xfree(comment);
8efc0c15 53}
54
55void
5068f573 56delete_all(AuthenticationConnection *ac)
8efc0c15 57{
8efc0c15 58 /* Send a request to remove all identities. */
59 if (ssh_remove_all_identities(ac))
60 fprintf(stderr, "All identities removed.\n");
61 else
62 fprintf(stderr, "Failed to remove all identitities.\n");
8efc0c15 63}
64
65void
5068f573 66add_file(AuthenticationConnection *ac, const char *filename)
8efc0c15 67{
68 RSA *key;
69 RSA *public_key;
dad9a31e 70 char *saved_comment, *comment;
71 int success;
72
8efc0c15 73 key = RSA_new();
74 public_key = RSA_new();
75 if (!load_public_key(filename, public_key, &saved_comment))
76 {
77 printf("Bad key file %s: %s\n", filename, strerror(errno));
78 return;
79 }
80 RSA_free(public_key);
8efc0c15 81
dad9a31e 82 /* At first, try empty passphrase */
83 success = load_private_key(filename, "", key, &comment);
84 if (!success) {
85 printf("Need passphrase for %s (%s).\n", filename, saved_comment);
86 if (!isatty(STDIN_FILENO)) {
87#ifdef USE_EXTERNAL_ASKPASS
88 int prompts = 3;
89
90 while (prompts && !success)
91 {
92 success = askpass(filename, key, saved_comment, &comment);
93 prompts--;
94 }
95 if (!success)
96 {
97 xfree(saved_comment);
98 return;
99 }
100#else /* !USE_EXTERNAL_ASKPASS */
045672f9 101 xfree(saved_comment);
102 return;
dad9a31e 103#endif /* USE_EXTERNAL_ASKPASS */
8efc0c15 104 }
8efc0c15 105
dad9a31e 106 while (!success) {
107 char *pass = read_passphrase("Enter passphrase: ", 1);
108 if (strcmp(pass, "") == 0){
109 xfree(pass);
110 xfree(saved_comment);
111 return;
112 }
113 success = load_private_key(filename, pass, key, &comment);
114 memset(pass, 0, strlen(pass));
115 xfree(pass);
116 if (success)
117 break;
118
119 printf("Bad passphrase.\n");
120 }
121 }
8efc0c15 122 xfree(saved_comment);
123
8efc0c15 124 if (ssh_add_identity(ac, key, comment))
125 fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
126 else
127 fprintf(stderr, "Could not add identity: %s\n", filename);
128 RSA_free(key);
129 xfree(comment);
8efc0c15 130}
131
132void
5068f573 133list_identities(AuthenticationConnection *ac)
8efc0c15 134{
8efc0c15 135 BIGNUM *e, *n;
4d195447 136 int status;
8efc0c15 137 char *comment;
138 int had_identities;
139
8efc0c15 140 e = BN_new();
141 n = BN_new();
142 had_identities = 0;
4d195447 143 for (status = ssh_get_first_identity(ac, e, n, &comment);
8efc0c15 144 status;
4d195447 145 status = ssh_get_next_identity(ac, e, n, &comment))
8efc0c15 146 {
4d195447 147 char *ebuf, *nbuf;
8efc0c15 148 had_identities = 1;
4d195447 149 ebuf = BN_bn2dec(e);
150 if (ebuf == NULL) {
151 error("list_identities: BN_bn2dec(e) failed.");
152 }else{
153 nbuf = BN_bn2dec(n);
154 if (nbuf == NULL) {
155 error("list_identities: BN_bn2dec(n) failed.");
156 }else{
157 unsigned int bits = BN_num_bits(n);
158 printf("%d %s %s %s\n", bits, ebuf, nbuf, comment);
159 free(nbuf);
160 }
161 free(ebuf);
5bae4ab8 162 }
8efc0c15 163 xfree(comment);
164 }
165 BN_clear_free(e);
166 BN_clear_free(n);
167 if (!had_identities)
168 printf("The agent has no identities.\n");
8efc0c15 169}
170
171int
5068f573 172main(int argc, char **argv)
8efc0c15 173{
5068f573 174 AuthenticationConnection *ac = NULL;
8efc0c15 175 struct passwd *pw;
176 char buf[1024];
177 int no_files = 1;
178 int i;
179 int deleting = 0;
180
181 /* check if RSA support exists */
182 if (rsa_alive() == 0) {
8efc0c15 183
184 fprintf(stderr,
185 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
186 __progname);
187 exit(1);
188 }
189
5068f573 190 /* At first, get a connection to the authentication agent. */
191 ac = ssh_get_authentication_connection();
192 if (ac == NULL) {
193 fprintf(stderr, "Could not open a connection to your authentication agent.\n");
194 exit(1);
195 }
196
197 for (i = 1; i < argc; i++)
8efc0c15 198 {
5068f573 199 if (strcmp(argv[i], "-l") == 0)
8efc0c15 200 {
5068f573 201 list_identities(ac);
8efc0c15 202 no_files = 0; /* Don't default-add/delete if -l. */
203 continue;
204 }
5068f573 205 if (strcmp(argv[i], "-d") == 0)
8efc0c15 206 {
207 deleting = 1;
208 continue;
209 }
5068f573 210 if (strcmp(argv[i], "-D") == 0)
8efc0c15 211 {
5068f573 212 delete_all(ac);
8efc0c15 213 no_files = 0;
214 continue;
215 }
216 no_files = 0;
217 if (deleting)
5068f573 218 delete_file(ac, argv[i]);
8efc0c15 219 else
5068f573 220 add_file(ac, argv[i]);
8efc0c15 221 }
222 if (no_files)
223 {
224 pw = getpwuid(getuid());
225 if (!pw)
226 {
227 fprintf(stderr, "No user found with uid %d\n", (int)getuid());
5068f573 228 ssh_close_authentication_connection(ac);
8efc0c15 229 exit(1);
230 }
231 snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY);
232 if (deleting)
5068f573 233 delete_file(ac, buf);
8efc0c15 234 else
5068f573 235 add_file(ac, buf);
8efc0c15 236 }
5068f573 237 ssh_close_authentication_connection(ac);
8efc0c15 238 exit(0);
239}
dad9a31e 240
241#ifdef USE_EXTERNAL_ASKPASS
242int askpass(const char *filename, RSA *key, const char *saved_comment, char **comment)
243{
244 int pipes[2];
245 char buf[1024];
246 int tmp;
247 pid_t child;
248 FILE *pipef;
249
250 /* Check that we are X11-capable */
251 if (getenv("DISPLAY") == NULL)
252 exit(1);
253
254 if (pipe(pipes) == -1) {
255 fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno));
256 exit(1);
257 }
258
259 if (fflush(NULL) == EOF) {
260 fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno));
261 exit(1);
262 }
263
264 child = fork();
265 if (child == -1) {
266 fprintf(stderr, "Cannot fork: %s\n", strerror(errno));
267 exit(1);
268 }
269
270 if (child == 0) {
271 /* In child */
272
273 close(pipes[0]);
274 if (dup2(pipes[1], 1) ==-1) {
275 fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
276 exit(1);
277 }
278
279 tmp = snprintf(buf, sizeof(buf), "Need passphrase for %s (%s)", filename, saved_comment);
280 /* skip the prompt if it won't fit */
281 if ((tmp < 0) || (tmp >= sizeof(buf)))
282 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", 0);
283 else
284 tmp = execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0);
285
286 /* Shouldn't get this far */
287 fprintf(stderr, "Executing ssh-askpass failed: %s\n", strerror(errno));
288 exit(1);
289 }
290
291 /* In parent */
292 close(pipes[1]);
293
294 if ((pipef = fdopen(pipes[0], "r")) == NULL) {
295 fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
296 exit(1);
297 }
298
299 /* Read passphrase back from child, abort if none presented */
300 if(fgets(buf, sizeof(buf), pipef) == NULL)
301 exit(1);
302
303 fclose(pipef);
304
305 if (strchr(buf, '\n'))
306 *strchr(buf, '\n') = 0;
307
308 if (waitpid(child, NULL, 0) == -1) {
309 fprintf(stderr, "Waiting for child failed: %s\n",
310 strerror(errno));
311 exit(1);
312 }
313
314 /* Try password as it was presented */
315 tmp = load_private_key(filename, buf, key, comment);
316
317 memset(buf, 0, sizeof(buf));
318
319 return(tmp);
320}
321#endif /* USE_EXTERNAL_ASKPASS */
This page took 0.098384 seconds and 5 git commands to generate.