CPU: Wrong CPU Load %.
[tomato.git] / release / src / router / ppp / contrib / pppgetpass / pppgetpass.vt.c
bloba1520883cbbb2928c38b8398bca0431ceaf2c5eb
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <sys/stat.h>
8 #include <sys/ioctl.h>
9 #include <syslog.h>
10 #include <termios.h>
11 #include <sys/vt.h>
13 static int console_owner(uid_t, int);
15 int main(int argc, char **argv)
17 int console;
18 uid_t uid;
19 struct vt_stat origstate;
20 int openvtnum;
21 char openvtname[256];
22 int openvt;
23 gid_t gid;
24 int chowned;
25 FILE *fp;
26 struct termios t;
27 char pass[256], *nl;
28 int outfd, passlen;
29 ssize_t wrote;
30 console=open("/dev/console", O_RDWR);
32 uid=getuid();
33 gid=getgid();
34 seteuid(uid);
36 openlog(argv[0], LOG_PID, LOG_DAEMON);
38 if(argc!=4) {
39 syslog(LOG_WARNING, "Usage error");
40 return 1;
43 if(console<0) {
44 syslog(LOG_ERR, "open(/dev/console): %m");
45 return 1;
48 if(ioctl(console, VT_GETSTATE, &origstate)<0) {
49 syslog(LOG_ERR, "VT_GETSTATE: %m");
50 return 1;
53 if(uid) {
54 if(!console_owner(uid, origstate.v_active)) {
55 int i;
56 for(i=0;i<64;++i) {
57 if(i!=origstate.v_active && console_owner(uid, i))
58 break;
60 if(i==64) {
61 syslog(LOG_WARNING, "run by uid %lu not at console", (unsigned long)uid);
62 return 1;
67 if(ioctl(console, VT_OPENQRY, &openvtnum)<0) {
68 syslog(LOG_ERR, "VT_OPENQRY: %m");
69 return 1;
71 if(openvtnum==-1) {
72 syslog(LOG_ERR, "No free VTs");
73 return 1;
76 snprintf(openvtname, sizeof openvtname, "/dev/tty%d", openvtnum);
77 seteuid(0);
78 openvt=open(openvtname, O_RDWR);
79 if(openvt<0) {
80 seteuid(uid);
81 syslog(LOG_ERR, "open(%s): %m", openvtname);
82 return 1;
85 chowned=fchown(openvt, uid, gid);
86 if(chowned<0) {
87 seteuid(uid);
88 syslog(LOG_ERR, "fchown(%s): %m", openvtname);
89 return 1;
92 close(console);
94 if(ioctl(openvt, VT_ACTIVATE, openvtnum)<0) {
95 seteuid(uid);
96 syslog(LOG_ERR, "VT_ACTIVATE(%d): %m", openvtnum);
97 return 1;
100 while(ioctl(openvt, VT_WAITACTIVE, openvtnum)<0) {
101 if(errno!=EINTR) {
102 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
103 seteuid(uid);
104 syslog(LOG_ERR, "VT_WAITACTIVE(%d): %m", openvtnum);
105 return 1;
109 seteuid(uid);
110 fp=fdopen(openvt, "r+");
111 if(!fp) {
112 seteuid(0);
113 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
114 seteuid(uid);
115 syslog(LOG_ERR, "fdopen(%s): %m", openvtname);
116 return 1;
119 if(tcgetattr(openvt, &t)<0) {
120 seteuid(0);
121 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
122 seteuid(uid);
123 syslog(LOG_ERR, "tcgetattr(%s): %m", openvtname);
124 return 1;
126 t.c_lflag &= ~ECHO;
127 if(tcsetattr(openvt, TCSANOW, &t)<0) {
128 seteuid(0);
129 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
130 seteuid(uid);
131 syslog(LOG_ERR, "tcsetattr(%s): %m", openvtname);
132 return 1;
135 if(fprintf(fp, "\033[2J\033[H")<0) {
136 seteuid(0);
137 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
138 seteuid(uid);
139 syslog(LOG_ERR, "write error on %s: %m", openvtname);
140 return 1;
142 if(argv[1][0] && argv[2][0]) {
143 if(fprintf(fp, "Password for PPP client %s on server %s: ", argv[1], argv[2])<0) {
144 seteuid(0);
145 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
146 seteuid(uid);
147 syslog(LOG_ERR, "write error on %s: %m", openvtname);
148 return 1;
150 } else if(argv[1][0] && !argv[2][0]) {
151 if(fprintf(fp, "Password for PPP client %s: ", argv[1])<0) {
152 syslog(LOG_ERR, "write error on %s: %m", openvtname);
153 seteuid(0);
154 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
155 seteuid(uid);
156 return 1;
158 } else if(!argv[1][0] && argv[2][0]) {
159 if(fprintf(fp, "Password for PPP on server %s: ", argv[2])<0) {
160 seteuid(0);
161 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
162 seteuid(uid);
163 syslog(LOG_ERR, "write error on %s: %m", openvtname);
164 return 1;
166 } else {
167 if(fprintf(fp, "Enter PPP password: ")<0) {
168 seteuid(0);
169 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
170 seteuid(uid);
171 syslog(LOG_ERR, "write error on %s: %m", openvtname);
172 return 1;
176 if(!fgets(pass, sizeof pass, fp)) {
177 seteuid(0);
178 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
179 seteuid(uid);
180 if(ferror(fp)) {
181 syslog(LOG_ERR, "read error on %s: %m", openvtname);
183 return 1;
185 if((nl=strchr(pass, '\n')))
186 *nl=0;
187 passlen=strlen(pass);
189 outfd=atoi(argv[3]);
190 if((wrote=write(outfd, pass, passlen))!=passlen) {
191 seteuid(0);
192 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
193 seteuid(uid);
194 if(wrote<0)
195 syslog(LOG_ERR, "write error on outpipe: %m");
196 else
197 syslog(LOG_ERR, "short write on outpipe");
198 return 1;
201 seteuid(0);
202 ioctl(openvt, VT_ACTIVATE, origstate.v_active);
203 seteuid(uid);
204 return 0;
207 static int console_owner(uid_t uid, int cons)
209 char name[256];
210 struct stat st;
211 snprintf(name, sizeof name, "/dev/tty%d", cons);
212 if(stat(name, &st)<0) {
213 if(errno!=ENOENT)
214 syslog(LOG_ERR, "stat(%s): %m", name);
215 return 0;
217 return uid==st.st_uid;