]>
code.delx.au - pulseaudio/blob - src/pulsecore/authkey.c
2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
38 #include <pulse/util.h>
39 #include <pulsecore/core-error.h>
40 #include <pulsecore/core-util.h>
41 #include <pulsecore/log.h>
42 #include <pulsecore/random.h>
43 #include <pulsecore/macro.h>
47 /* Generate a new authorization key, store it in file fd and return it in *data */
48 static int generate(int fd
, void *ret_data
, size_t length
) {
53 pa_assert(length
> 0);
55 pa_random(ret_data
, length
);
57 lseek(fd
, (off_t
) 0, SEEK_SET
);
58 (void) ftruncate(fd
, (off_t
) 0);
60 if ((r
= pa_loop_write(fd
, ret_data
, length
, NULL
)) < 0 || (size_t) r
!= length
) {
61 pa_log("Failed to write cookie file: %s", pa_cstrerror(errno
));
76 /* Load an euthorization cookie from file fn and store it in data. If
77 * the cookie file doesn't exist, create it */
78 static int load(const char *fn
, void *data
, size_t length
) {
81 int unlock
= 0, ret
= -1;
86 pa_assert(length
> 0);
88 if ((fd
= open(fn
, O_RDWR
|O_CREAT
|O_BINARY
|O_NOCTTY
, S_IRUSR
|S_IWUSR
)) < 0) {
90 if (errno
!= EACCES
|| (fd
= open(fn
, O_RDONLY
|O_BINARY
|O_NOCTTY
)) < 0) {
91 pa_log_warn("Failed to open cookie file '%s': %s", fn
, pa_cstrerror(errno
));
97 unlock
= pa_lock_fd(fd
, 1) >= 0;
99 if ((r
= pa_loop_read(fd
, data
, length
, NULL
)) < 0) {
100 pa_log("Failed to read cookie file '%s': %s", fn
, pa_cstrerror(errno
));
104 if ((size_t) r
!= length
) {
105 pa_log_debug("Got %d bytes from cookie file '%s', expected %d", (int) r
, fn
, (int) length
);
108 pa_log_warn("Unable to write cookie to read-only file");
112 if (generate(fd
, data
, length
) < 0)
125 if (pa_close(fd
) < 0) {
126 pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno
));
134 /* Load a cookie from a cookie file. If the file doesn't exist, create it. */
135 int pa_authkey_load(const char *path
, void *data
, size_t length
) {
140 pa_assert(length
> 0);
142 if ((ret
= load(path
, data
, length
)) < 0)
143 pa_log_warn("Failed to load authorization key '%s': %s", path
, (ret
< 0) ? pa_cstrerror(errno
) : "File corrupt");
148 /* If the specified file path starts with / return it, otherwise
149 * return path prepended with home directory */
150 static const char *normalize_path(const char *fn
, char *s
, size_t l
) {
159 if (strlen(fn
) < 3 || !isalpha(fn
[0]) || fn
[1] != ':' || fn
[2] != '\\') {
161 char homedir
[PATH_MAX
];
163 if (!pa_get_home_dir(homedir
, sizeof(homedir
)))
167 pa_snprintf(s
, l
, "%s/%s", homedir
, fn
);
169 pa_snprintf(s
, l
, "%s\\%s", homedir
, fn
);
177 /* Load a cookie from a file in the home directory. If the specified
178 * path starts with /, use it as absolute path instead. */
179 int pa_authkey_load_auto(const char *fn
, void *data
, size_t length
) {
185 pa_assert(length
> 0);
187 if (!(p
= normalize_path(fn
, path
, sizeof(path
))))
190 return pa_authkey_load(p
, data
, length
);
193 /* Store the specified cookie in the specified cookie file */
194 int pa_authkey_save(const char *fn
, const void *data
, size_t length
) {
196 int unlock
= 0, ret
= -1;
203 pa_assert(length
> 0);
205 if (!(p
= normalize_path(fn
, path
, sizeof(path
))))
208 if ((fd
= open(p
, O_RDWR
|O_CREAT
|O_NOCTTY
, S_IRUSR
|S_IWUSR
)) < 0) {
209 pa_log_warn("Failed to open cookie file '%s': %s", fn
, pa_cstrerror(errno
));
213 unlock
= pa_lock_fd(fd
, 1) >= 0;
215 if ((r
= pa_loop_write(fd
, data
, length
, NULL
)) < 0 || (size_t) r
!= length
) {
216 pa_log("Failed to read cookie file '%s': %s", fn
, pa_cstrerror(errno
));
229 if (pa_close(fd
) < 0) {
230 pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno
));