]>
code.delx.au - pulseaudio/blob - src/pulsecore/authkey.c
4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
7 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as
11 published by the Free Software Foundation; either version 2.1 of the
12 License, or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
40 #include <pulse/util.h>
41 #include <pulsecore/core-error.h>
42 #include <pulsecore/core-util.h>
43 #include <pulsecore/log.h>
44 #include <pulsecore/random.h>
45 #include <pulsecore/macro.h>
49 /* Generate a new authorization key, store it in file fd and return it in *data */
50 static int generate(int fd
, void *ret_data
, size_t length
) {
55 pa_assert(length
> 0);
57 pa_random(ret_data
, length
);
59 lseek(fd
, 0, SEEK_SET
);
60 (void) ftruncate(fd
, 0);
62 if ((r
= pa_loop_write(fd
, ret_data
, length
, NULL
)) < 0 || (size_t) r
!= length
) {
63 pa_log("Failed to write cookie file: %s", pa_cstrerror(errno
));
78 /* Load an euthorization cookie from file fn and store it in data. If
79 * the cookie file doesn't exist, create it */
80 static int load(const char *fn
, void *data
, size_t length
) {
83 int unlock
= 0, ret
= -1;
88 pa_assert(length
> 0);
90 if ((fd
= open(fn
, O_RDWR
|O_CREAT
|O_BINARY
|O_NOCTTY
, S_IRUSR
|S_IWUSR
)) < 0) {
92 if (errno
!= EACCES
|| (fd
= open(fn
, O_RDONLY
|O_BINARY
|O_NOCTTY
)) < 0) {
93 pa_log("Failed to open cookie file '%s': %s", fn
, pa_cstrerror(errno
));
99 unlock
= pa_lock_fd(fd
, 1) >= 0;
101 if ((r
= pa_loop_read(fd
, data
, length
, NULL
)) < 0) {
102 pa_log("Failed to read cookie file '%s': %s", fn
, pa_cstrerror(errno
));
106 if ((size_t) r
!= length
) {
107 pa_log_debug("Got %d bytes from cookie file '%s', expected %d", (int) r
, fn
, (int) length
);
110 pa_log("Unable to write cookie to read only file");
114 if (generate(fd
, data
, length
) < 0)
127 if (pa_close(fd
) < 0) {
128 pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno
));
136 /* Load a cookie from a cookie file. If the file doesn't exist, create it. */
137 int pa_authkey_load(const char *path
, void *data
, size_t length
) {
142 pa_assert(length
> 0);
144 if ((ret
= load(path
, data
, length
)) < 0)
145 pa_log("Failed to load authorization key '%s': %s", path
, (ret
< 0) ? pa_cstrerror(errno
) : "File corrupt");
150 /* If the specified file path starts with / return it, otherwise
151 * return path prepended with home directory */
152 static const char *normalize_path(const char *fn
, char *s
, size_t l
) {
161 if (strlen(fn
) < 3 || !isalpha(fn
[0]) || fn
[1] != ':' || fn
[2] != '\\') {
163 char homedir
[PATH_MAX
];
165 if (!pa_get_home_dir(homedir
, sizeof(homedir
)))
169 pa_snprintf(s
, l
, "%s/%s", homedir
, fn
);
171 pa_snprintf(s
, l
, "%s\\%s", homedir
, fn
);
179 /* Load a cookie from a file in the home directory. If the specified
180 * path starts with /, use it as absolute path instead. */
181 int pa_authkey_load_auto(const char *fn
, void *data
, size_t length
) {
187 pa_assert(length
> 0);
189 if (!(p
= normalize_path(fn
, path
, sizeof(path
))))
192 return pa_authkey_load(p
, data
, length
);
195 /* Store the specified cookie in the speicified cookie file */
196 int pa_authkey_save(const char *fn
, const void *data
, size_t length
) {
198 int unlock
= 0, ret
= -1;
205 pa_assert(length
> 0);
207 if (!(p
= normalize_path(fn
, path
, sizeof(path
))))
210 if ((fd
= open(p
, O_RDWR
|O_CREAT
|O_NOCTTY
, S_IRUSR
|S_IWUSR
)) < 0) {
211 pa_log("Failed to open cookie file '%s': %s", fn
, pa_cstrerror(errno
));
215 unlock
= pa_lock_fd(fd
, 1) >= 0;
217 if ((r
= pa_loop_write(fd
, data
, length
, NULL
)) < 0 || (size_t) r
!= length
) {
218 pa_log("Failed to read cookie file '%s': %s", fn
, pa_cstrerror(errno
));
231 if (pa_close(fd
) < 0) {
232 pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno
));