Controlling a child's stdin/stdout (not working with scp)


 
Thread Tools Search this Thread
Top Forums Programming Controlling a child's stdin/stdout (not working with scp)
# 1  
Old 03-10-2010
Controlling a child's stdin/stdout (not working with scp)

All,

Ok...so I know I *should* be able to control a process's stdin and stdout from the parent by creating pipes and then dup'ing them in the child. And, this works with all "normal" programs that I've tried. Unfortunately, I want to intercept the stdin/out of the scp application and it seems scp is actively refusing to allow me to. The code is:

Code:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main()
{
	char	usr[32];
	char	host[32];
	char	remote_path[64];
	char	local_path[64];
	
	int	outfd[2];
	int	infd[2];
	
	/* set usr/host/remote_path/local_path to something meaningful */
	
	/* create pipes for stdin/out to dup in the child */	
	
	pipe(outfd); /* Where the parent is going to write to */
	pipe(infd); /* From where parent is going to read */
	
	if(!fork())
	{
		char	cmd[1024];
		
		/* child, close stdin/out and use parent pipes instead */
			
		close(STDOUT_FILENO);
		close(STDIN_FILENO);
		
		dup2(outfd[0], STDIN_FILENO);
		dup2(infd[1], STDOUT_FILENO);
		
		/* close all pipe ends, needed end has been dup'd other end
		     is not needed */
		     
		close(outfd[0]);
		close(outfd[1]);
		close(infd[0]);
		close(infd[1]);
		
		/* execute scp */
		
		sprintf(cmd, "scp %s@%s:%s %s",
			usr, host, remote_path, local_path);
		
		return system(cmd);
	}

	/* parent */
	
	char input[100];
		
	close(outfd[0]); /* These are being used by the child */
	close(infd[1]);
	
	input[read(infd[0],input,100)] = 0; /* Read from child's stdout */
	
	printf("%s",input);

	/* once I can actually read/write to scp here, I'll have to determine if this is
	     the password prompt or the "add to host key file" prompt and respond
	     accordingly. */
	
	close(outfd[1]);
	close(infd[0]);
}

I know the code works if I use something other than scp, I can write and read to the pipes all day long and control the process as desired. But, it seems that scp is specifically figuring out what the controlling terminal of the process is and actively refusing to co-operate with my pipes.

I then thought maybe I could try to "disown" the terminal by calling "setsid()" right before invoking scp (and tried it right after the fork). Well, that "works," but then the stupid thing connects to my X server and pops up a box to ask for the password. Of course, preventing scp from asking me anything is the exact reason I want to control the standard in of the process so I can funnel the password in through there.

So...does any one have another idea how I can redirect stdin/stdout for this most difficult process? It seems I'll actually need to "hook into" the terminal directly since scp is "so smart." Indeed, I believe scp may be openning up its own connection to the terminal to get input and send output....

Thanks....

P.S. I know there is a better way to do this, like creating the ssh keys so scp never asks for passwords to begin with. Unfortunately, the environment where I'm trying to use this disallows this. They want us to enter passwords every time and this "stupid" rule is circumventing my ability to automate tasks through scp; of course ftp is also taboo. So...I want this "scp wrapper" to read my local password file and just pass it through so I can get back to my regularly scheduled automation. Otherwise, I'll have to enter the passwords again and again while the scripts run...and that's just...well...pointless.
# 2  
Old 03-10-2010
Yes, it does, and no, it won't let you, and that's for a reason -- stored passwords are not only inherently dangerous but completely unnecessary. Use shared keys, that's what they're there for. There's instructions for them plastered all over the internet and you can use them in ways that obey the spirit and letter of that rule -- give the shared key a password and use ssh-agent. That way you need to type the password once, to get the key, after which you can use the key to login automatically until your ssh-agent session finishes.
# 3  
Old 03-10-2010
scp, sftp, and ssh are specifically engineered to stop what you are trying to do.
Corona is being kind. If you do not want to create ssh keys, then use ftp or commands like rcp. Don't make something insecure out of something that works hard to be secure.
# 4  
Old 03-11-2010
Corona: There are 50+ hosts that this script needs to transfer files to/from. Each host has a different user/password. That user is the only one with access to the files I need to remote copy (besides root, of course). Can shared keys help here? The way I understand it, shared keys allow one user access to several hosts. They are tied to the user id. That won't help if this is true.

Jim: ftp/rcp are blocked, they aren't secure. Of course, neither is a password dictionary; but if you knew our password policy (and read above about the number of accounts all with disparite passwords), you'd realize everyone keeps them anyway. So...our security policy is so secure that it's insecure, lol. I'd just be making life easier if I could make this work.
# 5  
Old 03-11-2010
You generate one key only - on the box you intend to do all the connections from.
Place the public key on all 50 remote boxes. Voila! ssh anyboxinthelist or sftp anyboxinthelist works magically. No passwords required.

Hereis how to do it:
ssh-keygen: password-less SSH login

