1
/* This is a sample implementation of a libssh based SSH server */
3
Copyright 2003-2009 Aris Adamantiadis
5
This file is part of the SSH Library
7
You are free to copy this file, modify it in any way, consider it being public
8
domain. This does not apply to the rest of the library though, but it is
9
allowed to cut-and-paste working code from this file to any license of
11
The goal is to show the API in action. It's not a reference on how terminal
12
clients must be made or how a client should react.
17
#include <libssh/libssh.h>
18
#include <libssh/server.h>
31
#define KEYS_FOLDER "/etc/ssh/"
35
static int auth_password(char *user, char *password){
36
if(strcmp(user,"aris"))
38
if(strcmp(password,"lala"))
40
return 1; // authenticated
43
const char *argp_program_version = "libssh server example "
44
SSH_STRINGIFY(LIBSSH_VERSION);
45
const char *argp_program_bug_address = "<libssh@libssh.org>";
47
/* Program documentation. */
48
static char doc[] = "libssh -- a Secure Shell protocol implementation";
50
/* A description of the arguments we accept. */
51
static char args_doc[] = "BINDADDR";
53
/* The options we understand. */
54
static struct argp_option options[] = {
60
.doc = "Set the port to bind.",
68
.doc = "Set the host key.",
76
.doc = "Set the dsa key.",
84
.doc = "Set the rsa key.",
92
.doc = "Get verbose output.",
95
{NULL, 0, 0, 0, NULL, 0}
98
/* Parse a single option. */
99
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
100
/* Get the input argument from argp_parse, which we
101
* know is a pointer to our arguments structure.
103
ssh_bind sshbind = state->input;
107
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
110
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
113
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
116
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
119
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
122
if (state->arg_num >= 1) {
123
/* Too many arguments. */
126
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
129
if (state->arg_num < 1) {
130
/* Not enough arguments. */
135
return ARGP_ERR_UNKNOWN;
141
/* Our argp parser. */
142
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
143
#endif /* HAVE_ARGP_H */
145
int main(int argc, char **argv){
156
sshbind=ssh_bind_new();
159
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
160
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
164
* Parse our arguments; every option seen by parse_opt will
165
* be reflected in arguments.
167
argp_parse (&argp, argc, argv, 0, 0, sshbind);
169
if(ssh_bind_listen(sshbind)<0){
170
printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
173
r=ssh_bind_accept(sshbind,session);
175
printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
178
if(ssh_accept(session)){
179
printf("ssh_accept: %s\n",ssh_get_error(session));
183
message=ssh_message_get(session);
186
switch(ssh_message_type(message)){
187
case SSH_REQUEST_AUTH:
188
switch(ssh_message_subtype(message)){
189
case SSH_AUTH_METHOD_PASSWORD:
190
printf("User %s wants to auth with pass %s\n",
191
ssh_message_auth_user(message),
192
ssh_message_auth_password(message));
193
if(auth_password(ssh_message_auth_user(message),
194
ssh_message_auth_password(message))){
196
ssh_message_auth_reply_success(message,0);
199
// not authenticated, send default message
200
case SSH_AUTH_METHOD_NONE:
202
ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
203
ssh_message_reply_default(message);
208
ssh_message_reply_default(message);
210
ssh_message_free(message);
213
printf("auth error: %s\n",ssh_get_error(session));
214
ssh_disconnect(session);
218
message=ssh_message_get(session);
220
switch(ssh_message_type(message)){
221
case SSH_REQUEST_CHANNEL_OPEN:
222
if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
223
chan=ssh_message_channel_request_open_reply_accept(message);
227
ssh_message_reply_default(message);
229
ssh_message_free(message);
231
} while(message && !chan);
233
printf("error : %s\n",ssh_get_error(session));
238
message=ssh_message_get(session);
239
if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL &&
240
ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){
241
// if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
243
ssh_message_channel_request_reply_success(message);
248
ssh_message_reply_default(message);
250
ssh_message_free(message);
251
} while (message && !sftp);
253
printf("error : %s\n",ssh_get_error(session));
256
printf("it works !\n");
259
i=channel_read_buffer(chan,buf,0,0);
261
write(1,buffer_get(buf),buffer_get_len(buf));
264
ssh_disconnect(session);
265
ssh_bind_free(sshbind);