Controlling ssh from an external C program - Code Follows
From: Jeff Anderson (jander_at_hundredacrewood.org)
Date: 10/23/04
- Previous message: C. Linus Hicks: "Re: port forwarding and oracle"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: secureshell@securityfocus.com Date: Fri, 22 Oct 2004 19:42:20 -0400
Earlier, I had asked the list for any suggestions on how to control ssh from
an external program without using expect. Since this seems to be a topic that
comes up frequently, I will share what I have found (maybe this could be
added to a FAQ?)
I would like to thank everyone who has sent suggestions to me -
Here are the solutions offered:
Expect and/or like expect modules for perl/python
Net::SSH::Perl (available from CPAN - I had actually prototyped my app in Perl
using this. However, the final version of the app needs to be in C)
Empty passphrase keypairs (however, does not allow for systems which no
keypair exists)
ssh-agent: (Same problem as above)
Here is my final solution: I am apologizing in advance ;-)
Suggestions for improvement welcome (as well as any case I hadn't thought of)
/* sshopen.c */
#include <pty.h>
#include <stdio.h>
#include <unistd.h>
#include <utmp.h>
#define MAX 4096
// You will need to do a close from your external calling program
// from you main program alll you need to do is:
// if((ssh=sshopen(argv[1], argv[2], argv[3], argv[4])) == NULL ) {
// printf("Error opening %s\n", argv[2]);
// exit(1);
// }
//
// while(fgets(buff, MAX, ssh) != NULL ) {
// printf("line: "); /* do something */
// printf("%s\n",buff);
// }
FILE *sshopen( char *username, char *host, char *rcommand, char *pass) {
int fd, count;
pid_t pid;
char buffer[MAX];
char target[MAX];
char tmpchar[2];
char remotecmd[MAX];
FILE *sshcmd;
// Build the command options
strcpy(target, username);
strcat(target, "@");
strcat(target, host);
strcpy(remotecmd,"echo __Found__ ; ");
strcat(remotecmd, rcommand);
pid = forkpty(&fd, 0, 0, 0);
if (pid == 0) {
execlp("ssh", "ssh", target, remotecmd, (void *)0);
exit(1);
} else if (pid == -1) {
return (FILE *)NULL;
} else {
sshcmd=fdopen(fd, "a+");
strcpy(buffer,"\0");
// Read 1 char at a time and build up a string
// This will wait forever until "__Found__" is found... Adjust as necessary
count=0;
while((fgets(tmpchar, 2, sshcmd) != NULL ) && (count++ <
MAX)){
strcat(buffer, tmpchar);
if ((int *)strstr(buffer,"ssword:") != NULL) {
fprintf(sshcmd, pass);
fprintf(sshcmd, "\n");
fflush(sshcmd);
// reset search string
strcpy(buffer,"\0");
}
if ((int *)strstr(buffer,"connecting (yes/no)?") !=
NULL) {
fprintf (sshcmd,"yes\n");
fflush (sshcmd);
// reset search string
strcpy(buffer,"\0");
}
if ((int *)strstr(buffer,"Enter passphrase") != NULL)
{
fprintf(sshcmd, pass);
fprintf(sshcmd, "\n");
fflush(sshcmd);
// reset search string
strcpy(buffer,"\0");
}
if ((int *)strstr(buffer,"No route to host") != NULL)
{
fclose(sshcmd);
return (FILE *)NULL;
}
if ((int *)strstr(buffer,"Permission denied") != NULL)
{
fclose(sshcmd);
return (FILE *)NULL;
}
if ((int *)strstr(buffer,"Connection refused") !=
NULL) {
fclose(sshcmd);
return (FILE *)NULL;
}
if ((int *)strstr(buffer,"__Found__") != NULL) {
printf("found it\n");
return (FILE *)sshcmd;
}
}
}
}
=====================================================
Jeff Anderson
- Previous message: C. Linus Hicks: "Re: port forwarding and oracle"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]