source: trunk/third/openssh/logintest.c @ 16801

Revision 16801, 9.0 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16800, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 2000 Andre Lucas.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 * 3. All advertising materials mentioning features or use of this software
13 *    must display the following acknowledgement:
14 *      This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/**
31 ** logintest.c:  simple test driver for platform-independent login recording
32 **               and lastlog retrieval
33 **/
34
35#include "includes.h"
36
37#include <sys/types.h>
38#include <sys/wait.h>
39#include <unistd.h>
40#include <stdlib.h>
41#include <stdio.h>
42#include <string.h>
43#include <pwd.h>
44#include <netdb.h>
45#ifdef HAVE_TIME_H
46#include <time.h>
47#endif
48
49#include "loginrec.h"
50
51RCSID("$Id: logintest.c,v 1.1.1.1 2001-11-15 19:24:35 ghudson Exp $");
52
53#ifdef HAVE___PROGNAME
54extern char *__progname;
55#else
56char *__progname;
57#endif
58
59#define PAUSE_BEFORE_LOGOUT 3
60
61int nologtest = 0;
62int compile_opts_only = 0;
63int be_verbose = 0;
64
65
66/* Dump a logininfo to stdout. Assumes a tab size of 8 chars. */
67void
68dump_logininfo(struct logininfo *li, char *descname)
69{
70        /* yes I know how nasty this is */
71        printf("struct logininfo %s = {\n\t"
72               "progname\t'%s'\n\ttype\t\t%d\n\t"
73               "pid\t\t%d\n\tuid\t\t%d\n\t"
74               "line\t\t'%s'\n\tusername\t'%s'\n\t"
75               "hostname\t'%s'\n\texit\t\t%d\n\ttermination\t%d\n\t"
76               "tv_sec\t%d\n\ttv_usec\t%d\n\t"
77               "struct login_netinfo hostaddr {\n\t\t"
78               "struct sockaddr sa {\n"
79               "\t\t\tfamily\t%d\n\t\t}\n"
80               "\t}\n"
81               "}\n",
82               descname, li->progname, li->type,
83               li->pid, li->uid, li->line,
84               li->username, li->hostname, li->exit,
85               li->termination, li->tv_sec, li->tv_usec,
86               li->hostaddr.sa.sa_family);
87}
88
89
90int
91testAPI()
92{
93        struct logininfo *li1;
94        struct passwd *pw;
95        struct hostent *he;
96        struct sockaddr_in sa_in4;
97        char cmdstring[256], stripline[8];
98        char username[32];
99#ifdef HAVE_TIME_H
100        time_t t0, t1, t2, logintime, logouttime;
101        char s_t0[64],s_t1[64],s_t2[64];
102        char s_logintime[64], s_logouttime[64]; /* ctime() strings */
103#endif
104
105        printf("**\n** Testing the API...\n**\n");
106
107        pw = getpwuid(getuid());
108        strlcpy(username, pw->pw_name, sizeof(username));
109
110        /* gethostname(hostname, sizeof(hostname)); */
111
112        printf("login_alloc_entry test (no host info):\n");
113
114        /* FIXME fake tty more effectively - this could upset some platforms */
115        li1 = login_alloc_entry((int)getpid(), username, NULL, ttyname(0));
116        strlcpy(li1->progname, "OpenSSH-logintest", sizeof(li1->progname));
117
118        if (be_verbose)
119                dump_logininfo(li1, "li1");
120
121        printf("Setting host address info for 'localhost' (may call out):\n");
122        if (! (he = gethostbyname("localhost"))) {
123                printf("Couldn't set hostname(lookup failed)\n");
124        } else {
125                /* NOTE: this is messy, but typically a program wouldn't have to set
126                 *  any of this, a sockaddr_in* would be already prepared */
127                memcpy((void *)&(sa_in4.sin_addr), (void *)&(he->h_addr_list[0][0]),
128                       sizeof(struct in_addr));
129                login_set_addr(li1, (struct sockaddr *) &sa_in4, sizeof(sa_in4));
130                strlcpy(li1->hostname, "localhost", sizeof(li1->hostname));
131        }
132        if (be_verbose)
133                dump_logininfo(li1, "li1");
134
135        if ((int)geteuid() != 0) {
136                printf("NOT RUNNING LOGIN TESTS - you are not root!\n");
137                return 1;
138        }
139
140        if (nologtest)
141                return 1;
142
143        line_stripname(stripline, li1->line, sizeof(stripline));
144
145        printf("Performing an invalid login attempt (no type field)\n--\n");
146        login_write(li1);
147        printf("--\n(Should have written errors to stderr)\n");
148
149#ifdef HAVE_TIME_H
150        (void)time(&t0);
151        strlcpy(s_t0, ctime(&t0), sizeof(s_t0));
152        t1 = login_get_lastlog_time(getuid());
153        strlcpy(s_t1, ctime(&t1), sizeof(s_t1));
154        printf("Before logging in:\n\tcurrent time is %d - %s\t"
155               "lastlog time is %d - %s\n",
156               (int)t0, s_t0, (int)t1, s_t1);
157#endif
158
159        printf("Performing a login on line %s ", stripline);
160#ifdef HAVE_TIME_H
161        (void)time(&logintime);
162        strlcpy(s_logintime, ctime(&logintime), sizeof(s_logintime));
163        printf("at %d - %s", (int)logintime, s_logintime);
164#endif
165        printf("--\n");
166        login_login(li1);
167
168        snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '",
169                 stripline);
170        system(cmdstring);
171
172        printf("--\nPausing for %d second(s)...\n", PAUSE_BEFORE_LOGOUT);
173        sleep(PAUSE_BEFORE_LOGOUT);
174
175        printf("Performing a logout ");
176#ifdef HAVE_TIME_H
177        (void)time(&logouttime);
178        strlcpy(s_logouttime, ctime(&logouttime), sizeof(s_logouttime));
179        printf("at %d - %s", (int)logouttime, s_logouttime);
180#endif
181        printf("\nThe root login shown above should be gone.\n"
182               "If the root login hasn't gone, but another user on the same\n"
183               "pty has, this is OK - we're hacking it here, and there\n"
184               "shouldn't be two users on one pty in reality...\n"
185               "-- ('who' output follows)\n");
186        login_logout(li1);
187
188        system(cmdstring);
189        printf("-- ('who' output ends)\n");
190
191#ifdef HAVE_TIME_H
192        t2 = login_get_lastlog_time(getuid());
193        strlcpy(s_t2, ctime(&t2), sizeof(s_t2));
194        printf("After logging in, lastlog time is %d - %s\n", (int)t2, s_t2);
195        if (t1 == t2)
196                printf("The lastlog times before and after logging in are the "
197                       "same.\nThis indicates that lastlog is ** NOT WORKING "
198                       "CORRECTLY **\n");
199        else if (t0 != t2)
200                /* We can be off by a second or so, even when recording works fine.
201                 * I'm not 100% sure why, but it's true. */
202                printf("** The login time and the lastlog time differ.\n"
203                       "** This indicates that lastlog is either recording the "
204                       "wrong time,\n** or retrieving the wrong entry.\n"
205                       "If it's off by less than %d second(s) "
206                       "run the test again.\n", PAUSE_BEFORE_LOGOUT);
207        else
208                printf("lastlog agrees with the login time. This is a good thing.\n");
209
210#endif
211
212        printf("--\nThe output of 'last' shown next should have "
213               "an entry for root \n  on %s for the time shown above:\n--\n",
214               stripline);
215        snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3",
216                 stripline);
217        system(cmdstring);
218
219        printf("--\nEnd of login test.\n");
220
221        login_free_entry(li1);
222
223        return 1;
224} /* testAPI() */
225
226
227void
228testLineName(char *line)
229{
230        /* have to null-terminate - these functions are designed for
231         * structures with fixed-length char arrays, and don't null-term.*/
232        char full[17], strip[9], abbrev[5];
233
234        memset(full, '\0', sizeof(full));
235        memset(strip, '\0', sizeof(strip));
236        memset(abbrev, '\0', sizeof(abbrev));
237
238        line_fullname(full, line, sizeof(full)-1);
239        line_stripname(strip, full, sizeof(strip)-1);
240        line_abbrevname(abbrev, full, sizeof(abbrev)-1);
241        printf("%s: %s, %s, %s\n", line, full, strip, abbrev);
242
243} /* testLineName() */
244
245
246int
247testOutput()
248{
249        printf("**\n** Testing linename functions\n**\n");
250        testLineName("/dev/pts/1");
251        testLineName("pts/1");
252        testLineName("pts/999");
253        testLineName("/dev/ttyp00");
254        testLineName("ttyp00");
255
256        return 1;
257} /* testOutput() */
258
259
260/* show which options got compiled in */
261void
262showOptions(void)
263{
264        printf("**\n** Compile-time options\n**\n");
265
266        printf("login recording methods selected:\n");
267#ifdef USE_LOGIN
268        printf("\tUSE_LOGIN\n");
269#endif
270#ifdef USE_UTMP
271        printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE);
272#endif
273#ifdef USE_UTMPX
274        printf("\tUSE_UTMPX (UTMPX_FILE=%s)\n", UTMPX_FILE);
275#endif
276#ifdef USE_WTMP
277        printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE);
278#endif
279#ifdef USE_WTMPX
280        printf("\tUSE_WTMPX (WTMPX_FILE=%s)\n", WTMPX_FILE);
281#endif
282#ifdef USE_LASTLOG
283        printf("\tUSE_LASTLOG (LASTLOG_FILE=%s)\n", LASTLOG_FILE);
284#endif
285        printf("\n");
286
287} /* showOptions() */
288
289
290int
291main(int argc, char *argv[])
292{
293        printf("Platform-independent login recording test driver\n");
294
295        __progname = get_progname(argv[0]);
296        if (argc == 2) {
297                if (strncmp(argv[1], "-i", 3) == 0)
298                        compile_opts_only = 1;
299                else if (strncmp(argv[1], "-v", 3) == 0)
300                        be_verbose=1;
301        }
302
303        if (!compile_opts_only) {
304                if (be_verbose && !testOutput())
305                        return 1;
306
307                if (!testAPI())
308                        return 1;
309        }
310
311        showOptions();
312
313        return 0;
314} /* main() */
315
Note: See TracBrowser for help on using the repository browser.