225 extern int krb5_setenv(const char *, const char *, int);
226 /* need to know what FD to use to talk to the crypto module */
227 static int cryptmod_fd = -1;
228
229 #define LOGIN_PROGRAM "/bin/login"
230
231 /*
232 * State for recv fsm
233 */
234 #define TS_DATA 0 /* base state */
235 #define TS_IAC 1 /* look for double IAC's */
236 #define TS_CR 2 /* CR-LF ->'s CR */
237 #define TS_SB 3 /* throw away begin's... */
238 #define TS_SE 4 /* ...end's (suboption negotiation) */
239 #define TS_WILL 5 /* will option negotiation */
240 #define TS_WONT 6 /* wont " */
241 #define TS_DO 7 /* do " */
242 #define TS_DONT 8 /* dont " */
243
244 static int ncc;
245 static int master; /* master side of pty */
246 static int pty; /* side of pty that gets ioctls */
247 static int net;
248 static int inter;
249 extern char **environ;
250 static char *line;
251 static int SYNCHing = 0; /* we are in TELNET SYNCH mode */
252 static int state = TS_DATA;
253
254 static int env_ovar = -1; /* XXX.sparker */
255 static int env_ovalue = -1; /* XXX.sparker */
256 static char pam_svc_name[64];
257 static boolean_t telmod_init_done = B_FALSE;
258
259 static void doit(int, struct sockaddr_storage *);
260 static void willoption(int);
261 static void wontoption(int);
262 static void dooption(int);
263 static void dontoption(int);
264 static void fatal(int, char *);
265 static void fatalperror(int, char *, int);
2737 doit(int f, struct sockaddr_storage *who)
2738 {
2739 char *host;
2740 char host_name[MAXHOSTNAMELEN];
2741 int p, t, tt;
2742 struct sgttyb b;
2743 int ptmfd; /* fd of logindmux connected to pty */
2744 int netfd; /* fd of logindmux connected to netf */
2745 struct stat buf;
2746 struct protocol_arg telnetp;
2747 struct strioctl telnetmod;
2748 struct envlist *env, *next;
2749 int nsize = 0;
2750 char abuf[INET6_ADDRSTRLEN];
2751 struct sockaddr_in *sin;
2752 struct sockaddr_in6 *sin6;
2753 socklen_t wholen;
2754 char username[MAXUSERNAMELEN];
2755 int len;
2756 uchar_t passthru;
2757 char *slavename;
2758
2759 if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) {
2760 fatalperror(f, "open /dev/ptmx", errno);
2761 }
2762 if (grantpt(p) == -1)
2763 fatal(f, "could not grant slave pty");
2764 if (unlockpt(p) == -1)
2765 fatal(f, "could not unlock slave pty");
2766 if ((slavename = ptsname(p)) == NULL)
2767 fatal(f, "could not enable slave pty");
2768 (void) dup2(f, 0);
2769 if ((t = open(slavename, O_RDWR | O_NOCTTY)) == -1)
2770 fatal(f, "could not open slave pty");
2771 if (ioctl(t, I_PUSH, "ptem") == -1)
2772 fatalperror(f, "ioctl I_PUSH ptem", errno);
2773 if (ioctl(t, I_PUSH, "ldterm") == -1)
2774 fatalperror(f, "ioctl I_PUSH ldterm", errno);
2775 if (ioctl(t, I_PUSH, "ttcompat") == -1)
2776 fatalperror(f, "ioctl I_PUSH ttcompat", errno);
2777
2778 line = slavename;
2779
2780 pty = t;
2781
2782 if (ioctl(t, TIOCGETP, &b) == -1)
2783 syslog(LOG_INFO, "ioctl TIOCGETP pty t: %m\n");
2784 b.sg_flags = O_CRMOD|O_XTABS|O_ANYP;
2785 /* XXX - ispeed and ospeed must be non-zero */
2786 b.sg_ispeed = B38400;
2787 b.sg_ospeed = B38400;
2788 if (ioctl(t, TIOCSETN, &b) == -1)
2789 syslog(LOG_INFO, "ioctl TIOCSETN pty t: %m\n");
2790 if (ioctl(pty, TIOCGETP, &b) == -1)
2791 syslog(LOG_INFO, "ioctl TIOCGETP pty pty: %m\n");
2792 b.sg_flags &= ~O_ECHO;
2793 if (ioctl(pty, TIOCSETN, &b) == -1)
2794 syslog(LOG_INFO, "ioctl TIOCSETN pty pty: %m\n");
2795
2796 if (who->ss_family == AF_INET) {
2797 char *addrbuf = NULL;
2798 char *portbuf = NULL;
3022
3023 /*
3024 * Figure out the device number of the net's mux fd, and pass that
3025 * to the ptm's mux.
3026 */
3027 if (fstat(netfd, &buf) < 0) {
3028 fatalperror(f, "fstat netfd failed", errno);
3029 }
3030 telnetp.dev = buf.st_rdev;
3031 telnetp.flag = 1;
3032
3033 telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE;
3034 telnetmod.ic_timout = -1;
3035 telnetmod.ic_len = sizeof (struct protocol_arg);
3036 telnetmod.ic_dp = (char *)&telnetp;
3037
3038 if (ioctl(ptmfd, I_STR, &telnetmod) < 0)
3039 fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n");
3040
3041 net = netfd;
3042 master = ptmfd;
3043 cryptmod_fd = netfd;
3044
3045 /*
3046 * Show banner that getty never gave, but
3047 * only if the user did not automatically authenticate.
3048 */
3049 if (getenv("USER") == NULL && auth_status < AUTH_USER)
3050 showbanner();
3051
3052 /*
3053 * If the user automatically authenticated with Kerberos
3054 * we must set the service name that PAM will use. We
3055 * need to do it BEFORE the child fork so that 'cleanup'
3056 * in the parent can call the PAM cleanup stuff with the
3057 * same PAM service that /bin/login will use to authenticate
3058 * this session.
3059 */
3060 if (auth_level >= 0 && auth_status >= AUTH_USER &&
3061 (AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) {
3062 (void) strcpy(pam_svc_name, "ktelnet");
3083 if (!myopts[TELOPT_ECHO]) {
3084 dooption(TELOPT_ECHO);
3085 }
3086
3087 /*
3088 * Is the client side a 4.2 (NOT 4.3) system? We need to know this
3089 * because 4.2 clients are unable to deal with TCP urgent data.
3090 *
3091 * To find out, we send out a "DO ECHO". If the remote system
3092 * answers "WILL ECHO" it is probably a 4.2 client, and we note
3093 * that fact ("WILL ECHO" ==> that the client will echo what
3094 * WE, the server, sends it; it does NOT mean that the client will
3095 * echo the terminal input).
3096 */
3097 send_do(TELOPT_ECHO);
3098 remopts[TELOPT_ECHO] = OPT_YES_BUT_ALWAYS_LOOK;
3099
3100 if ((pid = fork()) < 0)
3101 fatalperror(netfd, "fork", errno);
3102 if (pid)
3103 telnet(net, master);
3104 /*
3105 * The child process needs to be the session leader
3106 * and have the pty as its controlling tty. Thus we need
3107 * to re-open the slave side of the pty no without
3108 * the O_NOCTTY flag that we have been careful to
3109 * use up to this point.
3110 */
3111 (void) setsid();
3112
3113 tt = open(line, O_RDWR);
3114 if (tt < 0)
3115 fatalperror(netfd, line, errno);
3116 (void) close(netfd);
3117 (void) close(ptmfd);
3118 (void) close(f);
3119 (void) close(p);
3120 (void) close(t);
3121 if (tt != 0)
3122 (void) dup2(tt, 0);
3123 if (tt != 1)
3124 (void) dup2(tt, 1);
3125 if (tt != 2)
3126 (void) dup2(tt, 2);
3127 if (tt > 2)
3175
3176 /* If the current auth status is less than the required level, exit */
3177 if (auth_status < auth_level) {
3178 fatal(net, "Authentication failed\n");
3179 exit(EXIT_FAILURE);
3180 }
3181
3182 /*
3183 * If AUTH_VALID (proper authentication REQUIRED and we have
3184 * a krb5_name), exec '/bin/login', make sure it uses the
3185 * correct PAM service name (pam_svc_name). If possible,
3186 * make sure the krb5 authenticated user's name (krb5_name)
3187 * is in the PAM REPOSITORY for krb5.
3188 */
3189 if (auth_level >= 0 &&
3190 (auth_status == AUTH_VALID || auth_status == AUTH_USER) &&
3191 ((krb5_name != NULL) && strlen(krb5_name)) &&
3192 ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) {
3193 (void) execl(LOGIN_PROGRAM, "login",
3194 "-p",
3195 "-d", slavename,
3196 "-h", host,
3197 "-u", krb5_name,
3198 "-s", pam_svc_name,
3199 "-R", KRB5_REPOSITORY_NAME,
3200 AuthenticatingUser, 0);
3201 } else if (auth_level >= 0 &&
3202 auth_status >= AUTH_USER &&
3203 (((AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) ||
3204 getenv("USER"))) {
3205 /*
3206 * If we only know the name but not the principal,
3207 * login will have to authenticate further.
3208 */
3209 (void) execl(LOGIN_PROGRAM, "login",
3210 "-p",
3211 "-d", slavename,
3212 "-h", host,
3213 "-s", pam_svc_name, "--",
3214 (AuthenticatingUser != NULL ? AuthenticatingUser :
3215 getenv("USER")), 0);
3216
3217 } else /* default, no auth. info available, login does it all */ {
3218 (void) execl(LOGIN_PROGRAM, "login",
3219 "-p", "-h", host, "-d", slavename, "--",
3220 getenv("USER"), 0);
3221 }
3222
3223 fatalperror(netfd, LOGIN_PROGRAM, errno);
3224 /*NOTREACHED*/
3225 }
3226
3227 static void
3228 fatal(int f, char *msg)
3229 {
3230 char buf[BUFSIZ];
3231
3232 (void) snprintf(buf, sizeof (buf), "telnetd: %s.\r\n", msg);
3233 (void) write(f, buf, strlen(buf));
3234 exit(EXIT_FAILURE);
3235 /*NOTREACHED*/
3236 }
3237
3238 static void
3239 fatalperror(int f, char *msg, int errnum)
3240 {
3241 char buf[BUFSIZ];
3242
3243 (void) snprintf(buf, sizeof (buf),
3244 "%s: %s\r\n", msg, strerror(errnum));
3245 fatal(f, buf);
3246 /*NOTREACHED*/
3247 }
3248
3249 /*
3250 * Main loop. Select from pty and network, and
3251 * hand data to telnet receiver finite state machine
3252 * when it receives telnet protocol. Regular data
3253 * flow between pty and network takes place through
3254 * inkernel telnet streams module (telmod).
3255 */
3256 static void
3257 telnet(int net, int master)
3258 {
3259 int on = 1;
3260 char mode;
3261 struct strioctl telnetmod;
3262 int nsize = 0;
3263 char binary_in = 0;
3264 char binary_out = 0;
3265
3266 if (ioctl(net, FIONBIO, &on) == -1)
3267 syslog(LOG_INFO, "ioctl FIONBIO net: %m\n");
3268 if (ioctl(master, FIONBIO, &on) == -1)
3269 syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n");
3270 (void) signal(SIGTSTP, SIG_IGN);
3271 (void) signal(SIGCHLD, (void (*)())cleanup);
3272 (void) setpgrp();
3273
3274 /*
3275 * Call telrcv() once to pick up anything received during
3276 * terminal type negotiation.
3277 */
3278 telrcv();
3279
3280 netflush();
3281 ptyflush();
3282
3283 for (;;) {
3284 fd_set ibits, obits, xbits;
3285 int c;
3286
3287 if (ncc < 0)
3288 break;
3289
3290 FD_ZERO(&ibits);
3291 FD_ZERO(&obits);
3292 FD_ZERO(&xbits);
3293
3294 /*
3295 * If we couldn't flush all our output to the network,
3296 * keep checking for when we can.
3297 */
3298 if (nfrontp - nbackp)
3299 FD_SET(net, &obits);
3300 /*
3301 * Never look for input if there's still
3302 * stuff in the corresponding output buffer
3303 */
3304 if (pfrontp - pbackp) {
3305 FD_SET(master, &obits);
3306 } else {
3307 FD_SET(net, &ibits);
3308 }
3309 if (!SYNCHing) {
3310 FD_SET(net, &xbits);
3311 }
3312
3313 #define max(x, y) (((x) < (y)) ? (y) : (x))
3314
3315 /*
3316 * make an ioctl to telnet module (net side) to send
3317 * binary mode of telnet daemon. binary_in and
3318 * binary_out are 0 if not in binary mode.
3319 */
3320 if (binary_in != myopts[TELOPT_BINARY] ||
3321 binary_out != remopts[TELOPT_BINARY]) {
3322
3323 mode = 0;
3324 if (myopts[TELOPT_BINARY] != OPT_NO)
3325 mode |= TEL_BINARY_IN;
3373
3374 netip = netibuf;
3375 (void) memset(netibuf, 0, netibufsize);
3376
3377 ncc = 0;
3378 }
3379 } else {
3380 /*
3381 * state not changed to TS_DATA and hence, more to read
3382 * send ioctl to get one more message block.
3383 */
3384 telnetmod.ic_cmd = TEL_IOC_GETBLK;
3385 telnetmod.ic_timout = -1;
3386 telnetmod.ic_len = 0;
3387 telnetmod.ic_dp = NULL;
3388
3389 if (ioctl(net, I_STR, &telnetmod) < 0)
3390 fatal(net, "ioctl TEL_IOC_GETBLK failed\n");
3391 }
3392
3393 if ((c = select(max(net, master) + 1, &ibits, &obits, &xbits,
3394 (struct timeval *)0)) < 1) {
3395 if (c == -1) {
3396 if (errno == EINTR) {
3397 continue;
3398 }
3399 }
3400 (void) sleep(5);
3401 continue;
3402 }
3403
3404 /*
3405 * Any urgent data?
3406 */
3407 if (FD_ISSET(net, &xbits)) {
3408 SYNCHing = 1;
3409 }
3410
3411 /*
3412 * Something to read from the network...
3413 */
3414 if (FD_ISSET(net, &ibits)) {
3415 ncc = read(net, netibuf, netibufsize);
3416 if (ncc < 0 && errno == EWOULDBLOCK)
3417 ncc = 0;
3418 else {
3419 if (ncc <= 0) {
3420 break;
3421 }
3422 netip = netibuf;
3423 }
3424 }
3425
3426 if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0)
3427 netflush();
3428 if (ncc > 0)
3429 telrcv();
3430 if (FD_ISSET(master, &obits) && (pfrontp - pbackp) > 0)
3431 ptyflush();
3432 }
3433 cleanup(0);
3434 }
3435
3436 static void
3437 telrcv(void)
3438 {
3439 int c;
3440
3441 while (ncc > 0) {
3442 if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
3443 return;
3444 c = *netip & 0377;
3445 /*
3446 * Once we hit data, we want to transition back to
3447 * in-kernel processing. However, this code is shared
3448 * by getterminaltype()/ttloop() which run before the
3449 * in-kernel plumbing is available. So if we are still
3450 * processing the initial option negotiation, even TS_DATA
4262 {
4263 struct sgttyb b;
4264 struct tchars tchars;
4265
4266 ptyflush(); /* half-hearted */
4267 (void) ioctl(pty, TIOCGETP, &b);
4268 if (b.sg_flags & O_RAW) {
4269 *pfrontp++ = '\0';
4270 return;
4271 }
4272 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ?
4273 '\034' : tchars.t_quitc;
4274 }
4275
4276 static void
4277 ptyflush(void)
4278 {
4279 int n;
4280
4281 if ((n = pfrontp - pbackp) > 0)
4282 n = write(master, pbackp, n);
4283 if (n < 0)
4284 return;
4285 pbackp += n;
4286 if (pbackp == pfrontp)
4287 pbackp = pfrontp = ptyobuf;
4288 }
4289
4290 /*
4291 * nextitem()
4292 *
4293 * Return the address of the next "item" in the TELNET data
4294 * stream. This will be the address of the next character if
4295 * the current address is a user data character, or it will
4296 * be the address of the character following the TELNET command
4297 * if the current address is a TELNET IAC ("I Am a Command")
4298 * character.
4299 */
4300
4301 static char *
4302 nextitem(char *current)
4430 return;
4431 }
4432
4433 nbackp += n;
4434
4435 if (nbackp >= neturg) {
4436 neturg = 0;
4437 }
4438 if (nbackp == nfrontp) {
4439 nbackp = nfrontp = netobuf;
4440 }
4441 }
4442
4443 /* ARGSUSED */
4444 static void
4445 cleanup(int signum)
4446 {
4447 /*
4448 * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to
4449 * handle closing differently. We close "net" first and then
4450 * "master" in that order. We do close(net) first because
4451 * we have no other way to disconnect forwarding between the network
4452 * and master. So by issuing the close()'s we ensure that no further
4453 * data rises from TCP. A more complex fix would be adding proper
4454 * support for throwing a "stop" switch for forwarding data between
4455 * logindmux peers. It's possible to block in the close of the tty
4456 * while the network still receives data and the telmod module is
4457 * TEL_STOPPED. A denial-of-service attack generates this case,
4458 * see 4102102.
4459 */
4460
4461 if (!telmod_init_done) {
4462 (void) close(net);
4463 (void) close(master);
4464 }
4465 rmut();
4466
4467 exit(EXIT_FAILURE);
4468 }
4469
4470 static void
4471 rmut(void)
4472 {
4473 pam_handle_t *pamh;
4474 struct utmpx *up;
4475 char user[sizeof (up->ut_user) + 1];
4476 char ttyn[sizeof (up->ut_line) + 1];
4477 char rhost[sizeof (up->ut_host) + 1];
4478
4479 /* while cleaning up don't allow disruption */
4480 (void) signal(SIGCHLD, SIG_IGN);
4481
4482 setutxent();
4483 while (up = getutxent()) {
|
225 extern int krb5_setenv(const char *, const char *, int);
226 /* need to know what FD to use to talk to the crypto module */
227 static int cryptmod_fd = -1;
228
229 #define LOGIN_PROGRAM "/bin/login"
230
231 /*
232 * State for recv fsm
233 */
234 #define TS_DATA 0 /* base state */
235 #define TS_IAC 1 /* look for double IAC's */
236 #define TS_CR 2 /* CR-LF ->'s CR */
237 #define TS_SB 3 /* throw away begin's... */
238 #define TS_SE 4 /* ...end's (suboption negotiation) */
239 #define TS_WILL 5 /* will option negotiation */
240 #define TS_WONT 6 /* wont " */
241 #define TS_DO 7 /* do " */
242 #define TS_DONT 8 /* dont " */
243
244 static int ncc;
245 static int manager; /* manager side of pty */
246 static int pty; /* side of pty that gets ioctls */
247 static int net;
248 static int inter;
249 extern char **environ;
250 static char *line;
251 static int SYNCHing = 0; /* we are in TELNET SYNCH mode */
252 static int state = TS_DATA;
253
254 static int env_ovar = -1; /* XXX.sparker */
255 static int env_ovalue = -1; /* XXX.sparker */
256 static char pam_svc_name[64];
257 static boolean_t telmod_init_done = B_FALSE;
258
259 static void doit(int, struct sockaddr_storage *);
260 static void willoption(int);
261 static void wontoption(int);
262 static void dooption(int);
263 static void dontoption(int);
264 static void fatal(int, char *);
265 static void fatalperror(int, char *, int);
2737 doit(int f, struct sockaddr_storage *who)
2738 {
2739 char *host;
2740 char host_name[MAXHOSTNAMELEN];
2741 int p, t, tt;
2742 struct sgttyb b;
2743 int ptmfd; /* fd of logindmux connected to pty */
2744 int netfd; /* fd of logindmux connected to netf */
2745 struct stat buf;
2746 struct protocol_arg telnetp;
2747 struct strioctl telnetmod;
2748 struct envlist *env, *next;
2749 int nsize = 0;
2750 char abuf[INET6_ADDRSTRLEN];
2751 struct sockaddr_in *sin;
2752 struct sockaddr_in6 *sin6;
2753 socklen_t wholen;
2754 char username[MAXUSERNAMELEN];
2755 int len;
2756 uchar_t passthru;
2757 char *subsidname;
2758
2759 if ((p = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1) {
2760 fatalperror(f, "open /dev/ptmx", errno);
2761 }
2762 if (grantpt(p) == -1)
2763 fatal(f, "could not grant subsidiary pty");
2764 if (unlockpt(p) == -1)
2765 fatal(f, "could not unlock subsidiary pty");
2766 if ((subsidname = ptsname(p)) == NULL)
2767 fatal(f, "could not enable subsidiary pty");
2768 (void) dup2(f, 0);
2769 if ((t = open(subsidname, O_RDWR | O_NOCTTY)) == -1)
2770 fatal(f, "could not open subsidiary pty");
2771 if (ioctl(t, I_PUSH, "ptem") == -1)
2772 fatalperror(f, "ioctl I_PUSH ptem", errno);
2773 if (ioctl(t, I_PUSH, "ldterm") == -1)
2774 fatalperror(f, "ioctl I_PUSH ldterm", errno);
2775 if (ioctl(t, I_PUSH, "ttcompat") == -1)
2776 fatalperror(f, "ioctl I_PUSH ttcompat", errno);
2777
2778 line = subsidname;
2779
2780 pty = t;
2781
2782 if (ioctl(t, TIOCGETP, &b) == -1)
2783 syslog(LOG_INFO, "ioctl TIOCGETP pty t: %m\n");
2784 b.sg_flags = O_CRMOD|O_XTABS|O_ANYP;
2785 /* XXX - ispeed and ospeed must be non-zero */
2786 b.sg_ispeed = B38400;
2787 b.sg_ospeed = B38400;
2788 if (ioctl(t, TIOCSETN, &b) == -1)
2789 syslog(LOG_INFO, "ioctl TIOCSETN pty t: %m\n");
2790 if (ioctl(pty, TIOCGETP, &b) == -1)
2791 syslog(LOG_INFO, "ioctl TIOCGETP pty pty: %m\n");
2792 b.sg_flags &= ~O_ECHO;
2793 if (ioctl(pty, TIOCSETN, &b) == -1)
2794 syslog(LOG_INFO, "ioctl TIOCSETN pty pty: %m\n");
2795
2796 if (who->ss_family == AF_INET) {
2797 char *addrbuf = NULL;
2798 char *portbuf = NULL;
3022
3023 /*
3024 * Figure out the device number of the net's mux fd, and pass that
3025 * to the ptm's mux.
3026 */
3027 if (fstat(netfd, &buf) < 0) {
3028 fatalperror(f, "fstat netfd failed", errno);
3029 }
3030 telnetp.dev = buf.st_rdev;
3031 telnetp.flag = 1;
3032
3033 telnetmod.ic_cmd = LOGDMX_IOC_QEXCHANGE;
3034 telnetmod.ic_timout = -1;
3035 telnetmod.ic_len = sizeof (struct protocol_arg);
3036 telnetmod.ic_dp = (char *)&telnetp;
3037
3038 if (ioctl(ptmfd, I_STR, &telnetmod) < 0)
3039 fatal(netfd, "ioctl LOGDMX_IOC_QEXCHANGE of ptmfd failed\n");
3040
3041 net = netfd;
3042 manager = ptmfd;
3043 cryptmod_fd = netfd;
3044
3045 /*
3046 * Show banner that getty never gave, but
3047 * only if the user did not automatically authenticate.
3048 */
3049 if (getenv("USER") == NULL && auth_status < AUTH_USER)
3050 showbanner();
3051
3052 /*
3053 * If the user automatically authenticated with Kerberos
3054 * we must set the service name that PAM will use. We
3055 * need to do it BEFORE the child fork so that 'cleanup'
3056 * in the parent can call the PAM cleanup stuff with the
3057 * same PAM service that /bin/login will use to authenticate
3058 * this session.
3059 */
3060 if (auth_level >= 0 && auth_status >= AUTH_USER &&
3061 (AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) {
3062 (void) strcpy(pam_svc_name, "ktelnet");
3083 if (!myopts[TELOPT_ECHO]) {
3084 dooption(TELOPT_ECHO);
3085 }
3086
3087 /*
3088 * Is the client side a 4.2 (NOT 4.3) system? We need to know this
3089 * because 4.2 clients are unable to deal with TCP urgent data.
3090 *
3091 * To find out, we send out a "DO ECHO". If the remote system
3092 * answers "WILL ECHO" it is probably a 4.2 client, and we note
3093 * that fact ("WILL ECHO" ==> that the client will echo what
3094 * WE, the server, sends it; it does NOT mean that the client will
3095 * echo the terminal input).
3096 */
3097 send_do(TELOPT_ECHO);
3098 remopts[TELOPT_ECHO] = OPT_YES_BUT_ALWAYS_LOOK;
3099
3100 if ((pid = fork()) < 0)
3101 fatalperror(netfd, "fork", errno);
3102 if (pid)
3103 telnet(net, manager);
3104 /*
3105 * The child process needs to be the session leader
3106 * and have the pty as its controlling tty. Thus we need
3107 * to re-open the subsidiary side of the pty no without
3108 * the O_NOCTTY flag that we have been careful to
3109 * use up to this point.
3110 */
3111 (void) setsid();
3112
3113 tt = open(line, O_RDWR);
3114 if (tt < 0)
3115 fatalperror(netfd, line, errno);
3116 (void) close(netfd);
3117 (void) close(ptmfd);
3118 (void) close(f);
3119 (void) close(p);
3120 (void) close(t);
3121 if (tt != 0)
3122 (void) dup2(tt, 0);
3123 if (tt != 1)
3124 (void) dup2(tt, 1);
3125 if (tt != 2)
3126 (void) dup2(tt, 2);
3127 if (tt > 2)
3175
3176 /* If the current auth status is less than the required level, exit */
3177 if (auth_status < auth_level) {
3178 fatal(net, "Authentication failed\n");
3179 exit(EXIT_FAILURE);
3180 }
3181
3182 /*
3183 * If AUTH_VALID (proper authentication REQUIRED and we have
3184 * a krb5_name), exec '/bin/login', make sure it uses the
3185 * correct PAM service name (pam_svc_name). If possible,
3186 * make sure the krb5 authenticated user's name (krb5_name)
3187 * is in the PAM REPOSITORY for krb5.
3188 */
3189 if (auth_level >= 0 &&
3190 (auth_status == AUTH_VALID || auth_status == AUTH_USER) &&
3191 ((krb5_name != NULL) && strlen(krb5_name)) &&
3192 ((AuthenticatingUser != NULL) && strlen(AuthenticatingUser))) {
3193 (void) execl(LOGIN_PROGRAM, "login",
3194 "-p",
3195 "-d", subsidname,
3196 "-h", host,
3197 "-u", krb5_name,
3198 "-s", pam_svc_name,
3199 "-R", KRB5_REPOSITORY_NAME,
3200 AuthenticatingUser, 0);
3201 } else if (auth_level >= 0 &&
3202 auth_status >= AUTH_USER &&
3203 (((AuthenticatingUser != NULL) && strlen(AuthenticatingUser)) ||
3204 getenv("USER"))) {
3205 /*
3206 * If we only know the name but not the principal,
3207 * login will have to authenticate further.
3208 */
3209 (void) execl(LOGIN_PROGRAM, "login",
3210 "-p",
3211 "-d", subsidname,
3212 "-h", host,
3213 "-s", pam_svc_name, "--",
3214 (AuthenticatingUser != NULL ? AuthenticatingUser :
3215 getenv("USER")), 0);
3216
3217 } else /* default, no auth. info available, login does it all */ {
3218 (void) execl(LOGIN_PROGRAM, "login",
3219 "-p", "-h", host, "-d", subsidname, "--",
3220 getenv("USER"), 0);
3221 }
3222
3223 fatalperror(netfd, LOGIN_PROGRAM, errno);
3224 /*NOTREACHED*/
3225 }
3226
3227 static void
3228 fatal(int f, char *msg)
3229 {
3230 char buf[BUFSIZ];
3231
3232 (void) snprintf(buf, sizeof (buf), "telnetd: %s.\r\n", msg);
3233 (void) write(f, buf, strlen(buf));
3234 exit(EXIT_FAILURE);
3235 /*NOTREACHED*/
3236 }
3237
3238 static void
3239 fatalperror(int f, char *msg, int errnum)
3240 {
3241 char buf[BUFSIZ];
3242
3243 (void) snprintf(buf, sizeof (buf),
3244 "%s: %s\r\n", msg, strerror(errnum));
3245 fatal(f, buf);
3246 /*NOTREACHED*/
3247 }
3248
3249 /*
3250 * Main loop. Select from pty and network, and
3251 * hand data to telnet receiver finite state machine
3252 * when it receives telnet protocol. Regular data
3253 * flow between pty and network takes place through
3254 * inkernel telnet streams module (telmod).
3255 */
3256 static void
3257 telnet(int net, int manager)
3258 {
3259 int on = 1;
3260 char mode;
3261 struct strioctl telnetmod;
3262 int nsize = 0;
3263 char binary_in = 0;
3264 char binary_out = 0;
3265
3266 if (ioctl(net, FIONBIO, &on) == -1)
3267 syslog(LOG_INFO, "ioctl FIONBIO net: %m\n");
3268 if (ioctl(manager, FIONBIO, &on) == -1)
3269 syslog(LOG_INFO, "ioctl FIONBIO pty p: %m\n");
3270 (void) signal(SIGTSTP, SIG_IGN);
3271 (void) signal(SIGCHLD, (void (*)())cleanup);
3272 (void) setpgrp();
3273
3274 /*
3275 * Call telrcv() once to pick up anything received during
3276 * terminal type negotiation.
3277 */
3278 telrcv();
3279
3280 netflush();
3281 ptyflush();
3282
3283 for (;;) {
3284 fd_set ibits, obits, xbits;
3285 int c;
3286
3287 if (ncc < 0)
3288 break;
3289
3290 FD_ZERO(&ibits);
3291 FD_ZERO(&obits);
3292 FD_ZERO(&xbits);
3293
3294 /*
3295 * If we couldn't flush all our output to the network,
3296 * keep checking for when we can.
3297 */
3298 if (nfrontp - nbackp)
3299 FD_SET(net, &obits);
3300 /*
3301 * Never look for input if there's still
3302 * stuff in the corresponding output buffer
3303 */
3304 if (pfrontp - pbackp) {
3305 FD_SET(manager, &obits);
3306 } else {
3307 FD_SET(net, &ibits);
3308 }
3309 if (!SYNCHing) {
3310 FD_SET(net, &xbits);
3311 }
3312
3313 #define max(x, y) (((x) < (y)) ? (y) : (x))
3314
3315 /*
3316 * make an ioctl to telnet module (net side) to send
3317 * binary mode of telnet daemon. binary_in and
3318 * binary_out are 0 if not in binary mode.
3319 */
3320 if (binary_in != myopts[TELOPT_BINARY] ||
3321 binary_out != remopts[TELOPT_BINARY]) {
3322
3323 mode = 0;
3324 if (myopts[TELOPT_BINARY] != OPT_NO)
3325 mode |= TEL_BINARY_IN;
3373
3374 netip = netibuf;
3375 (void) memset(netibuf, 0, netibufsize);
3376
3377 ncc = 0;
3378 }
3379 } else {
3380 /*
3381 * state not changed to TS_DATA and hence, more to read
3382 * send ioctl to get one more message block.
3383 */
3384 telnetmod.ic_cmd = TEL_IOC_GETBLK;
3385 telnetmod.ic_timout = -1;
3386 telnetmod.ic_len = 0;
3387 telnetmod.ic_dp = NULL;
3388
3389 if (ioctl(net, I_STR, &telnetmod) < 0)
3390 fatal(net, "ioctl TEL_IOC_GETBLK failed\n");
3391 }
3392
3393 if ((c = select(max(net, manager) + 1, &ibits, &obits, &xbits,
3394 (struct timeval *)0)) < 1) {
3395 if (c == -1) {
3396 if (errno == EINTR) {
3397 continue;
3398 }
3399 }
3400 (void) sleep(5);
3401 continue;
3402 }
3403
3404 /*
3405 * Any urgent data?
3406 */
3407 if (FD_ISSET(net, &xbits)) {
3408 SYNCHing = 1;
3409 }
3410
3411 /*
3412 * Something to read from the network...
3413 */
3414 if (FD_ISSET(net, &ibits)) {
3415 ncc = read(net, netibuf, netibufsize);
3416 if (ncc < 0 && errno == EWOULDBLOCK)
3417 ncc = 0;
3418 else {
3419 if (ncc <= 0) {
3420 break;
3421 }
3422 netip = netibuf;
3423 }
3424 }
3425
3426 if (FD_ISSET(net, &obits) && (nfrontp - nbackp) > 0)
3427 netflush();
3428 if (ncc > 0)
3429 telrcv();
3430 if (FD_ISSET(manager, &obits) && (pfrontp - pbackp) > 0)
3431 ptyflush();
3432 }
3433 cleanup(0);
3434 }
3435
3436 static void
3437 telrcv(void)
3438 {
3439 int c;
3440
3441 while (ncc > 0) {
3442 if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
3443 return;
3444 c = *netip & 0377;
3445 /*
3446 * Once we hit data, we want to transition back to
3447 * in-kernel processing. However, this code is shared
3448 * by getterminaltype()/ttloop() which run before the
3449 * in-kernel plumbing is available. So if we are still
3450 * processing the initial option negotiation, even TS_DATA
4262 {
4263 struct sgttyb b;
4264 struct tchars tchars;
4265
4266 ptyflush(); /* half-hearted */
4267 (void) ioctl(pty, TIOCGETP, &b);
4268 if (b.sg_flags & O_RAW) {
4269 *pfrontp++ = '\0';
4270 return;
4271 }
4272 *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ?
4273 '\034' : tchars.t_quitc;
4274 }
4275
4276 static void
4277 ptyflush(void)
4278 {
4279 int n;
4280
4281 if ((n = pfrontp - pbackp) > 0)
4282 n = write(manager, pbackp, n);
4283 if (n < 0)
4284 return;
4285 pbackp += n;
4286 if (pbackp == pfrontp)
4287 pbackp = pfrontp = ptyobuf;
4288 }
4289
4290 /*
4291 * nextitem()
4292 *
4293 * Return the address of the next "item" in the TELNET data
4294 * stream. This will be the address of the next character if
4295 * the current address is a user data character, or it will
4296 * be the address of the character following the TELNET command
4297 * if the current address is a TELNET IAC ("I Am a Command")
4298 * character.
4299 */
4300
4301 static char *
4302 nextitem(char *current)
4430 return;
4431 }
4432
4433 nbackp += n;
4434
4435 if (nbackp >= neturg) {
4436 neturg = 0;
4437 }
4438 if (nbackp == nfrontp) {
4439 nbackp = nfrontp = netobuf;
4440 }
4441 }
4442
4443 /* ARGSUSED */
4444 static void
4445 cleanup(int signum)
4446 {
4447 /*
4448 * If the TEL_IOC_ENABLE ioctl hasn't completed, then we need to
4449 * handle closing differently. We close "net" first and then
4450 * "manager" in that order. We do close(net) first because
4451 * we have no other way to disconnect forwarding between the network
4452 * and manager. So by issuing the close()'s we ensure that no further
4453 * data rises from TCP. A more complex fix would be adding proper
4454 * support for throwing a "stop" switch for forwarding data between
4455 * logindmux peers. It's possible to block in the close of the tty
4456 * while the network still receives data and the telmod module is
4457 * TEL_STOPPED. A denial-of-service attack generates this case,
4458 * see 4102102.
4459 */
4460
4461 if (!telmod_init_done) {
4462 (void) close(net);
4463 (void) close(manager);
4464 }
4465 rmut();
4466
4467 exit(EXIT_FAILURE);
4468 }
4469
4470 static void
4471 rmut(void)
4472 {
4473 pam_handle_t *pamh;
4474 struct utmpx *up;
4475 char user[sizeof (up->ut_user) + 1];
4476 char ttyn[sizeof (up->ut_line) + 1];
4477 char rhost[sizeof (up->ut_host) + 1];
4478
4479 /* while cleaning up don't allow disruption */
4480 (void) signal(SIGCHLD, SIG_IGN);
4481
4482 setutxent();
4483 while (up = getutxent()) {
|