password from stdin through some C program.

I have an utility named setsqlnk
which takes verious input
as well as password.

This utility stores the information
read by the script in one ini file.
The password is stored in encrypted
manner.
I want to use this utility setsqlnk
from a C program. This means I want
to give the inputs through a file
and redirecting it to the stdin of the
utility.
i.e. setsqlnk < inpfilename

When I does so, it just escape the password entry.

Is there any mean to do so ? I mean can I run this utility through some other b/g process without entering the password from keyboard.

Thanks in advance.

Note : I don't think the utility is using
crypt command to encrypt the password.
OS : Linux 2.2.12-20
LVL 2
basantAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

rbrCommented:
use

FILE *pf;

pf=popen ("setsqlng < inpfilenne","r");

Now you can read the output of the programm setsqlng by using the FILE-pointer pf.

0
basantAuthor Commented:
Sorry rbr,
  Either u didn't read the question
properly or I was not able to explain my question properly.

Question is not that I was not able to read the output. The question is how will I pass the password to utility setsqlnk. The input redirection < 
works for other inputs but fails for the password entry.
0
ozoCommented:
man pty
man expect
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

basantAuthor Commented:
Dear ozo, Thanks for telling about
the utility expect.
I tried the utility and run
the following commands :

spawn setsqlnk
send "2\n"
send "Trail3\n"
send "Trialjdf\n"
send "Hello\n"
send "1\n"
send "dev-31\n"
send "4\n"
send "sa\n"
send "hello\n"
send "12\n"
send "SLSocket\n"
send "sales-05\n"
send "0\n"
send "0\n"
exit

Note that "sa" is the username and
"hello" is the password. This worked when I tried this utility from command
line shell.
But when I tried to run the utility
by typing these commands in file and
running :
expect -f filename

I found out that my original program
setsqlnk is waiting on password itself.

Can u suggest something.
Meanwhile I am trying to use 'C' program
to do the same. Hope I get some success.
~
0
basantAuthor Commented:
Dear ozo, Thanks for telling about
the utility expect.
I tried the utility and run
the following commands :

spawn setsqlnk
send "2\n"
send "Trail3\n"
send "Trialjdf\n"
send "Hello\n"
send "1\n"
send "dev-31\n"
send "4\n"
send "sa\n"
send "hello\n"
send "12\n"
send "SLSocket\n"
send "sales-05\n"
send "0\n"
send "0\n"
exit

Note that "sa" is the username and
"hello" is the password. This worked when I tried this utility from command
line shell.
But when I tried to run the utility
by typing these commands in file and
running :
expect -f filename

I found out that my original program
setsqlnk is waiting on password itself.

Can u suggest something.
Meanwhile I am trying to use 'C' program
to do the same. Hope I get some success.
~
0
jlevieCommented:
I don't think you've done your expect script correctly. My guess is that your program outputs a prompt and waits for an answer. If I had the following on the screen from an interactive program:

levie> gork
Username: mildred
Password: ******
levie>

I'd need an expect script that would look like:

#!/usr/local/bin/expect
# Interact with gork
#
spawn gork
expect "Username: "
send "mildred\r"
expect "Password: "
send "the-password\r"
send_user "\n"

Note that I send the data terminated by a carriage return, not a newline. That's what would have been sent if you were interacting directly.
0
basantAuthor Commented:
Dear Jlevie,
  Thanks for ur comment.
But as I wrote things works
when I use the expect utility in
command line and sends different strings one by one but when I try to send the same thing by typing the same commands in a file. The utility just
waits at the password.

Another point is :
At the time of asking passwords, the
echo remains off, similar to su
utility.

Any more comment is welcome.
Can u send me some 'C' source code of the expect utility. I mean can u tell where can I find that.
0
jlevieCommented:
And the difference is that when you use expect from the command line you are sending a carriage return (\r), but in your script you told it to use a new-line (\n). They are not even close to being the same thing and the special mode the program is in when it's expecting the password cares which is used.
0
basantAuthor Commented:
But I used \n in both the command line
and in script. It worked in command line mode of except but it failed with filename of except. ( I mean except -f filename). I didn't use \r.

Can u please explain what is happening when I use redirection operator <.
Why does it skip password. I think this is certainly related with terminal i/o. We tried to trap system calls using strance.

This is the output from strace when I use redirection <. It shows that it calls ioctl with TCGETS option.

[pid  8536] write(1, "*Password[*****] :", 17) = 17
[pid  8536] _llseek(0, -27, 0xbfffe3e0, 0x4017c48c /* SEEK_??? */) = -1 EINVAL (Invalid argument)                               [pid  8536] ioctl(0, TCGETS, 0xbfffe314 ) = -1 EINVAL (Invalid argument)
[pid  8536] write(1, "\n", 1)           = 1

