2 * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
4 * This file is part of the pam_usb project. pam_usb is free software;
5 * you can redistribute it and/or modify it under the terms of the GNU General
6 * Public License version 2, as published by the Free Software Foundation.
8 * pam_usb is distributed in the hope that it will be useful, but WITHOUT ANY
9 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <sys/types.h>
27 #include <libhal-storage.h>
33 static FILE *pusb_pad_open_device(t_pusb_options
*opts
,
40 const char *mnt_point
;
43 mnt_point
= (char *)libhal_volume_get_mount_point(volume
);
46 memset(path
, 0x00, PATH_MAX
);
47 snprintf(path
, PATH_MAX
, "%s/%s", mnt_point
, opts
->device_pad_directory
);
48 if (stat(path
, &sb
) != 0)
50 log_debug("Directory %s does not exist, creating one.\n", path
);
51 if (mkdir(path
, S_IRUSR
| S_IWUSR
| S_IXUSR
) != 0)
53 log_debug("Unable to create directory %s: %s\n", path
,
57 memset(path
, 0x00, PATH_MAX
);
59 snprintf(path
, PATH_MAX
, "%s/%s/%s.%s.pad", mnt_point
,
60 opts
->device_pad_directory
, user
, opts
->hostname
);
61 f
= fopen(path
, mode
);
64 log_debug("Cannot open device file: %s\n", strerror(errno
));
70 static FILE *pusb_pad_open_system(t_pusb_options
*opts
,
76 struct passwd
*user_ent
= NULL
;
79 if (!(user_ent
= getpwnam(user
)) || !(user_ent
->pw_dir
))
81 log_error("Unable to retrieve informations for user \"%s\": %s\n",
85 memset(path
, 0x00, PATH_MAX
);
86 snprintf(path
, PATH_MAX
, "%s/%s", user_ent
->pw_dir
,
87 opts
->system_pad_directory
);
88 if (stat(path
, &sb
) != 0)
90 log_debug("Directory %s does not exist, creating one.\n", path
);
91 if (mkdir(path
, S_IRUSR
| S_IWUSR
| S_IXUSR
) != 0)
93 log_debug("Unable to create directory %s: %s\n", path
,
97 chown(path
, user_ent
->pw_uid
, user_ent
->pw_gid
);
98 chmod(path
, S_IRUSR
| S_IWUSR
| S_IXUSR
);
100 memset(path
, 0x00, PATH_MAX
);
101 snprintf(path
, PATH_MAX
, "%s/%s/%s.pad", user_ent
->pw_dir
,
102 opts
->system_pad_directory
, opts
->device
.name
);
103 f
= fopen(path
, mode
);
106 log_debug("Cannot open system file: %s\n", strerror(errno
));
112 static int pusb_pad_protect(const char *user
, int fd
)
114 struct passwd
*user_ent
= NULL
;
116 log_debug("Protecting pad file...\n");
117 if (!(user_ent
= getpwnam(user
)))
119 log_error("Unable to retrieve informations for user \"%s\": %s\n",
123 if (fchown(fd
, user_ent
->pw_uid
, user_ent
->pw_gid
) == -1)
125 log_debug("Unable to change owner of the pad: %s\n",
129 if (fchmod(fd
, S_IRUSR
| S_IWUSR
) == -1)
131 log_debug("Unable to change mode of the pad: %s\n",
138 static int pusb_pad_should_update(t_pusb_options
*opts
, const char *user
)
140 FILE *f_system
= NULL
;
145 log_debug("Checking whether pads are expired or not...\n");
146 if (!(f_system
= pusb_pad_open_system(opts
, user
, "r")))
148 log_debug("Unable to open system pad, pads must be generated.\n");
151 if (fstat(fileno(f_system
), &st
) == -1)
158 if (time(&now
) == ((time_t)-1))
160 log_error("Unable to fetch current time.\n");
164 delta
= now
- st
.st_mtime
;
166 if (delta
> opts
->pad_expiration
)
168 log_debug("Pads expired %u seconds ago, updating...\n",
169 delta
- opts
->pad_expiration
);
174 log_debug("Pads were generated %u seconds ago, not updating.\n",
181 static void pusb_pad_update(t_pusb_options
*opts
,
182 LibHalVolume
*volume
,
185 FILE *f_device
= NULL
;
186 FILE *f_system
= NULL
;
190 if (!pusb_pad_should_update(opts
, user
))
192 log_info("Regenerating new pads...\n");
193 if (!(f_device
= pusb_pad_open_device(opts
, volume
, user
, "w+")))
195 log_error("Unable to update pads.\n");
198 pusb_pad_protect(user
, fileno(f_device
));
200 if (!(f_system
= pusb_pad_open_system(opts
, user
, "w+")))
202 log_error("Unable to update pads.\n");
206 pusb_pad_protect(user
, fileno(f_system
));
208 log_debug("Generating %d bytes unique pad...\n", sizeof(magic
));
209 srand(getpid() * time(NULL
));
210 for (i
= 0; i
< sizeof(magic
); ++i
)
211 magic
[i
] = (char)rand();
212 log_debug("Writing pad to the device...\n");
213 fwrite(magic
, sizeof(char), sizeof(magic
), f_system
);
214 log_debug("Writing pad to the system...\n");
215 fwrite(magic
, sizeof(char), sizeof(magic
), f_device
);
216 log_debug("Synchronizing filesystems...\n");
220 log_debug("One time pads updated.\n");
223 static int pusb_pad_compare(t_pusb_options
*opts
, LibHalVolume
*volume
,
226 FILE *f_device
= NULL
;
227 FILE *f_system
= NULL
;
228 char magic_device
[1024];
229 char magic_system
[1024];
232 if (!(f_system
= pusb_pad_open_system(opts
, user
, "r")))
234 if (!(f_device
= pusb_pad_open_device(opts
, volume
, user
, "r")))
239 log_debug("Loading device pad...\n");
240 fread(magic_device
, sizeof(char), sizeof(magic_device
), f_device
);
241 log_debug("Loading system pad...\n");
242 fread(magic_system
, sizeof(char), sizeof(magic_system
), f_system
);
243 retval
= memcmp(magic_system
, magic_device
, sizeof(magic_system
));
247 log_debug("Pad match.\n");
248 return (retval
== 0);
251 int pusb_pad_check(t_pusb_options
*opts
, LibHalContext
*ctx
,
254 LibHalVolume
*volume
= NULL
;
257 volume
= pusb_volume_get(opts
, ctx
);
260 retval
= pusb_pad_compare(opts
, volume
, user
);
262 pusb_pad_update(opts
, volume
, user
);
264 log_error("Pad checking failed !\n");
265 pusb_volume_destroy(volume
);