]> andersk Git - openssh.git/blame - logintest.c
more
[openssh.git] / logintest.c
CommitLineData
1d7b9b20 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
2b87da3b 30/**
1d7b9b20 31 ** logintest.c: simple test driver for platform-independent login recording
32 ** and lastlog retrieval
33 **/
34
4fc05dfe 35#include "includes.h"
1d7b9b20 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$");
52
63f7e231 53#ifdef HAVE___PROGNAME
54extern char *__progname;
55#else
56char *__progname;
57#endif
1d7b9b20 58
4fc05dfe 59#define PAUSE_BEFORE_LOGOUT 3
60
1d7b9b20 61int nologtest = 0;
62int compile_opts_only = 0;
63int be_verbose = 0;
64
65
1d7b9b20 66/* Dump a logininfo to stdout. Assumes a tab size of 8 chars. */
5548b03a 67void
68dump_logininfo(struct logininfo *li, char *descname)
564dd50a 69{
5548b03a 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"
5548b03a 80 "\t}\n"
81 "}\n",
2b87da3b 82 descname, li->progname, li->type,
5548b03a 83 li->pid, li->uid, li->line,
2b87da3b 84 li->username, li->hostname, li->exit,
85 li->termination, li->tv_sec, li->tv_usec,
5548b03a 86 li->hostaddr.sa.sa_family);
1d7b9b20 87}
88
89
5548b03a 90int
91testAPI()
564dd50a 92{
5548b03a 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];
1d7b9b20 99#ifdef HAVE_TIME_H
4fc05dfe 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 */
1d7b9b20 103#endif
104
5548b03a 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");
4fc05dfe 113
114 /* FIXME fake tty more effectively - this could upset some platforms */
5548b03a 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");
4fc05dfe 137 return 1;
5548b03a 138 }
139
140 if (nologtest)
141 return 1;
2b87da3b 142
5548b03a 143 line_stripname(stripline, li1->line, sizeof(stripline));
1d7b9b20 144
5548b03a 145 printf("Performing an invalid login attempt (no type field)\n--\n");
146 login_write(li1);
4fc05dfe 147 printf("--\n(Should have written errors to stderr)\n");
1d7b9b20 148
149#ifdef HAVE_TIME_H
5548b03a 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);
1d7b9b20 157#endif
158
4fc05dfe 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");
5548b03a 166 login_login(li1);
2b87da3b 167
5548b03a 168 snprintf(cmdstring, sizeof(cmdstring), "who | grep '%s '",
169 stripline);
170 system(cmdstring);
2b87da3b 171
4fc05dfe 172 printf("--\nPausing for %d second(s)...\n", PAUSE_BEFORE_LOGOUT);
173 sleep(PAUSE_BEFORE_LOGOUT);
1d7b9b20 174
5548b03a 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
4fc05dfe 181 printf("\nThe root login shown above should be gone.\n"
5548b03a 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);
1d7b9b20 187
5548b03a 188 system(cmdstring);
189 printf("-- ('who' output ends)\n");
1d7b9b20 190
191#ifdef HAVE_TIME_H
5548b03a 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)
4fc05dfe 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. */
5548b03a 202 printf("** The login time and the lastlog time differ.\n"
203 "** This indicates that lastlog is either recording the "
4fc05dfe 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);
5548b03a 207 else
208 printf("lastlog agrees with the login time. This is a good thing.\n");
1d7b9b20 209
210#endif
211
5548b03a 212 printf("--\nThe output of 'last' shown next should have "
2b87da3b 213 "an entry for root \n on %s for the time shown above:\n--\n",
5548b03a 214 stripline);
215 snprintf(cmdstring, sizeof(cmdstring), "last | grep '%s ' | head -3",
216 stripline);
217 system(cmdstring);
2b87da3b 218
5548b03a 219 printf("--\nEnd of login test.\n");
1d7b9b20 220
5548b03a 221 login_free_entry(li1);
1d7b9b20 222
5548b03a 223 return 1;
1d7b9b20 224} /* testAPI() */
225
226
5548b03a 227void
228testLineName(char *line)
564dd50a 229{
5548b03a 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];
1d7b9b20 233
5548b03a 234 memset(full, '\0', sizeof(full));
235 memset(strip, '\0', sizeof(strip));
236 memset(abbrev, '\0', sizeof(abbrev));
1d7b9b20 237
5548b03a 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);
1d7b9b20 242
243} /* testLineName() */
244
245
5548b03a 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;
1d7b9b20 257} /* testOutput() */
258
259
260/* show which options got compiled in */
5548b03a 261void
262showOptions(void)
2b87da3b 263{
5548b03a 264 printf("**\n** Compile-time options\n**\n");
2b87da3b 265
5548b03a 266 printf("login recording methods selected:\n");
1d7b9b20 267#ifdef USE_LOGIN
5548b03a 268 printf("\tUSE_LOGIN\n");
1d7b9b20 269#endif
270#ifdef USE_UTMP
5548b03a 271 printf("\tUSE_UTMP (UTMP_FILE=%s)\n", UTMP_FILE);
1d7b9b20 272#endif
273#ifdef USE_UTMPX
5548b03a 274 printf("\tUSE_UTMPX (UTMPX_FILE=%s)\n", UTMPX_FILE);
1d7b9b20 275#endif
276#ifdef USE_WTMP
5548b03a 277 printf("\tUSE_WTMP (WTMP_FILE=%s)\n", WTMP_FILE);
1d7b9b20 278#endif
279#ifdef USE_WTMPX
5548b03a 280 printf("\tUSE_WTMPX (WTMPX_FILE=%s)\n", WTMPX_FILE);
1d7b9b20 281#endif
282#ifdef USE_LASTLOG
5548b03a 283 printf("\tUSE_LASTLOG (LASTLOG_FILE=%s)\n", LASTLOG_FILE);
1d7b9b20 284#endif
5548b03a 285 printf("\n");
1d7b9b20 286
1d7b9b20 287} /* showOptions() */
288
289
5548b03a 290int
291main(int argc, char *argv[])
564dd50a 292{
5548b03a 293 printf("Platform-independent login recording test driver\n");
294
63f7e231 295 __progname = get_progname(argv[0]);
5548b03a 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 }
2b87da3b 302
5548b03a 303 if (!compile_opts_only) {
304 if (be_verbose && !testOutput())
305 return 1;
2b87da3b 306
5548b03a 307 if (!testAPI())
308 return 1;
309 }
1d7b9b20 310
5548b03a 311 showOptions();
2b87da3b 312
5548b03a 313 return 0;
1d7b9b20 314} /* main() */
315
This page took 0.152564 seconds and 5 git commands to generate.