0
jlevieCommented:
I might be off track with the \r, but other programs that I've had to script that required an interactive password (no echo, prints "*"s, typical stuff) won't take the password if it's terminated with a new-line, but will if it's terminated with "\r". Did you try using "\r's?

Okay as to input redirection with "<". The program is changing modes on its tty to turn off echo, etc. Since redirection is acutally a file and not a tty the I/O calls to set these modes aren't available and it fails.
0
basantAuthor Commented:
Dear jlevie, Thanks for ur comments.

There was not difference in \n and
in \r atleast in my case.
However I got a lot of success.
The problem was solved using sleep.

Actually before and after password,
I need to put sleep which result in
scheduling of actual utility setsql.

Also I used sleep 2; and interact; call to flush the output.

spawn setsqlnk; send "2\n";
send "Arbit1\n";
send "Trialjdf\n";
send "Hello\n";
send "1\n";
send "dev-31\n";
send "4\n";
send "sa\n";
sleep 2;
send "hello\n";
sleep 2;
send "12\n";
send "SLSocket\n";
send "sales-05\n";
send "0\n";
send "0\n";
sleep 2;
interact;
exit;


However this solution of using sleep
doesn't seems to be perfect. I need to use some of the wait calls to that process. Can u suggest that how to know that the process has read the inputs which expect has sent it.
Also before exit, it need to do the same
otherwise the utility just closes without completing the task.

I guess that "send" just copies the
data in the stdin of the process but
it don't wait for the other process to read it. That's why the things were working with command line and was not working with command file.
What is ur opinion.

I will grade this question soon.
0
jlevieCommented:
Okay, I stand corrected, it wasn't the difference between "\r" and "\n". The reason the the sleep made it work in the scripted version is that it is giving the setsqlnk utility time to process the data, but that's not a good (or reliable) way to do it.

Doesn't setsqlnk prompt for input? I would expect that it output's some prompt and waits for you to type in the response. Referring back to the simple example in one of my previous comments, I said that given a utility that has a screen display of:

levie> gork
Username: mildred
Password: ******
levie>

