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