~ubuntu-branches/ubuntu/trusty/libssh/trusty-security

« back to all changes in this revision

Viewing changes to examples/samplesshd.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2009-12-12 14:29:12 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20091212142912-ha5g2iibt6nfnjq8
Tags: 0.4.0-1
* New upstream release.
  - Bump soname
  - Adjust .symbols file
* Readd static library in -dev package
* Let dh_lintian install override file
* debian/README.Debian: Update file
* debian/rules: Add list-missing rule

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This is a sample implementation of a libssh based SSH server */
 
2
/*
 
3
Copyright 2003-2009 Aris Adamantiadis
 
4
 
 
5
This file is part of the SSH Library
 
6
 
 
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
 
10
program.
 
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.
 
13
*/
 
14
 
 
15
#include "config.h"
 
16
 
 
17
#include <libssh/libssh.h>
 
18
#include <libssh/server.h>
 
19
 
 
20
#ifdef HAVE_ARGP_H
 
21
#include <argp.h>
 
22
#endif
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
#include <stdio.h>
 
26
#include <unistd.h>
 
27
#ifndef KEYS_FOLDER
 
28
#ifdef _WIN32
 
29
#define KEYS_FOLDER
 
30
#else
 
31
#define KEYS_FOLDER "/etc/ssh/"
 
32
#endif
 
33
#endif
 
34
 
 
35
static int auth_password(char *user, char *password){
 
36
    if(strcmp(user,"aris"))
 
37
        return 0;
 
38
    if(strcmp(password,"lala"))
 
39
        return 0;
 
40
    return 1; // authenticated
 
41
}
 
42
#ifdef HAVE_ARGP_H
 
43
const char *argp_program_version = "libssh server example "
 
44
  SSH_STRINGIFY(LIBSSH_VERSION);
 
45
const char *argp_program_bug_address = "<libssh@libssh.org>";
 
46
 
 
47
/* Program documentation. */
 
48
static char doc[] = "libssh -- a Secure Shell protocol implementation";
 
49
 
 
50
/* A description of the arguments we accept. */
 
51
static char args_doc[] = "BINDADDR";
 
52
 
 
53
/* The options we understand. */
 
54
static struct argp_option options[] = {
 
55
  {
 
56
    .name  = "port",
 
57
    .key   = 'p',
 
58
    .arg   = "PORT",
 
59
    .flags = 0,
 
60
    .doc   = "Set the port to bind.",
 
61
    .group = 0
 
62
  },
 
63
  {
 
64
    .name  = "hostkey",
 
65
    .key   = 'k',
 
66
    .arg   = "FILE",
 
67
    .flags = 0,
 
68
    .doc   = "Set the host key.",
 
69
    .group = 0
 
70
  },
 
71
  {
 
72
    .name  = "dsakey",
 
73
    .key   = 'd',
 
74
    .arg   = "FILE",
 
75
    .flags = 0,
 
76
    .doc   = "Set the dsa key.",
 
77
    .group = 0
 
78
  },
 
79
  {
 
80
    .name  = "rsakey",
 
81
    .key   = 'r',
 
82
    .arg   = "FILE",
 
83
    .flags = 0,
 
84
    .doc   = "Set the rsa key.",
 
85
    .group = 0
 
86
  },
 
87
  {
 
88
    .name  = "verbose",
 
89
    .key   = 'v',
 
90
    .arg   = NULL,
 
91
    .flags = 0,
 
92
    .doc   = "Get verbose output.",
 
93
    .group = 0
 
94
  },
 
95
  {NULL, 0, 0, 0, NULL, 0}
 
96
};
 
97
 
 
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.
 
102
   */
 
103
  ssh_bind sshbind = state->input;
 
104
 
 
105
  switch (key) {
 
106
    case 'p':
 
107
      ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
 
108
      break;
 
109
    case 'd':
 
110
      ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
 
111
      break;
 
112
    case 'k':
 
113
      ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
 
114
      break;
 
115
    case 'r':
 
116
      ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
 
117
      break;
 
118
    case 'v':
 
119
      ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
 
120
      break;
 
121
    case ARGP_KEY_ARG:
 
122
      if (state->arg_num >= 1) {
 
123
        /* Too many arguments. */
 
124
        argp_usage (state);
 
125
      }
 
126
      ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
 
127
      break;
 
128
    case ARGP_KEY_END:
 
129
      if (state->arg_num < 1) {
 
130
        /* Not enough arguments. */
 
131
        argp_usage (state);
 
132
      }
 
133
      break;
 
134
    default:
 
135
      return ARGP_ERR_UNKNOWN;
 
136
  }
 
