chiark / gitweb /
bus: parse uid/gid/pid/tid meta data from kdbus messages
[elogind.git] / src / libsystemd-bus / bus-internal.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "bus-internal.h"
23
24 bool object_path_is_valid(const char *p) {
25         const char *q;
26         bool slash;
27
28         if (!p)
29                 return false;
30
31         if (p[0] != '/')
32                 return false;
33
34         if (p[1] == 0)
35                 return true;
36
37         for (slash = true, q = p+1; *q; q++)
38                 if (*q == '/') {
39                         if (slash)
40                                 return false;
41
42                         slash = true;
43                 } else {
44                         bool good;
45
46                         good =
47                                 (*q >= 'a' && *q <= 'z') ||
48                                 (*q >= 'A' && *q <= 'Z') ||
49                                 (*q >= '0' && *q <= '9') ||
50                                 *q == '_';
51
52                         if (!good)
53                                 return false;
54
55                         slash = false;
56                 }
57
58         if (slash)
59                 return false;
60
61         return true;
62 }
63
64 bool interface_name_is_valid(const char *p) {
65         const char *q;
66         bool dot, found_dot;
67
68         if (isempty(p))
69                 return false;
70
71         for (dot = true, q = p; *q; q++)
72                 if (*q == '.') {
73                         if (dot)
74                                 return false;
75
76                         found_dot = dot = true;
77                 } else {
78                         bool good;
79
80                         good =
81                                 (*q >= 'a' && *q <= 'z') ||
82                                 (*q >= 'A' && *q <= 'Z') ||
83                                 (!dot && *q >= '0' && *q <= '9') ||
84                                 *q == '_';
85
86                         if (!good)
87                                 return false;
88
89                         dot = false;
90                 }
91
92         if (q - p > 255)
93                 return false;
94
95         if (dot)
96                 return false;
97
98         if (!found_dot)
99                 return false;
100
101         return true;
102 }
103
104 bool service_name_is_valid(const char *p) {
105         const char *q;
106         bool dot, found_dot, unique;
107
108         if (isempty(p))
109                 return false;
110
111         unique = p[0] == ':';
112
113         for (dot = true, q = unique ? p+1 : p; *q; q++)
114                 if (*q == '.') {
115                         if (dot)
116                                 return false;
117
118                         found_dot = dot = true;
119                 } else {
120                         bool good;
121
122                         good =
123                                 (*q >= 'a' && *q <= 'z') ||
124                                 (*q >= 'A' && *q <= 'Z') ||
125                                 ((!dot || unique) && *q >= '0' && *q <= '9') ||
126                                 *q == '_' || *q == '-';
127
128                         if (!good)
129                                 return false;
130
131                         dot = false;
132                 }
133
134         if (q - p > 255)
135                 return false;
136
137         if (dot)
138                 return false;
139
140         if (!found_dot)
141                 return false;
142
143         return true;
144
145 }
146
147 bool member_name_is_valid(const char *p) {
148         const char *q;
149
150         if (isempty(p))
151                 return false;
152
153         for (q = p; *q; q++) {
154                 bool good;
155
156                 good =
157                         (*q >= 'a' && *q <= 'z') ||
158                         (*q >= 'A' && *q <= 'Z') ||
159                         (*q >= '0' && *q <= '9') ||
160                         *q == '_';
161
162                 if (!good)
163                         return false;
164         }
165
166         if (q - p > 255)
167                 return false;
168
169         return true;
170 }
171
172 static bool complex_pattern_check(char c, const char *a, const char *b) {
173         bool separator = false;
174
175         for (;;) {
176                 if (*a != *b)
177                         return (separator && (*a == 0 || *b == 0)) ||
178                                 (*a == 0 && *b == c && b[1] == 0) ||
179                                 (*b == 0 && *a == c && a[1] == 0);
180
181                 if (*a == 0)
182                         return true;
183
184                 separator = *a == c;
185
186                 a++, b++;
187         }
188 }
189
190 bool namespace_complex_pattern(const char *pattern, const char *value) {
191         return complex_pattern_check('.', pattern, value);
192 }
193
194 bool path_complex_pattern(const char *pattern, const char *value) {
195         return complex_pattern_check('/', pattern, value);
196 }
197
198 static bool simple_pattern_check(char c, const char *a, const char *b) {
199         for (;;) {
200                 if (*a != *b)
201                         return *a == 0 && *b == c;
202
203                 if (*a == 0)
204                         return true;
205
206                 a++, b++;
207         }
208 }
209
210 bool namespace_simple_pattern(const char *pattern, const char *value) {
211         return simple_pattern_check('.', pattern, value);
212 }
213
214 bool path_simple_pattern(const char *pattern, const char *value) {
215         return simple_pattern_check('/', pattern, value);
216 }
217
218 int bus_message_type_from_string(const char *s, uint8_t *u) {
219         if (streq(s, "signal"))
220                 *u = SD_BUS_MESSAGE_TYPE_SIGNAL;
221         else if (streq(s, "method_call"))
222                 *u = SD_BUS_MESSAGE_TYPE_METHOD_CALL;
223         else if (streq(s, "error"))
224                 *u = SD_BUS_MESSAGE_TYPE_METHOD_ERROR;
225         else if (streq(s, "method_return"))
226                 *u = SD_BUS_MESSAGE_TYPE_METHOD_RETURN;
227         else
228                 return -EINVAL;
229
230         return 0;
231 }