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

« back to all changes in this revision

Viewing changes to .pc/545-track_scm.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.2 2004/11/07 15:47:43 ianb 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
#include <syslog.h>
 
55
 
 
56
#ifndef _PATH_LOGIN
 
57
#define _PATH_LOGIN "/bin/login"
 
58
#endif
 
59
 
 
60
extern char **environ;
 
61
 
 
62
static const char *remhost = NULL;
 
63
 
 
64
static void die(const char *, ...) __attribute__ ((noreturn));
 
65
 
 
66
static void die(const char *fmt, ...) {
 
67
   va_list ap;
 
68
   openlog("telnetlogin", LOG_PID, LOG_AUTHPRIV);
 
69
   va_start(ap, fmt);
 
70
   vsyslog(LOG_CRIT, fmt, ap);
 
71
   va_end(ap);
 
72
   exit(1);
 
73
}
 
74
 
 
75
static int check_a_hostname(char *hname) {
 
76
   int i=0;
 
77
   /* should we check length? */
 
78
   for (i=0; hname[i]; i++) {
 
79
      if ((hname[i]<=32) || (hname[i]>126)) return -1;
 
80
   }
 
81
   return 0;
 
82
}
 
83
 
 
84
static int check_username(char *username) {
 
85
   int i;
 
86
   if (strlen(username) > 32) return -1;
 
87
   for (i=0; username[i]; i++) {
 
88
      if ((username[i]<=32) || (username[i]>126)) return -1;
 
89
   }
 
90
   return 0;
 
91
}
 
92
 
 
93
static int check_term(char *termtype) {
 
94
   int i;
 
95
   if (strlen(termtype) > 32) return -1;
 
96
   for (i=0; termtype[i]; i++) {
 
97
      if (!isalnum(termtype[i]) && !strchr("+._-", termtype[i])) return -1;
 
98
   }
 
99
   return 0;
 
100
}
 
101
 
 
102
static int check_remotehost(char *val) {
 
103
   if (check_a_hostname(val)) return -1;
 
104
   if (remhost && strcmp(val, remhost)) return -1;
 
105
   return 0;
 
106
}
 
107
 
 
108
struct {
 
109
   const char *name;
 
110
   int (*validator)(char *);
 
111
} legal_envs[] = {
 
112
   { "TERM", check_term },
 
113
   { "REMOTEHOST", check_remotehost },
 
114
   { NULL, NULL }
 
115
};
 
116
 
 
117
static void validate_tty(void) {
 
118
   struct stat buf, buf2;
 
119
   const char *tty;
 
120
   pid_t pgrp;
 
121
 
 
122
   tty = ttyname(0);
 
123
   if (!tty) die("stdin not a tty");
 
124
 
 
125
   if (fstat(0, &buf)) die("fstat stdin");
 
126
   if (!S_ISCHR(buf.st_mode)) die("stdin not char device");
 
127
 
 
128
   if (fstat(1, &buf2)) die("fstat stdout");
 
129
   if (!S_ISCHR(buf2.st_mode)) die("stdout not char device");
 
130
   if (buf.st_rdev!=buf2.st_rdev) die("stdout and stdin not same tty");
 
131
 
 
132
   if (fstat(2, &buf2)) die("fstat stderr");
 
133
   if (!S_ISCHR(buf2.st_mode)) die("stderr not char device");
 
134
   if (buf.st_rdev!=buf2.st_rdev) die("stderr and stdin not same tty");
 
135
   
 
136
   if (ioctl(0, TIOCGPGRP, &pgrp)) die("cannot get tty process group");
 
137
   if (pgrp != getpgrp()) die("not foreground pgrp of tty");
 
138
   if (pgrp != getpid()) die("not process group leader");
 
139
}
 
