看到段牛牛和大湿聊了一下批量ssh的东西,然后看到有个ssh的程序,
挺有意思,学习一下,然后实现了一下,记录下来了
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <libssh/libssh.h>
- int show_remote_processes(ssh_session session, unsigned char *command)
- {
- ssh_channel channel;
- int rc;
- char buffer[256];
- unsigned int nbytes;
- channel = ssh_channel_new(session);
- if (channel == NULL)
- return SSH_ERROR;
- rc = ssh_channel_open_session(channel);
- if (rc != SSH_OK)
- {
- ssh_channel_free(channel);
- return rc;
- }
- rc = ssh_channel_request_exec(channel, command);
- if (rc != SSH_OK)
- {
- ssh_channel_close(channel);
- ssh_channel_free(channel);
- return rc;
- }
- nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
- while (nbytes > 0)
- {
- if (write(1, buffer, nbytes) != nbytes)
- {
- ssh_channel_close(channel);
- ssh_channel_free(channel);
- return SSH_ERROR;
- }
- nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
- }
- if (nbytes < 0)
- {
- ssh_channel_close(channel);
- ssh_channel_free(channel);
- return SSH_ERROR;
- }
- ssh_channel_send_eof(channel);
- ssh_channel_close(channel);
- ssh_channel_free(channel);
- return SSH_OK;
- }
- int verify_knownhost(ssh_session session)
- {
- int state, hlen;
- unsigned char *hash = NULL;
- char *hexa;
- char buf[10];
- state = ssh_is_server_known(session);
- hlen = ssh_get_pubkey_hash(session, &hash);
- if (hlen < 0)
- return -1;
- switch (state)
- {
- case SSH_SERVER_KNOWN_OK:
- break; /* ok */
- case SSH_SERVER_KNOWN_CHANGED:
- fprintf(stderr, "Host key for server changed: it is now:\n");
- ssh_print_hexa("Public key hash", hash, hlen);
- fprintf(stderr, "For security reasons, connection will be stopped\n");
- free(hash);
- return -1;
- case SSH_SERVER_FOUND_OTHER:
- fprintf(stderr, "The host key for this server was not found but an other"
- "type of key exists.\n");
- fprintf(stderr, "An attacker might change the default server key to"
- "confuse your client into thinking the key does not exist\n");
- free(hash);
- return -1;
- case SSH_SERVER_FILE_NOT_FOUND:
- fprintf(stderr, "Could not find known host file.\n");
- fprintf(stderr, "If you accept the host key here, the file will be"
- "automatically created.\n");
- /* fallback to SSH_SERVER_NOT_KNOWN behavior */
- case SSH_SERVER_NOT_KNOWN:
- hexa = ssh_get_hexa(hash, hlen);
- fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
- fprintf(stderr, "Public key hash: %s\n", hexa);
- free(hexa);
- if (fgets(buf, sizeof(buf), stdin) == NULL)
- {
- free(hash);
- return -1;
- }
- if (strncasecmp(buf, "yes", 3) != 0)
- {
- free(hash);
- return -1;
- }
- if (ssh_write_knownhost(session) < 0)
- {
- fprintf(stderr, "Error %s\n", "error");
- free(hash);
- return -1;
- }
- break;
- case SSH_SERVER_ERROR:
- fprintf(stderr, "Error %s", ssh_get_error(session));
- free(hash);
- return -1;
- }
- free(hash);
- return 0;
- }
- static int ssh_connect_test(unsigned char *ipaddr, unsigned char *command)
- {
- int rc = 0;
- char *password;
- ssh_session my_ssh_session = ssh_new();
- if (!my_ssh_session) {
- fprintf(stderr, "cannot alloc new ssh\r\n");
- return -1;
- }
- ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, ipaddr);
- rc = ssh_connect(my_ssh_session);
- if (rc != SSH_OK)
- {
- fprintf(stderr, "Error connecting to localhost: %s\n", ssh_get_error(my_ssh_session));
- exit(-1);
- }
- if (verify_knownhost(my_ssh_session) < 0)
- {
- ssh_disconnect(my_ssh_session);
- ssh_free(my_ssh_session);
- exit(-1);
- }
- password = "passwordsamples";
- rc = ssh_userauth_password(my_ssh_session, NULL, password);
- if (rc != SSH_AUTH_SUCCESS)
- {
- fprintf(stderr, "Error authenticating with password: %s\n", ssh_get_error(my_ssh_session));
- ssh_disconnect(my_ssh_session);
- ssh_free(my_ssh_session);
- exit(-1);
- }
- show_remote_processes(my_ssh_session, command);
- fprintf(stderr, "alloc success\r\n");
- ssh_free(my_ssh_session);
- return 0;
- }
- int main(int argc, char *argv[])
- {
- int ret = 0;
- ret = ssh_connect_test(argv[1], argv[2]);
- if (ret < 0) {
- fprintf(stderr, "connect error \r\n");
- return -1;
- }
- return 0;
- }
Makefile如下
- CFLAGS += -Werror -I/usr/local/include -L/usr/local/lib
- CC =gcc
- LIBS = -lssh
- OBJS += \
- 1.o
- TARGET = target
- all:$(OBJS)
- gcc $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
- clean:
- rm -rf $(OBJS) $(TARGET)
然后直接make即可生成可执行文件target
然后执行效果如下
- [liuqi@btg example_libssh]$ ./target 192.168.0.118 date
- 2011年 06月 13日 星期一 14:07:04 CST
- alloc success
- [liuqi@btg example_libssh]$ ./target 192.168.0.118 who
- liuqi tty1 2011-06-13 10:28 (:0)
- liuqi pts/0 2011-06-13 10:29 (:0.0)
- liuqi pts/1 2011-06-13 10:29 (:0.0)
- liuqi pts/2 2011-06-13 13:54 (:0.0)
- liuqi pts/3 2011-06-13 14:02 (:0.0)
- alloc success
- [liuqi@btg example_libssh]$