Chinaunix
标题:
libssh2示例修改版
[打印本页]
作者:
diyself
时间:
2010-01-13 12:59
标题:
libssh2示例修改版
主要把代码做了分离。稍作修改可以做交互式的执行命令。
libssh2_exec.h
#ifndef __LIBSSH2_EXEC_H
#define __LIBSSH2_EXEC_H
#include "libssh2_config.h"
#include <libssh2.h>
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
# ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
static int waitsocket(int *socket_fd, LIBSSH2_SESSION *session);
void close_channel(LIBSSH2_CHANNEL *channel);
void shutdown_socket(int *sock, LIBSSH2_SESSION *session);
int connect_sock(int *sock, LIBSSH2_SESSION **session,LIBSSH2_CHANNEL **channel);
int create_channel(int *sock, LIBSSH2_SESSION **session,LIBSSH2_CHANNEL **channel);
int cmd_request(int *sock, LIBSSH2_SESSION *session,LIBSSH2_CHANNEL *channel,char *cmdline);
#endif
复制代码
[
本帖最后由 diyself 于 2010-1-13 13:07 编辑
]
作者:
diyself
时间:
2010-01-13 13:00
libssh2_exec.c
#include "libssh2_exec.h"
//#include "libssh2_config.h"
//#include <libssh2.h>
static int waitsocket(int *socket_fd, LIBSSH2_SESSION *session)
{
struct timeval timeout;
int rc;
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
int dir;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
FD_ZERO(&fd);
FD_SET(*socket_fd, &fd);
/* now make sure we wait in the correct direction */
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
readfd = &fd;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
writefd = &fd;
rc = select(*socket_fd + 1, readfd, writefd, NULL, &timeout);
return rc;
}
void close_channel(LIBSSH2_CHANNEL *channel)
{
libssh2_channel_free(channel);
channel = NULL;
}
void shutdown_socket(int *sock, LIBSSH2_SESSION *session)
{
libssh2_session_disconnect(session,"Normal Shutdown, Thank you for playing");
libssh2_session_free(session);
close(*sock);
}
/***********************************************
函数名称:connect_sock
函数功能:建立ssh 连接
传入参数:
返回数据:
***********************************************/
int connect_sock(int *sock, LIBSSH2_SESSION **session,LIBSSH2_CHANNEL **channel)
{
const char *hostname = "127.0.0.1";
const char *username = "root";
const char *password = "root";
unsigned long hostaddr;
struct sockaddr_in sin;
const char *fingerprint;
int rc;
int exitcode;
int bytecount = 0;
size_t len;
LIBSSH2_KNOWNHOSTS *nh;
int type;
hostaddr = inet_addr(hostname);
/* Ultra basic "connect to port 22 on localhost"
* Your code is responsible for creating the socket establishing the
* connection
*/
*sock = socket(AF_INET, SOCK_STREAM, 0); //建立ssh socket
sin.sin_family = AF_INET;
sin.sin_port = htons(22);
sin.sin_addr.s_addr = hostaddr;
if (connect(*sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in)) != 0) {
fprintf(stderr, "failed to connect!\n");
return -1;
}
/* Create a *session instance */
*session = libssh2_session_init();
if (!*session)
return -1;
/* tell libssh2 we want it all done non-blocking */
libssh2_session_set_blocking(*session, 0); //建立ssh 会话
/* ... start it up. This will trade welcome banners, exchange keys,
* and setup crypto, compression, and MAC layers
*/
while ((rc = libssh2_session_startup(*session, *sock)) == LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Failure establishing SSH *session: %d\n", rc);
return -1;
}
nh = libssh2_knownhost_init(*session);
if(!nh) {
/* eeek, do cleanup here */
return 2;
}
/* read all hosts from here */
libssh2_knownhost_readfile(nh, "known_hosts",
LIBSSH2_KNOWNHOST_FILE_OPENSSH);
/* store all known hosts to here */
libssh2_knownhost_writefile(nh, "dumpfile", LIBSSH2_KNOWNHOST_FILE_OPENSSH);
fingerprint = libssh2_session_hostkey(*session, &len, &type);
if(fingerprint) {
struct libssh2_knownhost *host;
int check = libssh2_knownhost_check(nh, (char *)hostname,
(char *)fingerprint, len,
LIBSSH2_KNOWNHOST_TYPE_PLAIN|
LIBSSH2_KNOWNHOST_KEYENC_RAW,
&host);
// fprintf(stderr, "Host check: %d, key: %s\n", check,
// (check <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
// host->key:"<none>");
/*****
* At this point, we could verify that 'check' tells us the key is
* fine or bail out.
*****/
}
else {
/* eeek, do cleanup here */
return 3;
}
libssh2_knownhost_free(nh);
if ( strlen(password) != 0 ) {
/* We could authenticate via password *///进行密码验证
while ((rc = libssh2_userauth_password(*session, username, password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "Authentication by password failed.\n");
shutdown_socket(sock, *session);
return 1;
}
}
else {
/* Or by public key */
while ((rc = libssh2_userauth_publickey_fromfile(*session, username,
"/home/user/"
".ssh/id_rsa.pub",
"/home/user/"
".ssh/id_rsa",
password)) ==
LIBSSH2_ERROR_EAGAIN);
if (rc) {
fprintf(stderr, "\tAuthentication by public key failed\n");
shutdown_socket(sock, *session);
}
}
/* Exec non-blocking on the remove host */
return 0;
}
/***********************************************
函数名称:create_channel
函数功能:创建ssh通道
传入参数:
返回数据:
***********************************************/
int create_channel(int *sock, LIBSSH2_SESSION **session,LIBSSH2_CHANNEL **channel)
{
while( (*channel = libssh2_channel_open_session(*session)) == NULL &&
libssh2_session_last_error(*session,NULL,NULL,0) ==
LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, *session);
}
if( *channel == NULL )
{
fprintf(stderr,"Error\n");
exit( 1 );
}
return 0;
}
/***********************************************
函数名称:cmd_request
函数功能:执行请求的命令
传入参数:
返回数据:
***********************************************/
int cmd_request(int *sock, LIBSSH2_SESSION *session,LIBSSH2_CHANNEL *channel,char *cmdline)
{
int rc=0,exitcode=0,bytecount=0;
while( (rc = libssh2_channel_exec(channel, cmdline)) == LIBSSH2_ERROR_EAGAIN )//执行请求的命令
{
waitsocket(sock, session);
}
if( rc != 0 )
{
fprintf(stderr,"Error\n");
exit( 1 );
}
char buffer[2048];
for( ;; )
{
// loop until we block
int rc=0,exitcode=0;
do
{
memset(&buffer,0,sizeof(buffer));
rc = libssh2_channel_read( channel, buffer, sizeof(buffer)-1 );//分批接收命令执行结果
buffer[rc] = '\0';
printf("\n%s\n",buffer);
}
while( rc > 0 );
// this is due to blocking that would occur otherwise so we loop on
// this condition
if( rc == LIBSSH2_ERROR_EAGAIN )
{
waitsocket(sock, session);
}
else
break;
}
exitcode = 127;
while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
waitsocket(sock, session);
if( rc == 0 )
{
exitcode = libssh2_channel_get_exit_status( channel );
}
if(exitcode == 127)
{
}
return 0;
}
复制代码
[
本帖最后由 diyself 于 2010-1-13 13:12 编辑
]
作者:
diyself
时间:
2010-01-13 13:01
server.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <pthread.h>
#include "libssh2_exec.h"
int main()
{
int sock,rc;
LIBSSH2_SESSION *session = NULL;
LIBSSH2_CHANNEL *channel = NULL;
char buff[1024];
if(connect_sock(&sock, &session,&channel)!=0)
{
printf("连接sshd失败'的信息。\n");
return 1;
}
create_channel(&sock, &session,&channel);
strcpy(buff,"ls -l"); //执行ls -l
cmd_request(&sock, session,channel,buff);
strcpy(buff,"ps aux"); //执行ps aux
create_channel(&sock, &session,&channel);
cmd_request(&sock, session,channel,buff);
/*也可用下面的代替上面6行
strcpy(buff,"ls -l;ps aux"); //执行ls -l;ps aux
create_channel(&sock, &session,&channel);
cmd_request(&sock, session,channel,buff);
*/
close_channel(channel);
shutdown_socket(&sock, session);
return 0;
}
复制代码
[
本帖最后由 diyself 于 2010-1-13 13:20 编辑
]
作者:
diyself
时间:
2010-01-13 13:02
标题:
来自源代码的文件
libssh2_config.h
/* src/libssh2_config.h. Generated from libssh2_config.h.in by configure. */
/* src/libssh2_config.h.in. Generated from configure.in by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#define HAVE_ALLOCA_H 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* disabled non-blocking sockets */
/* #undef HAVE_DISABLED_NONBLOCKING */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* use FIONBIO for non-blocking sockets */
/* #undef HAVE_FIONBIO */
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* use ioctlsocket() for non-blocking sockets */
/* #undef HAVE_IOCTLSOCKET */
/* use Ioctlsocket() for non-blocking sockets */
/* #undef HAVE_IOCTLSOCKET_CASE */
/* Define if you have the gcrypt library. */
/* #undef HAVE_LIBGCRYPT */
/* Define if you have the ssl library. */
#define HAVE_LIBSSL 1
/* Define if you have the z library. */
#define HAVE_LIBZ 1
/* Define to 1 if the compiler supports the 'long long' data type. */
#define HAVE_LONGLONG 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* use O_NONBLOCK for non-blocking sockets */
#define HAVE_O_NONBLOCK 1
/* Define to 1 if you have the `poll' function. */
#define HAVE_POLL 1
/* Define to 1 if you have the select function. */
#define HAVE_SELECT 1
/* use SO_NONBLOCK for non-blocking sockets */
/* #undef HAVE_SO_NONBLOCK */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <windows.h> header file. */
/* #undef HAVE_WINDOWS_H */
/* Define to 1 if you have the <winsock2.h> header file. */
/* #undef HAVE_WINSOCK2_H */
/* Define to 1 if you have the <ws2tcpip.h> header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Enable "none" cipher -- NOT RECOMMENDED */
/* #undef LIBSSH2_CRYPT_NONE */
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
#define LIBSSH2_DH_GEX_NEW 1
/* Compile in zlib support */
#define LIBSSH2_HAVE_ZLIB 1
/* Use libgcrypt */
/* #undef LIBSSH2_LIBGCRYPT */
/* Enable "none" MAC -- NOT RECOMMENDED */
/* #undef LIBSSH2_MAC_NONE */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
/* #undef NEED_REENTRANT */
/* Name of package */
#define PACKAGE "libssh2"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "libssh2-[email]devel@lists.sourceforge.net[/email]"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libssh2"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libssh2 -"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libssh2"
/* Define to the version of this package. */
#define PACKAGE_VERSION "-"
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "1.2"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#define _FILE_OFFSET_BITS 64
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
复制代码
作者:
diyself
时间:
2010-01-13 13:03
编译:
gcc -lssh2 -o server server.c libssh2_exec.* libssh2_config.h
运行:
./server
作者:
prolj
时间:
2010-01-13 13:05
明天给10个小手,今天没有了。
gcc -lssh2 -o server server.c libssh2_exec.* libssh2_config.h
*是什么意思啊?
这个server的功能是?
作者:
diyself
时间:
2010-01-13 13:08
libssh2_exec.*==libssh2_exec.c + libssh2_exec.h
连接到sshd,执行命令。
[
本帖最后由 diyself 于 2010-1-13 13:09 编辑
]
作者:
prolj
时间:
2010-01-13 13:11
那么不交互,我指定多个命令,怎么个写法啊?
比如,我指定ls update 和 pwd 命令
作者:
diyself
时间:
2010-01-13 13:13
标题:
回复 #8 prolj 的帖子
请看三楼
作者:
prolj
时间:
2010-01-13 13:16
标题:
回复 #9 diyself 的帖子
谢谢!忙完手头的东西慢慢看。
作者:
ubuntuer
时间:
2010-01-13 15:15
不错 学习下
作者:
hani97
时间:
2017-10-15 11:27
回复
5#
diyself
你好 ,请问一下 这个对应的服务器端代码怎么编写啊 谢谢大神
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2