Oh & when you are generating the key DO NOT enter any passphrase, just press return.
# 6  
Old 03-11-2010
Quote:
Originally Posted by jim mcnamara
You generate one key only - on the box you intend to do all the connections from.
Place the public key on all 50 remote boxes. Voila! ssh anyboxinthelist or sftp anyboxinthelist works magically. No passwords required.

Hereis how to do it:
ssh-keygen: password-less SSH login

Oh & when you are generating the key DO NOT enter any passphrase, just press return.
I got that, but I still don't see anything that says this works for multiple accounts. So, if I'm logged in to box1 as "dreamwarrior" and do the ssh-keygen, then I put the key file on box2 and try to do: "ssh user1@box2" it won't see "dreamwarrior's" key. Or am I misunderstanding something here? Can I put the "dreamwarrior" key on box2 in a location that allows ssh for ANY user? I would love it if "ssh box2" as dreamwarrior would work, but the fact is the "dreamwarrior" account on box2 won't have access to the "user1" files I need, so the scp will fail for permissions.
# 7  
Old 03-11-2010
You put your dreasmwarrior key into the directory (.ssh) for the user you want to be. e.g., whoever.
then
Code:
ssh whoever@remotebox
#or
sftp whoever@anotherbox

You are now whoever, not dreamwarrior, on the remote box. So all you have to keep straight is what username goes with what remote box.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

[stdin / stdout] Strategies for redirecting outputs

Well.. let's say i need to write a pretty simple script. In my script i have 2 variables which can have value of 0 or 1. $VERBOSE $LOG I need to implement these cases: ($VERBOSE = 0 && $LOG = 0) => ONLY ERROR output (STDERR to console && STDOUT to /dev/null) ($VERBOSE = 1... (5 Replies)
Discussion started by: Marmz
5 Replies

2. Shell Programming and Scripting

Controlling the Number of Child processes

I am trying to implement the below using Ksh script on a Lx machine. There is a file(input_file) with 100K records. For each of these records, certain script(process_rec) needs to be called with the record as input. Sequential processing is time-consuming and parallel processing would eat up... (2 Replies)
Discussion started by: APT_3009
2 Replies

3. UNIX for Dummies Questions & Answers

STDIN and STDOUT

Hallo, i have a script like: if ;then echo "OK" else echo "ERROR $2 is missing" fi; if ;then touch $2 fi; if ;then cat $1 | grep xy > $2 (1 Reply)
Discussion started by: eightball
1 Replies

4. Programming

read and write stdin/stdout in unix

Hi, i am using the below program to read from the standard input or to write to standard out put. i know that using highlevel functions this can be done better than what i have done here. i just want to know is there any other method by which i find the exact number of characters ( this... (3 Replies)
Discussion started by: MrUser
3 Replies

5. Shell Programming and Scripting

Redirecting stdin/stdout to/from command from/to string

Hi, I am working on a project where I have to generate and execute nasm code on-the-fly. I generate the code in a file program.asm and then execute it.This output is to stdout which i redirect to an output file which i read back to compare results: system("nasm -f elf program.asm >... (5 Replies)
Discussion started by: doc_cypher
5 Replies

6. Shell Programming and Scripting

can't close stdin/stdout in shell

#!/bin/sh exec 0</dev/null exec 1>/dev/null ls -l /proc/self/fd >&2 produces total 0 lr-x------ 1 tyler users 64 Feb 18 10:38 0 -> /proc/7886/fd lrwx------ 1 tyler users 64 Feb 18 10:38 1 -> /dev/pts/4 lrwx------ 1 tyler users 64 Feb 18 10:38 2 -> /dev/pts/4 I've verified the shell is... (10 Replies)
Discussion started by: Corona688
10 Replies

7. UNIX for Dummies Questions & Answers

Redirect stdin stdout to multiple files

Hi, i know how to a) redirect stdout and stderr to one file, b) and write to two files concurrently with same output using tee command Now, i want to do both the above together. I have a script and it should write both stdout and stderr in one file and also write the same content to... (8 Replies)
Discussion started by: ysrini
8 Replies

8. Programming

stdout/stdin + flushing buffers

Hi all I've run into a snag in a program of mine where part of what I entered in at the start of run-time, instead of the current value within printf() is being printed out. After failing with fflush() and setbuf(), I tried the following approach void BufferFlusher() { int in=0;... (9 Replies)
Discussion started by: JamesGoh
9 Replies

9. Programming

C++ How to use pipe() & fork() with stdin and stdout to another program

Hi, Program A: uses pipe() I am able to read the stdout of PROGAM B (stdout got through system() command) into PROGRAM A using: * child -> dup2(fd, STDOUT_FILENO); -> execl("/path/PROGRAM B", "PROGRAM B", NULL); * parent -> char line; -> read(fd, line, 100); Question:... (2 Replies)
Discussion started by: vvaidyan
2 Replies

10. Programming

Controlling child processes

Hello all, I am trying to create n child processes and control them from a parent process; say make child 3 print its pid and then child 5 do the same and some other stuff. Is there a way to accomplishing this after all the child processes are created via a call to fork(). Thank you, FG (23 Replies)
Discussion started by: forumGuy
23 Replies
Login or Register to Ask a Question