122347Spst/* opietest.c: Quick, though definitely not complete, regression test for
222347Spst               libopie. This is intended to catch two things:
322347Spst
422347Spst	(1) when changes break something
522347Spst        (2) if some system wierdness (libc, compiler, or CPU/hardware) is
622347Spst            not getting along at all with OPIE.
722347Spst
822347Spst        It's safe to say that, if tests fail, OPIE isn't going to work right
922347Spston your system. The converse is not such a safe statement.
1022347Spst
1129964Sache%%% copyright-cmetz-96
1292906SmarkmThis software is Copyright 1996-2001 by Craig Metz, All Rights Reserved.
1392906SmarkmThe Inner Net License Version 3 applies to this software.
1422347SpstYou should have received a copy of the license with this software. If
1522347Spstyou didn't get a copy, you may request one from <license@inner.net>.
1622347Spst
1722347Spst        History:
1822347Spst
1992906Smarkm	Modified by cmetz for OPIE 2.4. Use struct opie_key for key blocks.
2029964Sache	Modified by cmetz for OPIE 2.31. Added a couple of new checks,
2129964Sache		removed a few commented-out checks for functions that
2229964Sache		no longer exist, added test-skip capability.
2322347Spst	Modified by cmetz for OPIE 2.3. Use new calling conventions for
2422347Spst		opiebtoa8()/atob8(). opiegenerator() outputs hex now.
2522347Spst	Modified by cmetz for OPIE 2.22. Test opielock()/opieunlock()
2622347Spst		refcount support.
2722347Spst	Created by cmetz for OPIE 2.2.
2822347Spst*/
2922347Spst#include "opie_cfg.h"
3022347Spst#include <stdio.h>
3122347Spst#include "opie.h"
3222347Spst
3322347Spstchar buffer[1024];
3422347Spst
3522347Spstint testatob8()
3622347Spst{
3722347Spst  static char testin[] = "0123456789abcdef";
3892906Smarkm  static unsigned char testout[sizeof(struct opie_otpkey)] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
3992906Smarkm  struct opie_otpkey key;
4092906Smarkm
4192906Smarkm  if (!opieatob8(&key, testin))
4222347Spst    return -1;
4322347Spst
4492906Smarkm  if (memcmp(&key, testout, sizeof(testout)))
4522347Spst    return -1;
4622347Spst
4722347Spst  return 0;
4822347Spst}
4922347Spst
5022347Spstint testbtoa8()
5122347Spst{
5292906Smarkm  static unsigned char testin[sizeof(struct opie_otpkey)] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
5322347Spst  static char testout[] = "0123456789abcdef";
5492906Smarkm  struct opie_otpkey testin_aligned;
5592906Smarkm
5692906Smarkm  memcpy(&testin_aligned, testin, sizeof(struct opie_otpkey));
5722347Spst
5892906Smarkm  if (!opiebtoa8(buffer, &testin_aligned))
5922347Spst    return -1;
6022347Spst
6122347Spst  if (memcmp(buffer, testout, sizeof(testout)))
6222347Spst    return -1;
6322347Spst
6422347Spst  return 0;
6522347Spst}
6622347Spst
6722347Spstint testbtoe()
6822347Spst{
6992906Smarkm  static unsigned char testin[sizeof(struct opie_otpkey)] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
7022347Spst  static char testout[] = "AIM HEW BLUM FED MITE WARM";
7192906Smarkm  struct opie_otpkey testin_aligned;
7292906Smarkm
7392906Smarkm  memcpy(&testin_aligned, testin, sizeof(struct opie_otpkey));
7422347Spst
7592906Smarkm  if (!opiebtoe(buffer, &testin_aligned))
7622347Spst    return -1;
7722347Spst
7822347Spst  if (memcmp(buffer, testout, sizeof(testout)))
7922347Spst    return -1;
8022347Spst
8122347Spst  return 0;
8222347Spst}
8322347Spst
8422347Spstint testetob()
8522347Spst{
8622347Spst  static char testin[] = "AIM HEW BLUM FED MITE WARM";
8792906Smarkm  static unsigned char testout[sizeof(struct opie_otpkey)] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
8892906Smarkm  struct opie_otpkey key;
8922347Spst
9092906Smarkm  if (opieetob(&key, testin) != 1)
9122347Spst    return -1;
9222347Spst
9392906Smarkm  if (memcmp(&key, testout, sizeof(testout)))
9422347Spst    return -1;
9522347Spst
9622347Spst  return 0;
9722347Spst}
9822347Spst
9922347Spstint testgenerator()
10022347Spst{
10122347Spst  static char testin1[] = "otp-md5 123 ke1234";
10222347Spst  static char testin2[] = "this is a test";
10322347Spst  /*  static char testout[] = "END KERN BALM NICK EROS WAVY"; */
10422347Spst  static char testout[] = "11D4 C147 E227 C1F1";
10522347Spst
10622347Spst  if (opiegenerator(testin1, testin2, buffer))
10722347Spst    return -1;
10822347Spst
10922347Spst  if (memcmp(buffer, testout, sizeof(testout)))
11022347Spst    return -1;
11122347Spst
11222347Spst  return 0;
11322347Spst}
11422347Spst
11522347Spstint testgetsequence()
11622347Spst{
11722347Spst  struct opie testin;
11822347Spst  testin.opie_n = 42;
11922347Spst
12022347Spst  if (opiegetsequence(&testin) != 42)
12122347Spst    return -1;
12222347Spst
12322347Spst  return 0;
12422347Spst}
12522347Spst
12622347Spstint testhashmd4()
12722347Spst{
12892906Smarkm  static unsigned char testin[sizeof(struct opie_otpkey)] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
12992906Smarkm  static unsigned char testout[sizeof(struct opie_otpkey)] = { 0x9f, 0x40, 0xfb, 0x84, 0xb, 0xf8, 0x7f, 0x4b };
13092906Smarkm  struct opie_otpkey testin_aligned;
13122347Spst
13292906Smarkm  memcpy(&testin_aligned, testin, sizeof(struct opie_otpkey));
13322347Spst
13492906Smarkm  opiehash(&testin_aligned, 4);
13592906Smarkm
13692906Smarkm  if (memcmp(&testin_aligned, testout, sizeof(struct opie_otpkey)))
13722347Spst    return -1;
13822347Spst
13922347Spst  return 0;
14022347Spst}
14122347Spst
14222347Spstint testhashmd5()
14322347Spst{
14422347Spst  static unsigned char testin[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
14522347Spst  static unsigned char testout[] = { 0x78, 0xdd, 0x1a, 0x37, 0xf8, 0x91, 0x54, 0xe1 };
14692906Smarkm  struct opie_otpkey testin_aligned;
14722347Spst
14892906Smarkm  memcpy(&testin_aligned, testin, sizeof(struct opie_otpkey));
14922347Spst
15092906Smarkm  opiehash(&testin_aligned, 5);
15192906Smarkm
15292906Smarkm  if (memcmp(&testin_aligned, testout, sizeof(struct opie_otpkey)))
15322347Spst    return -1;
15422347Spst
15522347Spst  return 0;
15622347Spst}
15722347Spst
15829964Sacheint testinsecure()
15929964Sache{
16029964Sache  opieinsecure();
16129964Sache
16229964Sache  return 0;
16329964Sache}
16429964Sache
16522347Spstint testkeycrunch()
16622347Spst{
16722347Spst  static char testin1[] = "ke1234";
16822347Spst  static char testin2[] = "this is a test";
16992906Smarkm  static unsigned char testout[sizeof(struct opie_otpkey)] = { 0x2e, 0xd3, 0x5d, 0x74, 0x3e, 0xa9, 0xe9, 0xe8 };
17092906Smarkm  struct opie_otpkey opie_otpkey;
17122347Spst
17292906Smarkm  if (opiekeycrunch(5, &opie_otpkey, testin1, testin2))
17322347Spst    return -1;
17422347Spst
17592906Smarkm  if (memcmp(&opie_otpkey, testout, sizeof(struct opie_otpkey)))
17622347Spst    return -1;
17722347Spst
17822347Spst  return 0;
17922347Spst}
18022347Spst
18122347Spstint testlock()
18222347Spst{
18322347Spst  int i;
18422347Spst
18529964Sache  if (getuid())
18629964Sache    return -2;
18729964Sache
18822347Spst  for (i = 0; i < 3; i++)
18922347Spst    if (opielock("__opietest"))
19022347Spst      return -1;
19122347Spst
19222347Spst  return 0;
19322347Spst}
19422347Spst
19522347Spstint testpasscheck()
19622347Spst{
19722347Spst  static char testin1[] = "abadone";
19822347Spst  static char testin2[] = "A more reasonable choice.";
19922347Spst
20022347Spst  if (!opiepasscheck(testin1))
20122347Spst    return -1;
20222347Spst
20322347Spst  if (opiepasscheck(testin2))
20422347Spst    return -1;
20522347Spst
20622347Spst  return 0;
20722347Spst}
20822347Spst
20929964Sacheint testrandomchallenge()
21029964Sache{
21129964Sache  char buffer[OPIE_CHALLENGE_MAX+1];
21229964Sache
21329964Sache  opierandomchallenge(buffer);
21429964Sache
21529964Sache  if (strncmp(buffer, "otp-", 4))
21629964Sache    return -1;
21729964Sache
21829964Sache  return 0;
21929964Sache}
22029964Sache
22122347Spstint testunlock()
22222347Spst{
22322347Spst  int i;
22422347Spst
22529964Sache  if (getuid())
22629964Sache    return -2;
22729964Sache
22822347Spst  for (i = 0; i < 3; i++)
22922347Spst    if (opieunlock())
23022347Spst      return -1;
23122347Spst
23222347Spst  if (opieunlock() != -1)
23322347Spst    return -1;
23422347Spst
23522347Spst  return 0;
23622347Spst}
23722347Spst
23822347Spststruct opietest {
23922347Spst  int (*f)();
24022347Spst  char *n;
24122347Spst};
24222347Spst
24322347Spststatic struct opietest opietests[] = {
24422347Spst  { testatob8, "atob8" },
24522347Spst  { testbtoa8, "btoa8" },
24622347Spst  { testbtoe, "btoe" },
24722347Spst  { testetob, "etob" },
24829964Sache/*  { testchallenge, "challenge" }, */
24922347Spst  { testgenerator, "generator" },
25022347Spst  { testgetsequence, "getsequence" },
25122347Spst  { testhashmd4, "hash(MD4)" },
25222347Spst  { testhashmd5, "hash(MD5)" },
25329964Sache  { testinsecure, "insecure" },
25422347Spst  { testkeycrunch, "keycrunch" },
25522347Spst  { testlock, "lock" },
25629964Sache  { testrandomchallenge, "randomchallenge" },
25722347Spst/* { testreadpass, "readpass" }, */
25822347Spst  { testunlock, "unlock" },
25929964Sache/*  { testverify, "verify" }, */
26022347Spst  { NULL, NULL }
26122347Spst};
26222347Spst
26322347Spstint main FUNCTION((argc, argv), int argc AND char *argv[])
26422347Spst{
26522347Spst  struct opietest *opietest;
26629964Sache  int tests_passed = 0;
26729964Sache  int tests_failed = 0;
26829964Sache  int tests_skipped = 0;
26929964Sache  int ntests = 0, testn = 0;
27022347Spst
27129964Sache  if (getuid() != geteuid()) {
27229964Sache    fprintf(stderr, "opietest: do not make this program setuid!\n");
27329964Sache    exit(1);
27429964Sache  };
27529964Sache
27622347Spst  for (opietest = opietests; opietest->n; opietest++)
27722347Spst    ntests++;
27822347Spst
27922347Spst  printf("opietest: executing %d tests\n", ntests);
28022347Spst
28122347Spst  for (opietest = opietests, testn = 1; opietest->n; opietest++) {
28222347Spst    printf("(%2d/%2d) testing opie%s... ", testn++, ntests, opietest->n);
28329964Sache    switch(opietest->f()) {
28429964Sache      case -2:
28529964Sache        printf("skipped\n");
28629964Sache        tests_skipped++;
28729964Sache        opietest->f = NULL;
28829964Sache        break;
28929964Sache      case -1:
29029964Sache        printf("FAILED!\n");
29129964Sache        tests_failed++;
29229964Sache        break;
29329964Sache      case 0:
29429964Sache        printf("passed\n");
29529964Sache        tests_passed++;
29629964Sache        opietest->f = NULL;
29729964Sache        break;
29822347Spst    }
29922347Spst  }
30022347Spst
30129964Sache  printf("opietest: completed %d tests. %d tests passed, %d tests skipped, %d tests failed.\n", ntests, tests_passed, tests_skipped, tests_failed);
30222347Spst  if (tests_failed) {
30322347Spst    printf("opietest: please correct the following failures before attempting to use OPIE:\n");
30422347Spst    for (opietest = opietests; opietest->n; opietest++)
30522347Spst      if (opietest->f)
30622347Spst	printf("          opie%s\n", opietest->n);
30722347Spst    exit(1);
30822347Spst  }
30922347Spst  exit(0);
31022347Spst}
311