]> code.delx.au - pulseaudio/blob - src/pulsecore/authkey.c
Get rid of some warnings: -Wunused-result
[pulseaudio] / src / pulsecore / authkey.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
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
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <string.h>
30 #include <errno.h>
31 #include <stdio.h>
32 #include <inttypes.h>
33 #include <stdlib.h>
34 #include <limits.h>
35 #include <sys/stat.h>
36
37 #include <pulse/util.h>
38 #include <pulse/xmalloc.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>
44
45 #include "authkey.h"
46
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) {
49 ssize_t r;
50
51 pa_assert(fd >= 0);
52 pa_assert(ret_data);
53 pa_assert(length > 0);
54
55 pa_random(ret_data, length);
56
57 lseek(fd, (off_t) 0, SEEK_SET);
58 if (ftruncate(fd, (off_t) 0) < 0) {
59 pa_log("Failed to truncate cookie file: %s", pa_cstrerror(errno));
60 return -1;
61 }
62
63 if ((r = pa_loop_write(fd, ret_data, length, NULL)) < 0 || (size_t) r != length) {
64 pa_log("Failed to write cookie file: %s", pa_cstrerror(errno));
65 return -1;
66 }
67
68 return 0;
69 }
70
71 #ifndef O_BINARY
72 #define O_BINARY 0
73 #endif
74
75 /* Load an euthorization cookie from file fn and store it in data. If
76 * the cookie file doesn't exist, create it */
77 static int load(const char *fn, void *data, size_t length) {
78 int fd = -1;
79 int writable = 1;
80 int unlock = 0, ret = -1;
81 ssize_t r;
82
83 pa_assert(fn);
84 pa_assert(data);
85 pa_assert(length > 0);
86
87 if ((fd = pa_open_cloexec(fn, O_RDWR|O_CREAT|O_BINARY, S_IRUSR|S_IWUSR)) < 0) {
88
89 if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY)) < 0) {
90 pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
91 goto finish;
92 } else
93 writable = 0;
94 }
95
96 unlock = pa_lock_fd(fd, 1) >= 0;
97
98 if ((r = pa_loop_read(fd, data, length, NULL)) < 0) {
99 pa_log("Failed to read cookie file '%s': %s", fn, pa_cstrerror(errno));
100 goto finish;
101 }
102
103 if ((size_t) r != length) {
104 pa_log_debug("Got %d bytes from cookie file '%s', expected %d", (int) r, fn, (int) length);
105
106 if (!writable) {
107 pa_log_warn("Unable to write cookie to read-only file");
108 goto finish;
109 }
110
111 if (generate(fd, data, length) < 0)
112 goto finish;
113 }
114
115 ret = 0;
116
117 finish:
118
119 if (fd >= 0) {
120
121 if (unlock)
122 pa_lock_fd(fd, 0);
123
124 if (pa_close(fd) < 0) {
125 pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno));
126 ret = -1;
127 }
128 }
129
130 return ret;
131 }
132
133 /* Load a cookie from a cookie file. If the file doesn't exist, create it. */
134 int pa_authkey_load(const char *path, void *data, size_t length) {
135 int ret;
136
137 pa_assert(path);
138 pa_assert(data);
139 pa_assert(length > 0);
140
141 if ((ret = load(path, data, length)) < 0)
142 pa_log_warn("Failed to load authorization key '%s': %s", path, (ret < 0) ? pa_cstrerror(errno) : "File corrupt");
143
144 return ret;
145 }
146
147 /* If the specified file path starts with / return it, otherwise
148 * return path prepended with home directory */
149 static char *normalize_path(const char *fn) {
150
151 pa_assert(fn);
152
153 #ifndef OS_IS_WIN32
154 if (fn[0] != '/') {
155 #else
156 if (strlen(fn) < 3 || !IsCharAlpha(fn[0]) || fn[1] != ':' || fn[2] != '\\') {
157 #endif
158 char *homedir, *s;
159
160 if (!(homedir = pa_get_home_dir_malloc()))
161 return NULL;
162
163 s = pa_sprintf_malloc("%s" PA_PATH_SEP "%s", homedir, fn);
164 pa_xfree(homedir);
165
166 return s;
167 }
168
169 return pa_xstrdup(fn);
170 }
171
172 /* Load a cookie from a file in the home directory. If the specified
173 * path starts with /, use it as absolute path instead. */
174 int pa_authkey_load_auto(const char *fn, void *data, size_t length) {
175 char *p;
176 int ret;
177
178 pa_assert(fn);
179 pa_assert(data);
180 pa_assert(length > 0);
181
182 if (!(p = normalize_path(fn)))
183 return -2;
184
185 ret = pa_authkey_load(p, data, length);
186 pa_xfree(p);
187
188 return ret;
189 }
190
191 /* Store the specified cookie in the specified cookie file */
192 int pa_authkey_save(const char *fn, const void *data, size_t length) {
193 int fd = -1;
194 int unlock = 0, ret = -1;
195 ssize_t r;
196 char *p;
197
198 pa_assert(fn);
199 pa_assert(data);
200 pa_assert(length > 0);
201
202 if (!(p = normalize_path(fn)))
203 return -2;
204
205 if ((fd = pa_open_cloexec(p, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
206 pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
207 goto finish;
208 }
209
210 unlock = pa_lock_fd(fd, 1) >= 0;
211
212 if ((r = pa_loop_write(fd, data, length, NULL)) < 0 || (size_t) r != length) {
213 pa_log("Failed to read cookie file '%s': %s", fn, pa_cstrerror(errno));
214 goto finish;
215 }
216
217 ret = 0;
218
219 finish:
220
221 if (fd >= 0) {
222
223 if (unlock)
224 pa_lock_fd(fd, 0);
225
226 if (pa_close(fd) < 0) {
227 pa_log_warn("Failed to close cookie file: %s", pa_cstrerror(errno));
228 ret = -1;
229 }
230 }
231
232 pa_xfree(p);
233
234 return ret;
235 }