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