OSDN Git Service

b7fc927d679bfb8c918a0818078ee863bfbbb8f2
[openpts/openpts.git] / src / ssh.c
1 /*
2  * This file is part of the OpenPTS project.
3  *
4  * The Initial Developer of the Original Code is International
5  * Business Machines Corporation. Portions created by IBM
6  * Corporation are Copyright (C) 2011 International Business
7  * Machines Corporation. All Rights Reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the Common Public License as published by
11  * IBM Corporation; either version 1 of the License, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * Common Public License for more details.
18  *
19  * You should have received a copy of the Common Public License
20  * along with this program; if not, a copy can be viewed at
21  * http://www.opensource.org/licenses/cpl1.0.php.
22  */
23
24 /**
25  * \file src/ssh.c
26  * \brief SSH conenction
27  * @author Olivier Valentin <olivier.valentin@us.ibm.com>
28  * @author Alexandre Ratchov <alexandre.ratchov@bull.net>
29  * @date 2010-03-31
30  * cleanup 2011-04-26 SM
31  *
32  */
33
34 #include <unistd.h>
35 #include <limits.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <fcntl.h>
40 #include <sys/socket.h>
41
42 #include <openpts.h>
43 // #include <log.h>
44
45 /* chanegd by unit test */
46 char *ptsc_command = "/usr/sbin/ptsc -m";
47
48 /** 
49  * ssh_connect
50  *
51  * opens a communication channel (a socket) to a target using ssh.
52  * 
53  * @param host host name of the target. Is used as the SSH host name parameter.
54  * @param ssh_username If not NULL, specifies the SSH user name to login as
55  *        (defaults to the current user).
56  * @param ssh_port If not 0, specifiesd the port of the remote SSH daemon.
57  * @param key_file If not NULL, specifies the key to use.
58  * @param socket Filed with the result socket. Use it for later communication.
59  * @result the PID of the child SSH process or -1 in case of an error.
60  */
61 pid_t ssh_connect(char *host, char *ssh_username, char *ssh_port, char *key_file, int *socket) {
62     pid_t pid;
63     int socket_pair[2];  // socket[1] is the SSH side
64
65
66     if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair) == -1) {
67         ERROR("socketpair()");
68         goto err;
69     }
70
71     if ((pid = fork()) == -1) {
72         ERROR("fork()");
73         goto err_close;
74     }
75
76     if (pid == 0) {
77         // child process
78         char *arguments[16];
79         int arg_idx = 0;
80         char identity_string[PATH_MAX + /* "IdentityFile " */ 13];
81
82         // these belong to father
83         close(socket_pair[0]);
84         close(0);
85         close(1);
86
87         // replace stdin and stdout with the socket end
88         dup2(socket_pair[1], 0);
89         dup2(socket_pair[1], 1);
90         close(socket_pair[1]);  // no longer needed
91
92         arguments[arg_idx++] = "ssh";
93         arguments[arg_idx++] = "-2";
94         if (ssh_username != NULL) {
95             arguments[arg_idx++] = "-l";
96             arguments[arg_idx++] = ssh_username;
97         }
98         if (ssh_port != NULL) {
99             arguments[arg_idx++] = "-p";
100             arguments[arg_idx++] = ssh_port;
101         }
102         /* // should be specified in the ssh_conf file 
103         arguments[arg_idx++] = "-o";
104         arguments[arg_idx++] = "BatchMode yes";
105         */
106         if (key_file != NULL) {
107             snprintf(identity_string, PATH_MAX + 13, "IdentityFile %s", key_file);
108             arguments[arg_idx++] = "-o";
109             arguments[arg_idx++] = identity_string;
110         }
111         arguments[arg_idx++] = host;
112         arguments[arg_idx++] = ptsc_command;
113         // arguments[arg_idx++] = "ptsc";
114         // arguments[arg_idx++] = "-m";
115 #if 0
116         /* Sync verbose level between verifier and collector? */
117         // {
118            int verboseLevel;
119             for ( verboseLevel = 0; (verboseLevel < getVerbosity()) && (arg_idx < 15); verboseLevel++ ) {
120                 arguments[arg_idx++] = "-v";
121             }
122         // }
123 #endif
124         arguments[arg_idx++] = NULL;
125
126 DEBUG("ptsc_command %s\n", ptsc_command);
127
128         execvp("ssh", arguments);
129         ERROR("execvp(ssh)");
130         exit(1);
131     }
132
133     close(socket_pair[1]);
134     *socket = socket_pair[0];
135
136     fcntl(*socket, F_SETFD, FD_CLOEXEC);
137
138     // success
139     return pid;
140
141   err_close:
142     close(socket_pair[0]);
143     close(socket_pair[1]);
144   err:
145     return -1;
146 }
147