~ubuntu-branches/debian/lenny/dropbear/lenny

« back to all changes in this revision

Viewing changes to runopts.c

  • Committer: Bazaar Package Importer
  • Author(s): Gerrit Pape
  • Date: 2005-05-25 22:38:17 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050525223817-fdl653extybmz1zb
Tags: 0.45-3
* debian/dropbear.init: init script prints human readable message in case
  it's disabled (closes: #309099).
* debian/dropbear.postinst: configure: restart service through init script
  instead of start.
* debian/dropbear.prerm: set -u -> set -e.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Dropbear - a SSH2 server
3
 
 * 
4
 
 * Copyright (c) 2002,2003 Matt Johnston
5
 
 * All rights reserved.
6
 
 * 
7
 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 
 * of this software and associated documentation files (the "Software"), to deal
9
 
 * in the Software without restriction, including without limitation the rights
10
 
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 
 * copies of the Software, and to permit persons to whom the Software is
12
 
 * furnished to do so, subject to the following conditions:
13
 
 * 
14
 
 * The above copyright notice and this permission notice shall be included in
15
 
 * all copies or substantial portions of the Software.
16
 
 * 
17
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 
 * SOFTWARE. */
24
 
 
25
 
#include "includes.h"
26
 
#include "runopts.h"
27
 
#include "signkey.h"
28
 
#include "buffer.h"
29
 
#include "dbutil.h"
30
 
#include "algo.h"
31
 
 
32
 
static sign_key * loadhostkeys(const char * dsskeyfile,
33
 
                const char * rsakeyfile);
34
 
static int readhostkey(const char * filename, sign_key * hostkey, int type);
35
 
static void printhelp(const char * progname);
36
 
 
37
 
static void printhelp(const char * progname) {
38
 
 
39
 
        fprintf(stderr, "Dropbear sshd v%s\n"
40
 
                                        "Usage: %s [options]\n"
41
 
                                        "Options are:\n"
42
 
                                        "-b bannerfile  Display the contents of bannerfile"
43
 
                                        " before user login\n"
44
 
                                        "               (default: none)\n"
45
 
#ifdef DROPBEAR_DSS
46
 
                                        "-d dsskeyfile  Use dsskeyfile for the dss host key\n"
47
 
                                        "               (default: %s)\n"
48
 
#endif
49
 
#ifdef DROPBEAR_RSA
50
 
                                        "-r rsakeyfile  Use rsakeyfile for the rsa host key\n"
51
 
                                        "               (default: %s)\n"
52
 
#endif
53
 
                                        "-F             Don't fork into background\n"
54
 
#ifdef DISABLE_SYSLOG
55
 
                                        "(Syslog support not compiled in, using stderr)\n"
56
 
#else
57
 
                                        "-E             Log to stderr rather than syslog\n"
58
 
#endif
59
 
#ifdef DO_MOTD
60
 
                                        "-m             Don't display the motd on login\n"
61
 
#endif
62
 
                                        "-w             Disallow root logins\n"
63
 
#ifdef DROPBEAR_PASSWORD_AUTH
64
 
                                        "-s             Disable password logins\n"
65
 
                                        "-g             Disable password logins for root\n"
66
 
#endif
67
 
#ifndef DISABLE_LOCALTCPFWD
68
 
                                        "-j             Disable local port forwarding\n"
69
 
#endif
70
 
#ifndef DISABLE_REMOTETCPFWD
71
 
                                        "-k             Disable remote port forwarding\n"
72
 
#endif
73
 
#ifdef INETD_MODE
74
 
                                        "-i             Start for inetd\n"
75
 
#endif
76
 
                                        "-p port        Listen on specified tcp port, up to %d can be specified\n"
77
 
                                        "               (default %d if none specified)\n"
78
 
/*                                      "-4/-6          Disable listening on ipv4/ipv6 respectively\n"*/
79
 
 
80
 
                                        ,DROPBEAR_VERSION, progname,
81
 
#ifdef DROPBEAR_DSS
82
 
                                        DSS_PRIV_FILENAME,
83
 
#endif
84
 
#ifdef DROPBEAR_RSA
85
 
                                        RSA_PRIV_FILENAME,
86
 
#endif
87
 
                                        DROPBEAR_MAX_PORTS, DROPBEAR_PORT);
88
 
}
89
 
 
90
 
/* returns NULL on failure, or a pointer to a freshly allocated
91
 
 * runopts structure */
92
 
