1 /*
2  * One-time password login library
3  *
4  * Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/>
5  */
6 
7 #ifndef OTPW_H
8 #define OTPW_H
9 
10 #include <pwd.h>
11 #include <sys/types.h>
12 #include "md.h"
13 
14 /* password authentication results (returned by otpw_verify()) */
15 
16 #define OTPW_OK     0   /* this was the correct password */
17 #define OTPW_WRONG  1   /* this was the wrong password */
18 #define OTPW_ERROR  2   /* user has not registered for the OTPW service
19 			 * or something else went wrong */
20 
21 /* flags for otpw_prepare() */
22 
23 #define OTPW_DEBUG   1  /* output debugging messages via DEBUG_LOG macro */
24 #define OTPW_NOLOCK  2  /* disable locking, never create or check OTPW_LOCK */
25 
26 /*
27  * A data structure used by otpw_prepare to return the
28  * selected challenge
29  */
30 
31 struct challenge {
32   char challenge[81];   /* print this string before "Password:" */
33   int passwords;        /* number of req. passwords (0, 1, otpw_multi) */
34   int locked;           /* flag, whether lock has been set */
35   int entries;          /* number of entries in OTPW file */
36   int pwlen;            /* number of characters in password */
37   int challen;          /* number of characters in challenge string */
38   int hlen;             /* number of characters in hash value */
39   int remaining;        /* number of remaining unused OTPW file entries */
40   uid_t uid;            /* effective uid for OTPW file/lock access */
41   gid_t gid;            /* effective gid for OTPW file/lock access */
42   int *selection;       /* position of the otpw_multi requested passwords */
43   char **hash;          /* base64 hash values of the otpw_multi requested
44 			   passwords, each otpw_hlen+1 bytes long */
45   int flags;            /* 1 : debug messages, 2: no locking */
46   char *filename;       /* path of .otpw file (malloc'ed) */
47   char *lockfilename;   /* path of .optw.lock file (malloc'ed) */
48 };
49 
50 /*
51  * Call otpw_prepare() after the user has entered their login name and
52  * has requested OTPW authentication, and after and you have retrieved
53  * their password database entry *user. After the call, ch->challenge
54  * will contain a string that you have to present to the user before
55  * they can enter the password. If ch->challenge[0] == 0 then one-time
56  * password authentication is not possible at this time. Once you have
57  * received the password, pass it to otpw_verify() along with the same
58  * struct *ch used here.
59  */
60 
61 void otpw_prepare(struct challenge *ch, struct passwd *user, int flags);
62 
63 /*
64  * After the one-time password has been entered, call optw_verify() to
65  * find out whether the password was ok. The parameters are the
66  * challenge structure filled previously by otpw_prepare() and the
67  * password that the user has provided ('\0' terminated). Accept the
68  * user if and only if the return value is OTPW_OK.
69  *
70  * IMPORTANT: If otpw_prepare() returned a non-empty challenge string
71  * (ch->challenge[0] != 0), then you MUST call otpw_verify(), even if
72  * the login was aborted and you are not any more interested in the
73  * result. Otherwise a stale lock might remain.
74  *
75  * After a successful login, check whether ch->entries > 2 *
76  * ch->remaining and remind the user to generate new passwords if
77  * so.
78  */
79 
80 int otpw_verify(struct challenge *ch, char *password);
81 
82 /* buffer to hold the result of getpwnam_r() or getpwuid_r();
83  * essentially a struct passwd plus space for the strings
84  * that it might refer to */
85 struct otpw_pwdbuf {
86   struct passwd pwd;
87   size_t buflen;
88   char buf[0]; /* actual size is buflen if allocated by otpw_malloc_pwdbuf() */
89 };
90 
91 /* some functions for dealing with struct pwdbuf */
92 
93 int otpw_getpwnam(const char *name, struct otpw_pwdbuf **result);
94 int otpw_getpwuid(uid_t uid, struct otpw_pwdbuf **result);
95 
96 /*
97  * Check if the user otpw_autopseudouser exists and had a UID of not
98  * higher than otpw_autopseudouser_maxuid. If so, malloc and set
99  * otpw_pseudouser accordingly.
100  */
101 int otpw_set_pseudouser();
102 
103 /* some global variables with configuration options */
104 
105 extern char *otpw_file;
106 extern char *otpw_locksuffix;
107 extern int otpw_multi;
108 extern int otpw_hlen;
109 extern char *otpw_magic;
110 extern double otpw_locktimeout;
111 extern struct otpw_pwdbuf *otpw_pseudouser;
112 
113 #endif
114