2 * Copyright (C) 2014 Red Hat Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 /* There is a program called 'sshpass' which does roughly the same
20 * as this simplified example. We run ssh as a subprocess, and log
21 * in using the given password from the command line.
23 * The first argument is the password to send at the password prompt.
24 * The remaining arguments are passed to the ssh subprocess.
27 * sshpass 123456 ssh remote.example.com
28 * sshpass 123456 ssh -l root remote.example.com
41 #include "miniexpect.h"
43 static pcre *compile_re (const char *rex);
46 main (int argc, char *argv[])
51 pcre *password_re, *prompt_re, *hello_re;
52 const int ovecsize = 12;
53 int ovector[ovecsize];
56 fprintf (stderr, "usage: sshpass PASSWORD ssh [SSH-ARGS...] HOST\n");
62 printf ("starting ssh command ...\n");
64 h = mexp_spawnv (argv[2], &argv[2]);
66 perror ("mexp_spawnv: ssh");
70 /* Wait for the password prompt. */
71 password_re = compile_re ("assword");
72 switch (mexp_expect (h,
74 { 100, .re = password_re },
81 fprintf (stderr, "error: ssh closed the connection unexpectedly\n");
84 fprintf (stderr, "error: timeout before reaching the password prompt\n");
87 perror ("mexp_expect");
90 fprintf (stderr, "error: PCRE error: %d\n", mexp_get_pcre_error (h));
94 /* Got the password prompt, so send a password. */
95 printf ("sending the password ...\n");
97 if (mexp_printf (h, "%s\n", password) == -1) {
98 perror ("mexp_printf");
102 /* We have to wait for the prompt before we can send commands
103 * (because the ssh connection may not be fully established). If we
104 * get "password" again, then probably the password was wrong. This
105 * expect checks all these possibilities. Unfortunately since all
106 * prompts are a little bit different, we have to guess here.
108 prompt_re = compile_re ("[#$]");
109 switch (mexp_expect (h,
111 { 100, .re = password_re },
112 { 101, .re = prompt_re },
115 ovector, ovecsize)) {
116 case 100: /* Password. */
117 fprintf (stderr, "error: ssh asked for password again, probably the password supplied is wrong\n");
119 case 101: /* Prompt. */
122 fprintf (stderr, "error: ssh closed the connection unexpectedly\n");
125 fprintf (stderr, "error: timeout before reaching the prompt\n");
128 perror ("mexp_expect");
130 case MEXP_PCRE_ERROR:
131 fprintf (stderr, "error: PCRE error: %d\n", mexp_get_pcre_error (h));
135 /* Send a command which will have expected output. */
136 printf ("sending a test command ...\n");
138 if (mexp_printf (h, "echo h''ello\n") == -1) {
139 perror ("mexp_printf");
143 /* Wait for expected output from echo hello command. */
144 hello_re = compile_re ("hello");
145 switch (mexp_expect (h,
147 { 100, .re = hello_re },
150 ovector, ovecsize)) {
154 fprintf (stderr, "error: ssh closed the connection unexpectedly\n");
157 fprintf (stderr, "error: timeout before reading command output\n");
160 perror ("mexp_expect");
162 case MEXP_PCRE_ERROR:
163 fprintf (stderr, "error: PCRE error: %d\n", mexp_get_pcre_error (h));
167 /* Send exit command and wait for ssh to exit. */
168 printf ("sending the exit command ...\n");
170 if (mexp_printf (h, "exit\n") == -1) {
171 perror ("mexp_printf");
175 switch (mexp_expect (h, NULL, NULL, 0)) {
177 /* This is what we're expecting: ssh will close the connection. */
180 fprintf (stderr, "error: timeout before ssh closed the connection\n");
183 perror ("mexp_expect");
185 case MEXP_PCRE_ERROR:
186 fprintf (stderr, "error: unexpected return value from mexp_expect\n");
190 /* Close the ssh connection. */
191 status = mexp_close (h);
193 fprintf (stderr, "error: bad exit status from ssh subprocess (status=%d)\n",
198 printf ("test was successful\n");
207 /* Helper function to compile a PCRE regexp. */
209 compile_re (const char *rex)
215 ret = pcre_compile (rex, 0, &errptr, &erroffset, NULL);
217 fprintf (stderr, "error: failed to compile regular expression '%s': %s at offset %d\n",
218 rex, errptr, erroffset);