~ubuntu-branches/ubuntu/breezy/netkit-ftp-ssl/breezy

« back to all changes in this revision

Viewing changes to ftp/ruserpass.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Martin
  • Date: 2002-03-23 12:10:37 UTC
  • Revision ID: james.westby@ubuntu.com-20020323121037-11rjw8euzjmcgpm4
Tags: upstream-0.17.9+0.2
ImportĀ upstreamĀ versionĀ 0.17.9+0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1985 Regents of the University of California.
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 * 1. Redistributions of source code must retain the above copyright
 
9
 *    notice, this list of conditions and the following disclaimer.
 
10
 * 2. Redistributions in binary form must reproduce the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer in the
 
12
 *    documentation and/or other materials provided with the distribution.
 
13
 * 3. All advertising materials mentioning features or use of this software
 
14
 *    must display the following acknowledgement:
 
15
 *      This product includes software developed by the University of
 
16
 *      California, Berkeley and its contributors.
 
17
 * 4. Neither the name of the University nor the names of its contributors
 
18
 *    may be used to endorse or promote products derived from this software
 
19
 *    without specific prior written permission.
 
20
 *
 
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
31
 * SUCH DAMAGE.
 
32
 */
 
33
 
 
34
/*
 
35
 * from: @(#)ruserpass.c        5.3 (Berkeley) 3/1/91
 
36
 */
 
37
char ruserpass_rcsid[] = 
 
38
  "$Id: ruserpass.c,v 1.9 1999/10/02 19:12:33 dholland Exp $";
 
39
 
 
40
#include <stdio.h>
 
41
#include <stdlib.h>
 
42
#include <utmp.h>
 
43
#include <ctype.h>
 
44
#include <sys/stat.h>
 
45
#include <errno.h>
 
46
#include <string.h>
 
47
#include <unistd.h>
 
48
#include "ftp_var.h"
 
49
#include "main.h"
 
50
 
 
51
static FILE *cfile;
 
52
static int token(void);
 
53
 
 
54
#define DEFAULT 1
 
55
#define LOGIN   2
 
56
#define PASSWD  3
 
57
#define ACCOUNT 4
 
58
#define MACDEF  5
 
59
#define ID      10
 
60
#define MACH    11
 
61
 
 
62
static char tokval[100];
 
63
 
 
64
static struct toktab {
 
65
        const char *tokstr;
 
66
        int tval;
 
67
} toktab[]= {
 
68
        { "default",    DEFAULT },
 
69
        { "login",      LOGIN },
 
70
        { "password",   PASSWD },
 
71
        { "passwd",     PASSWD },
 
72
        { "account",    ACCOUNT },
 
73
        { "machine",    MACH },
 
74
        { "macdef",     MACDEF },
 
75
        { NULL,         0 }
 
76
};
 
77
 
 
78
int
 
79
xruserpass(const char *host, char **aname, char **apass, char **aacct)
 
