1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/*
2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Dropbear - a SSH2 server
3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Copied from OpenSSH-3.5p1 source, modified by Matt Johnston 2003
5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Author: Tatu Ylonen <ylo@cs.hut.fi>
7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *                    All rights reserved
9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Allocating a pseudo-terminal, and making it the controlling tty.
10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * As far as I am concerned, the code I have written for this software
12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * can be used freely for any purpose.  Any derived versions of this
13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * software must be clearly marked as such, and if the derived work is
14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * incompatible with the protocol description in the RFC file, it must be
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * called by a name other than "ssh" or "Secure Shell".
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/*RCSID("OpenBSD: sshpty.c,v 1.7 2002/06/24 17:57:20 deraadt Exp ");*/
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "includes.h"
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "dbutil.h"
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "errno.h"
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "sshpty.h"
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#undef HAVE_DEV_PTMX
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef HAVE_PTY_H
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project# include <pty.h>
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#if defined(USE_DEV_PTMX) && defined(HAVE_STROPTS_H)
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project# include <stropts.h>
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef O_NOCTTY
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define O_NOCTTY 0
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/*
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Allocates and opens a pty.  Returns 0 if no pty could be allocated, or
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * nonzero if a pty was successfully allocated.  On success, open file
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * descriptors for the pty and tty sides and the name of the tty side are
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * returned (the buffer must be able to hold at least 64 characters).
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectpty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#if defined(HAVE_OPENPTY)
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* exists in recent (4.4) BSDs and OSF/1 */
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	char *name;
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int i;
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	i = openpty(ptyfd, ttyfd, NULL, NULL, NULL);
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (i < 0) {
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"pty_allocate: openpty: %.100s", strerror(errno));
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	name = ttyname(*ttyfd);
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (!name) {
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("ttyname fails for openpty device");
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	strlcpy(namebuf, name, namebuflen);	/* possible truncation */
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	return 1;
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else /* HAVE_OPENPTY */
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef HAVE__GETPTY
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/*
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * pty's automagically when needed
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 */
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	char *slave;
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	slave = _getpty(ptyfd, O_RDWR, 0622, 0);
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (slave == NULL) {
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"pty_allocate: _getpty: %.100s", strerror(errno));
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	strlcpy(namebuf, slave, namebuflen);
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Open the slave side. */
85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (*ttyfd < 0) {
87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"pty_allocate error: ttyftd open error");
89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		close(*ptyfd);
90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	return 1;
93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else /* HAVE__GETPTY */
94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#if defined(USE_DEV_PTMX)
95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/*
96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * also has bsd-style ptys, but they simply do not work.)
98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 *
99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * Linux systems may have the /dev/ptmx device, but this code won't work.
100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 */
101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int ptm;
102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	char *pts;
103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ptm < 0) {
106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"pty_allocate: /dev/ptmx: %.100s", strerror(errno));
108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (grantpt(ptm) < 0) {
111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"grantpt: %.100s", strerror(errno));
113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (unlockpt(ptm) < 0) {
116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"unlockpt: %.100s", strerror(errno));
118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	pts = ptsname(ptm);
121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (pts == NULL) {
122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"Slave pty side name could not be obtained.");
124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	strlcpy(namebuf, pts, namebuflen);
126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	*ptyfd = ptm;
127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Open the slave side. */
129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (*ttyfd < 0) {
131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"error opening pts %.100s: %.100s", namebuf, strerror(errno));
133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		close(*ptyfd);
134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef HAVE_CYGWIN
137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/*
138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * Push the appropriate streams modules, as described in Solaris pts(7).
139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * HP-UX pts(7) doesn't have ttcompat module.
140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 */
141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) {
142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"ioctl I_PUSH ptem: %.100s", strerror(errno));
144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) {
146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"ioctl I_PUSH ldterm: %.100s", strerror(errno));
148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef __hpux
150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) {
151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_WARNING,
152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"ioctl I_PUSH ttcompat: %.100s", strerror(errno));
153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	return 1;
157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else /* USE_DEV_PTMX */
158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef HAVE_DEV_PTS_AND_PTC
159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* AIX-style pty code. */
160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	const char *name;
161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (*ptyfd < 0) {
164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"Could not open /dev/ptc: %.100s", strerror(errno));
166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	name = ttyname(*ptyfd);
169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (!name) {
170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("ttyname fails for /dev/ptc device");
171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	strlcpy(namebuf, name, namebuflen);
173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	*ttyfd = open(name, O_RDWR | O_NOCTTY);
174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (*ttyfd < 0) {
175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"Could not open pty slave side %.100s: %.100s",
177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		    name, strerror(errno));
178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		close(*ptyfd);
179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 0;
180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	return 1;
182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else /* HAVE_DEV_PTS_AND_PTC */
183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* BSD-style pty code. */
185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	char buf[64];
186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int i;
187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	const char *ptyminors = "0123456789abcdef";
189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int num_minors = strlen(ptyminors);
190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int num_ptys = strlen(ptymajors) * num_minors;
191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	struct termios tio;
192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	for (i = 0; i < num_ptys; i++) {
194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			 ptyminors[i % num_minors]);
196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		snprintf(namebuf, namebuflen, "/dev/tty%c%c",
197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		    ptymajors[i / num_minors], ptyminors[i % num_minors]);
198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		*ptyfd = open(buf, O_RDWR | O_NOCTTY);
200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (*ptyfd < 0) {
201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			/* Try SCO style naming */
202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			*ptyfd = open(buf, O_RDWR | O_NOCTTY);
205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			if (*ptyfd < 0) {
206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				continue;
207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			}
208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* Open the slave side. */
211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (*ttyfd < 0) {
213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			dropbear_log(LOG_ERR,
214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"pty_allocate: %.100s: %.100s", namebuf, strerror(errno));
215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			close(*ptyfd);
216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			return 0;
217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* set tty modes to a sane state for broken clients */
219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (tcgetattr(*ptyfd, &tio) < 0) {
220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			dropbear_log(LOG_WARNING,
221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"ptyallocate: tty modes failed: %.100s", strerror(errno));
222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		} else {
223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			tio.c_lflag |= (ECHO | ISIG | ICANON);
224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			tio.c_oflag |= (OPOST | ONLCR);
225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			tio.c_iflag |= ICRNL;
226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			/* Set the new modes for the terminal. */
228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) {
229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				dropbear_log(LOG_WARNING,
230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project					"Setting tty modes for pty failed: %.100s",
231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project					strerror(errno));
232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			}
233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		return 1;
236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	dropbear_log(LOG_WARNING, "failed to open any /dev/pty?? devices");
238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	return 0;
239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* HAVE_DEV_PTS_AND_PTC */
240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* USE_DEV_PTMX */
241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* HAVE__GETPTY */
242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* HAVE_OPENPTY */
243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Releases the tty.  Its ownership is returned to root, and permissions to 0666. */
246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid
248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectpty_release(const char *tty_name)
249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (chown(tty_name, (uid_t) 0, (gid_t) 0) < 0
251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			&& (errno != ENOENT)) {
252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"chown %.100s 0 0 failed: %.100s", tty_name, strerror(errno));
254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (chmod(tty_name, (mode_t) 0666) < 0
256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			&& (errno != ENOENT)) {
257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"chmod %.100s 0666 failed: %.100s", tty_name, strerror(errno));
259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Makes the tty the processes controlling tty and sets it to sane modes. */
263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid
265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectpty_make_controlling_tty(int *ttyfd, const char *tty_name)
266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int fd;
268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef USE_VHANGUP
269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	void *old;
270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* USE_VHANGUP */
271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Solaris has a problem with TIOCNOTTY for a bg process, so
273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * we disable the signal which would STOP the process - matt */
274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	signal(SIGTTOU, SIG_IGN);
275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* First disconnect from the old controlling tty. */
277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef TIOCNOTTY
278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (fd >= 0) {
280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		(void) ioctl(fd, TIOCNOTTY, NULL);
281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		close(fd);
282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* TIOCNOTTY */
284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (setsid() < 0) {
285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"setsid: %.100s", strerror(errno));
287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/*
290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * Verify that we are successfully disconnected from the controlling
291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * tty.
292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 */
293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (fd >= 0) {
295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				"Failed to disconnect from controlling tty.\n");
297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		close(fd);
298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Make it our controlling tty. */
300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef TIOCSCTTY
301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) {
302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"ioctl(TIOCSCTTY): %.100s", strerror(errno));
304f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
305f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* TIOCSCTTY */
306f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef HAVE_NEWS4
307f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (setpgrp(0,0) < 0) {
308f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
309f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			error("SETPGRP %s",strerror(errno)));
310f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
311f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* HAVE_NEWS4 */
312f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef USE_VHANGUP
313f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	old = mysignal(SIGHUP, SIG_IGN);
314f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	vhangup();
315f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	mysignal(SIGHUP, old);
316f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* USE_VHANGUP */
317f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	fd = open(tty_name, O_RDWR);
318f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (fd < 0) {
319f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
320f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"%.100s: %.100s", tty_name, strerror(errno));
321f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
322f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef USE_VHANGUP
323f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		close(*ttyfd);
324f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		*ttyfd = fd;
325f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else /* USE_VHANGUP */
326f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		close(fd);
327f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* USE_VHANGUP */
328f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
329f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Verify that we now have a controlling tty. */
330f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	fd = open(_PATH_TTY, O_WRONLY);
331f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (fd < 0) {
332f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_log(LOG_ERR,
333f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			"open /dev/tty failed - could not set controlling tty: %.100s",
334f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		    strerror(errno));
335f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
336f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		close(fd);
337f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
338f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
339f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
340f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Changes the window size associated with the pty. */
341f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
342f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid
343f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectpty_change_window_size(int ptyfd, int row, int col,
344f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int xpixel, int ypixel)
345f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
346f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	struct winsize w;
347f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
348f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	w.ws_row = row;
349f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	w.ws_col = col;
350f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	w.ws_xpixel = xpixel;
351f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	w.ws_ypixel = ypixel;
352f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	(void) ioctl(ptyfd, TIOCSWINSZ, &w);
353f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
354f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
355f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid
356f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectpty_setowner(struct passwd *pw, const char *tty_name)
357f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
358f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	struct group *grp;
359f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	gid_t gid;
360f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	mode_t mode;
361f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	struct stat st;
362f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
363f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Determine the group to make the owner of the tty. */
364f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	grp = getgrnam("tty");
365f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (grp) {
366f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		gid = grp->gr_gid;
367f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		mode = S_IRUSR | S_IWUSR | S_IWGRP;
368f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
369f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		gid = pw->pw_gid;
370f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
371f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
372f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
373f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/*
374f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * Change owner and mode of the tty as required.
375f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * Warn but continue if filesystem is read-only and the uids match/
376f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * tty is owned by root.
377f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 */
378f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (stat(tty_name, &st)) {
379f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("pty_setowner: stat(%.101s) failed: %.100s",
380f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				tty_name, strerror(errno));
381f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
382f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
383f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
384f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (chown(tty_name, pw->pw_uid, gid) < 0) {
385f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			if (errno == EROFS &&
386f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			    (st.st_uid == pw->pw_uid || st.st_uid == 0)) {
387f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				dropbear_log(LOG_ERR,
388f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project					"chown(%.100s, %u, %u) failed: %.100s",
389f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project						tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid,
390f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project						strerror(errno));
391f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			} else {
392f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				dropbear_exit("chown(%.100s, %u, %u) failed: %.100s",
393f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				    tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid,
394f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				    strerror(errno));
395f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			}
396f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
397f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
398f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
399f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {
400f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (chmod(tty_name, mode) < 0) {
401f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			if (errno == EROFS &&
402f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			    (st.st_mode & (S_IRGRP | S_IROTH)) == 0) {
403f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				dropbear_log(LOG_ERR,
404f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project					"chmod(%.100s, 0%o) failed: %.100s",
405f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project					tty_name, mode, strerror(errno));
406f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			} else {
407f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				dropbear_exit("chmod(%.100s, 0%o) failed: %.100s",
408f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				    tty_name, mode, strerror(errno));
409f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			}
410f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
411f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
412f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
413