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"
44 compile_re (const char *rex)
50 ret = pcre_compile (rex, 0, &errptr, &erroffset, NULL);
52 fprintf (stderr, "error: failed to compile regular expression '%s': %s at offset %d\n",
53 rex, errptr, erroffset);
60 main (int argc, char *argv[])
65 pcre *password_re, *prompt_re, *hello_re;
66 const int ovecsize = 12;
67 int ovector[ovecsize];
71 fprintf (stderr, "usage: sshpass PASSWORD ssh [SSH-ARGS...] HOST\n");
77 printf ("starting ssh command ...\n");
79 h = mexp_spawnv ("ssh", &argv[2]);
81 perror ("mexp_spawnv: ssh");
85 /* Wait for the password prompt. */
86 password_re = compile_re ("assword");
87 switch (mexp_expect (h, password_re, NULL, 0, ovector, ovecsize, &pcre_err)) {
89 fprintf (stderr, "error: ssh closed the connection unexpectedly\n");
92 perror ("mexp_expect");
95 fprintf (stderr, "error: timeout before reaching the password prompt\n");
98 fprintf (stderr, "error: PCRE error: %d\n", pcre_err);
104 /* Got the password prompt, so send a password. */
105 printf ("sending the password ...\n");
107 if (mexp_printf (h, "%s\n", password) == -1) {
108 perror ("mexp_printf");
112 /* We have to wait for the prompt before we can send commands
113 * (because the ssh connection may not be fully established). If we
114 * get "password" again, then probably the password was wrong. This
115 * expect checks all these possibilities. Unfortunately since all
116 * prompts are a little bit different, we have to guess here.
118 prompt_re = compile_re ("(assword)|([#$])");
119 switch (mexp_expect (h, prompt_re, NULL, 0, ovector, ovecsize, &pcre_err)) {
121 fprintf (stderr, "error: ssh closed the connection unexpectedly\n");
124 perror ("mexp_expect");
127 fprintf (stderr, "error: timeout before reaching the prompt\n");
129 case MEXP_PCRE_ERROR:
130 fprintf (stderr, "error: PCRE error: %d\n", pcre_err);
133 /* Which part of the regexp matched? */
134 if (ovector[2] >= 0) { /* password */
135 fprintf (stderr, "error: ssh asked for password again, probably the password supplied is wrong\n");
138 else if (ovector[4] >= 0) { /* prompt */
142 abort (); /* shouldn't happen */
145 /* Send a command which will have expected output. */
146 printf ("sending a test command ...\n");
148 if (mexp_printf (h, "echo h''ello\n") == -1) {
149 perror ("mexp_printf");
153 /* Wait for expected output from echo hello command. */
154 hello_re = compile_re ("hello");
155 switch (mexp_expect (h, hello_re, NULL, 0, ovector, ovecsize, &pcre_err)) {
157 fprintf (stderr, "error: ssh closed the connection unexpectedly\n");
160 perror ("mexp_expect");
163 fprintf (stderr, "error: timeout before reading command output\n");
165 case MEXP_PCRE_ERROR:
166 fprintf (stderr, "error: PCRE error: %d\n", pcre_err);
172 /* Send exit command and wait for ssh to exit. */
173 printf ("sending the exit command ...\n");
175 if (mexp_printf (h, "exit\n") == -1) {
176 perror ("mexp_printf");
180 switch (mexp_expect (h, NULL, NULL, 0, NULL, 0, NULL)) {
182 /* This is what we're expecting: ssh will close the connection. */
185 perror ("mexp_expect");
188 fprintf (stderr, "error: timeout before ssh closed the connection\n");
190 case MEXP_PCRE_ERROR:
192 fprintf (stderr, "error: unexpected return value from mexp_expect\n");
196 /* Close the ssh connection. */
197 status = mexp_close (h);
199 fprintf (stderr, "error: bad exit status from ssh subprocess (status=%d)\n",
204 printf ("test was successful\n");