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 "\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 | write (fd, "\r\n", 2); |
119 | for (s = load_banner (); *s; s++) |
| |
| 15 | | Returned allocated memory | |
|
| 16 | | Loop condition is true. Entering loop body | |
|
120 | { |
121 | for (t = s; *t && *t != '\\'; t++) ; |
| 17 | | Loop condition is false. Execution continues on line 123 | |
|
122 | |
123 | write (fd, s, t - s); |
124 | if (! *t) |
| |
125 | return; |
| 19 | | Memory is never released; potential leak of memory pointed to by 't' |
|
126 | |
127 | switch (*(t + 1)) |
128 | { |
129 | case '\\': |
130 | expansion = "\\"; |
131 | break; |
132 | case 's': |
133 | expansion = u.sysname; |
134 | break; |
135 | case 'r': |
136 | expansion = u.release; |
137 | break; |
138 | case 'n': |
139 | expansion = localhost () ?: "?"; |
140 | break; |
141 | case 'l': |
142 | expansion = basename (ttyname); |
143 | break; |
144 | default: |
145 | expansion = "?"; |
146 | } |
147 | write (fd, expansion, strlen (expansion)); |
148 | |
149 | s = t + 1; |
150 | } |
151 | } |
152 | |
153 | int |
154 | main (int argc, char **argv) |
155 | { |
156 | char *linespec, *ttyname; |
157 | int tty; |
158 | struct ttyent *tt; |
159 | char *arg; |
160 | |
161 | openlog ("getty", LOG_ODELAY0x04|LOG_CONS0x02|LOG_PID0x01, LOG_AUTH(4<<3)); |
162 | |
163 | |
164 | if (argc != 3) |
| 1 | Assuming 'argc' is equal to 3 | |
|
| |
165 | { |
166 | syslog (LOG_ERR3, "Bad syntax"); |
167 | closelog (); |
168 | exit (1); |
169 | } |
170 | |
171 | |
172 | linespec = argv[1]; |
173 | |
174 | tt = getttynam (argv[2]); |
175 | asprintf (&ttyname, "%s/%s", _PATH_DEV"/dev/", argv[2]); |
176 | |
177 | chown (ttyname, 0, 0); |
178 | chmod (ttyname, 0600); |
179 | revoke (ttyname); |
180 | sleep (2); |
181 | |
182 | do |
| 4 | | Loop condition is false. Exiting loop | |
|
183 | { |
184 | tty = open (ttyname, O_RDWR(0x0001|0x0002)); |
185 | if (tty == -1) |
| |
186 | { |
187 | syslog (LOG_ERR3, "%s: %m", ttyname); |
188 | closelog (); |
189 | sleep (60); |
190 | } |
191 | } |
192 | while (tty == -1); |
193 | |
194 | set_speed (tty, linespec); |
195 | |
196 | print_banner (tty, ttyname); |
| |
197 | |
198 | if (login_tty (tty) == -1) |
199 | syslog (LOG_ERR3, "cannot set controlling terminal to %s: %m", ttyname); |
200 | |
201 | asprintf (&arg, "TERM=%s", tt ? tt->ty_type : "unknown"); |
202 | |
203 | if (tt && strcmp (tt->ty_type, "dialup") == 0) |
204 | |
205 | execl (_PATH_LOGIN"/bin/login", "login", "-e", arg, NULL((void*)0)); |
206 | else |
207 | |
208 | execl (_PATH_LOGIN"/bin/login", "login", "-e", arg, "-aNOAUTH_TIMEOUT", NULL((void*)0)); |
209 | |
210 | syslog (LOG_ERR3, "%s: %m", _PATH_LOGIN"/bin/login"); |
211 | |
212 | return 1; |
213 | } |