1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | #include <syslog.h> |
25 | #include <unistd.h> |
26 | #include <ttyent.h> |
27 | #include <stdio.h> |
28 | #include <fcntl.h> |
29 | #include <sys/stat.h> |
30 | #include <errno(*__errno_location ()).h> |
31 | #include <error.h> |
32 | #include <sys/utsname.h> |
33 | #include <stdlib.h> |
34 | #include <string.h> |
35 | #include <utmp.h> |
36 | #include <sys/ioctl.h> |
37 | #include <termios.h> |
38 | |
39 | |
40 | extern char *localhost (); |
41 | |
42 | #define _PATH_LOGIN"/bin/login" "/bin/login" |
43 | #define _PATH_ISSUE"/etc/issue" "/etc/issue" |
44 | |
45 | |
46 | static void |
47 | set_speed (int tty, char *speedstr) |
48 | { |
49 | error_t err; |
50 | struct termios ttystat; |
51 | speed_t speed; |
52 | char *tail; |
53 | |
54 | errno(*__errno_location ()) = 0; |
55 | speed = strtoul (speedstr, &tail, 0); |
56 | if (errno(*__errno_location ()) || *tail) |
57 | return; |
58 | |
59 | err = tcgetattr (tty, &ttystat); |
60 | if (!err && !cfsetspeed (&ttystat, speed)) |
61 | tcsetattr (tty, TCSAFLUSH2, &ttystat); |
62 | } |
63 | |
64 | |
65 | |
66 | static char * |
67 | load_banner (void) |
68 | { |
69 | char *buf = NULL((void*)0), *p; |
70 | struct stat st; |
71 | int fd; |
72 | ssize_t remaining, count; |
73 | |
74 | fd = open (_PATH_ISSUE"/etc/issue", O_RDONLY0x0001); |
75 | if (fd == -1) |
| |
76 | goto out; |
77 | |
78 | if (fstat (fd, &st) == -1) |
| |
79 | goto out; |
80 | |
81 | buf = malloc (st.st_size + 1); |
| |
82 | if (buf == NULL((void*)0)) |
| 11 | | Assuming 'buf' is not equal to null | |
|
| |
83 | goto out; |
84 | |
85 | remaining = st.st_size; |
86 | p = buf; |
87 | while (remaining > 0) |
| 13 | | Assuming 'remaining' is <= 0 | |
|
| 14 | | Loop condition is false. Execution continues on line 99 | |
|
88 | { |
89 | count = read (fd, p, remaining); |
90 | if (count == -1) |
91 | { |
92 | close (fd); |
93 | goto out; |
94 | } |
95 | p += count; |
96 | remaining -= count; |
97 | } |
98 | |
99 | buf[st.st_size] = '\0'; |
100 | close (fd); |
101 | return buf; |
102 | |
103 | out: |
104 | free (buf); |
105 | return "\r\n\n\\s \\r (\\n) (\\l)\r\n\n"; |
106 | } |
107 | |
108 | |
109 | static void |
110 | print_banner (int fd, char *ttyname) |
111 | { |
112 | char *s, *t, *expansion; |
113 | struct utsname u; |
114 | |
115 | if (uname (&u)) |
| |
116 | u.sysname[0] = u.release[0] = '\0'; |
117 | |
118 | for (s = load_banner (); *s; s++) |
| |
| 15 | | Returned allocated memory | |
|
| 16 | | Loop condition is true. Entering loop body | |
|
119 | { |
120 | for (t = s; *t && *t != '\\'; t++) ; |
| 17 | | Loop condition is false. Execution continues on line 122 | |
|
121 | |
122 | write (fd, s, t - s); |
123 | if (! *t) |
| |
124 | return; |
| 19 | | Memory is never released; potential leak of memory pointed to by 't' |
|
125 | |
126 | switch (*(t + 1)) |
127 | { |
128 | case '\\': |
129 | expansion = "\\"; |
130 | break; |
131 | case 's': |
132 | expansion = u.sysname; |
133 | break; |
134 | case 'r': |
135 | expansion = u.release; |
136 | break; |
137 | case 'n': |
138 | expansion = localhost () ?: "?"; |
139 | break; |
140 | case 'l': |
141 | expansion = basename (ttyname); |
142 | break; |
143 | default: |
144 | expansion = "?"; |
145 | } |
146 | write (fd, expansion, strlen (expansion)); |
147 | |
148 | s = t + 1; |
149 | } |
150 | } |
151 | |
152 | int |
153 | main (int argc, char **argv) |
154 | { |
155 | char *linespec, *ttyname; |
156 | int tty; |
157 | struct ttyent *tt; |
158 | char *arg; |
159 | |
160 | openlog ("getty", LOG_ODELAY0x04|LOG_CONS0x02|LOG_PID0x01, LOG_AUTH(4<<3)); |
161 | |
162 | |
163 | if (argc != 3) |
| 1 | Assuming 'argc' is equal to 3 | |
|
| |
164 | { |
165 | syslog (LOG_ERR3, "Bad syntax"); |
166 | closelog (); |
167 | exit (1); |
168 | } |
169 | |
170 | |
171 | linespec = argv[1]; |
172 | |
173 | tt = getttynam (argv[2]); |
174 | asprintf (&ttyname, "%s/%s", _PATH_DEV"/dev/", argv[2]); |
175 | |
176 | chown (ttyname, 0, 0); |
177 | chmod (ttyname, 0600); |
178 | revoke (ttyname); |
179 | sleep (2); |
180 | |
181 | do |
| 4 | | Loop condition is false. Exiting loop | |
|
182 | { |
183 | tty = open (ttyname, O_RDWR(0x0001|0x0002)); |
184 | if (tty == -1) |
| |
185 | { |
186 | syslog (LOG_ERR3, "%s: %m", ttyname); |
187 | closelog (); |
188 | sleep (60); |
189 | } |
190 | } |
191 | while (tty == -1); |
192 | |
193 | set_speed (tty, linespec); |
194 | |
195 | print_banner (tty, ttyname); |
| |
196 | |
197 | if (login_tty (tty) == -1) |
198 | syslog (LOG_ERR3, "cannot set controlling terminal to %s: %m", ttyname); |
199 | |
200 | asprintf (&arg, "TERM=%s", tt ? tt->ty_type : "unknown"); |
201 | |
202 | if (tt && strcmp (tt->ty_type, "dialup") == 0) |
203 | |
204 | execl (_PATH_LOGIN"/bin/login", "login", "-e", arg, NULL((void*)0)); |
205 | else |
206 | |
207 | execl (_PATH_LOGIN"/bin/login", "login", "-e", arg, "-aNOAUTH_TIMEOUT", NULL((void*)0)); |
208 | |
209 | syslog (LOG_ERR3, "%s: %m", _PATH_LOGIN"/bin/login"); |
210 | |
211 | return 1; |
212 | } |