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