I could use an expect script to talk to it. The operative part (and what's different about my script) is that I expect something from the spawned program "expect "Username: "" and once I've seen that I "send "mildred\n"". This locks the spawned program and the input in sequence, making expect wait for the prompt before supplying the answer, just like you'd do on the command line.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ozoCommented:
you probablly need an
expect «prompt»;
before the
send «password»
0
basantAuthor Commented:
Hi ozo and jlevie,

by using expect and wait internal commands of expect utility I have removed the two
sleep statements. So my new Code is like this :


spawn setsqlnk;
send "2\n";
send "Arbit9\n";
send "Trialjdf\n";
send "Hello\n";
send "1\n";
send "dev-31\n";
send "4\n";
expect "User"
send "sa\n";
expect -ex "Password\[*****\]:"
sleep 2;
send "hello\n";
expect "The following service"
send "12\n";
expect "Name"
send "SLSocket\n";
send "sales-05\n";
expect "Select an action"
send "0\n";
wait;
exit;




but still if I remove the sleep statement my expect thing stops working and my setsqlnk utility remains still waiting for Password.

I am not able to understand that even though the expect got the prompt "Password[**]" Why should it give chance the utility setsqlnk to run ( this will be the result of sleep , I think so)
0
jlevieCommented:
Getting closer... each of the "send somethings" in the script needs to be preceeded by an "expect something". The whole idea of expect is to exactly duplicate what you'd see and when you'd respond if you were running the utility interactively. I think that the program output on the screen looked something like:

User sa
Password ******

The expect script for that portion would look like:

expect "User "
send "sa\r"
expect "Password "
send "some-password\r"

Note that I'm not asking the expect program to wait for "Password ******". The prompt was "Password" and the "*****" were the hidden password you typed in.

Let's make this easy. If you'll run the program interactively and type into a comment exactly what you see on the screen, I'll write you an expect script that ought to work.
0
basantAuthor Commented:
Hi ozo and jlevie,

by using expect and wait internal commands of expect utility I have removed the two
sleep statements. So my new Code is like this :


spawn setsqlnk;
send "2\n";
send "Arbit9\n";
send "Trialjdf\n";
send "Hello\n";
send "1\n";
send "dev-31\n";
send "4\n";
expect "User"
send "sa\n";
expect -ex "Password\[*****\]:"
sleep 2;
send "hello\n";
expect "The following service"
send "12\n";
expect "Name"
send "SLSocket\n";
send "sales-05\n";
expect "Select an action"
send "0\n";
wait;
exit;




but still if I remove the sleep statement my expect thing stops working and my setsqlnk utility remains still waiting for Password.

I am not able to understand that even though the expect got the prompt "Password[**]" Why should it give chance the utility setsqlnk to run ( this will be the result of sleep , I think so)
0
basantAuthor Commented:
Dear jlevie,
  Sorry my comment reappeared as by mistake I set refresh scren in my browser which posted the comment again.
Sorry it happened twice.

Well Coming to the point :

See the trial shell script named inp:
#!/bin/sh
printf "\n Enter some value [**0]: "
stty -echo
read aVal
stty echo
printf "\n The Value is $aVal"
printf "\n"


If u want to run this shell script using expect :

spawn -noecho inp
expect -ex "some value \[**0\]:"
send_tty "\n Spawn Id is $spawn_id"
exp_pid -i $spawn_id
send "56\n";
expect "The Val" {
    stty -echo
}
send_tty "\n End of script\n"
exit;

This works fine but this is not the
case of with my orignal utility setsqlnk. This setsqlnk is a script which actually start a process which is an executable named sqlnkcau.


>Note that I'm not asking the expect >program to wait for "Password ******". >The prompt was "Password" and the >"*****" were the hidden password you >typed in.

I think, there is a communication gap here. When the executable asks for a password, it set the echo off similar to su command. No * appears when u really type the password.
However the string prompting for password is : "Password[*****]:" [ These * appears as a prompt, not when the user types.

Thus The command
expect -ex "Password\[*****\]:"
returns success immediately.
But without sleep after this prompt, it doesn't work. I don't understand why ?
0
jlevieCommented:
Now I understand what's happening.

I've been thinking that setsqlnk was program (you called it a utility in the question). Now I find that it's not an actual program, but instead it's a shell script that gathers data and uses that data in the execution of an actual binary... That explains why you could get it to work with a sleep (gives the sqlnkcau time to start) and also exlains why everthing isn't synching up via the expect/send sequence.

Am I correct in assuming that it's sqlnkcau that prompts for the username & password? What else does setsqlnk do?

I can think of several ways to solve this, but to be able to offer a solution I probably need to know what setsqlnk does and what sqlnkcau does.
0
basantAuthor Commented:
I am sorry that I was not able to communicate the problem properly.

OK following is the setsqlnk shell script.

#!/bin/sh
if [ -f /opt/bk/casp/asp-apache-3476/odbc.ini ]; then
      . /opt/bk/casp/chsetup.sh
      . /opt/bk/casp/asp-apache-3476/odbc.sh

      cd /opt/bk/casp/odbc/sqlnk/bin
      ./sqlnkcau
else
      echo "setsqlnk: No odbc.ini found in /opt/bk/casp/asp-apache-3476."
fi


Thus this utility does not do much but run another shell script odbc.sh & chsetup.sh and then run the executable sqlnkcau.

Note that all the input reading comes from the executable , not the shell script including password.

These shell scripts only setup the envirionment e.g. proper env Variable setup like LD_LIBRARY_PATH and so.

Regarding ur comment :
>That explains why you could get it to >work with a sleep (gives the sqlnkcau >time to start) and also exlains why >everthing isn't synching up via the >expect/send sequence.

Well I do think that one can send many inputs simultaneously and then may expect for some inputs. Do u mean to say that my
expect -ex "Password\[*****\]:"
fails. If it is successful then the sqlnkcau has already written this string and now it is waiting for input in read system call. Amn't I correct.
0
basantAuthor Commented:
Dear jlevie,
   I tried to run the program sqlnkcau directly with expect even though the result is same. I mean it doesn't work without the sleep statement.
With sleep it works just perfect.
0
jlevieCommented:
How about running sqlnkcau interactively (in a terminal window) and putting exactly what is on the screen into a comment so I can see it. I'd like to see everything from the shell prompt line where you execute sqlnkcau to the shell prompt after it is done, like:

user> sqlnkcau
....
.... lines of
.... ineraction
.... with sqlnkcau
....
user>
0
basantAuthor Commented:
I will post it soon.
Basant.
0
basantAuthor Commented:
Dear jlevie,
   I tried to write the 'C' program using libexpect there I used the same thing what I was doing in utility but even in 'C' programme, if I don't go for sleep, the same thing happens.

However I solved the problem by calling strace utility to the sqlnkcau. when strace utility shows that it is waiting at read then I kill the strace utility and then use expect and send and then it works.

Here is the partial code :

int WriteNewSQLDSN( vector<string>& vecCmds, const string& strDir)
{
      int fd1, fd2;
      char szBuf[80];

      exp_loguser = 1;
      exp_timeout = 3600;
      string strSetSqlnkPath= strDir;
      strSetSqlnkPath += "/setsqlnk";
      fd1 = exp_spawnl( (char*) strSetSqlnkPath.c_str() ,
                  "setsqlnk", (char*) 0 );
      cout << "\n pid = " << exp_pid;
      cout << "\n Enter the sqlcau pid :";
      int nActPid;
      //cin >> nActPid;
      /*
      char* pCmd[20] = {
                  "2\r",
                  "Arbit9\r",
                  "Trialjdf\r",
                  "Hello\r",
                  "1\r",
                  "dev-31\r",
                  "4\r",
                  "sa\r",
                  "hello\r\n",
                  "12\r",
                  "SLSocket\r",
                  "sales-05\r",
                  "0"
                  };
      */
      cout << "\n before expectl ";
      cout.flush();
      if (-1 == exp_expectl(fd1, exp_exact,"Select an action",0,
                        exp_end))      
      {
            cout << "\n exp_expectl failed ";
            cout.flush();
            return -1;
      }
      nActPid = ReadSqlcauPid();
      cout << "\n after expectl ";
      cout.flush();
      int nIndex = 0;
      for( nIndex = 0; nIndex < 7; ++nIndex)
      {
          if (-1 == write(fd1,vecCmds[nIndex].c_str() ,strlen(
                                    vecCmds[nIndex].c_str() ) ))
            {
                  cout << "\n write failed";
                  return -1;
            }
      }
      if (-1 == exp_expectl(fd1, exp_exact,"User",0,
                        exp_end))      
      {
            cout << "\n exp_expectl failed ";
            cout.flush();
            return -1;
      }
    if (-1 == write(fd1,vecCmds[nIndex].c_str() ,strlen(
                                    vecCmds[nIndex].c_str()) ))
      {
            cout << "\n write failed";
            return -1;
      }
      ++nIndex;

      if (-1 == exp_expectl(fd1, exp_exact,"Password[*****]:",0,
                        exp_end))      
      {
            cout << "\n exp_expectl failed ";
            cout.flush();
            return -1;
      }
      RunStrace( nActPid);
      cout << "\n After Password prompt";
      cout.flush();
    if (-1 == write(fd1,vecCmds[nIndex].c_str() ,strlen(
                  vecCmds[nIndex].c_str()) ))
      {
            cout << "\n write failed";
            return -1;
      }
      ++nIndex;
      cout << "\n After Password write";
      cout.flush();

      if (-1 == exp_expectl(fd1, exp_exact,"The following service", 0,
                        exp_end))      
      {
            cout << "\n exp_expectl failed ";
            cout.flush();
            return -1;
      }
      for( ; nIndex < 12; ++nIndex)
      {
          if (-1 == write(fd1,vecCmds[nIndex].c_str() ,strlen(
            vecCmds[nIndex].c_str()) ))
            {
                  cout << "\n write failed";
                  return -1;
            }
      }
      if (-1 == exp_expectl(fd1, exp_exact,"Select an action", 0,
                        exp_end))      
      {
            cout << "\n exp_expectl failed ";
            cout.flush();
            return -1;
      }
    if (-1 == write(fd1,vecCmds[nIndex].c_str() ,strlen(
                                    vecCmds[nIndex].c_str()) ))
      {
            cout << "\n write failed";
            return -1;
      }
      /*
      cout << "\n Enter some number :";
      int nNumber;
      cin >> nNumber;
      int n = read(fd1,szBuf,80);
      if( n > 0 )
      {
            szBuf[n]='\0';
            cout << "Output = " <<szBuf;
      }
      */
      cout << "\n End of Program";
return 0;      
}

main()
{
      string strDir = "/opt/bk/casp/asp-apache-3476";
      char* pCmd[20] = {
                  "2\r",
                  "Arbit9\r",
                  "Trialjdf\r",
                  "Hello\r",
                  "1\r",
                  "dev-31\r",
                  "4\r",
                  "sa\r",
                  "hello\r\n",
                  "12\r",
                  "SLSocket\r",
                  "sales-05\r",
                  "0"
                  };
      int nNoOfArg = 13;
      int nIndex = 0;
      vector<string> vecArgs( nNoOfArg );
      for( nIndex = 0; nIndex < nNoOfArg; ++nIndex)
      {
            vecArgs[nIndex] = pCmd[nIndex];
      }
      WriteNewSQLDSN( vecArgs, strDir) ;
}



Anyway I should give points to u. If u have something to comment then u can write.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.