140
 
 
141
int main(int argc, char *argv[]) {
 
142
   static char argv0[] = "login";
 
143
   int argn, i, j;
 
144
   const char *rh = NULL;
 
145
   char **envs = environ;
 
146
 
 
147
   /* first, make sure our stdin/stdout/stderr are aimed somewhere */
 
148
   i = open("/", O_RDONLY);
 
149
   if (i<3) {
 
150
      /* Oops. Can't even print an error message... */
 
151
      exit(100);
 
152
   }
 
153
   close(i);
 
154
 
 
155
   /* check args */
 
156
   argn=1;
 
157
   if (argc<1) {
 
158
      die("Illegal args: argc < 1");
 
159
   }
 
160
   if (argn < argc && !strcmp(argv[argn], "-h")) {
 
161
      argn++;
 
162
      if (argn==argc) die("Illegal args: -h requires argument");
 
163
      if (check_a_hostname(argv[argn])) die("Illegal remote host specified");
 
164
      rh = argv[argn];
 
165
      argn++;
 
166
   }
 
167
   if (argn < argc && !strcmp(argv[argn], "-p")) {
 
168
      argn++;
 
169
   }
 
170
   if (argn < argc && !strcmp(argv[argn], "-f")) {
 
171
      argn++;
 
172
      if (argn==argc) die("Illegal args: -f requires argument");
 
173
      if (check_username(argv[argn])) die("Illegal remote username specified");
 
174
      argn++;
 
175
   }
 
176
   if (argn < argc && argv[argn][0] != '-') {
 
177
      argn++;
 
178
   }
 
179
   if (argn < argc) die("Illegal args: too many args");
 
180
   argv[0] = argv0;
 
181
 
 
182
   /* check environment */
 
183
   if (envs) for (i=0; envs[i]; i++) {
 
184
      char *testenv = envs[i];
 
185
      size_t testlen = strlen(testenv);
 
186
      for (j=0; legal_envs[j].name; j++) {
 
187
         const char *okenv = legal_envs[j].name;
 
188
         size_t oklen = strlen(okenv);
 
189
         int sign;
 
190
 
 
191
         if (testlen < oklen) continue;
 
192
         if (testenv[oklen]!='=') continue;
 
193
         if ((sign = memcmp(testenv, okenv, oklen)) < 0) {
 
194
            continue;
 
195
         } else if (sign > 0) {
 
196
            break;
 
197
         }
 
198
         if (legal_envs[j].validator(testenv+oklen+1)) {
 
199
            die("Invalid environment: bad value for %s", okenv);
 
200
         }
 
201
         break;
 
202
      }
 
203
   }
 
204
 
 
205
   /* unignore all signals so they get cleared at exec time */
 
206
   for (i=1; i<NSIG; i++) {
 
207
      signal(i, SIG_DFL);
 
208
   }
 
209
 
 
210
   /* just in case */
 
211
   if (chdir("/")) die("chdir to / failed");
 
212
 
 
213
   /* 
 
214
    * don't do anything with uids and gids, as login is normally meant
 
215
    * to be able to take care of them.  
 
216
    * 
 
217
    * but, should we insist that ruid==nobody?
 
218
    */
 
219
 
 
220
#ifdef debian
 
221
   /*
 
222
    * Debian's /bin/login doesn't work properly unless we're really root.
 
223
    */
 
224
   setuid(0);
 
225
#endif
 
226
 
 
227
   /*
 
228
    * don't do anything with limits, itimers, or process priority either
 
229
    */
 
230
 
 
231
   /*
 
232
    * should we check to make sure stdin=stdout=stderr and they're a tty
 
233
    * and it's our controlling tty [hard] and we're the leader of the 
 
234
    * foreground process group?
 
235
    *
 
236
    * Yeah, we should.
 
237
    */
 
238
   validate_tty();
 
239
 
 
240
   /*
 
241
    * now exec login
 
242
    * argv[0] was set up above.
 
243
    */
 
244
   execve(_PATH_LOGIN, argv, envs);
 
245
   exit(255);
 
246
}