Added initial unfs3 sources for version 0.9.22+dfsg-1maemo2
[unfs3] / unfs3 / password.c
1
2 /*
3  * UNFS3 mount password support routines
4  * (C) 2004, Peter Astrand <astrand@cendio.se>
5  * see file LICENSE for license details
6  */
7
8 #include "config.h"
9
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <rpc/rpc.h>
13 #include <limits.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #ifndef WIN32
17 #include <syslog.h>
18 #include <unistd.h>
19 #include <sys/times.h>                 /* times */
20 #endif                                 /* WIN32 */
21 #include <fcntl.h>
22 #include <sys/time.h>                  /* gettimeofday */
23 #include "md5.h"
24 #include "backend.h"
25 #include "daemon.h"                    /* logmsg */
26
27 #ifndef WIN32
28 int gen_nonce(char *nonce)
29 {
30     struct stat st;
31     struct tms tmsbuf;
32     md5_state_t state;
33     unsigned int *arr;
34     int bytes_read, fd;
35
36     if (((fd = open("/dev/urandom", O_RDONLY)) != -1)
37         || ((fd = open("/dev/random", O_RDONLY)) != -1)) {
38         bytes_read = read(fd, nonce, 32);
39         close(fd);
40         if (bytes_read == 32)
41             return 0;
42     }
43
44     /* No /dev/random; do it by hand */
45     arr = (unsigned int *) nonce;
46     stat("/tmp", &st);
47     arr[0] = st.st_mtime;
48     arr[1] = st.st_atime;
49     arr[2] = st.st_ctime;
50     arr[3] = times(&tmsbuf);
51     arr[4] = tmsbuf.tms_cutime;
52     arr[5] = tmsbuf.tms_cstime;
53     gettimeofday((struct timeval *) &arr[6], NULL);
54
55     md5_init(&state);
56     md5_append(&state, (md5_byte_t *) nonce, 32);
57     md5_finish(&state, (md5_byte_t *) nonce);
58     return 0;
59 }
60 #endif                                 /* WIN32 */
61
62 static char nibble_as_hexchar(unsigned char c)
63 {
64     if (c <= 9)
65         return c + '0';
66
67     return c - 10 + 'a';
68 }
69
70 static void hexify(md5_byte_t digest[16], char hexdigest[32])
71 {
72     int i, j;
73
74     for (i = j = 0; i < 16; i++) {
75         char c;
76
77         /* The first four bits */
78         c = (digest[i] >> 4) & 0xf;
79         hexdigest[j++] = nibble_as_hexchar(c);
80         /* The next four bits */
81         c = (digest[i] & 0xf);
82         hexdigest[j++] = nibble_as_hexchar(c);
83     }
84 }
85
86 /* Handle mount commands:
87  * Advance dpath to first slash
88  * Copy command arguments to arg. 
89 */
90 void mnt_cmd_argument(char **dpath, const char *cmd, char *arg, size_t maxlen)
91 {
92     char *slash;
93
94     *dpath += strlen(cmd);
95     strncpy(arg, *dpath, maxlen);
96     arg[maxlen] = '\0';
97
98     slash = strchr(arg, '/');
99     if (slash != NULL)
100         *slash = '\0';
101
102     *dpath += strlen(arg);
103 }
104
105 void otp_digest(char nonce[32], char *password, char hexdigest[32])
106 {
107     md5_state_t state;
108     md5_byte_t digest[16];
109
110     /* Calculate the digest, in the same way as the client did */
111     md5_init(&state);
112     md5_append(&state, (md5_byte_t *) nonce, 32);
113     md5_append(&state, (md5_byte_t *) password, strlen(password));
114     md5_finish(&state, digest);
115     hexify(digest, hexdigest);
116 }