137
 
 
138
  return 0;
 
139
}
 
140
 
 
141
/* Our argp parser. */
 
142
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
 
143
#endif /* HAVE_ARGP_H */
 
144
 
 
145
int main(int argc, char **argv){
 
146
    ssh_session session;
 
147
    ssh_bind sshbind;
 
148
    ssh_message message;
 
149
    ssh_channel chan=0;
 
150
    ssh_buffer buf;
 
151
    int auth=0;
 
152
    int sftp=0;
 
153
    int i;
 
154
    int r;
 
155
 
 
156
    sshbind=ssh_bind_new();
 
157
    session=ssh_new();
 
158
 
 
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");
 
161
 
 
162
#ifdef HAVE_ARGP_H
 
163
    /*
 
164
     * Parse our arguments; every option seen by parse_opt will
 
165
     * be reflected in arguments.
 
166
     */
 
167
    argp_parse (&argp, argc, argv, 0, 0, sshbind);
 
168
#endif
 
169
    if(ssh_bind_listen(sshbind)<0){
 
170
        printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
 
171
        return 1;
 
172
    }
 
173
    r=ssh_bind_accept(sshbind,session);
 
174
    if(r==SSH_ERROR){
 
175
      printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
 
176
      return 1;
 
177
    }
 
178
    if(ssh_accept(session)){
 
179
        printf("ssh_accept: %s\n",ssh_get_error(session));
 
180
        return 1;
 
181
    }
 
182
    do {
 
183
        message=ssh_message_get(session);
 
184
        if(!message)
 
185
            break;
 
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))){
 
195
                               auth=1;
 
196
                               ssh_message_auth_reply_success(message,0);
 
197
                               break;
 
198
                           }
 
199
                        // not authenticated, send default message
 
200
                    case SSH_AUTH_METHOD_NONE:
 
201
                    default:
 
202
                        ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
 
203
                        ssh_message_reply_default(message);
 
204
                        break;
 
205
                }
 
206
                break;
 
207
            default:
 
208
                ssh_message_reply_default(message);
 
209
        }
 
210
        ssh_message_free(message);
 
211
    } while (!auth);
 
212
    if(!auth){
 
213
        printf("auth error: %s\n",ssh_get_error(session));
 
214
        ssh_disconnect(session);
 
215
        return 1;
 
216
    }
 
217
    do {
 
218
        message=ssh_message_get(session);
 
219
        if(message){
 
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);
 
224
                        break;
 
225
                    }
 
226
                default:
 
227
                ssh_message_reply_default(message);
 
228
            }
 
229
            ssh_message_free(message);
 
230
        }
 
231
    } while(message && !chan);
 
232
    if(!chan){
 
233
        printf("error : %s\n",ssh_get_error(session));
 
234
        ssh_finalize();
 
235
        return 1;
 
236
    }
 
237
    do {
 
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")){
 
242
                sftp=1;
 
243
                ssh_message_channel_request_reply_success(message);
 
244
                break;
 
245
 //           }
 
246
           }
 
247
        if(!sftp){
 
248
            ssh_message_reply_default(message);
 
249
        }
 
250
        ssh_message_free(message);
 
251
    } while (message && !sftp);
 
252
    if(!sftp){
 
253
        printf("error : %s\n",ssh_get_error(session));
 
254
        return 1;
 
255
    }
 
256
    printf("it works !\n");
 
257
    buf=buffer_new();
 
258
    do{
 
259
        i=channel_read_buffer(chan,buf,0,0);
 
260
        if(i>0)
 
261
            write(1,buffer_get(buf),buffer_get_len(buf));
 
262
    } while (i>0);
 
263
    buffer_free(buf);
 
264
    ssh_disconnect(session);
 
265
    ssh_bind_free(sshbind);
 
266
    ssh_finalize();
 
267
    return 0;
 
268
}
 
269