runopts * getrunopts(int argc, char ** argv) {
93
 
 
94
 
        unsigned int i;
95
 
        char ** next = 0;
96
 
        runopts * opts;
97
 
        unsigned int portnum = 0;
98
 
        char *portstring[DROPBEAR_MAX_PORTS];
99
 
        unsigned int longport;
100
 
 
101
 
        /* see printhelp() for options */
102
 
        opts = (runopts*)m_malloc(sizeof(runopts));
103
 
        opts->rsakeyfile = NULL;
104
 
        opts->dsskeyfile = NULL;
105
 
        opts->bannerfile = NULL;
106
 
        opts->banner = NULL;
107
 
        opts->forkbg = 1;
108
 
        opts->norootlogin = 0;
109
 
        opts->noauthpass = 0;
110
 
        opts->norootpass = 0;
111
 
        opts->nolocaltcp = 0;
112
 
        opts->noremotetcp = 0;
113
 
        /* not yet
114
 
        opts->ipv4 = 1;
115
 
        opts->ipv6 = 1;
116
 
        */
117
 
#ifdef DO_MOTD
118
 
        opts->domotd = 1;
119
 
#endif
120
 
#ifndef DISABLE_SYSLOG
121
 
        usingsyslog = 1;
122
 
#endif
123
 
        opts->inetdmode = 0;
124
 
 
125
 
        for (i = 1; i < (unsigned int)argc; i++) {
126
 
                if (next) {
127
 
                        *next = argv[i];
128
 
                        if (*next == NULL) {
129
 
                                dropbear_exit("Invalid null argument");
130
 
                        }
131
 
                        next = 0x00;
132
 
                        continue;
133
 
                }
134
 
 
135
 
                if (argv[i][0] == '-') {
136
 
                        switch (argv[i][1]) {
137
 
                                case 'b':
138
 
                                        next = &opts->bannerfile;
139
 
                                        break;
140
 
#ifdef DROPBEAR_DSS
141
 
                                case 'd':
142
 
                                        next = &opts->dsskeyfile;
143
 
                                        break;
144
 
#endif
145
 
#ifdef DROPBEAR_RSA
146
 
                                case 'r':
147
 
                                        next = &opts->rsakeyfile;
148
 
                                        break;
149
 
#endif
150
 
                                case 'F':
151
 
                                        opts->forkbg = 0;
152
 
                                        break;
153
 
#ifndef DISABLE_SYSLOG
154
 
                                case 'E':
155
 
                                        usingsyslog = 0;
156
 
                                        break;
157
 
#endif
158
 
#ifndef DISABLE_LOCALTCPFWD
159
 
                                case 'j':
160
 
                                        opts->nolocaltcp = 1;
161
 
                                        break;
162
 
#endif
163
 
#ifndef DISABLE_REMOTETCPFWD
164
 
                                case 'k':
165
 
                                        opts->noremotetcp = 1;
166
 
                                        break;
167
 
#endif
168
 
                                case 'p':
169
 
                                        if (portnum < DROPBEAR_MAX_PORTS) {
170
 
                                                portstring[portnum] = NULL;
171
 
                                                next = &portstring[portnum];
172
 
                                                portnum++;
173
 
                                        }
174
 
                                        break;
175
 
#ifdef DO_MOTD
176
 
                                /* motd is displayed by default, -m turns it off */
177
 
                                case 'm':
178
 
                                        opts->domotd = 0;
179
 
                                        break;
180
 
#endif
181
 
                                case 'w':
182
 
                                        opts->norootlogin = 1;
183
 
                                        break;
184
 
#ifdef DROPBEAR_PASSWORD_AUTH
185
 
                                case 's':
186
 
                                        opts->noauthpass = 1;
187
 
                                        break;
188
 
                                case 'g':
189
 
                                        opts->norootpass = 1;
190
 
                                        break;
191
 
#endif
192
 
                                case 'h':
193
 
                                        printhelp(argv[0]);
194
 
                                        exit(EXIT_FAILURE);
195
 
                                        break;
196
 
                                        /*
197
 
                                case '4':
198
 
                                        opts->ipv4 = 0;
199
 
                                        break;
200
 
                                case '6':
201
 
                                        opts->ipv6 = 0;
202
 
                                        break;
203
 
                                        */
204
 
#ifdef INETD_MODE
205
 
                                case 'i':
206
 
                                        opts->inetdmode = 1;
207
 
                                        break;
208
 
#endif
209
 
                                default:
210
 
                                        fprintf(stderr, "Unknown argument %s\n", argv[i]);
211
 
                                        printhelp(argv[0]);
212
 
                                        exit(EXIT_FAILURE);
213
 
                                        break;
214
 
                        }
215
 
                }
216
 
        }
217
 
 
218
 
        if (opts->dsskeyfile == NULL) {
219
 
                opts->dsskeyfile = DSS_PRIV_FILENAME;
220
 
        }
221
 
        if (opts->rsakeyfile == NULL) {
222
 
                opts->rsakeyfile = RSA_PRIV_FILENAME;
223
 
        }
224
 
        opts->hostkey = loadhostkeys(opts->dsskeyfile, opts->rsakeyfile);
225
 
 
226
 
        if (opts->bannerfile) {
227
 
                struct stat buf;
228
 
                if (stat(opts->bannerfile, &buf) != 0) {
229
 
                        dropbear_exit("Error opening banner file '%s'",
230
 
                                        opts->bannerfile);
231
 
                }
232
 
                
233
 
                if (buf.st_size > MAX_BANNER_SIZE) {
234
 
                        dropbear_exit("Banner file too large, max is %d bytes",
235
 
                                        MAX_BANNER_SIZE);
236
 
                }
237
 
 
238
 
                opts->banner = buf_new(buf.st_size);
239
 
                if (buf_readfile(opts->banner, opts->bannerfile)!=DROPBEAR_SUCCESS) {
240
 
                        dropbear_exit("Error reading banner file '%s'",
241
 
                                        opts->bannerfile);
242
 
                }
243
 
                buf_setpos(opts->banner, 0);
244
 
        }
245
 
 
246
 
        /* not yet
247
 
        if (!(opts->ipv4 || opts->ipv6)) {
248
 
                fprintf(stderr, "You can't disable ipv4 and ipv6.\n");
249
 
                exit(1);
250
 
        }
251
 
        */
252
 
 
253
 
        /* create the array of listening ports */
254
 
        if (portnum == 0) {
255
 
                /* non specified */
256
 
                opts->portcount = 1;
257
 
                opts->ports = m_malloc(sizeof(uint16_t));
258
 
                opts->ports[0] = DROPBEAR_PORT;
259
 
        } else {
260
 
                opts->portcount = portnum;
261
 
                opts->ports = (uint16_t*)m_malloc(sizeof(uint16_t)*portnum);
262
 
                for (i = 0; i < portnum; i++) {
263
 
                        if (portstring[i]) {
264
 
                                longport = atoi(portstring[i]);
265
 
                                        if (longport <= 65535 && longport > 0) {
266
 
                                                opts->ports[i] = (uint16_t)longport;
267
 
                                                continue;
268
 
                                        }
269
 
                        }
270
 
                        fprintf(stderr, "Bad port '%s'\n",
271
 
                                        portstring[i] ? portstring[i] : "null");
272
 
                }
273
 
        }
274
 
 
275
 
        return opts;
276
 
}
277
 
 
278
 
