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