<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>dbus-keyring.c Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.15 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>dbus-keyring.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* dbus-keyring.c Store secret cookies in your homedir</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2003 Red Hat Inc.</font> 00005 <font class="comment"> *</font> 00006 <font class="comment"> * Licensed under the Academic Free License version 2.0</font> 00007 <font class="comment"> * </font> 00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font> 00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> 00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font> 00011 <font class="comment"> * (at your option) any later version.</font> 00012 <font class="comment"> *</font> 00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font> 00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</font> 00016 <font class="comment"> * GNU General Public License for more details.</font> 00017 <font class="comment"> * </font> 00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font> 00019 <font class="comment"> * along with this program; if not, write to the Free Software</font> 00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00021 <font class="comment"> *</font> 00022 <font class="comment"> */</font> 00023 00024 <font class="preprocessor">#include "dbus-keyring.h"</font> 00025 <font class="preprocessor">#include "dbus-userdb.h"</font> 00026 <font class="preprocessor">#include <dbus/dbus-string.h></font> 00027 <font class="preprocessor">#include <dbus/dbus-list.h></font> 00028 <font class="preprocessor">#include <dbus/dbus-sysdeps.h></font> 00029 <a name="l00066"></a><a class="code" href="group__DBusKeyringInternals.html#a7">00066</a> <font class="preprocessor">#define NEW_KEY_TIMEOUT_SECONDS (60*5)</font> 00067 <font class="preprocessor"></font> <a name="l00072"></a><a class="code" href="group__DBusKeyringInternals.html#a8">00072</a> <font class="preprocessor">#define EXPIRE_KEYS_TIMEOUT_SECONDS (NEW_KEY_TIMEOUT_SECONDS + (60*2))</font> 00073 <font class="preprocessor"></font> <a name="l00076"></a><a class="code" href="group__DBusKeyringInternals.html#a9">00076</a> <font class="preprocessor">#define MAX_TIME_TRAVEL_SECONDS (60*5)</font> 00077 <font class="preprocessor"></font> 00082 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> <a name="l00083"></a><a class="code" href="group__DBusKeyringInternals.html#a10">00083</a> <font class="preprocessor"></font><font class="preprocessor">#define MAX_KEYS_IN_FILE 10</font> 00084 <font class="preprocessor"></font><font class="preprocessor">#else</font> 00085 <font class="preprocessor"></font><font class="preprocessor">#define MAX_KEYS_IN_FILE 256</font> 00086 <font class="preprocessor"></font><font class="preprocessor">#endif</font> 00087 <font class="preprocessor"></font> <a name="l00091"></a><a class="code" href="structDBusKey.html">00091</a> <font class="keyword">typedef</font> <font class="keyword">struct</font> 00092 <font class="keyword"></font>{ <a name="l00093"></a><a class="code" href="structDBusKey.html#m0">00093</a> dbus_int32_t id; <a name="l00095"></a><a class="code" href="structDBusKey.html#m1">00095</a> <font class="keywordtype">long</font> creation_time; <a name="l00100"></a><a class="code" href="structDBusKey.html#m2">00100</a> <a class="code" href="structDBusString.html">DBusString</a> secret; 00102 } <a class="code" href="structDBusKey.html">DBusKey</a>; 00103 <a name="l00110"></a><a class="code" href="structDBusKeyring.html">00110</a> <font class="keyword">struct </font><a class="code" href="structDBusKeyring.html">DBusKeyring</a> 00111 { <a name="l00112"></a><a class="code" href="structDBusKeyring.html#m0">00112</a> <font class="keywordtype">int</font> <a class="code" href="structDBusKeyring.html#m0">refcount</a>; <a name="l00113"></a><a class="code" href="structDBusKeyring.html#m1">00113</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusKeyring.html#m1">username</a>; <a name="l00114"></a><a class="code" href="structDBusKeyring.html#m2">00114</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusKeyring.html#m2">directory</a>; <a name="l00115"></a><a class="code" href="structDBusKeyring.html#m3">00115</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusKeyring.html#m3">filename</a>; <a name="l00116"></a><a class="code" href="structDBusKeyring.html#m4">00116</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusKeyring.html#m4">filename_lock</a>; <a name="l00117"></a><a class="code" href="structDBusKeyring.html#m5">00117</a> <a class="code" href="structDBusKey.html">DBusKey</a> *<a class="code" href="structDBusKeyring.html#m5">keys</a>; <a name="l00118"></a><a class="code" href="structDBusKeyring.html#m6">00118</a> <font class="keywordtype">int</font> <a class="code" href="structDBusKeyring.html#m6">n_keys</a>; 00119 }; 00120 00121 <font class="keyword">static</font> <a class="code" href="structDBusKeyring.html">DBusKeyring</a>* 00122 _dbus_keyring_new (<font class="keywordtype">void</font>) 00123 { 00124 <a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring; 00125 00126 keyring = dbus_new0 (<a class="code" href="structDBusKeyring.html">DBusKeyring</a>, 1); 00127 <font class="keywordflow">if</font> (keyring == NULL) 00128 <font class="keywordflow">goto</font> out_0; 00129 00130 <font class="keywordflow">if</font> (!_dbus_string_init (&keyring-><a class="code" href="structDBusKeyring.html#m2">directory</a>)) 00131 <font class="keywordflow">goto</font> out_1; 00132 00133 <font class="keywordflow">if</font> (!_dbus_string_init (&keyring-><a class="code" href="structDBusKeyring.html#m3">filename</a>)) 00134 <font class="keywordflow">goto</font> out_2; 00135 00136 <font class="keywordflow">if</font> (!_dbus_string_init (&keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>)) 00137 <font class="keywordflow">goto</font> out_3; 00138 00139 <font class="keywordflow">if</font> (!_dbus_string_init (&keyring-><a class="code" href="structDBusKeyring.html#m1">username</a>)) 00140 <font class="keywordflow">goto</font> out_4; 00141 00142 keyring-><a class="code" href="structDBusKeyring.html#m0">refcount</a> = 1; 00143 keyring-><a class="code" href="structDBusKeyring.html#m5">keys</a> = NULL; 00144 keyring-><a class="code" href="structDBusKeyring.html#m6">n_keys</a> = 0; 00145 00146 <font class="keywordflow">return</font> keyring; 00147 00148 out_4: 00149 _dbus_string_free (&keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>); 00150 out_3: 00151 _dbus_string_free (&keyring-><a class="code" href="structDBusKeyring.html#m3">filename</a>); 00152 out_2: 00153 _dbus_string_free (&keyring-><a class="code" href="structDBusKeyring.html#m2">directory</a>); 00154 out_1: 00155 dbus_free (keyring); 00156 out_0: 00157 <font class="keywordflow">return</font> NULL; 00158 } 00159 00160 <font class="keyword">static</font> <font class="keywordtype">void</font> 00161 free_keys (<a class="code" href="structDBusKey.html">DBusKey</a> *keys, 00162 <font class="keywordtype">int</font> n_keys) 00163 { 00164 <font class="keywordtype">int</font> i; 00165 00166 <font class="comment">/* should be safe for args NULL, 0 */</font> 00167 00168 i = 0; 00169 <font class="keywordflow">while</font> (i < n_keys) 00170 { 00171 _dbus_string_free (&keys[i].secret); 00172 ++i; 00173 } 00174 00175 dbus_free (keys); 00176 } 00177 00178 <font class="comment">/* Our locking scheme is highly unreliable. However, there is</font> 00179 <font class="comment"> * unfortunately no reliable locking scheme in user home directories;</font> 00180 <font class="comment"> * between bugs in Linux NFS, people using Tru64 or other total crap</font> 00181 <font class="comment"> * NFS, AFS, random-file-system-of-the-week, and so forth, fcntl() in</font> 00182 <font class="comment"> * homedirs simply generates tons of bug reports. This has been</font> 00183 <font class="comment"> * learned through hard experience with GConf, unfortunately.</font> 00184 <font class="comment"> *</font> 00185 <font class="comment"> * This bad hack might work better for the kind of lock we have here,</font> 00186 <font class="comment"> * which we don't expect to hold for any length of time. Crashing</font> 00187 <font class="comment"> * while we hold it should be unlikely, and timing out such that we</font> 00188 <font class="comment"> * delete a stale lock should also be unlikely except when the</font> 00189 <font class="comment"> * filesystem is running really slowly. Stuff might break in corner</font> 00190 <font class="comment"> * cases but as long as it's not a security-level breakage it should</font> 00191 <font class="comment"> * be OK.</font> 00192 <font class="comment"> */</font> 00193 <a name="l00195"></a><a class="code" href="group__DBusKeyringInternals.html#a11">00195</a> <font class="preprocessor">#define MAX_LOCK_TIMEOUTS 32</font> 00196 <font class="preprocessor"></font> <a name="l00197"></a><a class="code" href="group__DBusKeyringInternals.html#a12">00197</a> <font class="preprocessor">#define LOCK_TIMEOUT_MILLISECONDS 250</font> 00198 <font class="preprocessor"></font> 00199 <font class="keyword">static</font> dbus_bool_t 00200 _dbus_keyring_lock (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring) 00201 { 00202 <font class="keywordtype">int</font> n_timeouts; 00203 00204 n_timeouts = 0; 00205 <font class="keywordflow">while</font> (n_timeouts < MAX_LOCK_TIMEOUTS) 00206 { 00207 <a class="code" href="structDBusError.html">DBusError</a> error; 00208 00209 dbus_error_init (&error); 00210 <font class="keywordflow">if</font> (_dbus_create_file_exclusively (&keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>, 00211 &error)) 00212 <font class="keywordflow">break</font>; 00213 00214 _dbus_verbose (<font class="stringliteral">"Did not get lock file, sleeping %d milliseconds (%s)\n"</font>, 00215 LOCK_TIMEOUT_MILLISECONDS, error.<a class="code" href="structDBusError.html#m1">message</a>); 00216 dbus_error_free (&error); 00217 00218 _dbus_sleep_milliseconds (LOCK_TIMEOUT_MILLISECONDS); 00219 00220 ++n_timeouts; 00221 } 00222 00223 <font class="keywordflow">if</font> (n_timeouts == MAX_LOCK_TIMEOUTS) 00224 { 00225 <a class="code" href="structDBusError.html">DBusError</a> error; 00226 00227 _dbus_verbose (<font class="stringliteral">"Lock file timed out %d times, assuming stale\n"</font>, 00228 n_timeouts); 00229 00230 dbus_error_init (&error); 00231 00232 <font class="keywordflow">if</font> (!_dbus_delete_file (&keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>, &error)) 00233 { 00234 _dbus_verbose (<font class="stringliteral">"Couldn't delete old lock file: %s\n"</font>, 00235 error.<a class="code" href="structDBusError.html#m1">message</a>); 00236 dbus_error_free (&error); 00237 <font class="keywordflow">return</font> FALSE; 00238 } 00239 00240 <font class="keywordflow">if</font> (!_dbus_create_file_exclusively (&keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>, 00241 &error)) 00242 { 00243 _dbus_verbose (<font class="stringliteral">"Couldn't create lock file after deleting stale one: %s\n"</font>, 00244 error.<a class="code" href="structDBusError.html#m1">message</a>); 00245 dbus_error_free (&error); 00246 <font class="keywordflow">return</font> FALSE; 00247 } 00248 } 00249 00250 <font class="keywordflow">return</font> TRUE; 00251 } 00252 00253 <font class="keyword">static</font> <font class="keywordtype">void</font> 00254 _dbus_keyring_unlock (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring) 00255 { 00256 <a class="code" href="structDBusError.html">DBusError</a> error; 00257 dbus_error_init (&error); 00258 <font class="keywordflow">if</font> (!_dbus_delete_file (&keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>, &error)) 00259 { 00260 _dbus_warn (<font class="stringliteral">"Failed to delete lock file: %s\n"</font>, 00261 error.<a class="code" href="structDBusError.html#m1">message</a>); 00262 dbus_error_free (&error); 00263 } 00264 } 00265 00266 <font class="keyword">static</font> <a class="code" href="structDBusKey.html">DBusKey</a>* 00267 find_key_by_id (<a class="code" href="structDBusKey.html">DBusKey</a> *keys, 00268 <font class="keywordtype">int</font> n_keys, 00269 <font class="keywordtype">int</font> id) 00270 { 00271 <font class="keywordtype">int</font> i; 00272 00273 i = 0; 00274 <font class="keywordflow">while</font> (i < n_keys) 00275 { 00276 <font class="keywordflow">if</font> (keys[i].<a class="code" href="structDBusKey.html#m0">id</a> == id) 00277 <font class="keywordflow">return</font> &keys[i]; 00278 00279 ++i; 00280 } 00281 00282 <font class="keywordflow">return</font> NULL; 00283 } 00284 00285 <font class="keyword">static</font> dbus_bool_t 00286 add_new_key (<a class="code" href="structDBusKey.html">DBusKey</a> **keys_p, 00287 <font class="keywordtype">int</font> *n_keys_p, 00288 <a class="code" href="structDBusError.html">DBusError</a> *error) 00289 { 00290 <a class="code" href="structDBusKey.html">DBusKey</a> *<font class="keyword">new</font>; 00291 <a class="code" href="structDBusString.html">DBusString</a> bytes; 00292 <font class="keywordtype">int</font> id; 00293 <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> timestamp; 00294 <font class="keyword">const</font> <font class="keywordtype">unsigned</font> <font class="keywordtype">char</font> *s; 00295 dbus_bool_t retval; 00296 <a class="code" href="structDBusKey.html">DBusKey</a> *keys; 00297 <font class="keywordtype">int</font> n_keys; 00298 00299 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00300 00301 <font class="keywordflow">if</font> (!_dbus_string_init (&bytes)) 00302 { 00303 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00304 <font class="keywordflow">return</font> FALSE; 00305 } 00306 00307 keys = *keys_p; 00308 n_keys = *n_keys_p; 00309 retval = FALSE; 00310 00311 <font class="comment">/* Generate an integer ID and then the actual key. */</font> 00312 retry: 00313 00314 <font class="keywordflow">if</font> (!_dbus_generate_random_bytes (&bytes, 4)) 00315 { 00316 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00317 <font class="keywordflow">goto</font> out; 00318 } 00319 00320 s = (<font class="keyword">const</font> <font class="keywordtype">unsigned</font> <font class="keywordtype">char</font>*) _dbus_string_get_const_data (&bytes); 00321 00322 id = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); 00323 <font class="keywordflow">if</font> (id < 0) 00324 id = - id; 00325 _dbus_assert (id >= 0); 00326 00327 <font class="keywordflow">if</font> (find_key_by_id (keys, n_keys, id) != NULL) 00328 { 00329 _dbus_string_set_length (&bytes, 0); 00330 _dbus_verbose (<font class="stringliteral">"Key ID %d already existed, trying another one\n"</font>, 00331 id); 00332 <font class="keywordflow">goto</font> retry; 00333 } 00334 00335 _dbus_verbose (<font class="stringliteral">"Creating key with ID %d\n"</font>, id); 00336 00337 <font class="preprocessor">#define KEY_LENGTH_BYTES 24</font> 00338 <font class="preprocessor"></font> _dbus_string_set_length (&bytes, 0); 00339 <font class="keywordflow">if</font> (!_dbus_generate_random_bytes (&bytes, KEY_LENGTH_BYTES)) 00340 { 00341 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00342 <font class="keywordflow">goto</font> out; 00343 } 00344 00345 <font class="keyword">new</font> = dbus_realloc (keys, <font class="keyword">sizeof</font> (<a class="code" href="structDBusKey.html">DBusKey</a>) * (n_keys + 1)); 00346 <font class="keywordflow">if</font> (<font class="keyword">new</font> == NULL) 00347 { 00348 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00349 <font class="keywordflow">goto</font> out; 00350 } 00351 00352 keys = <font class="keyword">new</font>; 00353 *keys_p = keys; <font class="comment">/* otherwise *keys_p ends up invalid */</font> 00354 n_keys += 1; 00355 00356 <font class="keywordflow">if</font> (!_dbus_string_init (&keys[n_keys-1].secret)) 00357 { 00358 n_keys -= 1; <font class="comment">/* we don't want to free the one we didn't init */</font> 00359 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00360 <font class="keywordflow">goto</font> out; 00361 } 00362 00363 _dbus_get_current_time (&timestamp, NULL); 00364 00365 keys[n_keys-1].<a class="code" href="structDBusKey.html#m0">id</a> = id; 00366 keys[n_keys-1].<a class="code" href="structDBusKey.html#m1">creation_time</a> = timestamp; 00367 <font class="keywordflow">if</font> (!_dbus_string_move (&bytes, 0, 00368 &keys[n_keys-1].secret, 00369 0)) 00370 { 00371 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00372 _dbus_string_free (&keys[n_keys-1].secret); 00373 n_keys -= 1; 00374 <font class="keywordflow">goto</font> out; 00375 } 00376 00377 retval = TRUE; 00378 00379 out: 00380 *n_keys_p = n_keys; 00381 00382 _dbus_string_free (&bytes); 00383 <font class="keywordflow">return</font> retval; 00384 } 00385 00400 <font class="keyword">static</font> dbus_bool_t 00401 _dbus_keyring_reload (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring, 00402 dbus_bool_t add_new, 00403 <a class="code" href="structDBusError.html">DBusError</a> *error) 00404 { 00405 <a class="code" href="structDBusString.html">DBusString</a> contents; 00406 <a class="code" href="structDBusString.html">DBusString</a> line; 00407 dbus_bool_t retval; 00408 dbus_bool_t have_lock; 00409 <a class="code" href="structDBusKey.html">DBusKey</a> *keys; 00410 <font class="keywordtype">int</font> n_keys; 00411 <font class="keywordtype">int</font> i; 00412 <font class="keywordtype">long</font> now; 00413 <a class="code" href="structDBusError.html">DBusError</a> tmp_error; 00414 00415 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00416 00417 <font class="keywordflow">if</font> (!_dbus_string_init (&contents)) 00418 { 00419 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00420 <font class="keywordflow">return</font> FALSE; 00421 } 00422 00423 <font class="keywordflow">if</font> (!_dbus_string_init (&line)) 00424 { 00425 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00426 _dbus_string_free (&contents); 00427 <font class="keywordflow">return</font> FALSE; 00428 } 00429 00430 keys = NULL; 00431 n_keys = 0; 00432 retval = FALSE; 00433 have_lock = FALSE; 00434 00435 _dbus_get_current_time (&now, NULL); 00436 00437 <font class="keywordflow">if</font> (add_new) 00438 { 00439 <font class="keywordflow">if</font> (!_dbus_keyring_lock (keyring)) 00440 { 00441 dbus_set_error (error, DBUS_ERROR_FAILED, 00442 <font class="stringliteral">"Could not lock keyring file to add to it"</font>); 00443 <font class="keywordflow">goto</font> out; 00444 } 00445 00446 have_lock = TRUE; 00447 } 00448 00449 dbus_error_init (&tmp_error); 00450 <font class="keywordflow">if</font> (!_dbus_file_get_contents (&contents, 00451 &keyring-><a class="code" href="structDBusKeyring.html#m3">filename</a>, 00452 &tmp_error)) 00453 { 00454 _dbus_verbose (<font class="stringliteral">"Failed to load keyring file: %s\n"</font>, 00455 tmp_error.<a class="code" href="structDBusError.html#m1">message</a>); 00456 <font class="comment">/* continue with empty keyring file, so we recreate it */</font> 00457 dbus_error_free (&tmp_error); 00458 } 00459 00460 <font class="keywordflow">if</font> (!_dbus_string_validate_ascii (&contents, 0, 00461 _dbus_string_get_length (&contents))) 00462 { 00463 _dbus_warn (<font class="stringliteral">"Secret keyring file contains non-ASCII! Ignoring existing contents\n"</font>); 00464 _dbus_string_set_length (&contents, 0); 00465 } 00466 00467 <font class="comment">/* FIXME this is badly inefficient for large keyring files</font> 00468 <font class="comment"> * (not that large keyring files exist outside of test suites)</font> 00469 <font class="comment"> */</font> 00470 <font class="keywordflow">while</font> (_dbus_string_pop_line (&contents, &line)) 00471 { 00472 <font class="keywordtype">int</font> next; 00473 <font class="keywordtype">long</font> val; 00474 <font class="keywordtype">int</font> id; 00475 <font class="keywordtype">long</font> timestamp; 00476 <font class="keywordtype">int</font> len; 00477 <font class="keywordtype">int</font> end; 00478 <a class="code" href="structDBusKey.html">DBusKey</a> *<font class="keyword">new</font>; 00479 00480 <font class="comment">/* Don't load more than the max. */</font> 00481 <font class="keywordflow">if</font> (n_keys >= (add_new ? MAX_KEYS_IN_FILE : MAX_KEYS_IN_FILE - 1)) 00482 <font class="keywordflow">break</font>; 00483 00484 next = 0; 00485 <font class="keywordflow">if</font> (!_dbus_string_parse_int (&line, 0, &val, &next)) 00486 { 00487 _dbus_verbose (<font class="stringliteral">"could not parse secret key ID at start of line\n"</font>); 00488 <font class="keywordflow">continue</font>; 00489 } 00490 00491 <font class="keywordflow">if</font> (val > _DBUS_INT_MAX || val < 0) 00492 { 00493 _dbus_verbose (<font class="stringliteral">"invalid secret key ID at start of line\n"</font>); 00494 <font class="keywordflow">continue</font>; 00495 } 00496 00497 id = val; 00498 00499 _dbus_string_skip_blank (&line, next, &next); 00500 00501 <font class="keywordflow">if</font> (!_dbus_string_parse_int (&line, next, &timestamp, &next)) 00502 { 00503 _dbus_verbose (<font class="stringliteral">"could not parse secret key timestamp\n"</font>); 00504 <font class="keywordflow">continue</font>; 00505 } 00506 00507 <font class="keywordflow">if</font> (timestamp < 0 || 00508 (now + MAX_TIME_TRAVEL_SECONDS) < timestamp || 00509 (now - EXPIRE_KEYS_TIMEOUT_SECONDS) > timestamp) 00510 { 00511 _dbus_verbose (<font class="stringliteral">"dropping/ignoring %ld-seconds old key with timestamp %ld as current time is %ld\n"</font>, 00512 now - timestamp, timestamp, now); 00513 <font class="keywordflow">continue</font>; 00514 } 00515 00516 _dbus_string_skip_blank (&line, next, &next); 00517 00518 len = _dbus_string_get_length (&line); 00519 00520 <font class="keywordflow">if</font> ((len - next) == 0) 00521 { 00522 _dbus_verbose (<font class="stringliteral">"no secret key after ID and timestamp\n"</font>); 00523 <font class="keywordflow">continue</font>; 00524 } 00525 00526 <font class="comment">/* We have all three parts */</font> 00527 <font class="keyword">new</font> = dbus_realloc (keys, <font class="keyword">sizeof</font> (<a class="code" href="structDBusKey.html">DBusKey</a>) * (n_keys + 1)); 00528 <font class="keywordflow">if</font> (<font class="keyword">new</font> == NULL) 00529 { 00530 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00531 <font class="keywordflow">goto</font> out; 00532 } 00533 00534 keys = <font class="keyword">new</font>; 00535 n_keys += 1; 00536 00537 <font class="keywordflow">if</font> (!_dbus_string_init (&keys[n_keys-1].secret)) 00538 { 00539 n_keys -= 1; <font class="comment">/* we don't want to free the one we didn't init */</font> 00540 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00541 <font class="keywordflow">goto</font> out; 00542 } 00543 00544 keys[n_keys-1].<a class="code" href="structDBusKey.html#m0">id</a> = id; 00545 keys[n_keys-1].<a class="code" href="structDBusKey.html#m1">creation_time</a> = timestamp; 00546 <font class="keywordflow">if</font> (!_dbus_string_hex_decode (&line, next, &end, 00547 &keys[n_keys-1].secret, 0)) 00548 { 00549 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00550 <font class="keywordflow">goto</font> out; 00551 } 00552 00553 <font class="keywordflow">if</font> (_dbus_string_get_length (&line) != end) 00554 { 00555 _dbus_verbose (<font class="stringliteral">"invalid hex encoding in keyring file\n"</font>); 00556 _dbus_string_free (&keys[n_keys - 1].secret); 00557 n_keys -= 1; 00558 <font class="keywordflow">continue</font>; 00559 } 00560 } 00561 00562 _dbus_verbose (<font class="stringliteral">"Successfully loaded %d existing keys\n"</font>, 00563 n_keys); 00564 00565 <font class="keywordflow">if</font> (add_new) 00566 { 00567 <font class="keywordflow">if</font> (!add_new_key (&keys, &n_keys, error)) 00568 { 00569 _dbus_verbose (<font class="stringliteral">"Failed to generate new key: %s\n"</font>, 00570 error ? <font class="stringliteral">"(unknown)"</font> : error-><a class="code" href="structDBusError.html#m1">message</a>); 00571 <font class="keywordflow">goto</font> out; 00572 } 00573 00574 _dbus_string_set_length (&contents, 0); 00575 00576 i = 0; 00577 <font class="keywordflow">while</font> (i < n_keys) 00578 { 00579 <font class="keywordflow">if</font> (!_dbus_string_append_int (&contents, 00580 keys[i].id)) 00581 <font class="keywordflow">goto</font> nomem; 00582 00583 <font class="keywordflow">if</font> (!_dbus_string_append_byte (&contents, <font class="charliteral">' '</font>)) 00584 <font class="keywordflow">goto</font> nomem; 00585 00586 <font class="keywordflow">if</font> (!_dbus_string_append_int (&contents, 00587 keys[i].creation_time)) 00588 <font class="keywordflow">goto</font> nomem; 00589 00590 <font class="keywordflow">if</font> (!_dbus_string_append_byte (&contents, <font class="charliteral">' '</font>)) 00591 <font class="keywordflow">goto</font> nomem; 00592 00593 <font class="keywordflow">if</font> (!_dbus_string_hex_encode (&keys[i].secret, 0, 00594 &contents, 00595 _dbus_string_get_length (&contents))) 00596 <font class="keywordflow">goto</font> nomem; 00597 00598 <font class="keywordflow">if</font> (!_dbus_string_append_byte (&contents, <font class="charliteral">'\n'</font>)) 00599 <font class="keywordflow">goto</font> nomem; 00600 00601 ++i; 00602 <font class="keywordflow">continue</font>; 00603 00604 nomem: 00605 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00606 <font class="keywordflow">goto</font> out; 00607 } 00608 00609 <font class="keywordflow">if</font> (!_dbus_string_save_to_file (&contents, &keyring-><a class="code" href="structDBusKeyring.html#m3">filename</a>, 00610 error)) 00611 <font class="keywordflow">goto</font> out; 00612 } 00613 00614 <font class="keywordflow">if</font> (keyring-><a class="code" href="structDBusKeyring.html#m5">keys</a>) 00615 free_keys (keyring-><a class="code" href="structDBusKeyring.html#m5">keys</a>, keyring-><a class="code" href="structDBusKeyring.html#m6">n_keys</a>); 00616 keyring-><a class="code" href="structDBusKeyring.html#m5">keys</a> = keys; 00617 keyring-><a class="code" href="structDBusKeyring.html#m6">n_keys</a> = n_keys; 00618 keys = NULL; 00619 n_keys = 0; 00620 00621 retval = TRUE; 00622 00623 out: 00624 <font class="keywordflow">if</font> (have_lock) 00625 _dbus_keyring_unlock (keyring); 00626 00627 <font class="keywordflow">if</font> (! ((retval == TRUE && (error == NULL || error-><a class="code" href="structDBusError.html#m0">name</a> == NULL)) || 00628 (retval == FALSE && (error == NULL || error-><a class="code" href="structDBusError.html#m0">name</a> != NULL)))) 00629 { 00630 <font class="keywordflow">if</font> (error && error-><a class="code" href="structDBusError.html#m0">name</a>) 00631 _dbus_verbose (<font class="stringliteral">"error is %s: %s\n"</font>, error-><a class="code" href="structDBusError.html#m0">name</a>, error-><a class="code" href="structDBusError.html#m1">message</a>); 00632 _dbus_warn (<font class="stringliteral">"returning %d but error pointer %p name %s\n"</font>, 00633 retval, error, error-><a class="code" href="structDBusError.html#m0">name</a> ? error-><a class="code" href="structDBusError.html#m0">name</a> : <font class="stringliteral">"(none)"</font>); 00634 _dbus_assert_not_reached (<font class="stringliteral">"didn't handle errors properly"</font>); 00635 } 00636 00637 <font class="keywordflow">if</font> (keys != NULL) 00638 { 00639 i = 0; 00640 <font class="keywordflow">while</font> (i < n_keys) 00641 { 00642 _dbus_string_zero (&keys[i].secret); 00643 _dbus_string_free (&keys[i].secret); 00644 ++i; 00645 } 00646 00647 dbus_free (keys); 00648 } 00649 00650 _dbus_string_free (&contents); 00651 _dbus_string_free (&line); 00652 00653 <font class="keywordflow">return</font> retval; 00654 } 00655 <font class="comment">/* end of internals */</font> 00657 00670 <a class="code" href="structDBusKeyring.html">DBusKeyring</a> * <a name="l00671"></a><a class="code" href="group__DBusKeyring.html#a0">00671</a> _dbus_keyring_ref (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring) 00672 { 00673 keyring-><a class="code" href="structDBusKeyring.html#m0">refcount</a> += 1; 00674 00675 <font class="keywordflow">return</font> keyring; 00676 } 00677 00684 <font class="keywordtype">void</font> <a name="l00685"></a><a class="code" href="group__DBusKeyring.html#a1">00685</a> _dbus_keyring_unref (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring) 00686 { 00687 keyring-><a class="code" href="structDBusKeyring.html#m0">refcount</a> -= 1; 00688 00689 <font class="keywordflow">if</font> (keyring-><a class="code" href="structDBusKeyring.html#m0">refcount</a> == 0) 00690 { 00691 _dbus_string_free (&keyring-><a class="code" href="structDBusKeyring.html#m1">username</a>); 00692 _dbus_string_free (&keyring-><a class="code" href="structDBusKeyring.html#m3">filename</a>); 00693 _dbus_string_free (&keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>); 00694 _dbus_string_free (&keyring-><a class="code" href="structDBusKeyring.html#m2">directory</a>); 00695 free_keys (keyring-><a class="code" href="structDBusKeyring.html#m5">keys</a>, keyring-><a class="code" href="structDBusKeyring.html#m6">n_keys</a>); 00696 dbus_free (keyring); 00697 } 00698 } 00699 00710 <a class="code" href="structDBusKeyring.html">DBusKeyring</a>* <a name="l00711"></a><a class="code" href="group__DBusKeyring.html#a2">00711</a> _dbus_keyring_new_homedir (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *username, 00712 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *context, 00713 <a class="code" href="structDBusError.html">DBusError</a> *error) 00714 { 00715 <a class="code" href="structDBusString.html">DBusString</a> homedir; 00716 <a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring; 00717 dbus_bool_t error_set; 00718 <a class="code" href="structDBusString.html">DBusString</a> dotdir; 00719 <a class="code" href="structDBusError.html">DBusError</a> tmp_error; 00720 00721 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00722 00723 keyring = NULL; 00724 error_set = FALSE; 00725 00726 <font class="keywordflow">if</font> (!_dbus_string_init (&homedir)) 00727 { 00728 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00729 <font class="keywordflow">return</font> FALSE; 00730 } 00731 00732 _dbus_string_init_const (&dotdir, <font class="stringliteral">".dbus-keyrings"</font>); 00733 00734 <font class="keywordflow">if</font> (username == NULL) 00735 { 00736 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *const_homedir; 00737 00738 <font class="keywordflow">if</font> (!_dbus_username_from_current_process (&username) || 00739 !_dbus_homedir_from_current_process (&const_homedir)) 00740 <font class="keywordflow">goto</font> failed; 00741 00742 <font class="keywordflow">if</font> (!_dbus_string_copy (const_homedir, 0, 00743 &homedir, 0)) 00744 <font class="keywordflow">goto</font> failed; 00745 } 00746 <font class="keywordflow">else</font> 00747 { 00748 <font class="keywordflow">if</font> (!_dbus_homedir_from_username (username, &homedir)) 00749 <font class="keywordflow">goto</font> failed; 00750 } 00751 00752 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 00753 <font class="preprocessor"></font> { 00754 <font class="keyword">const</font> <font class="keywordtype">char</font> *override; 00755 00756 override = _dbus_getenv (<font class="stringliteral">"DBUS_TEST_HOMEDIR"</font>); 00757 <font class="keywordflow">if</font> (override != NULL && *override != <font class="charliteral">'\0'</font>) 00758 { 00759 _dbus_string_set_length (&homedir, 0); 00760 <font class="keywordflow">if</font> (!_dbus_string_append (&homedir, override)) 00761 _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>); 00762 00763 _dbus_verbose (<font class="stringliteral">"Using fake homedir for testing: %s\n"</font>, 00764 _dbus_string_get_const_data (&homedir)); 00765 } 00766 <font class="keywordflow">else</font> 00767 { 00768 <font class="keyword">static</font> dbus_bool_t already_warned = FALSE; 00769 <font class="keywordflow">if</font> (!already_warned) 00770 { 00771 _dbus_warn (<font class="stringliteral">"Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"</font>); 00772 already_warned = TRUE; 00773 } 00774 } 00775 } 00776 <font class="preprocessor">#endif</font> 00777 <font class="preprocessor"></font> 00778 _dbus_assert (username != NULL); 00779 00780 keyring = _dbus_keyring_new (); 00781 <font class="keywordflow">if</font> (keyring == NULL) 00782 <font class="keywordflow">goto</font> failed; 00783 00784 <font class="comment">/* should have been validated already, but paranoia check here */</font> 00785 <font class="keywordflow">if</font> (!_dbus_keyring_validate_context (context)) 00786 { 00787 error_set = TRUE; 00788 dbus_set_error_const (error, 00789 DBUS_ERROR_FAILED, 00790 <font class="stringliteral">"Invalid context in keyring creation"</font>); 00791 <font class="keywordflow">goto</font> failed; 00792 } 00793 00794 <font class="keywordflow">if</font> (!_dbus_string_copy (username, 0, 00795 &keyring-><a class="code" href="structDBusKeyring.html#m1">username</a>, 0)) 00796 <font class="keywordflow">goto</font> failed; 00797 00798 <font class="keywordflow">if</font> (!_dbus_string_copy (&homedir, 0, 00799 &keyring-><a class="code" href="structDBusKeyring.html#m2">directory</a>, 0)) 00800 <font class="keywordflow">goto</font> failed; 00801 00802 <font class="keywordflow">if</font> (!_dbus_concat_dir_and_file (&keyring-><a class="code" href="structDBusKeyring.html#m2">directory</a>, 00803 &dotdir)) 00804 <font class="keywordflow">goto</font> failed; 00805 00806 <font class="keywordflow">if</font> (!_dbus_string_copy (&keyring-><a class="code" href="structDBusKeyring.html#m2">directory</a>, 0, 00807 &keyring-><a class="code" href="structDBusKeyring.html#m3">filename</a>, 0)) 00808 <font class="keywordflow">goto</font> failed; 00809 00810 <font class="keywordflow">if</font> (!_dbus_concat_dir_and_file (&keyring-><a class="code" href="structDBusKeyring.html#m3">filename</a>, 00811 context)) 00812 <font class="keywordflow">goto</font> failed; 00813 00814 <font class="keywordflow">if</font> (!_dbus_string_copy (&keyring-><a class="code" href="structDBusKeyring.html#m3">filename</a>, 0, 00815 &keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>, 0)) 00816 <font class="keywordflow">goto</font> failed; 00817 00818 <font class="keywordflow">if</font> (!_dbus_string_append (&keyring-><a class="code" href="structDBusKeyring.html#m4">filename_lock</a>, <font class="stringliteral">".lock"</font>)) 00819 <font class="keywordflow">goto</font> failed; 00820 00821 dbus_error_init (&tmp_error); 00822 <font class="keywordflow">if</font> (!_dbus_keyring_reload (keyring, FALSE, &tmp_error)) 00823 { 00824 _dbus_verbose (<font class="stringliteral">"didn't load an existing keyring: %s\n"</font>, 00825 tmp_error.<a class="code" href="structDBusError.html#m1">message</a>); 00826 dbus_error_free (&tmp_error); 00827 } 00828 00829 <font class="comment">/* We don't fail fatally if we can't create the directory,</font> 00830 <font class="comment"> * but the keyring will probably always be empty</font> 00831 <font class="comment"> * unless someone else manages to create it</font> 00832 <font class="comment"> */</font> 00833 dbus_error_init (&tmp_error); 00834 <font class="keywordflow">if</font> (!_dbus_create_directory (&keyring-><a class="code" href="structDBusKeyring.html#m2">directory</a>, 00835 &tmp_error)) 00836 { 00837 _dbus_verbose (<font class="stringliteral">"Creating keyring directory: %s\n"</font>, 00838 tmp_error.<a class="code" href="structDBusError.html#m1">message</a>); 00839 dbus_error_free (&tmp_error); 00840 } 00841 00842 _dbus_string_free (&homedir); 00843 00844 <font class="keywordflow">return</font> keyring; 00845 00846 failed: 00847 <font class="keywordflow">if</font> (!error_set) 00848 dbus_set_error_const (error, 00849 DBUS_ERROR_NO_MEMORY, 00850 NULL); 00851 <font class="keywordflow">if</font> (keyring) 00852 _dbus_keyring_unref (keyring); 00853 _dbus_string_free (&homedir); 00854 <font class="keywordflow">return</font> FALSE; 00855 00856 } 00857 00870 dbus_bool_t <a name="l00871"></a><a class="code" href="group__DBusKeyring.html#a3">00871</a> _dbus_keyring_validate_context (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *context) 00872 { 00873 <font class="keywordflow">if</font> (_dbus_string_get_length (context) == 0) 00874 { 00875 _dbus_verbose (<font class="stringliteral">"context is zero-length\n"</font>); 00876 <font class="keywordflow">return</font> FALSE; 00877 } 00878 00879 <font class="keywordflow">if</font> (!_dbus_string_validate_ascii (context, 0, 00880 _dbus_string_get_length (context))) 00881 { 00882 _dbus_verbose (<font class="stringliteral">"context not valid ascii\n"</font>); 00883 <font class="keywordflow">return</font> FALSE; 00884 } 00885 00886 <font class="comment">/* no directory separators */</font> 00887 <font class="keywordflow">if</font> (_dbus_string_find (context, 0, <font class="stringliteral">"/"</font>, NULL)) 00888 { 00889 _dbus_verbose (<font class="stringliteral">"context contains a slash\n"</font>); 00890 <font class="keywordflow">return</font> FALSE; 00891 } 00892 00893 <font class="keywordflow">if</font> (_dbus_string_find (context, 0, <font class="stringliteral">"\\"</font>, NULL)) 00894 { 00895 _dbus_verbose (<font class="stringliteral">"context contains a backslash\n"</font>); 00896 <font class="keywordflow">return</font> FALSE; 00897 } 00898 00899 <font class="comment">/* prevent attempts to use dotfiles or ".." or ".lock"</font> 00900 <font class="comment"> * all of which might allow some kind of attack</font> 00901 <font class="comment"> */</font> 00902 <font class="keywordflow">if</font> (_dbus_string_find (context, 0, <font class="stringliteral">"."</font>, NULL)) 00903 { 00904 _dbus_verbose (<font class="stringliteral">"context contains a dot\n"</font>); 00905 <font class="keywordflow">return</font> FALSE; 00906 } 00907 00908 <font class="comment">/* no spaces/tabs, those are used for separators in the protocol */</font> 00909 <font class="keywordflow">if</font> (_dbus_string_find_blank (context, 0, NULL)) 00910 { 00911 _dbus_verbose (<font class="stringliteral">"context contains a blank\n"</font>); 00912 <font class="keywordflow">return</font> FALSE; 00913 } 00914 00915 <font class="keywordflow">if</font> (_dbus_string_find (context, 0, <font class="stringliteral">"\n"</font>, NULL)) 00916 { 00917 _dbus_verbose (<font class="stringliteral">"context contains a newline\n"</font>); 00918 <font class="keywordflow">return</font> FALSE; 00919 } 00920 00921 <font class="keywordflow">if</font> (_dbus_string_find (context, 0, <font class="stringliteral">"\r"</font>, NULL)) 00922 { 00923 _dbus_verbose (<font class="stringliteral">"context contains a carriage return\n"</font>); 00924 <font class="keywordflow">return</font> FALSE; 00925 } 00926 00927 <font class="keywordflow">return</font> TRUE; 00928 } 00929 00930 <font class="keyword">static</font> <a class="code" href="structDBusKey.html">DBusKey</a>* 00931 find_recent_key (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring) 00932 { 00933 <font class="keywordtype">int</font> i; 00934 <font class="keywordtype">long</font> tv_sec, tv_usec; 00935 00936 _dbus_get_current_time (&tv_sec, &tv_usec); 00937 00938 i = 0; 00939 <font class="keywordflow">while</font> (i < keyring-><a class="code" href="structDBusKeyring.html#m6">n_keys</a>) 00940 { 00941 <a class="code" href="structDBusKey.html">DBusKey</a> *key = &keyring-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i]; 00942 00943 _dbus_verbose (<font class="stringliteral">"Key %d is %ld seconds old\n"</font>, 00944 i, tv_sec - key-><a class="code" href="structDBusKey.html#m1">creation_time</a>); 00945 00946 <font class="keywordflow">if</font> ((tv_sec - NEW_KEY_TIMEOUT_SECONDS) < key-><a class="code" href="structDBusKey.html#m1">creation_time</a>) 00947 <font class="keywordflow">return</font> key; 00948 00949 ++i; 00950 } 00951 00952 <font class="keywordflow">return</font> NULL; 00953 } 00954 00966 <font class="keywordtype">int</font> <a name="l00967"></a><a class="code" href="group__DBusKeyring.html#a5">00967</a> _dbus_keyring_get_best_key (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring, 00968 <a class="code" href="structDBusError.html">DBusError</a> *error) 00969 { 00970 <a class="code" href="structDBusKey.html">DBusKey</a> *key; 00971 00972 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00973 00974 key = find_recent_key (keyring); 00975 <font class="keywordflow">if</font> (key) 00976 <font class="keywordflow">return</font> key-><a class="code" href="structDBusKey.html#m0">id</a>; 00977 00978 <font class="comment">/* All our keys are too old, or we've never loaded the</font> 00979 <font class="comment"> * keyring. Create a new one.</font> 00980 <font class="comment"> */</font> 00981 <font class="keywordflow">if</font> (!_dbus_keyring_reload (keyring, TRUE, 00982 error)) 00983 <font class="keywordflow">return</font> -1; 00984 00985 key = find_recent_key (keyring); 00986 <font class="keywordflow">if</font> (key) 00987 <font class="keywordflow">return</font> key-><a class="code" href="structDBusKey.html#m0">id</a>; 00988 <font class="keywordflow">else</font> 00989 { 00990 dbus_set_error_const (error, 00991 DBUS_ERROR_FAILED, 00992 <font class="stringliteral">"No recent-enough key found in keyring, and unable to create a new key"</font>); 00993 <font class="keywordflow">return</font> -1; 00994 } 00995 } 00996 01005 dbus_bool_t <a name="l01006"></a><a class="code" href="group__DBusKeyring.html#a6">01006</a> _dbus_keyring_is_for_user (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring, 01007 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *username) 01008 { 01009 <font class="keywordflow">return</font> _dbus_string_equal (&keyring-><a class="code" href="structDBusKeyring.html#m1">username</a>, 01010 username); 01011 } 01012 01024 dbus_bool_t <a name="l01025"></a><a class="code" href="group__DBusKeyring.html#a7">01025</a> _dbus_keyring_get_hex_key (<a class="code" href="structDBusKeyring.html">DBusKeyring</a> *keyring, 01026 <font class="keywordtype">int</font> key_id, 01027 <a class="code" href="structDBusString.html">DBusString</a> *hex_key) 01028 { 01029 <a class="code" href="structDBusKey.html">DBusKey</a> *key; 01030 01031 key = find_key_by_id (keyring-><a class="code" href="structDBusKeyring.html#m5">keys</a>, 01032 keyring-><a class="code" href="structDBusKeyring.html#m6">n_keys</a>, 01033 key_id); 01034 <font class="keywordflow">if</font> (key == NULL) 01035 <font class="keywordflow">return</font> TRUE; <font class="comment">/* had enough memory, so TRUE */</font> 01036 01037 <font class="keywordflow">return</font> _dbus_string_hex_encode (&key-><a class="code" href="structDBusKey.html#m2">secret</a>, 0, 01038 hex_key, 01039 _dbus_string_get_length (hex_key)); 01040 } 01041 <font class="comment">/* end of exposed API */</font> 01043 01044 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 01045 <font class="preprocessor"></font><font class="preprocessor">#include "dbus-test.h"</font> 01046 <font class="preprocessor">#include <stdio.h></font> 01047 01048 dbus_bool_t 01049 _dbus_keyring_test (<font class="keywordtype">void</font>) 01050 { 01051 <a class="code" href="structDBusString.html">DBusString</a> context; 01052 <a class="code" href="structDBusKeyring.html">DBusKeyring</a> *ring1; 01053 <a class="code" href="structDBusKeyring.html">DBusKeyring</a> *ring2; 01054 <font class="keywordtype">int</font> id; 01055 <a class="code" href="structDBusError.html">DBusError</a> error; 01056 <font class="keywordtype">int</font> i; 01057 01058 ring1 = NULL; 01059 ring2 = NULL; 01060 01061 <font class="comment">/* Context validation */</font> 01062 01063 _dbus_string_init_const (&context, <font class="stringliteral">"foo"</font>); 01064 _dbus_assert (_dbus_keyring_validate_context (&context)); 01065 _dbus_string_init_const (&context, <font class="stringliteral">"org_freedesktop_blah"</font>); 01066 _dbus_assert (_dbus_keyring_validate_context (&context)); 01067 01068 _dbus_string_init_const (&context, <font class="stringliteral">""</font>); 01069 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01070 _dbus_string_init_const (&context, <font class="stringliteral">".foo"</font>); 01071 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01072 _dbus_string_init_const (&context, <font class="stringliteral">"bar.foo"</font>); 01073 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01074 _dbus_string_init_const (&context, <font class="stringliteral">"bar/foo"</font>); 01075 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01076 _dbus_string_init_const (&context, <font class="stringliteral">"bar\\foo"</font>); 01077 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01078 _dbus_string_init_const (&context, <font class="stringliteral">"foo\xfa\xf0"</font>); 01079 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01080 _dbus_string_init_const (&context, <font class="stringliteral">"foo\x80"</font>); 01081 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01082 _dbus_string_init_const (&context, <font class="stringliteral">"foo\x7f"</font>); 01083 _dbus_assert (_dbus_keyring_validate_context (&context)); 01084 _dbus_string_init_const (&context, <font class="stringliteral">"foo bar"</font>); 01085 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01086 01087 <font class="keywordflow">if</font> (!_dbus_string_init (&context)) 01088 _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>); 01089 <font class="keywordflow">if</font> (!_dbus_string_append_byte (&context, <font class="charliteral">'\0'</font>)) 01090 _dbus_assert_not_reached (<font class="stringliteral">"no memory"</font>); 01091 _dbus_assert (!_dbus_keyring_validate_context (&context)); 01092 _dbus_string_free (&context); 01093 01094 <font class="comment">/* Now verify that if we create a key in keyring 1,</font> 01095 <font class="comment"> * it is properly loaded in keyring 2</font> 01096 <font class="comment"> */</font> 01097 01098 _dbus_string_init_const (&context, <font class="stringliteral">"org_freedesktop_dbus_testsuite"</font>); 01099 dbus_error_init (&error); 01100 ring1 = _dbus_keyring_new_homedir (NULL, &context, 01101 &error); 01102 _dbus_assert (ring1); 01103 _dbus_assert (error.<a class="code" href="structDBusError.html#m0">name</a> == NULL); 01104 01105 id = _dbus_keyring_get_best_key (ring1, &error); 01106 <font class="keywordflow">if</font> (id < 0) 01107 { 01108 fprintf (stderr, <font class="stringliteral">"Could not load keyring: %s\n"</font>, error.<a class="code" href="structDBusError.html#m1">message</a>); 01109 dbus_error_free (&error); 01110 <font class="keywordflow">goto</font> failure; 01111 } 01112 01113 ring2 = _dbus_keyring_new_homedir (NULL, &context, &error); 01114 _dbus_assert (ring2); 01115 _dbus_assert (error.<a class="code" href="structDBusError.html#m0">name</a> == NULL); 01116 01117 <font class="keywordflow">if</font> (ring1-><a class="code" href="structDBusKeyring.html#m6">n_keys</a> != ring2-><a class="code" href="structDBusKeyring.html#m6">n_keys</a>) 01118 { 01119 fprintf (stderr, <font class="stringliteral">"Different number of keys in keyrings\n"</font>); 01120 <font class="keywordflow">goto</font> failure; 01121 } 01122 01123 <font class="comment">/* We guarantee we load and save keeping keys in a fixed</font> 01124 <font class="comment"> * order</font> 01125 <font class="comment"> */</font> 01126 i = 0; 01127 <font class="keywordflow">while</font> (i < ring1-><a class="code" href="structDBusKeyring.html#m6">n_keys</a>) 01128 { 01129 <font class="keywordflow">if</font> (ring1-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m0">id</a> != ring2-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m0">id</a>) 01130 { 01131 fprintf (stderr, <font class="stringliteral">"Keyring 1 has first key ID %d and keyring 2 has %d\n"</font>, 01132 ring1-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m0">id</a>, ring2-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m0">id</a>); 01133 <font class="keywordflow">goto</font> failure; 01134 } 01135 01136 <font class="keywordflow">if</font> (ring1-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m1">creation_time</a> != ring2-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m1">creation_time</a>) 01137 { 01138 fprintf (stderr, <font class="stringliteral">"Keyring 1 has first key time %ld and keyring 2 has %ld\n"</font>, 01139 ring1-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m1">creation_time</a>, ring2-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m1">creation_time</a>); 01140 <font class="keywordflow">goto</font> failure; 01141 } 01142 01143 <font class="keywordflow">if</font> (!_dbus_string_equal (&ring1-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m2">secret</a>, 01144 &ring2-><a class="code" href="structDBusKeyring.html#m5">keys</a>[i].<a class="code" href="structDBusKey.html#m2">secret</a>)) 01145 { 01146 fprintf (stderr, <font class="stringliteral">"Keyrings 1 and 2 have different secrets for same ID/timestamp\n"</font>); 01147 <font class="keywordflow">goto</font> failure; 01148 } 01149 01150 ++i; 01151 } 01152 01153 printf (<font class="stringliteral">" %d keys in test\n"</font>, ring1-><a class="code" href="structDBusKeyring.html#m6">n_keys</a>); 01154 01155 <font class="comment">/* Test ref/unref */</font> 01156 _dbus_keyring_ref (ring1); 01157 _dbus_keyring_ref (ring2); 01158 _dbus_keyring_unref (ring1); 01159 _dbus_keyring_unref (ring2); 01160 01161 01162 <font class="comment">/* really unref */</font> 01163 _dbus_keyring_unref (ring1); 01164 _dbus_keyring_unref (ring2); 01165 01166 <font class="keywordflow">return</font> TRUE; 01167 01168 failure: 01169 <font class="keywordflow">if</font> (ring1) 01170 _dbus_keyring_unref (ring1); 01171 <font class="keywordflow">if</font> (ring2) 01172 _dbus_keyring_unref (ring2); 01173 01174 <font class="keywordflow">return</font> FALSE; 01175 } 01176 01177 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font> 01178 </pre></div><hr><address align="right"><small>Generated on Wed Jun 9 05:01:25 2004 for D-BUS by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.15 </small></address> </body> </html>