]> andersk Git - openssh.git/blame - ssh-add.c
Thinko
[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
24void
5068f573 25delete_file(AuthenticationConnection *ac, const char *filename)
8efc0c15 26{
27 RSA *key;
28 char *comment;
8efc0c15 29
30 key = RSA_new();
31 if (!load_public_key(filename, key, &comment))
32 {
33 printf("Bad key file %s: %s\n", filename, strerror(errno));
34 return;
35 }
36
8efc0c15 37 if (ssh_remove_identity(ac, key))
38 fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment);
39 else
40 fprintf(stderr, "Could not remove identity: %s\n", filename);
41 RSA_free(key);
42 xfree(comment);
8efc0c15 43}
44
45void
5068f573 46delete_all(AuthenticationConnection *ac)
8efc0c15 47{
8efc0c15 48 /* Send a request to remove all identities. */
49 if (ssh_remove_all_identities(ac))
50 fprintf(stderr, "All identities removed.\n");
51 else
52 fprintf(stderr, "Failed to remove all identitities.\n");
8efc0c15 53}
54
e1a9c08d 55#define BUFSIZE 1024
8efc0c15 56void
5068f573 57add_file(AuthenticationConnection *ac, const char *filename)
8efc0c15 58{
59 RSA *key;
60 RSA *public_key;
8efc0c15 61 char *saved_comment, *comment, *pass;
62 int first;
045672f9 63#ifndef DISABLE_EXTERNAL_ASKPASS
e1a9c08d 64 int pipes[2];
65 char buf[BUFSIZE];
66 int tmp;
67 pid_t child;
68 FILE *pipef;
045672f9 69#endif /* !DISABLE_EXTERNAL_ASKPASS */
70
8efc0c15 71 key = RSA_new();
72 public_key = RSA_new();
73 if (!load_public_key(filename, public_key, &saved_comment))
74 {
75 printf("Bad key file %s: %s\n", filename, strerror(errno));
76 return;
77 }
78 RSA_free(public_key);
79
80 pass = xstrdup("");
81 first = 1;
82 while (!load_private_key(filename, pass, key, &comment))
83 {
84 /* Free the old passphrase. */
85 memset(pass, 0, strlen(pass));
86 xfree(pass);
87
88 /* Ask for a passphrase. */
89 if (getenv("DISPLAY") && !isatty(fileno(stdin)))
90 {
045672f9 91#ifndef DISABLE_EXTERNAL_ASKPASS
e1a9c08d 92 if (pipe(pipes) ==-1)
93 {
94 fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno));
95 exit(1);
96 }
97 if (fflush(NULL)==EOF)
98 {
99 fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno));
100 exit(1);
101 }
102 switch (child=fork())
103 {
104 case -1:
105 fprintf(stderr, "Cannot fork: %s\n", strerror(errno));
106 exit(1);
107 case 0:
108 close(pipes[0]);
109 if (dup2(pipes[1], 1) ==-1)
110 {
111 fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
112 exit(1);
113 }
114 tmp=snprintf(buf, BUFSIZE, "Need passphrase for %s (%s)",
115 filename, saved_comment);
116 /* skip the prompt if it won't fit */
117 if (tmp < 0 || tmp >= BUFSIZE)
d4f11b59 118 tmp=execlp(ASKPASS_PROGRAM, "ssh-askpass", 0);
e1a9c08d 119 else
d4f11b59 120 tmp=execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0);
e1a9c08d 121 if (tmp==-1)
122 {
123 fprintf(stderr, "Executing ssh-askpass failed: %s\n",
124 strerror(errno));
125 exit(1);
126 }
127 break;
128 default:
129 close(pipes[1]);
130 if ( (pipef=fdopen(pipes[0], "r")) ==NULL)
131 {
132 fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
133 exit(1);
134 }
135 if(fgets(buf, sizeof(buf), pipef)==NULL)
136 {
137 xfree(saved_comment);
138 return;
139 }
140 fclose(pipef);
141 if (strchr(buf, '\n'))
142 *strchr(buf, '\n') = 0;
143 pass = xstrdup(buf);
144 memset(buf, 0, sizeof(buf));
145 if (waitpid(child, NULL, 0) ==-1)
146 {
147 fprintf(stderr, "Waiting for child failed: %s\n",
148 strerror(errno));
149 exit(1);
150 }
151 if (strcmp(pass, "") == 0)
152 {
153 xfree(saved_comment);
154 xfree(pass);
155 return;
156 }
157 }
045672f9 158#else /* !DISABLE_EXTERNAL_ASKPASS */
159 xfree(saved_comment);
160 return;
161#endif /* !DISABLE_EXTERNAL_ASKPASS */
8efc0c15 162 }
163 else
164 {
165 if (first)
166 printf("Need passphrase for %s (%s).\n", filename, saved_comment);
167 else
168 printf("Bad passphrase.\n");
169 pass = read_passphrase("Enter passphrase: ", 1);
170 if (strcmp(pass, "") == 0)
171 {
172 xfree(saved_comment);
173 xfree(pass);
174 return;
175 }
176 }
177 first = 0;
178 }
179 memset(pass, 0, strlen(pass));
180 xfree(pass);
181
182 xfree(saved_comment);
183
8efc0c15 184 if (ssh_add_identity(ac, key, comment))
185 fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
186 else
187 fprintf(stderr, "Could not add identity: %s\n", filename);
188 RSA_free(key);
189 xfree(comment);
8efc0c15 190}
191
192void
5068f573 193list_identities(AuthenticationConnection *ac)
8efc0c15 194{
8efc0c15 195 BIGNUM *e, *n;
196 int bits, status;
197 char *comment;
198 int had_identities;
199
8efc0c15 200 e = BN_new();
201 n = BN_new();
202 had_identities = 0;
203 for (status = ssh_get_first_identity(ac, &bits, e, n, &comment);
204 status;
205 status = ssh_get_next_identity(ac, &bits, e, n, &comment))
206 {
207 char *buf;
208 had_identities = 1;
209 printf("%d ", bits);
210 buf = BN_bn2dec(e);
5bae4ab8 211 if (buf != NULL) {
212 printf("%s ", buf);
213 free (buf);
214 } else {
215 error("list_identities: BN_bn2dec #1 failed.");
216 }
8efc0c15 217 buf = BN_bn2dec(n);
5bae4ab8 218 if (buf != NULL) {
219 printf("%s %s\n", buf, comment);
220 free (buf);
221 } else {
222 error("list_identities: BN_bn2dec #2 failed.");
223 }
8efc0c15 224 xfree(comment);
225 }
226 BN_clear_free(e);
227 BN_clear_free(n);
228 if (!had_identities)
229 printf("The agent has no identities.\n");
8efc0c15 230}
231
232int
5068f573 233main(int argc, char **argv)
8efc0c15 234{
5068f573 235 AuthenticationConnection *ac = NULL;
8efc0c15 236 struct passwd *pw;
237 char buf[1024];
238 int no_files = 1;
239 int i;
240 int deleting = 0;
241
242 /* check if RSA support exists */
243 if (rsa_alive() == 0) {
244 extern char *__progname;
245
246 fprintf(stderr,
247 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
248 __progname);
249 exit(1);
250 }
251
5068f573 252 /* At first, get a connection to the authentication agent. */
253 ac = ssh_get_authentication_connection();
254 if (ac == NULL) {
255 fprintf(stderr, "Could not open a connection to your authentication agent.\n");
256 exit(1);
257 }
258
259 for (i = 1; i < argc; i++)
8efc0c15 260 {
5068f573 261 if (strcmp(argv[i], "-l") == 0)
8efc0c15 262 {
5068f573 263 list_identities(ac);
8efc0c15 264 no_files = 0; /* Don't default-add/delete if -l. */
265 continue;
266 }
5068f573 267 if (strcmp(argv[i], "-d") == 0)
8efc0c15 268 {
269 deleting = 1;
270 continue;
271 }
5068f573 272 if (strcmp(argv[i], "-D") == 0)
8efc0c15 273 {
5068f573 274 delete_all(ac);
8efc0c15 275 no_files = 0;
276 continue;
277 }
278 no_files = 0;
279 if (deleting)
5068f573 280 delete_file(ac, argv[i]);
8efc0c15 281 else
5068f573 282 add_file(ac, argv[i]);
8efc0c15 283 }
284 if (no_files)
285 {
286 pw = getpwuid(getuid());
287 if (!pw)
288 {
289 fprintf(stderr, "No user found with uid %d\n", (int)getuid());
5068f573 290 ssh_close_authentication_connection(ac);
8efc0c15 291 exit(1);
292 }
293 snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, SSH_CLIENT_IDENTITY);
294 if (deleting)
5068f573 295 delete_file(ac, buf);
8efc0c15 296 else
5068f573 297 add_file(ac, buf);
8efc0c15 298 }
5068f573 299 ssh_close_authentication_connection(ac);
8efc0c15 300 exit(0);
301}
This page took 0.098148 seconds and 5 git commands to generate.