void freerunopts(runopts* opts) {
279
 
 
280
 
        if (!opts) {
281
 
                return;
282
 
        }
283
 
 
284
 
        if (opts->hostkey) {
285
 
                sign_key_free(opts->hostkey);
286
 
                opts->hostkey = NULL;
287
 
        }
288
 
 
289
 
        m_free(opts->ports);
290
 
        m_free(opts);
291
 
}
292
 
 
293
 
/* returns success or failure */
294
 
static int readhostkey(const char * filename, sign_key * hostkey, int type) {
295
 
 
296
 
        int ret = DROPBEAR_FAILURE;
297
 
        int i;
298
 
        buffer *buf;
299
 
 
300
 
        buf = buf_new(2000);
301
 
 
302
 
        if (buf_readfile(buf, filename) == DROPBEAR_FAILURE) {
303
 
                goto out;
304
 
        }
305
 
        buf_setpos(buf, 0);
306
 
        if (buf_get_priv_key(buf, hostkey, &type) == DROPBEAR_FAILURE) {
307
 
                goto out;
308
 
        }
309
 
 
310
 
        ret = DROPBEAR_SUCCESS;
311
 
out:
312
 
        if (ret == DROPBEAR_FAILURE) {
313
 
                for (i = 0; sshhostkey[i].name != NULL; i++) {
314
 
                        if (sshhostkey[i].val == type) {
315
 
                                sshhostkey[i].usable = 0;
316
 
                                break;
317
 
                        }
318
 
                }
319
 
                fprintf(stderr, "Failed reading '%s', disabling %s\n", filename,
320
 
                                type == DROPBEAR_SIGNKEY_DSS ? "DSS" : "RSA");
321
 
        }
322
 
 
323
 
        buf_burn(buf);
324
 
        buf_free(buf);
325
 
        return ret;
326
 
}
327
 
 
328
 
static sign_key * loadhostkeys(const char * dsskeyfile, 
329
 
                const char * rsakeyfile) {
330
 
 
331
 
        sign_key * hostkey;
332
 
 
333
 
        TRACE(("enter loadhostkeys"));
334
 
 
335
 
        hostkey = new_sign_key();
336
 
 
337
 
#ifdef DROPBEAR_RSA
338
 
        (void)readhostkey(rsakeyfile, hostkey, DROPBEAR_SIGNKEY_RSA);
339
 
#endif
340
 
 
341
 
#ifdef DROPBEAR_DSS
342
 
        (void)readhostkey(dsskeyfile, hostkey, DROPBEAR_SIGNKEY_DSS);
343
 
#endif
344
 
 
345
 
        if ( 1
346
 
#ifdef DROPBEAR_DSS
347
 
                && hostkey->dsskey == NULL
348
 
#endif
349
 
#ifdef DROPBEAR_RSA
350
 
                && hostkey->rsakey == NULL
351
 
#endif
352
 
                ) {
353
 
                dropbear_exit("No hostkeys available");
354
 
        }
355
 
 
356
 
        TRACE(("leave loadhostkeys"));
357
 
        return hostkey;
358
 
}