/* * Verify an otp by asking otpd. * Returns an OTP_* code, or -1 on system failure. * Fills in reply. */ static int otp_verify(rlm_otp_t const *opt, otp_request_t const *request, otp_reply_t *reply) { otp_fd_t *fdp; int rc; int tryagain = 2; retry: if (!tryagain--) { return -1; } fdp = otp_getfd(opt); if (!fdp || fdp->fd == -1) { return -1; } rc = otp_write(fdp, (char const *) request, sizeof(*request)); if (rc != sizeof(*request)) { if (rc == 0) { goto retry; /* otpd disconnect */ /*TODO: pause */ } else { return -1; } } rc = otp_read(fdp, (char *) reply, sizeof(*reply)); if (rc != sizeof(*reply)) { if (rc == 0) { goto retry; /* otpd disconnect */ /*TODO: pause */ } else { return -1; } } /* validate the reply */ if (reply->version != 1) { AUTH("rlm_otp: otpd reply for [%s] invalid " "(version %d != 1)", request->username, reply->version); otp_putfd(fdp, 1); return -1; } if (reply->passcode[OTP_MAX_PASSCODE_LEN] != '\0') { AUTH("rlm_otp: otpd reply for [%s] invalid " "(passcode)", request->username); otp_putfd(fdp, 1); return -1; } otp_putfd(fdp, 0); return reply->rc; }
int otp_main(int argc, char *argv[]) { int getblocknum(int argnum) { if (argnum >= argc) { errx(1, "must specify a block number"); return -1; } else { int bnum = -1; sscanf(argv[argnum], "%d", &bnum); if (bnum < 0 || bnum >= OTP_NUM_BLOCKS) { errx(1, "invalid block number"); return -1; } else { return bnum; } } } if (argc < 2) { usage(NULL); } else { const char *cmd = argv[1]; if (!strcmp(cmd, "show")) { return otp_show(); } else if (!strcmp(cmd, "read") && argc == 3) { int bnum = getblocknum(2); if (bnum >= 0) { return otp_read(bnum); } } else if (!strcmp(cmd, "write") && argc == 5) { int bnum = getblocknum(2); uint32_t expectedcrc = strtol(argv[4], NULL, 16); if (bnum >= 0) { return otp_write(bnum, argv[3], expectedcrc); } } else if (!strcmp(cmd, "lock") && argc == 4) { int bnum = getblocknum(2); int bnum2 = getblocknum(3); if (bnum >= 0 && bnum == bnum2) { otp_lock(bnum); printf("LOCKED\n"); return 0; } else { printf("FAILED\n"); return 1; } } else { usage("Invalid arguments"); } } return 0; }