- key = RSA_new();
- public_key = RSA_new();
- if (!load_public_key(filename, public_key, &saved_comment))
- {
- printf("Bad key file %s: %s\n", filename, strerror(errno));
- return;
- }
- RSA_free(public_key);
-
- pass = xstrdup("");
- first = 1;
- while (!load_private_key(filename, pass, key, &comment))
- {
- /* Free the old passphrase. */
- memset(pass, 0, strlen(pass));
- xfree(pass);
-
- /* Ask for a passphrase. */
- if (getenv("DISPLAY") && !isatty(fileno(stdin)))
- {
-#ifndef DISABLE_EXTERNAL_ASKPASS
- if (pipe(pipes) ==-1)
- {
- fprintf(stderr, "Creating pipes failed: %s\n", strerror(errno));
- exit(1);
- }
- if (fflush(NULL)==EOF)
- {
- fprintf(stderr, "Cannot flush buffers: %s\n", strerror(errno));
- exit(1);
- }
- switch (child=fork())
- {
- case -1:
- fprintf(stderr, "Cannot fork: %s\n", strerror(errno));
- exit(1);
- case 0:
- close(pipes[0]);
- if (dup2(pipes[1], 1) ==-1)
- {
- fprintf(stderr, "dup2 failed: %s\n", strerror(errno));
- exit(1);
- }
- tmp=snprintf(buf, BUFSIZE, "Need passphrase for %s (%s)",
- filename, saved_comment);
- /* skip the prompt if it won't fit */
- if (tmp < 0 || tmp >= BUFSIZE)
- tmp=execlp(ASKPASS_PROGRAM, "ssh-askpass", 0);
- else
- tmp=execlp(ASKPASS_PROGRAM, "ssh-askpass", buf, 0);
- if (tmp==-1)
- {
- fprintf(stderr, "Executing ssh-askpass failed: %s\n",
- strerror(errno));
- exit(1);
- }
- break;
- default:
- close(pipes[1]);
- if ( (pipef=fdopen(pipes[0], "r")) ==NULL)
- {
- fprintf(stderr, "fdopen failed: %s\n", strerror(errno));
- exit(1);
- }
- if(fgets(buf, sizeof(buf), pipef)==NULL)
- {
- xfree(saved_comment);
- return;
- }
- fclose(pipef);
- if (strchr(buf, '\n'))
- *strchr(buf, '\n') = 0;
- pass = xstrdup(buf);
- memset(buf, 0, sizeof(buf));
- if (waitpid(child, NULL, 0) ==-1)
- {
- fprintf(stderr, "Waiting for child failed: %s\n",
- strerror(errno));
- exit(1);
- }
- if (strcmp(pass, "") == 0)
- {
- xfree(saved_comment);
- xfree(pass);
- return;
- }
- }
-#else /* !DISABLE_EXTERNAL_ASKPASS */
- xfree(saved_comment);
- return;
-#endif /* !DISABLE_EXTERNAL_ASKPASS */