80
{
 
81
        const char *hdir;
 
82
        char buf[BUFSIZ], *tmp;
 
83
        char myname[MAXHOSTNAMELEN];
 
84
        const char *mydomain;
 
85
        int t, i, c, usedefault = 0;
 
86
        struct stat stb;
 
87
 
 
88
        hdir = getenv("HOME");
 
89
        if (hdir == NULL)
 
90
                hdir = ".";
 
91
        snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
 
92
        cfile = fopen(buf, "r");
 
93
        if (cfile == NULL) {
 
94
                if (errno != ENOENT)
 
95
                        perror(buf);
 
96
                return(0);
 
97
        }
 
98
        if (gethostname(myname, sizeof(myname)) < 0)
 
99
                myname[0] = '\0';
 
100
        if ((mydomain = strchr(myname, '.')) == NULL)
 
101
                mydomain = "";
 
102
next:
 
103
        while ((t = token())) switch(t) {
 
104
 
 
105
        case DEFAULT:
 
106
                usedefault = 1;
 
107
                /* FALL THROUGH */
 
108
 
 
109
        case MACH:
 
110
                if (!usedefault) {
 
111
                        if (token() != ID)
 
112
                                continue;
 
113
                        /*
 
114
                         * Allow match either for user's input host name
 
115
                         * or official hostname.  Also allow match of 
 
116
                         * incompletely-specified host in local domain.
 
117
                         */
 
118
                        if (strcasecmp(host, tokval) == 0)
 
119
                                goto match;
 
120
                        if (strcasecmp(hostname, tokval) == 0)
 
121
                                goto match;
 
122
                        if ((tmp = index(hostname, '.')) != NULL &&
 
123
                            strcasecmp(tmp, mydomain) == 0 &&
 
124
                            strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
 
125
                            tokval[tmp - hostname] == '\0')
 
126
                                goto match;
 
127
                        if ((tmp = index(host, '.')) != NULL &&
 
128
                            strcasecmp(tmp, mydomain) == 0 &&
 
129
                            strncasecmp(host, tokval, tmp - host) == 0 &&
 
130
                            tokval[tmp - host] == '\0')
 
131
                                goto match;
 
132
                        continue;
 
133
                }
 
134
        match:
 
135
                while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
 
136
 
 
137
                case LOGIN:
 
138
                        if (token()) {
 
139
                                if (*aname == 0) { 
 
140
                                        *aname = obstack_copy(&mainobstack, tokval, strlen(tokval) + 1);
 
141
                                } else {
 
142
                                        if (strcmp(*aname, tokval))
 
143
                                                goto next;
 
144
                                }
 
145
                        }
 
146
                        break;
 
147
                case PASSWD:
 
148
                        if (*aname==NULL) {
 
149
        fprintf(stderr, "Error: `password' must follow `login' in .netrc\n");
 
150
                                goto bad;
 
151
                        }
 
152
                        if (strcmp(*aname, "anonymous") &&
 
153
                            fstat(fileno(cfile), &stb) >= 0 &&
 
154
                            (stb.st_mode & 077) != 0) {
 
155
        fprintf(stderr, "Error - .netrc file not correct permissions.\n");
 
156
        fprintf(stderr, "Remove password or correct mode (should be 600).\n");
 
157
                                goto bad;
 
158
                        }
 
159
                        if (token() && *apass == 0) {
 
160
                                *apass = obstack_copy(&mainobstack, tokval, strlen(tokval) + 1);
 
161
                        }
 
162
                        break;
 
163
                case ACCOUNT:
 
164
                        if (fstat(fileno(cfile), &stb) >= 0
 
165
                            && (stb.st_mode & 077) != 0) {
 
166
        fprintf(stderr, "Error - .netrc file not correct permissions.\n");
 
167
        fprintf(stderr, "Remove account or correct mode (should be 600).\n");
 
168
                                goto bad;
 
169
                        }
 
170
                        if (token() && *aacct == 0) {
 
171
                                *aacct = obstack_copy(&mainobstack, tokval, strlen(tokval) + 1);
 
172
                        }
 
173
                        break;
 
174
                case MACDEF:
 
175
                        if (proxy) {
 
176
                                (void) fclose(cfile);
 
177
                                return(0);
 
178
                        }
 
179
                        while ((c=getc(cfile)) != EOF && (c == ' ' || c == '\t'));
 
180
                        if (c == EOF || c == '\n') {
 
181
                                printf("Missing macdef name argument.\n");
 
182
                                goto bad;
 
183
                        }
 
184
                        if (macnum == 16) {
 
185
                                printf("Limit of 16 macros have already been defined\n");
 
186
                                goto bad;
 
187
                        }
 
188
                        tmp = macros[macnum].mac_name;
 
189
                        *tmp++ = c;
 
190
                        for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
 
191
                            !isspace(c); ++i) {
 
192
                                *tmp++ = c;
 
193
                        }
 
194
                        if (c == EOF) {
 
195
                                printf("Macro definition missing null line terminator.\n");
 
196
                                goto bad;
 
197
                        }
 
198
                        *tmp = '\0';
 
199
                        if (c != '\n') {
 
200
                                while ((c=getc(cfile)) != EOF && c != '\n');
 
201
                        }
 
202
                        if (c == EOF) {
 
203
                                printf("Macro definition missing null line terminator.\n");
 
204
                                goto bad;
 
205
                        }
 
206
                        if (macnum == 0) {
 
207
                                macros[macnum].mac_start = macbuf;
 
208
                        }
 
209
                        else {
 
210
                                macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
 
211
                        }
 
212
                        tmp = macros[macnum].mac_start;
 
213
                        while (tmp != macbuf + MACBUF_SIZE) {
 
214
                                if ((c=getc(cfile)) == EOF) {
 
215
                                printf("Macro definition missing null line terminator.\n");
 
216
                                        goto bad;
 
217
                                }
 
218
                                *tmp = c;
 
219
                                if (*tmp == '\n') {
 
220
                                        if (*(tmp-1) == '\0') {
 
221
                                           macros[macnum++].mac_end = tmp - 1;
 
222
                                           break;
 
223
                                        }
 
224
                                        *tmp = '\0';
 
225
                                }
 
226
                                tmp++;
 
227
                        }
 
228
                        if (tmp == macbuf + MACBUF_SIZE) {
 
229
                                printf("4K macro buffer exceeded\n");
 
230
                                goto bad;
 
231
                        }
 
232
                        break;
 
233
                default:
 
234
        fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
 
235
                        break;
 
236
                }
 
237
                goto done;
 
238
        }
 
239
done:
 
240
        (void) fclose(cfile);
 
241
        return(0);
 
242
bad:
 
243
        (void) fclose(cfile);
 
244
        return(-1);
 
245
}
 
246
 
 
247
static 
 
248
int
 
249
token(void)
 
250
{
 
251
        char *cp;
 
252
        int c;
 
253
        struct toktab *t;
 
254
 
 
255
        if (feof(cfile))
 
256
                return (0);
 
257
        while ((c = getc(cfile)) != EOF &&
 
258
            (c == '\n' || c == '\t' || c == ' ' || c == ','))
 
259
                continue;
 
260
        if (c == EOF)
 
261
                return (0);
 
262
        cp = tokval;
 
263
        if (c == '"') {
 
264
                while ((c = getc(cfile)) != EOF && c != '"') {
 
265
                        if (c == '\\')
 
266
                                c = getc(cfile);
 
267
                        *cp++ = c;
 
268
                }
 
269
        } else {
 
270
                *cp++ = c;
 
271
                while ((c = getc(cfile)) != EOF
 
272
                    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
 
273
                        if (c == '\\')
 
274
                                c = getc(cfile);
 
275
                        *cp++ = c;
 
276
                }
 
277
        }
 
278
        *cp = 0;
 
279
        if (tokval[0] == 0)
 
280
                return (0);
 
281
        for (t = toktab; t->tokstr; t++)
 
282
                if (!strcmp(t->tokstr, tokval))
 
283
                        return (t->tval);
 
284
        return (ID);
 
285
}