~ubuntu-branches/ubuntu/wily/netkit-telnet-ssl/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/010-full_set_in_18.diff/telnetlogin/telnetlogin.c

  • Committer: Package Import Robot
  • Author(s): Mats Erik Andersson
  • Date: 2015-04-27 23:20:22 UTC
  • mfrom: (7.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20150427232022-c2f04nl1gr4qyqom
Tags: 0.17.40+0.2-1
* Bring in package changes from experimental to unstable.
* Update to source version 0.17-40 of netkit-telnet.
  + debian/rules: Define and use the variable LDDEFS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2000 David A. Holland.
 
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 David A. Holland.
 
16
 * 4. Neither the name of the Author nor the names of any contributors
 
17
 *    may be used to endorse or promote products derived from this software
 
18
 *    without specific prior written permission.
 
19
 *
 
20
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND ANY CONTRIBUTORS ``AS IS'' AND
 
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR ANY CONTRIBUTORS BE LIABLE
 
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
30
 * SUCH DAMAGE.
 
31
 */
 
32
 
 
33
char copyright[] =
 
34
 "@(#) Copyright (c) 2000 David A. Holland.\n"
 
35
 "All rights reserved.\n";
 
36
 
 
37
char rcsid[] =
 
38
  "$Id: telnetlogin.c,v 1.1 2000/04/13 01:07:22 dholland Exp $";
 
39
#include "../version.h"
 
40
 
 
41
#include <sys/types.h>
 
42
#include <sys/stat.h>
 
43
#include <sys/ioctl.h>
 
44
#include <netdb.h>
 
45
#include <fcntl.h>
 
46
#include <ctype.h>
 
47
#include <paths.h>
 
48
#include <signal.h>
 
49
#include <unistd.h>
 
50
#include <stdlib.h>
 
51
#include <string.h>
 
52
#include <stdarg.h>
 
53
#include <stdio.h>
 
54
 
 
55
#ifndef _PATH_LOGIN
 
56
#define _PATH_LOGIN "/bin/login"
 
57
#endif
 
58
 
 
59
static const char *remhost = NULL;
 
60
 
 
61
static void die(const char *fmt, ...) {
 
62
   va_list ap;
 
63
   fprintf(stderr, "telnetlogin: ");
 
64
   va_start(ap, fmt);
 
65
   vfprintf(stderr, fmt, ap);
 
66
   va_end(ap);
 
67
   fprintf(stderr, "\n");
 
68
   exit(1);
 
69
}
 
70
 
 
71
static int check_a_hostname(char *hname) {
 
72
   int i=0;
 
73
   /* should we check length? */
 
74
   for (i=0; hname[i]; i++) {
 
75
      if (hname[i]<=32 && hname[i]>126) return -1;
 
76
   }
 
77
   return 0;
 
78
}
 
79
 
 
80
static int check_term(char *termtype) {
 
81
   int i;
 
82
   if (strlen(termtype) > 32) return -1;
 
83
   for (i=0; termtype[i]; i++) {
 
84
      if (!isalnum(termtype[i]) && !strchr("+._-", termtype[i])) return -1;
 
85
   }
 
86
   return 0;
 
87
}
 
88
 
 
89
static int check_display(char *disp) {
 
90
   char *colon, *s;
 
91
   struct hostent *hp;
 
92
   int num;
 
93
 
 
94
   colon = strchr(disp, ':');
 
95
   if (!colon) return -1;
 
96
   *colon = 0;  /* temporarily */
 
97
 
 
98
   if (check_a_hostname(disp)) return -1;
 
99
 
 
100
   hp = gethostbyname(disp);
 
101
   if (!hp) return -1;
 
102
 
 
103
   *colon = ':';
 
104
   s = colon+1;
 
105
   while (*s && isdigit(*s)) s++;
 
106
   if (*s) {
 
107
      if (*s!='.') return -1;
 
108
      s++;
 
109
      while (*s && isdigit(*s)) s++;
 
110
   }
 
111
   if (*s) return -1;
 
112
 
 
113
   num = atoi(colon+1);
 
114
   if (num<0 || num>99) return -1;
 
115
 
 
116
   return 0;
 
117
}
 
118
 
 
119
static int check_posixly_correct(char *val) {
 
120
   if (strlen(val)==0 || !strcmp(val, "1")) return 0;
 
121
   return -1;
 
122
}
 
123
 
 
124
static int check_remotehost(char *val) {
 
125
   if (check_a_hostname(val)) return -1;
 
126
   if (remhost && strcmp(val, remhost)) return -1;
 
127
   return 0;
 
128
}
 
129
 
 
130
struct {
 
131
   const char *name;
 
132
   int (*validator)(char *);
 
133
} legal_envs[] = {
 
134
   { "TERM", check_term },
 
135
   { "DISPLAY", check_display },
 
136
   { "POSIXLY_CORRECT", check_posixly_correct },
 
137
   { "REMOTEHOST", check_remotehost },
 
138
   { NULL, NULL }
 
139
};
 
140
 
 
141
static void validate_tty(void) {
 
142
   struct stat buf, buf2;
 
143
   const char *tty;
 
144
   pid_t pgrp;
 
145
 
 
146
   tty = ttyname(0);
 
147
   if (!tty) die("stdin not a tty");
 
148
 
 
149
   if (fstat(0, &buf)) die("fstat stdin");
 
150
   if (!S_ISCHR(buf.st_mode)) die("stdin not char device");
 
151
 
 
152
   if (fstat(1, &buf2)) die("fstat stdout");
 
153
   if (!S_ISCHR(buf2.st_mode)) die("stdout not char device");
 
154
   if (buf.st_rdev!=buf2.st_rdev) die("stdout and stdin not same tty");
 
155
 
 
156
   if (fstat(2, &buf2)) die("fstat stderr");
 
157
   if (!S_ISCHR(buf2.st_mode)) die("stderr not char device");
 
158
   if (buf.st_rdev!=buf2.st_rdev) die("stderr and stdin not same tty");
 
159
   
 
160
   if (ioctl(0, TIOCGPGRP, &pgrp)) die("cannot get tty process group");
 
161
   if (pgrp != getpgrp()) die("not foreground pgrp of tty");
 
162
   if (pgrp != getpid()) die("not process group leader");
 
163
}
 
164
 
 
165
int main(int argc, char *argv[]) {
 
166
   static char argv0[] = "login";
 
167
   int argn, i, j;
 
168
   const char *rh = NULL;
 
169
   char **envs = __environ;
 
170
 
 
171
   /* make as sure as possible no library routines or anything can use it */
 
172
   __environ = NULL;
 
173
 
 
174
   /* first, make sure our stdin/stdout/stderr are aimed somewhere */
 
175
   i = open("/", O_RDONLY);
 
176
   if (i<3) {
 
177
      /* Oops. Can't even print an error message... */
 
178
      exit(100);
 
179
   }
 
180
   close(i);
 
181
 
 
182
   /* check args */
 
183
   argn=1;
 
184
   if (argc<1) {
 
185
      die("Illegal args: argc < 1");
 
186
   }
 
187
   if (argn < argc && !strcmp(argv[argn], "-h")) {
 
188
      argn++;
 
189
      if (argn==argc) die("Illegal args: -h requires argument");
 
190
      if (check_a_hostname(argv[argn])) die("Illegal remote host specified");
 
191
      rh = argv[argn];
 
192
      argn++;
 
193
   }
 
194
   if (argn < argc && !strcmp(argv[argn], "-p")) {
 
195
      argn++;
 
196
   }
 
197
   if (argn < argc) die("Illegal args: too many args");
 
198
   argv[0] = argv0;
 
199
 
 
200
   /* check environment */
 
201
   if (envs) for (i=0; envs[i]; i++) {
 
202
      char *testenv = envs[i];
 
203
      size_t testlen = strlen(testenv);
 
204
      int ok = 0;
 
205
      for (j=0; legal_envs[j].name && !ok; j++) {
 
206
         const char *okenv = legal_envs[j].name;
 
207
         size_t oklen = strlen(okenv);
 
208
 
 
209
         if (testlen < oklen) continue;
 
210
         if (testenv[oklen]!='=') continue;
 
211
         if (memcmp(testenv, okenv, oklen)) continue;
 
212
         if (legal_envs[j].validator(testenv+oklen+1)) {
 
213
            die("Invalid environment: bad value for %s", okenv);
 
214
         }
 
215
         ok = 1;
 
216
      }
 
217
      if (!ok) {
 
218
         die("Illegal environment: forbidden variable");
 
219
      }
 
220
   }
 
221
 
 
222
   /* unignore all signals so they get cleared at exec time */
 
223
   for (i=1; i<NSIG; i++) {
 
224
      signal(i, SIG_DFL);
 
225
   }
 
226
 
 
227
   /* just in case */
 
228
   if (chdir("/")) die("chdir to / failed");
 
229
 
 
230
   /* 
 
231
    * don't do anything with uids and gids, as login is normally meant
 
232
    * to be able to take care of them.  
 
233
    * 
 
234
    * but, should we insist that ruid==nobody?
 
235
    */
 
236
 
 
237
   /*
 
238
    * don't do anything with limits, itimers, or process priority either
 
239
    */
 
240
 
 
241
   /*
 
242
    * should we check to make sure stdin=stdout=stderr and they're a tty
 
243
    * and it's our controlling tty [hard] and we're the leader of the 
 
244
    * foreground process group?
 
245
    *
 
246
    * Yeah, we should.
 
247
    */
 
248
   validate_tty();
 
249
 
 
250
   /*
 
251
    * now exec login
 
252
    * argv[0] was set up above.
 
253
    */
 
254
   execve(_PATH_LOGIN, argv, envs);
 
255
   exit(255);
 
256
}