<!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-auth.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-auth.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* dbus-auth.c Authentication</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2002, 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 <font class="preprocessor">#include "dbus-auth.h"</font> 00024 <font class="preprocessor">#include "dbus-string.h"</font> 00025 <font class="preprocessor">#include "dbus-list.h"</font> 00026 <font class="preprocessor">#include "dbus-internals.h"</font> 00027 <font class="preprocessor">#include "dbus-keyring.h"</font> 00028 <font class="preprocessor">#include "dbus-sha.h"</font> 00029 <font class="preprocessor">#include "dbus-userdb.h"</font> 00030 <a name="l00071"></a><a class="code" href="group__DBusAuthInternals.html#a0">00071</a> <font class="keyword">typedef</font> dbus_bool_t (* DBusInitialResponseFunction) (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00072 <a class="code" href="structDBusString.html">DBusString</a> *response); 00073 <a name="l00078"></a><a class="code" href="group__DBusAuthInternals.html#a1">00078</a> <font class="keyword">typedef</font> dbus_bool_t (* DBusAuthDataFunction) (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00079 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data); 00080 <a name="l00084"></a><a class="code" href="group__DBusAuthInternals.html#a2">00084</a> <font class="keyword">typedef</font> dbus_bool_t (* DBusAuthEncodeFunction) (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00085 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data, 00086 <a class="code" href="structDBusString.html">DBusString</a> *encoded); 00087 <a name="l00091"></a><a class="code" href="group__DBusAuthInternals.html#a3">00091</a> <font class="keyword">typedef</font> dbus_bool_t (* DBusAuthDecodeFunction) (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00092 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data, 00093 <a class="code" href="structDBusString.html">DBusString</a> *decoded); 00094 <a name="l00098"></a><a class="code" href="group__DBusAuthInternals.html#a4">00098</a> <font class="keyword">typedef</font> void (* DBusAuthShutdownFunction) (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth); 00099 <a name="l00103"></a><a class="code" href="structDBusAuthMechanismHandler.html">00103</a> <font class="keyword">typedef</font> <font class="keyword">struct</font> 00104 <font class="keyword"></font>{ <a name="l00105"></a><a class="code" href="structDBusAuthMechanismHandler.html#m0">00105</a> <font class="keyword">const</font> <font class="keywordtype">char</font> *mechanism; <a name="l00106"></a><a class="code" href="structDBusAuthMechanismHandler.html#m1">00106</a> DBusAuthDataFunction server_data_func; <a name="l00107"></a><a class="code" href="structDBusAuthMechanismHandler.html#m2">00107</a> DBusAuthEncodeFunction server_encode_func; <a name="l00108"></a><a class="code" href="structDBusAuthMechanismHandler.html#m3">00108</a> DBusAuthDecodeFunction server_decode_func; <a name="l00109"></a><a class="code" href="structDBusAuthMechanismHandler.html#m4">00109</a> DBusAuthShutdownFunction server_shutdown_func; <a name="l00110"></a><a class="code" href="structDBusAuthMechanismHandler.html#m5">00110</a> DBusInitialResponseFunction client_initial_response_func; <a name="l00111"></a><a class="code" href="structDBusAuthMechanismHandler.html#m6">00111</a> DBusAuthDataFunction client_data_func; <a name="l00112"></a><a class="code" href="structDBusAuthMechanismHandler.html#m7">00112</a> DBusAuthEncodeFunction client_encode_func; <a name="l00113"></a><a class="code" href="structDBusAuthMechanismHandler.html#m8">00113</a> DBusAuthDecodeFunction client_decode_func; <a name="l00114"></a><a class="code" href="structDBusAuthMechanismHandler.html#m9">00114</a> DBusAuthShutdownFunction client_shutdown_func; 00115 } <a class="code" href="structDBusAuthMechanismHandler.html">DBusAuthMechanismHandler</a>; 00116 <a name="l00120"></a><a class="code" href="group__DBusAuthInternals.html#a62">00120</a> <font class="keyword">typedef</font> <font class="keyword">enum</font> { 00121 DBUS_AUTH_COMMAND_AUTH, 00122 DBUS_AUTH_COMMAND_CANCEL, 00123 DBUS_AUTH_COMMAND_DATA, 00124 DBUS_AUTH_COMMAND_BEGIN, 00125 DBUS_AUTH_COMMAND_REJECTED, 00126 DBUS_AUTH_COMMAND_OK, 00127 DBUS_AUTH_COMMAND_ERROR, 00128 DBUS_AUTH_COMMAND_UNKNOWN 00129 } DBusAuthCommand; 00130 <a name="l00136"></a><a class="code" href="group__DBusAuthInternals.html#a5">00136</a> <font class="keyword">typedef</font> dbus_bool_t (* DBusAuthStateFunction) (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00137 DBusAuthCommand command, 00138 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args); 00139 <a name="l00143"></a><a class="code" href="structDBusAuthStateData.html">00143</a> <font class="keyword">typedef</font> <font class="keyword">struct</font> 00144 <font class="keyword"></font>{ <a name="l00145"></a><a class="code" href="structDBusAuthStateData.html#m0">00145</a> <font class="keyword">const</font> <font class="keywordtype">char</font> *name; <a name="l00146"></a><a class="code" href="structDBusAuthStateData.html#m1">00146</a> DBusAuthStateFunction handler; 00147 } <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a>; 00148 <a name="l00152"></a><a class="code" href="structDBusAuth.html">00152</a> <font class="keyword">struct </font><a class="code" href="structDBusAuth.html">DBusAuth</a> 00153 { <a name="l00154"></a><a class="code" href="structDBusAuth.html#m0">00154</a> <font class="keywordtype">int</font> <a class="code" href="structDBusAuth.html#m0">refcount</a>; <a name="l00155"></a><a class="code" href="structDBusAuth.html#m1">00155</a> <font class="keyword">const</font> <font class="keywordtype">char</font> *<a class="code" href="structDBusAuth.html#m1">side</a>; <a name="l00157"></a><a class="code" href="structDBusAuth.html#m2">00157</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusAuth.html#m2">incoming</a>; <a name="l00158"></a><a class="code" href="structDBusAuth.html#m3">00158</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusAuth.html#m3">outgoing</a>; <a name="l00160"></a><a class="code" href="structDBusAuth.html#m4">00160</a> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> *<a class="code" href="structDBusAuth.html#m4">state</a>; <a name="l00162"></a><a class="code" href="structDBusAuth.html#m5">00162</a> <font class="keyword">const</font> <a class="code" href="structDBusAuthMechanismHandler.html">DBusAuthMechanismHandler</a> *<a class="code" href="structDBusAuth.html#m5">mech</a>; <a name="l00164"></a><a class="code" href="structDBusAuth.html#m6">00164</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusAuth.html#m6">identity</a>; <a name="l00168"></a><a class="code" href="structDBusAuth.html#m7">00168</a> <a class="code" href="structDBusCredentials.html">DBusCredentials</a> <a class="code" href="structDBusAuth.html#m7">credentials</a>; <a name="l00172"></a><a class="code" href="structDBusAuth.html#m8">00172</a> <a class="code" href="structDBusCredentials.html">DBusCredentials</a> <a class="code" href="structDBusAuth.html#m8">authorized_identity</a>; <a name="l00174"></a><a class="code" href="structDBusAuth.html#m9">00174</a> <a class="code" href="structDBusCredentials.html">DBusCredentials</a> <a class="code" href="structDBusAuth.html#m9">desired_identity</a>; <a name="l00176"></a><a class="code" href="structDBusAuth.html#m10">00176</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusAuth.html#m10">context</a>; <a name="l00177"></a><a class="code" href="structDBusAuth.html#m11">00177</a> <a class="code" href="structDBusKeyring.html">DBusKeyring</a> *<a class="code" href="structDBusAuth.html#m11">keyring</a>; <a name="l00178"></a><a class="code" href="structDBusAuth.html#m12">00178</a> <font class="keywordtype">int</font> <a class="code" href="structDBusAuth.html#m12">cookie_id</a>; <a name="l00179"></a><a class="code" href="structDBusAuth.html#m13">00179</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusAuth.html#m13">challenge</a>; <a name="l00181"></a><a class="code" href="structDBusAuth.html#m14">00181</a> <font class="keywordtype">char</font> **<a class="code" href="structDBusAuth.html#m14">allowed_mechs</a>; <a name="l00185"></a><a class="code" href="structDBusAuth.html#m15">00185</a> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> <a class="code" href="structDBusAuth.html#m15">needed_memory</a> : 1; <a name="l00188"></a><a class="code" href="structDBusAuth.html#m16">00188</a> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> <a class="code" href="structDBusAuth.html#m16">already_got_mechanisms</a> : 1; <a name="l00189"></a><a class="code" href="structDBusAuth.html#m17">00189</a> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> <a class="code" href="structDBusAuth.html#m17">already_asked_for_initial_response</a> : 1; <a name="l00190"></a><a class="code" href="structDBusAuth.html#m18">00190</a> <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> <a class="code" href="structDBusAuth.html#m18">buffer_outstanding</a> : 1; 00191 }; 00192 <a name="l00196"></a><a class="code" href="structDBusAuthClient.html">00196</a> <font class="keyword">typedef</font> <font class="keyword">struct</font> 00197 <font class="keyword"></font>{ <a name="l00198"></a><a class="code" href="structDBusAuthClient.html#m0">00198</a> <a class="code" href="structDBusAuth.html">DBusAuth</a> base; <a name="l00200"></a><a class="code" href="structDBusAuthClient.html#m1">00200</a> <a class="code" href="structDBusList.html">DBusList</a> *mechs_to_try; 00202 } <a class="code" href="structDBusAuthClient.html">DBusAuthClient</a>; 00203 <a name="l00207"></a><a class="code" href="structDBusAuthServer.html">00207</a> <font class="keyword">typedef</font> <font class="keyword">struct</font> 00208 <font class="keyword"></font>{ <a name="l00209"></a><a class="code" href="structDBusAuthServer.html#m0">00209</a> <a class="code" href="structDBusAuth.html">DBusAuth</a> base; <a name="l00211"></a><a class="code" href="structDBusAuthServer.html#m1">00211</a> <font class="keywordtype">int</font> failures; <a name="l00212"></a><a class="code" href="structDBusAuthServer.html#m2">00212</a> <font class="keywordtype">int</font> max_failures; 00214 } <a class="code" href="structDBusAuthServer.html">DBusAuthServer</a>; 00215 00216 <font class="keyword">static</font> <font class="keywordtype">void</font> goto_state (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00217 <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> *new_state); 00218 <font class="keyword">static</font> dbus_bool_t send_auth (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00219 <font class="keyword">const</font> <a class="code" href="structDBusAuthMechanismHandler.html">DBusAuthMechanismHandler</a> *mech); 00220 <font class="keyword">static</font> dbus_bool_t send_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00221 <a class="code" href="structDBusString.html">DBusString</a> *data); 00222 <font class="keyword">static</font> dbus_bool_t send_rejected (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth); 00223 <font class="keyword">static</font> dbus_bool_t send_error (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00224 <font class="keyword">const</font> <font class="keywordtype">char</font> *message); 00225 <font class="keyword">static</font> dbus_bool_t send_ok (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth); 00226 <font class="keyword">static</font> dbus_bool_t send_begin (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth); 00227 <font class="keyword">static</font> dbus_bool_t send_cancel (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth); 00228 00233 <font class="keyword">static</font> dbus_bool_t handle_server_state_waiting_for_auth (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00234 DBusAuthCommand command, 00235 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args); 00236 <font class="keyword">static</font> dbus_bool_t handle_server_state_waiting_for_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00237 DBusAuthCommand command, 00238 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args); 00239 <font class="keyword">static</font> dbus_bool_t handle_server_state_waiting_for_begin (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00240 DBusAuthCommand command, 00241 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args); 00242 00243 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> server_state_waiting_for_auth = { 00244 <font class="stringliteral">"WaitingForAuth"</font>, handle_server_state_waiting_for_auth 00245 }; 00246 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> server_state_waiting_for_data = { 00247 <font class="stringliteral">"WaitingForData"</font>, handle_server_state_waiting_for_data 00248 }; 00249 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> server_state_waiting_for_begin = { 00250 <font class="stringliteral">"WaitingForBegin"</font>, handle_server_state_waiting_for_begin 00251 }; 00252 00257 <font class="keyword">static</font> dbus_bool_t handle_client_state_waiting_for_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00258 DBusAuthCommand command, 00259 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args); 00260 <font class="keyword">static</font> dbus_bool_t handle_client_state_waiting_for_ok (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00261 DBusAuthCommand command, 00262 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args); 00263 <font class="keyword">static</font> dbus_bool_t handle_client_state_waiting_for_reject (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00264 DBusAuthCommand command, 00265 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args); 00266 00267 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> client_state_need_send_auth = { 00268 <font class="stringliteral">"NeedSendAuth"</font>, NULL 00269 }; 00270 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> client_state_waiting_for_data = { 00271 <font class="stringliteral">"WaitingForData"</font>, handle_client_state_waiting_for_data 00272 }; 00273 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> client_state_waiting_for_ok = { 00274 <font class="stringliteral">"WaitingForOK"</font>, handle_client_state_waiting_for_ok 00275 }; 00276 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> client_state_waiting_for_reject = { 00277 <font class="stringliteral">"WaitingForReject"</font>, handle_client_state_waiting_for_reject 00278 }; 00279 00284 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> common_state_authenticated = { 00285 <font class="stringliteral">"Authenticated"</font>, NULL 00286 }; 00287 00288 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> common_state_need_disconnect = { 00289 <font class="stringliteral">"NeedDisconnect"</font>, NULL 00290 }; 00291 00292 <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">char</font> auth_side_client[] = <font class="stringliteral">"client"</font>; 00293 <font class="keyword">static</font> <font class="keyword">const</font> <font class="keywordtype">char</font> auth_side_server[] = <font class="stringliteral">"server"</font>; <a name="l00298"></a><a class="code" href="group__DBusAuthInternals.html#a56">00298</a> <font class="preprocessor">#define DBUS_AUTH_IS_SERVER(auth) ((auth)->side == auth_side_server)</font> 00299 <font class="preprocessor"></font> <a name="l00303"></a><a class="code" href="group__DBusAuthInternals.html#a57">00303</a> <font class="preprocessor">#define DBUS_AUTH_IS_CLIENT(auth) ((auth)->side == auth_side_client)</font> 00304 <font class="preprocessor"></font> <a name="l00308"></a><a class="code" href="group__DBusAuthInternals.html#a58">00308</a> <font class="preprocessor">#define DBUS_AUTH_CLIENT(auth) ((DBusAuthClient*)(auth))</font> 00309 <font class="preprocessor"></font> <a name="l00313"></a><a class="code" href="group__DBusAuthInternals.html#a59">00313</a> <font class="preprocessor">#define DBUS_AUTH_SERVER(auth) ((DBusAuthServer*)(auth))</font> 00314 <font class="preprocessor"></font> <a name="l00320"></a><a class="code" href="group__DBusAuthInternals.html#a60">00320</a> <font class="preprocessor">#define DBUS_AUTH_NAME(auth) ((auth)->side)</font> 00321 <font class="preprocessor"></font> 00322 <font class="keyword">static</font> <a class="code" href="structDBusAuth.html">DBusAuth</a>* 00323 _dbus_auth_new (<font class="keywordtype">int</font> size) 00324 { 00325 <a class="code" href="structDBusAuth.html">DBusAuth</a> *auth; 00326 00327 auth = dbus_malloc0 (size); 00328 <font class="keywordflow">if</font> (auth == NULL) 00329 <font class="keywordflow">return</font> NULL; 00330 00331 auth-><a class="code" href="structDBusAuth.html#m0">refcount</a> = 1; 00332 00333 _dbus_credentials_clear (&auth-><a class="code" href="structDBusAuth.html#m7">credentials</a>); 00334 _dbus_credentials_clear (&auth-><a class="code" href="structDBusAuth.html#m8">authorized_identity</a>); 00335 _dbus_credentials_clear (&auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>); 00336 00337 auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> = NULL; 00338 auth-><a class="code" href="structDBusAuth.html#m12">cookie_id</a> = -1; 00339 00340 <font class="comment">/* note that we don't use the max string length feature,</font> 00341 <font class="comment"> * because you can't use that feature if you're going to</font> 00342 <font class="comment"> * try to recover from out-of-memory (it creates</font> 00343 <font class="comment"> * what looks like unrecoverable inability to alloc</font> 00344 <font class="comment"> * more space in the string). But we do handle</font> 00345 <font class="comment"> * overlong buffers in _dbus_auth_do_work().</font> 00346 <font class="comment"> */</font> 00347 00348 <font class="keywordflow">if</font> (!_dbus_string_init (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>)) 00349 <font class="keywordflow">goto</font> enomem_0; 00350 00351 <font class="keywordflow">if</font> (!_dbus_string_init (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>)) 00352 <font class="keywordflow">goto</font> enomem_1; 00353 00354 <font class="keywordflow">if</font> (!_dbus_string_init (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>)) 00355 <font class="keywordflow">goto</font> enomem_2; 00356 00357 <font class="keywordflow">if</font> (!_dbus_string_init (&auth-><a class="code" href="structDBusAuth.html#m10">context</a>)) 00358 <font class="keywordflow">goto</font> enomem_3; 00359 00360 <font class="keywordflow">if</font> (!_dbus_string_init (&auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>)) 00361 <font class="keywordflow">goto</font> enomem_4; 00362 00363 <font class="comment">/* default context if none is specified */</font> 00364 <font class="keywordflow">if</font> (!_dbus_string_append (&auth-><a class="code" href="structDBusAuth.html#m10">context</a>, <font class="stringliteral">"org_freedesktop_general"</font>)) 00365 <font class="keywordflow">goto</font> enomem_5; 00366 00367 <font class="keywordflow">return</font> auth; 00368 00369 enomem_5: 00370 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>); 00371 enomem_4: 00372 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m10">context</a>); 00373 enomem_3: 00374 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>); 00375 enomem_2: 00376 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>); 00377 enomem_1: 00378 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>); 00379 enomem_0: 00380 dbus_free (auth); 00381 <font class="keywordflow">return</font> NULL; 00382 } 00383 00384 <font class="keyword">static</font> <font class="keywordtype">void</font> 00385 shutdown_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 00386 { 00387 <font class="comment">/* Cancel any auth */</font> 00388 auth-><a class="code" href="structDBusAuth.html#m17">already_asked_for_initial_response</a> = FALSE; 00389 _dbus_string_set_length (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>, 0); 00390 00391 _dbus_credentials_clear (&auth-><a class="code" href="structDBusAuth.html#m8">authorized_identity</a>); 00392 _dbus_credentials_clear (&auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>); 00393 00394 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m5">mech</a> != NULL) 00395 { 00396 _dbus_verbose (<font class="stringliteral">"%s: Shutting down mechanism %s\n"</font>, 00397 DBUS_AUTH_NAME (auth), auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>); 00398 00399 <font class="keywordflow">if</font> (DBUS_AUTH_IS_CLIENT (auth)) 00400 (* auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m9">client_shutdown_func</a>) (auth); 00401 <font class="keywordflow">else</font> 00402 (* auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m4">server_shutdown_func</a>) (auth); 00403 00404 auth-><a class="code" href="structDBusAuth.html#m5">mech</a> = NULL; 00405 } 00406 } 00407 00408 <font class="comment">/* Returns TRUE but with an empty string hash if the</font> 00409 <font class="comment"> * cookie_id isn't known. As with all this code</font> 00410 <font class="comment"> * TRUE just means we had enough memory.</font> 00411 <font class="comment"> */</font> 00412 <font class="keyword">static</font> dbus_bool_t 00413 sha1_compute_hash (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00414 <font class="keywordtype">int</font> cookie_id, 00415 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *server_challenge, 00416 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *client_challenge, 00417 <a class="code" href="structDBusString.html">DBusString</a> *hash) 00418 { 00419 <a class="code" href="structDBusString.html">DBusString</a> cookie; 00420 <a class="code" href="structDBusString.html">DBusString</a> to_hash; 00421 dbus_bool_t retval; 00422 00423 _dbus_assert (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> != NULL); 00424 00425 retval = FALSE; 00426 00427 <font class="keywordflow">if</font> (!_dbus_string_init (&cookie)) 00428 <font class="keywordflow">return</font> FALSE; 00429 00430 <font class="keywordflow">if</font> (!_dbus_keyring_get_hex_key (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a>, cookie_id, 00431 &cookie)) 00432 <font class="keywordflow">goto</font> out_0; 00433 00434 <font class="keywordflow">if</font> (_dbus_string_get_length (&cookie) == 0) 00435 { 00436 retval = TRUE; 00437 <font class="keywordflow">goto</font> out_0; 00438 } 00439 00440 <font class="keywordflow">if</font> (!_dbus_string_init (&to_hash)) 00441 <font class="keywordflow">goto</font> out_0; 00442 00443 <font class="keywordflow">if</font> (!_dbus_string_copy (server_challenge, 0, 00444 &to_hash, _dbus_string_get_length (&to_hash))) 00445 <font class="keywordflow">goto</font> out_1; 00446 00447 <font class="keywordflow">if</font> (!_dbus_string_append (&to_hash, <font class="stringliteral">":"</font>)) 00448 <font class="keywordflow">goto</font> out_1; 00449 00450 <font class="keywordflow">if</font> (!_dbus_string_copy (client_challenge, 0, 00451 &to_hash, _dbus_string_get_length (&to_hash))) 00452 <font class="keywordflow">goto</font> out_1; 00453 00454 <font class="keywordflow">if</font> (!_dbus_string_append (&to_hash, <font class="stringliteral">":"</font>)) 00455 <font class="keywordflow">goto</font> out_1; 00456 00457 <font class="keywordflow">if</font> (!_dbus_string_copy (&cookie, 0, 00458 &to_hash, _dbus_string_get_length (&to_hash))) 00459 <font class="keywordflow">goto</font> out_1; 00460 00461 <font class="keywordflow">if</font> (!_dbus_sha_compute (&to_hash, hash)) 00462 <font class="keywordflow">goto</font> out_1; 00463 00464 retval = TRUE; 00465 00466 out_1: 00467 _dbus_string_zero (&to_hash); 00468 _dbus_string_free (&to_hash); 00469 out_0: 00470 _dbus_string_zero (&cookie); 00471 _dbus_string_free (&cookie); 00472 <font class="keywordflow">return</font> retval; 00473 } 00474 <a name="l00479"></a><a class="code" href="group__DBusAuthInternals.html#a61">00479</a> <font class="preprocessor">#define N_CHALLENGE_BYTES (128/8)</font> 00480 <font class="preprocessor"></font> 00481 <font class="keyword">static</font> dbus_bool_t 00482 sha1_handle_first_client_response (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00483 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data) 00484 { 00485 <font class="comment">/* We haven't sent a challenge yet, we're expecting a desired</font> 00486 <font class="comment"> * username from the client.</font> 00487 <font class="comment"> */</font> 00488 <a class="code" href="structDBusString.html">DBusString</a> tmp; 00489 <a class="code" href="structDBusString.html">DBusString</a> tmp2; 00490 dbus_bool_t retval; 00491 <a class="code" href="structDBusError.html">DBusError</a> error; 00492 00493 retval = FALSE; 00494 00495 _dbus_string_set_length (&auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>, 0); 00496 00497 <font class="keywordflow">if</font> (_dbus_string_get_length (data) > 0) 00498 { 00499 <font class="keywordflow">if</font> (_dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>) > 0) 00500 { 00501 <font class="comment">/* Tried to send two auth identities, wtf */</font> 00502 _dbus_verbose (<font class="stringliteral">"%s: client tried to send auth identity, but we already have one\n"</font>, 00503 DBUS_AUTH_NAME (auth)); 00504 <font class="keywordflow">return</font> send_rejected (auth); 00505 } 00506 <font class="keywordflow">else</font> 00507 { 00508 <font class="comment">/* this is our auth identity */</font> 00509 <font class="keywordflow">if</font> (!_dbus_string_copy (data, 0, &auth-><a class="code" href="structDBusAuth.html#m6">identity</a>, 0)) 00510 <font class="keywordflow">return</font> FALSE; 00511 } 00512 } 00513 00514 <font class="keywordflow">if</font> (!_dbus_credentials_from_username (data, &auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>)) 00515 { 00516 _dbus_verbose (<font class="stringliteral">"%s: Did not get a valid username from client\n"</font>, 00517 DBUS_AUTH_NAME (auth)); 00518 <font class="keywordflow">return</font> send_rejected (auth); 00519 } 00520 00521 <font class="keywordflow">if</font> (!_dbus_string_init (&tmp)) 00522 <font class="keywordflow">return</font> FALSE; 00523 00524 <font class="keywordflow">if</font> (!_dbus_string_init (&tmp2)) 00525 { 00526 _dbus_string_free (&tmp); 00527 <font class="keywordflow">return</font> FALSE; 00528 } 00529 00530 <font class="comment">/* we cache the keyring for speed, so here we drop it if it's the</font> 00531 <font class="comment"> * wrong one. FIXME caching the keyring here is useless since we use</font> 00532 <font class="comment"> * a different DBusAuth for every connection.</font> 00533 <font class="comment"> */</font> 00534 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> && 00535 !_dbus_keyring_is_for_user (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a>, 00536 data)) 00537 { 00538 _dbus_keyring_unref (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a>); 00539 auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> = NULL; 00540 } 00541 00542 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> == NULL) 00543 { 00544 <a class="code" href="structDBusError.html">DBusError</a> error; 00545 00546 dbus_error_init (&error); 00547 auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> = _dbus_keyring_new_homedir (data, 00548 &auth-><a class="code" href="structDBusAuth.html#m10">context</a>, 00549 &error); 00550 00551 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> == NULL) 00552 { 00553 <font class="keywordflow">if</font> (dbus_error_has_name (&error, 00554 DBUS_ERROR_NO_MEMORY)) 00555 { 00556 dbus_error_free (&error); 00557 <font class="keywordflow">goto</font> out; 00558 } 00559 <font class="keywordflow">else</font> 00560 { 00561 _DBUS_ASSERT_ERROR_IS_SET (&error); 00562 _dbus_verbose (<font class="stringliteral">"%s: Error loading keyring: %s\n"</font>, 00563 DBUS_AUTH_NAME (auth), error.<a class="code" href="structDBusError.html#m1">message</a>); 00564 <font class="keywordflow">if</font> (send_rejected (auth)) 00565 retval = TRUE; <font class="comment">/* retval is only about mem */</font> 00566 dbus_error_free (&error); 00567 <font class="keywordflow">goto</font> out; 00568 } 00569 } 00570 <font class="keywordflow">else</font> 00571 { 00572 _dbus_assert (!dbus_error_is_set (&error)); 00573 } 00574 } 00575 00576 _dbus_assert (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> != NULL); 00577 00578 dbus_error_init (&error); 00579 auth-><a class="code" href="structDBusAuth.html#m12">cookie_id</a> = _dbus_keyring_get_best_key (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a>, &error); 00580 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m12">cookie_id</a> < 0) 00581 { 00582 _DBUS_ASSERT_ERROR_IS_SET (&error); 00583 _dbus_verbose (<font class="stringliteral">"%s: Could not get a cookie ID to send to client: %s\n"</font>, 00584 DBUS_AUTH_NAME (auth), error.<a class="code" href="structDBusError.html#m1">message</a>); 00585 <font class="keywordflow">if</font> (send_rejected (auth)) 00586 retval = TRUE; 00587 dbus_error_free (&error); 00588 <font class="keywordflow">goto</font> out; 00589 } 00590 <font class="keywordflow">else</font> 00591 { 00592 _dbus_assert (!dbus_error_is_set (&error)); 00593 } 00594 00595 <font class="keywordflow">if</font> (!_dbus_string_copy (&auth-><a class="code" href="structDBusAuth.html#m10">context</a>, 0, 00596 &tmp2, _dbus_string_get_length (&tmp2))) 00597 <font class="keywordflow">goto</font> out; 00598 00599 <font class="keywordflow">if</font> (!_dbus_string_append (&tmp2, <font class="stringliteral">" "</font>)) 00600 <font class="keywordflow">goto</font> out; 00601 00602 <font class="keywordflow">if</font> (!_dbus_string_append_int (&tmp2, auth-><a class="code" href="structDBusAuth.html#m12">cookie_id</a>)) 00603 <font class="keywordflow">goto</font> out; 00604 00605 <font class="keywordflow">if</font> (!_dbus_string_append (&tmp2, <font class="stringliteral">" "</font>)) 00606 <font class="keywordflow">goto</font> out; 00607 00608 <font class="keywordflow">if</font> (!_dbus_generate_random_bytes (&tmp, N_CHALLENGE_BYTES)) 00609 <font class="keywordflow">goto</font> out; 00610 00611 _dbus_string_set_length (&auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>, 0); 00612 <font class="keywordflow">if</font> (!_dbus_string_hex_encode (&tmp, 0, &auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>, 0)) 00613 <font class="keywordflow">goto</font> out; 00614 00615 <font class="keywordflow">if</font> (!_dbus_string_hex_encode (&tmp, 0, &tmp2, 00616 _dbus_string_get_length (&tmp2))) 00617 <font class="keywordflow">goto</font> out; 00618 00619 <font class="keywordflow">if</font> (!send_data (auth, &tmp2)) 00620 <font class="keywordflow">goto</font> out; 00621 00622 goto_state (auth, &server_state_waiting_for_data); 00623 retval = TRUE; 00624 00625 out: 00626 _dbus_string_zero (&tmp); 00627 _dbus_string_free (&tmp); 00628 _dbus_string_zero (&tmp2); 00629 _dbus_string_free (&tmp2); 00630 00631 <font class="keywordflow">return</font> retval; 00632 } 00633 00634 <font class="keyword">static</font> dbus_bool_t 00635 sha1_handle_second_client_response (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00636 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data) 00637 { 00638 <font class="comment">/* We are expecting a response which is the hex-encoded client</font> 00639 <font class="comment"> * challenge, space, then SHA-1 hash of the concatenation of our</font> 00640 <font class="comment"> * challenge, ":", client challenge, ":", secret key, all</font> 00641 <font class="comment"> * hex-encoded.</font> 00642 <font class="comment"> */</font> 00643 <font class="keywordtype">int</font> i; 00644 <a class="code" href="structDBusString.html">DBusString</a> client_challenge; 00645 <a class="code" href="structDBusString.html">DBusString</a> client_hash; 00646 dbus_bool_t retval; 00647 <a class="code" href="structDBusString.html">DBusString</a> correct_hash; 00648 00649 retval = FALSE; 00650 00651 <font class="keywordflow">if</font> (!_dbus_string_find_blank (data, 0, &i)) 00652 { 00653 _dbus_verbose (<font class="stringliteral">"%s: no space separator in client response\n"</font>, 00654 DBUS_AUTH_NAME (auth)); 00655 <font class="keywordflow">return</font> send_rejected (auth); 00656 } 00657 00658 <font class="keywordflow">if</font> (!_dbus_string_init (&client_challenge)) 00659 <font class="keywordflow">goto</font> out_0; 00660 00661 <font class="keywordflow">if</font> (!_dbus_string_init (&client_hash)) 00662 <font class="keywordflow">goto</font> out_1; 00663 00664 <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, 0, i, &client_challenge, 00665 0)) 00666 <font class="keywordflow">goto</font> out_2; 00667 00668 _dbus_string_skip_blank (data, i, &i); 00669 00670 <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, i, 00671 _dbus_string_get_length (data) - i, 00672 &client_hash, 00673 0)) 00674 <font class="keywordflow">goto</font> out_2; 00675 00676 <font class="keywordflow">if</font> (_dbus_string_get_length (&client_challenge) == 0 || 00677 _dbus_string_get_length (&client_hash) == 0) 00678 { 00679 _dbus_verbose (<font class="stringliteral">"%s: zero-length client challenge or hash\n"</font>, 00680 DBUS_AUTH_NAME (auth)); 00681 <font class="keywordflow">if</font> (send_rejected (auth)) 00682 retval = TRUE; 00683 <font class="keywordflow">goto</font> out_2; 00684 } 00685 00686 <font class="keywordflow">if</font> (!_dbus_string_init (&correct_hash)) 00687 <font class="keywordflow">goto</font> out_2; 00688 00689 <font class="keywordflow">if</font> (!sha1_compute_hash (auth, auth-><a class="code" href="structDBusAuth.html#m12">cookie_id</a>, 00690 &auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>, 00691 &client_challenge, 00692 &correct_hash)) 00693 <font class="keywordflow">goto</font> out_3; 00694 00695 <font class="comment">/* if cookie_id was invalid, then we get an empty hash */</font> 00696 <font class="keywordflow">if</font> (_dbus_string_get_length (&correct_hash) == 0) 00697 { 00698 <font class="keywordflow">if</font> (send_rejected (auth)) 00699 retval = TRUE; 00700 <font class="keywordflow">goto</font> out_3; 00701 } 00702 00703 <font class="keywordflow">if</font> (!_dbus_string_equal (&client_hash, &correct_hash)) 00704 { 00705 <font class="keywordflow">if</font> (send_rejected (auth)) 00706 retval = TRUE; 00707 <font class="keywordflow">goto</font> out_3; 00708 } 00709 00710 <font class="keywordflow">if</font> (!send_ok (auth)) 00711 <font class="keywordflow">goto</font> out_3; 00712 00713 _dbus_verbose (<font class="stringliteral">"%s: authenticated client with UID "</font>DBUS_UID_FORMAT<font class="stringliteral">" using DBUS_COOKIE_SHA1\n"</font>, 00714 DBUS_AUTH_NAME (auth), auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>); 00715 00716 auth-><a class="code" href="structDBusAuth.html#m8">authorized_identity</a> = auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>; 00717 retval = TRUE; 00718 00719 out_3: 00720 _dbus_string_zero (&correct_hash); 00721 _dbus_string_free (&correct_hash); 00722 out_2: 00723 _dbus_string_zero (&client_hash); 00724 _dbus_string_free (&client_hash); 00725 out_1: 00726 _dbus_string_free (&client_challenge); 00727 out_0: 00728 <font class="keywordflow">return</font> retval; 00729 } 00730 00731 <font class="keyword">static</font> dbus_bool_t 00732 handle_server_data_cookie_sha1_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00733 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data) 00734 { 00735 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m12">cookie_id</a> < 0) 00736 <font class="keywordflow">return</font> sha1_handle_first_client_response (auth, data); 00737 <font class="keywordflow">else</font> 00738 <font class="keywordflow">return</font> sha1_handle_second_client_response (auth, data); 00739 } 00740 00741 <font class="keyword">static</font> <font class="keywordtype">void</font> 00742 handle_server_shutdown_cookie_sha1_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 00743 { 00744 auth-><a class="code" href="structDBusAuth.html#m12">cookie_id</a> = -1; 00745 _dbus_string_set_length (&auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>, 0); 00746 } 00747 00748 <font class="keyword">static</font> dbus_bool_t 00749 handle_client_initial_response_cookie_sha1_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00750 <a class="code" href="structDBusString.html">DBusString</a> *response) 00751 { 00752 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *username; 00753 dbus_bool_t retval; 00754 00755 retval = FALSE; 00756 00757 <font class="keywordflow">if</font> (!_dbus_username_from_current_process (&username)) 00758 <font class="keywordflow">goto</font> out_0; 00759 00760 <font class="keywordflow">if</font> (!_dbus_string_hex_encode (username, 0, 00761 response, 00762 _dbus_string_get_length (response))) 00763 <font class="keywordflow">goto</font> out_0; 00764 00765 retval = TRUE; 00766 00767 out_0: 00768 <font class="keywordflow">return</font> retval; 00769 } 00770 00771 <font class="keyword">static</font> dbus_bool_t 00772 handle_client_data_cookie_sha1_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00773 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data) 00774 { 00775 <font class="comment">/* The data we get from the server should be the cookie context</font> 00776 <font class="comment"> * name, the cookie ID, and the server challenge, separated by</font> 00777 <font class="comment"> * spaces. We send back our challenge string and the correct hash.</font> 00778 <font class="comment"> */</font> 00779 dbus_bool_t retval; 00780 <a class="code" href="structDBusString.html">DBusString</a> context; 00781 <a class="code" href="structDBusString.html">DBusString</a> cookie_id_str; 00782 <a class="code" href="structDBusString.html">DBusString</a> server_challenge; 00783 <a class="code" href="structDBusString.html">DBusString</a> client_challenge; 00784 <a class="code" href="structDBusString.html">DBusString</a> correct_hash; 00785 <a class="code" href="structDBusString.html">DBusString</a> tmp; 00786 <font class="keywordtype">int</font> i, j; 00787 <font class="keywordtype">long</font> val; 00788 00789 retval = FALSE; 00790 00791 <font class="keywordflow">if</font> (!_dbus_string_find_blank (data, 0, &i)) 00792 { 00793 <font class="keywordflow">if</font> (send_error (auth, 00794 <font class="stringliteral">"Server did not send context/ID/challenge properly"</font>)) 00795 retval = TRUE; 00796 <font class="keywordflow">goto</font> out_0; 00797 } 00798 00799 <font class="keywordflow">if</font> (!_dbus_string_init (&context)) 00800 <font class="keywordflow">goto</font> out_0; 00801 00802 <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, 0, i, 00803 &context, 0)) 00804 <font class="keywordflow">goto</font> out_1; 00805 00806 _dbus_string_skip_blank (data, i, &i); 00807 <font class="keywordflow">if</font> (!_dbus_string_find_blank (data, i, &j)) 00808 { 00809 <font class="keywordflow">if</font> (send_error (auth, 00810 <font class="stringliteral">"Server did not send context/ID/challenge properly"</font>)) 00811 retval = TRUE; 00812 <font class="keywordflow">goto</font> out_1; 00813 } 00814 00815 <font class="keywordflow">if</font> (!_dbus_string_init (&cookie_id_str)) 00816 <font class="keywordflow">goto</font> out_1; 00817 00818 <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, i, j - i, 00819 &cookie_id_str, 0)) 00820 <font class="keywordflow">goto</font> out_2; 00821 00822 <font class="keywordflow">if</font> (!_dbus_string_init (&server_challenge)) 00823 <font class="keywordflow">goto</font> out_2; 00824 00825 i = j; 00826 _dbus_string_skip_blank (data, i, &i); 00827 j = _dbus_string_get_length (data); 00828 00829 <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, i, j - i, 00830 &server_challenge, 0)) 00831 <font class="keywordflow">goto</font> out_3; 00832 00833 <font class="keywordflow">if</font> (!_dbus_keyring_validate_context (&context)) 00834 { 00835 <font class="keywordflow">if</font> (send_error (auth, <font class="stringliteral">"Server sent invalid cookie context"</font>)) 00836 retval = TRUE; 00837 <font class="keywordflow">goto</font> out_3; 00838 } 00839 00840 <font class="keywordflow">if</font> (!_dbus_string_parse_int (&cookie_id_str, 0, &val, NULL)) 00841 { 00842 <font class="keywordflow">if</font> (send_error (auth, <font class="stringliteral">"Could not parse cookie ID as an integer"</font>)) 00843 retval = TRUE; 00844 <font class="keywordflow">goto</font> out_3; 00845 } 00846 00847 <font class="keywordflow">if</font> (_dbus_string_get_length (&server_challenge) == 0) 00848 { 00849 <font class="keywordflow">if</font> (send_error (auth, <font class="stringliteral">"Empty server challenge string"</font>)) 00850 retval = TRUE; 00851 <font class="keywordflow">goto</font> out_3; 00852 } 00853 00854 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> == NULL) 00855 { 00856 <a class="code" href="structDBusError.html">DBusError</a> error; 00857 00858 dbus_error_init (&error); 00859 auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> = _dbus_keyring_new_homedir (NULL, 00860 &context, 00861 &error); 00862 00863 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> == NULL) 00864 { 00865 <font class="keywordflow">if</font> (dbus_error_has_name (&error, 00866 DBUS_ERROR_NO_MEMORY)) 00867 { 00868 dbus_error_free (&error); 00869 <font class="keywordflow">goto</font> out_3; 00870 } 00871 <font class="keywordflow">else</font> 00872 { 00873 _DBUS_ASSERT_ERROR_IS_SET (&error); 00874 00875 _dbus_verbose (<font class="stringliteral">"%s: Error loading keyring: %s\n"</font>, 00876 DBUS_AUTH_NAME (auth), error.<a class="code" href="structDBusError.html#m1">message</a>); 00877 00878 <font class="keywordflow">if</font> (send_error (auth, <font class="stringliteral">"Could not load cookie file"</font>)) 00879 retval = TRUE; <font class="comment">/* retval is only about mem */</font> 00880 00881 dbus_error_free (&error); 00882 <font class="keywordflow">goto</font> out_3; 00883 } 00884 } 00885 <font class="keywordflow">else</font> 00886 { 00887 _dbus_assert (!dbus_error_is_set (&error)); 00888 } 00889 } 00890 00891 _dbus_assert (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a> != NULL); 00892 00893 <font class="keywordflow">if</font> (!_dbus_string_init (&tmp)) 00894 <font class="keywordflow">goto</font> out_3; 00895 00896 <font class="keywordflow">if</font> (!_dbus_generate_random_bytes (&tmp, N_CHALLENGE_BYTES)) 00897 <font class="keywordflow">goto</font> out_4; 00898 00899 <font class="keywordflow">if</font> (!_dbus_string_init (&client_challenge)) 00900 <font class="keywordflow">goto</font> out_4; 00901 00902 <font class="keywordflow">if</font> (!_dbus_string_hex_encode (&tmp, 0, &client_challenge, 0)) 00903 <font class="keywordflow">goto</font> out_5; 00904 00905 <font class="keywordflow">if</font> (!_dbus_string_init (&correct_hash)) 00906 <font class="keywordflow">goto</font> out_5; 00907 00908 <font class="keywordflow">if</font> (!sha1_compute_hash (auth, val, 00909 &server_challenge, 00910 &client_challenge, 00911 &correct_hash)) 00912 <font class="keywordflow">goto</font> out_6; 00913 00914 <font class="keywordflow">if</font> (_dbus_string_get_length (&correct_hash) == 0) 00915 { 00916 <font class="comment">/* couldn't find the cookie ID or something */</font> 00917 <font class="keywordflow">if</font> (send_error (auth, <font class="stringliteral">"Don't have the requested cookie ID"</font>)) 00918 retval = TRUE; 00919 <font class="keywordflow">goto</font> out_6; 00920 } 00921 00922 _dbus_string_set_length (&tmp, 0); 00923 00924 <font class="keywordflow">if</font> (!_dbus_string_copy (&client_challenge, 0, &tmp, 00925 _dbus_string_get_length (&tmp))) 00926 <font class="keywordflow">goto</font> out_6; 00927 00928 <font class="keywordflow">if</font> (!_dbus_string_append (&tmp, <font class="stringliteral">" "</font>)) 00929 <font class="keywordflow">goto</font> out_6; 00930 00931 <font class="keywordflow">if</font> (!_dbus_string_copy (&correct_hash, 0, &tmp, 00932 _dbus_string_get_length (&tmp))) 00933 <font class="keywordflow">goto</font> out_6; 00934 00935 <font class="keywordflow">if</font> (!send_data (auth, &tmp)) 00936 <font class="keywordflow">goto</font> out_6; 00937 00938 retval = TRUE; 00939 00940 out_6: 00941 _dbus_string_zero (&correct_hash); 00942 _dbus_string_free (&correct_hash); 00943 out_5: 00944 _dbus_string_free (&client_challenge); 00945 out_4: 00946 _dbus_string_zero (&tmp); 00947 _dbus_string_free (&tmp); 00948 out_3: 00949 _dbus_string_free (&server_challenge); 00950 out_2: 00951 _dbus_string_free (&cookie_id_str); 00952 out_1: 00953 _dbus_string_free (&context); 00954 out_0: 00955 <font class="keywordflow">return</font> retval; 00956 } 00957 00958 <font class="keyword">static</font> <font class="keywordtype">void</font> 00959 handle_client_shutdown_cookie_sha1_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 00960 { 00961 auth-><a class="code" href="structDBusAuth.html#m12">cookie_id</a> = -1; 00962 _dbus_string_set_length (&auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>, 0); 00963 } 00964 00965 <font class="keyword">static</font> dbus_bool_t 00966 handle_server_data_external_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 00967 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data) 00968 { 00969 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m7">credentials</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a> == DBUS_UID_UNSET) 00970 { 00971 _dbus_verbose (<font class="stringliteral">"%s: no credentials, mechanism EXTERNAL can't authenticate\n"</font>, 00972 DBUS_AUTH_NAME (auth)); 00973 <font class="keywordflow">return</font> send_rejected (auth); 00974 } 00975 00976 <font class="keywordflow">if</font> (_dbus_string_get_length (data) > 0) 00977 { 00978 <font class="keywordflow">if</font> (_dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>) > 0) 00979 { 00980 <font class="comment">/* Tried to send two auth identities, wtf */</font> 00981 _dbus_verbose (<font class="stringliteral">"%s: client tried to send auth identity, but we already have one\n"</font>, 00982 DBUS_AUTH_NAME (auth)); 00983 <font class="keywordflow">return</font> send_rejected (auth); 00984 } 00985 <font class="keywordflow">else</font> 00986 { 00987 <font class="comment">/* this is our auth identity */</font> 00988 <font class="keywordflow">if</font> (!_dbus_string_copy (data, 0, &auth-><a class="code" href="structDBusAuth.html#m6">identity</a>, 0)) 00989 <font class="keywordflow">return</font> FALSE; 00990 } 00991 } 00992 00993 <font class="comment">/* Poke client for an auth identity, if none given */</font> 00994 <font class="keywordflow">if</font> (_dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>) == 0 && 00995 !auth-><a class="code" href="structDBusAuth.html#m17">already_asked_for_initial_response</a>) 00996 { 00997 <font class="keywordflow">if</font> (send_data (auth, NULL)) 00998 { 00999 _dbus_verbose (<font class="stringliteral">"%s: sending empty challenge asking client for auth identity\n"</font>, 01000 DBUS_AUTH_NAME (auth)); 01001 auth-><a class="code" href="structDBusAuth.html#m17">already_asked_for_initial_response</a> = TRUE; 01002 <font class="keywordflow">return</font> TRUE; 01003 } 01004 <font class="keywordflow">else</font> 01005 <font class="keywordflow">return</font> FALSE; 01006 } 01007 01008 _dbus_credentials_clear (&auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>); 01009 01010 <font class="comment">/* If auth->identity is still empty here, then client</font> 01011 <font class="comment"> * responded with an empty string after we poked it for</font> 01012 <font class="comment"> * an initial response. This means to try to auth the</font> 01013 <font class="comment"> * identity provided in the credentials.</font> 01014 <font class="comment"> */</font> 01015 <font class="keywordflow">if</font> (_dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>) == 0) 01016 { 01017 auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a> = auth-><a class="code" href="structDBusAuth.html#m7">credentials</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>; 01018 } 01019 <font class="keywordflow">else</font> 01020 { 01021 <font class="keywordflow">if</font> (!_dbus_uid_from_string (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>, 01022 &auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>)) 01023 { 01024 _dbus_verbose (<font class="stringliteral">"%s: could not get credentials from uid string\n"</font>, 01025 DBUS_AUTH_NAME (auth)); 01026 <font class="keywordflow">return</font> send_rejected (auth); 01027 } 01028 } 01029 01030 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a> == DBUS_UID_UNSET) 01031 { 01032 _dbus_verbose (<font class="stringliteral">"%s: desired user %s is no good\n"</font>, 01033 DBUS_AUTH_NAME (auth), 01034 _dbus_string_get_const_data (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>)); 01035 <font class="keywordflow">return</font> send_rejected (auth); 01036 } 01037 01038 <font class="keywordflow">if</font> (_dbus_credentials_match (&auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>, 01039 &auth-><a class="code" href="structDBusAuth.html#m7">credentials</a>)) 01040 { 01041 <font class="comment">/* client has authenticated */</font> 01042 <font class="keywordflow">if</font> (!send_ok (auth)) 01043 <font class="keywordflow">return</font> FALSE; 01044 01045 _dbus_verbose (<font class="stringliteral">"%s: authenticated client with UID "</font>DBUS_UID_FORMAT 01046 <font class="stringliteral">" matching socket credentials UID "</font>DBUS_UID_FORMAT<font class="stringliteral">"\n"</font>, 01047 DBUS_AUTH_NAME (auth), 01048 auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>, 01049 auth-><a class="code" href="structDBusAuth.html#m7">credentials</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>); 01050 01051 auth-><a class="code" href="structDBusAuth.html#m8">authorized_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a> = auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>; 01052 01053 <font class="keywordflow">return</font> TRUE; 01054 } 01055 <font class="keywordflow">else</font> 01056 { 01057 _dbus_verbose (<font class="stringliteral">"%s: credentials uid="</font>DBUS_UID_FORMAT 01058 <font class="stringliteral">" gid="</font>DBUS_GID_FORMAT 01059 <font class="stringliteral">" do not allow uid="</font>DBUS_UID_FORMAT 01060 <font class="stringliteral">" gid="</font>DBUS_GID_FORMAT<font class="stringliteral">"\n"</font>, 01061 DBUS_AUTH_NAME (auth), 01062 auth-><a class="code" href="structDBusAuth.html#m7">credentials</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>, auth-><a class="code" href="structDBusAuth.html#m7">credentials</a>.<a class="code" href="structDBusCredentials.html#m2">gid</a>, 01063 auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>, auth-><a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m2">gid</a>); 01064 <font class="keywordflow">return</font> send_rejected (auth); 01065 } 01066 } 01067 01068 <font class="keyword">static</font> <font class="keywordtype">void</font> 01069 handle_server_shutdown_external_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01070 { 01071 01072 } 01073 01074 <font class="keyword">static</font> dbus_bool_t 01075 handle_client_initial_response_external_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01076 <a class="code" href="structDBusString.html">DBusString</a> *response) 01077 { 01078 <font class="comment">/* We always append our UID as an initial response, so the server</font> 01079 <font class="comment"> * doesn't have to send back an empty challenge to check whether we</font> 01080 <font class="comment"> * want to specify an identity. i.e. this avoids a round trip that</font> 01081 <font class="comment"> * the spec for the EXTERNAL mechanism otherwise requires.</font> 01082 <font class="comment"> */</font> 01083 <a class="code" href="structDBusString.html">DBusString</a> plaintext; 01084 01085 <font class="keywordflow">if</font> (!_dbus_string_init (&plaintext)) 01086 <font class="keywordflow">return</font> FALSE; 01087 01088 <font class="keywordflow">if</font> (!_dbus_string_append_uint (&plaintext, 01089 _dbus_getuid ())) 01090 <font class="keywordflow">goto</font> failed; 01091 01092 <font class="keywordflow">if</font> (!_dbus_string_hex_encode (&plaintext, 0, 01093 response, 01094 _dbus_string_get_length (response))) 01095 <font class="keywordflow">goto</font> failed; 01096 01097 _dbus_string_free (&plaintext); 01098 01099 <font class="keywordflow">return</font> TRUE; 01100 01101 failed: 01102 _dbus_string_free (&plaintext); 01103 <font class="keywordflow">return</font> FALSE; 01104 } 01105 01106 <font class="keyword">static</font> dbus_bool_t 01107 handle_client_data_external_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01108 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *data) 01109 { 01110 01111 <font class="keywordflow">return</font> TRUE; 01112 } 01113 01114 <font class="keyword">static</font> <font class="keywordtype">void</font> 01115 handle_client_shutdown_external_mech (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01116 { 01117 01118 } 01119 01120 <font class="comment">/* Put mechanisms here in order of preference.</font> 01121 <font class="comment"> * What I eventually want to have is:</font> 01122 <font class="comment"> *</font> 01123 <font class="comment"> * - a mechanism that checks UNIX domain socket credentials</font> 01124 <font class="comment"> * - a simple magic cookie mechanism like X11 or ICE</font> 01125 <font class="comment"> * - mechanisms that chain to Cyrus SASL, so we can use anything it</font> 01126 <font class="comment"> * offers such as Kerberos, X509, whatever.</font> 01127 <font class="comment"> * </font> 01128 <font class="comment"> */</font> 01129 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthMechanismHandler.html">DBusAuthMechanismHandler</a> 01130 all_mechanisms[] = { 01131 { <font class="stringliteral">"EXTERNAL"</font>, 01132 handle_server_data_external_mech, 01133 NULL, NULL, 01134 handle_server_shutdown_external_mech, 01135 handle_client_initial_response_external_mech, 01136 handle_client_data_external_mech, 01137 NULL, NULL, 01138 handle_client_shutdown_external_mech }, 01139 { <font class="stringliteral">"DBUS_COOKIE_SHA1"</font>, 01140 handle_server_data_cookie_sha1_mech, 01141 NULL, NULL, 01142 handle_server_shutdown_cookie_sha1_mech, 01143 handle_client_initial_response_cookie_sha1_mech, 01144 handle_client_data_cookie_sha1_mech, 01145 NULL, NULL, 01146 handle_client_shutdown_cookie_sha1_mech }, 01147 { NULL, NULL } 01148 }; 01149 01150 <font class="keyword">static</font> <font class="keyword">const</font> <a class="code" href="structDBusAuthMechanismHandler.html">DBusAuthMechanismHandler</a>* 01151 find_mech (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *name, 01152 <font class="keywordtype">char</font> **allowed_mechs) 01153 { 01154 <font class="keywordtype">int</font> i; 01155 01156 <font class="keywordflow">if</font> (allowed_mechs != NULL && 01157 !_dbus_string_array_contains ((<font class="keyword">const</font> <font class="keywordtype">char</font>**) allowed_mechs, 01158 _dbus_string_get_const_data (name))) 01159 <font class="keywordflow">return</font> NULL; 01160 01161 i = 0; 01162 <font class="keywordflow">while</font> (all_mechanisms[i].<a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a> != NULL) 01163 { 01164 <font class="keywordflow">if</font> (_dbus_string_equal_c_str (name, 01165 all_mechanisms[i].mechanism)) 01166 01167 <font class="keywordflow">return</font> &all_mechanisms[i]; 01168 01169 ++i; 01170 } 01171 01172 <font class="keywordflow">return</font> NULL; 01173 } 01174 01175 <font class="keyword">static</font> dbus_bool_t 01176 send_auth (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, <font class="keyword">const</font> <a class="code" href="structDBusAuthMechanismHandler.html">DBusAuthMechanismHandler</a> *mech) 01177 { 01178 <a class="code" href="structDBusString.html">DBusString</a> auth_command; 01179 01180 <font class="keywordflow">if</font> (!_dbus_string_init (&auth_command)) 01181 <font class="keywordflow">return</font> FALSE; 01182 01183 <font class="keywordflow">if</font> (!_dbus_string_append (&auth_command, 01184 <font class="stringliteral">"AUTH "</font>)) 01185 { 01186 _dbus_string_free (&auth_command); 01187 <font class="keywordflow">return</font> FALSE; 01188 } 01189 01190 <font class="keywordflow">if</font> (!_dbus_string_append (&auth_command, 01191 mech-><a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>)) 01192 { 01193 _dbus_string_free (&auth_command); 01194 <font class="keywordflow">return</font> FALSE; 01195 } 01196 01197 <font class="keywordflow">if</font> (mech-><a class="code" href="structDBusAuthMechanismHandler.html#m5">client_initial_response_func</a> != NULL) 01198 { 01199 <font class="keywordflow">if</font> (!_dbus_string_append (&auth_command, <font class="stringliteral">" "</font>)) 01200 { 01201 _dbus_string_free (&auth_command); 01202 <font class="keywordflow">return</font> FALSE; 01203 } 01204 01205 <font class="keywordflow">if</font> (!(* mech-><a class="code" href="structDBusAuthMechanismHandler.html#m5">client_initial_response_func</a>) (auth, &auth_command)) 01206 { 01207 _dbus_string_free (&auth_command); 01208 <font class="keywordflow">return</font> FALSE; 01209 } 01210 } 01211 01212 <font class="keywordflow">if</font> (!_dbus_string_append (&auth_command, 01213 <font class="stringliteral">"\r\n"</font>)) 01214 { 01215 _dbus_string_free (&auth_command); 01216 <font class="keywordflow">return</font> FALSE; 01217 } 01218 01219 <font class="keywordflow">if</font> (!_dbus_string_copy (&auth_command, 0, 01220 &auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, 01221 _dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>))) 01222 { 01223 _dbus_string_free (&auth_command); 01224 <font class="keywordflow">return</font> FALSE; 01225 } 01226 01227 _dbus_string_free (&auth_command); 01228 shutdown_mech (auth); 01229 auth-><a class="code" href="structDBusAuth.html#m5">mech</a> = mech; 01230 goto_state (auth, &client_state_waiting_for_data); 01231 01232 <font class="keywordflow">return</font> TRUE; 01233 } 01234 01235 <font class="keyword">static</font> dbus_bool_t 01236 send_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, <a class="code" href="structDBusString.html">DBusString</a> *data) 01237 { 01238 <font class="keywordtype">int</font> old_len; 01239 01240 <font class="keywordflow">if</font> (data == NULL || _dbus_string_get_length (data) == 0) 01241 <font class="keywordflow">return</font> _dbus_string_append (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"DATA\r\n"</font>); 01242 <font class="keywordflow">else</font> 01243 { 01244 old_len = _dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>); 01245 <font class="keywordflow">if</font> (!_dbus_string_append (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"DATA "</font>)) 01246 <font class="keywordflow">goto</font> out; 01247 01248 <font class="keywordflow">if</font> (!_dbus_string_hex_encode (data, 0, &auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, 01249 _dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>))) 01250 <font class="keywordflow">goto</font> out; 01251 01252 <font class="keywordflow">if</font> (!_dbus_string_append (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"\r\n"</font>)) 01253 <font class="keywordflow">goto</font> out; 01254 01255 <font class="keywordflow">return</font> TRUE; 01256 01257 out: 01258 _dbus_string_set_length (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, old_len); 01259 01260 <font class="keywordflow">return</font> FALSE; 01261 } 01262 } 01263 01264 <font class="keyword">static</font> dbus_bool_t 01265 send_rejected (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01266 { 01267 <a class="code" href="structDBusString.html">DBusString</a> command; 01268 <a class="code" href="structDBusAuthServer.html">DBusAuthServer</a> *server_auth; 01269 <font class="keywordtype">int</font> i; 01270 01271 <font class="keywordflow">if</font> (!_dbus_string_init (&command)) 01272 <font class="keywordflow">return</font> FALSE; 01273 01274 <font class="keywordflow">if</font> (!_dbus_string_append (&command, 01275 <font class="stringliteral">"REJECTED"</font>)) 01276 <font class="keywordflow">goto</font> nomem; 01277 01278 i = 0; 01279 <font class="keywordflow">while</font> (all_mechanisms[i].<a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a> != NULL) 01280 { 01281 <font class="keywordflow">if</font> (!_dbus_string_append (&command, 01282 <font class="stringliteral">" "</font>)) 01283 <font class="keywordflow">goto</font> nomem; 01284 01285 <font class="keywordflow">if</font> (!_dbus_string_append (&command, 01286 all_mechanisms[i].mechanism)) 01287 <font class="keywordflow">goto</font> nomem; 01288 01289 ++i; 01290 } 01291 01292 <font class="keywordflow">if</font> (!_dbus_string_append (&command, <font class="stringliteral">"\r\n"</font>)) 01293 <font class="keywordflow">goto</font> nomem; 01294 01295 <font class="keywordflow">if</font> (!_dbus_string_copy (&command, 0, &auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, 01296 _dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>))) 01297 <font class="keywordflow">goto</font> nomem; 01298 01299 shutdown_mech (auth); 01300 01301 _dbus_assert (DBUS_AUTH_IS_SERVER (auth)); 01302 server_auth = DBUS_AUTH_SERVER (auth); 01303 server_auth-><a class="code" href="structDBusAuthServer.html#m1">failures</a> += 1; 01304 01305 <font class="keywordflow">if</font> (server_auth-><a class="code" href="structDBusAuthServer.html#m1">failures</a> >= server_auth-><a class="code" href="structDBusAuthServer.html#m2">max_failures</a>) 01306 goto_state (auth, &common_state_need_disconnect); 01307 <font class="keywordflow">else</font> 01308 goto_state (auth, &server_state_waiting_for_auth); 01309 01310 _dbus_string_free (&command); 01311 01312 <font class="keywordflow">return</font> TRUE; 01313 01314 nomem: 01315 _dbus_string_free (&command); 01316 <font class="keywordflow">return</font> FALSE; 01317 } 01318 01319 <font class="keyword">static</font> dbus_bool_t 01320 send_error (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, <font class="keyword">const</font> <font class="keywordtype">char</font> *message) 01321 { 01322 <font class="keywordflow">return</font> _dbus_string_append_printf (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, 01323 <font class="stringliteral">"ERROR \"%s\"\r\n"</font>, message); 01324 } 01325 01326 <font class="keyword">static</font> dbus_bool_t 01327 send_ok (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01328 { 01329 <font class="keywordflow">if</font> (_dbus_string_append (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"OK\r\n"</font>)) 01330 { 01331 goto_state (auth, &server_state_waiting_for_begin); 01332 <font class="keywordflow">return</font> TRUE; 01333 } 01334 <font class="keywordflow">else</font> 01335 <font class="keywordflow">return</font> FALSE; 01336 } 01337 01338 <font class="keyword">static</font> dbus_bool_t 01339 send_begin (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01340 { 01341 <font class="keywordflow">if</font> (_dbus_string_append (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"BEGIN\r\n"</font>)) 01342 { 01343 goto_state (auth, &common_state_authenticated); 01344 <font class="keywordflow">return</font> TRUE; 01345 } 01346 <font class="keywordflow">else</font> 01347 <font class="keywordflow">return</font> FALSE; 01348 } 01349 01350 <font class="keyword">static</font> dbus_bool_t 01351 send_cancel (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01352 { 01353 <font class="keywordflow">if</font> (_dbus_string_append (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"CANCEL\r\n"</font>)) 01354 { 01355 goto_state (auth, &client_state_waiting_for_reject); 01356 <font class="keywordflow">return</font> TRUE; 01357 } 01358 <font class="keywordflow">else</font> 01359 <font class="keywordflow">return</font> FALSE; 01360 } 01361 01362 <font class="keyword">static</font> dbus_bool_t 01363 process_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01364 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args, 01365 DBusAuthDataFunction data_func) 01366 { 01367 <font class="keywordtype">int</font> end; 01368 <a class="code" href="structDBusString.html">DBusString</a> decoded; 01369 01370 <font class="keywordflow">if</font> (!_dbus_string_init (&decoded)) 01371 <font class="keywordflow">return</font> FALSE; 01372 01373 <font class="keywordflow">if</font> (!_dbus_string_hex_decode (args, 0, &end, &decoded, 0)) 01374 { 01375 _dbus_string_free (&decoded); 01376 <font class="keywordflow">return</font> FALSE; 01377 } 01378 01379 <font class="keywordflow">if</font> (_dbus_string_get_length (args) != end) 01380 { 01381 _dbus_string_free (&decoded); 01382 <font class="keywordflow">if</font> (!send_error (auth, <font class="stringliteral">"Invalid hex encoding"</font>)) 01383 <font class="keywordflow">return</font> FALSE; 01384 01385 <font class="keywordflow">return</font> TRUE; 01386 } 01387 01388 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 01389 <font class="preprocessor"></font> <font class="keywordflow">if</font> (_dbus_string_validate_ascii (&decoded, 0, 01390 _dbus_string_get_length (&decoded))) 01391 _dbus_verbose (<font class="stringliteral">"%s: data: '%s'\n"</font>, 01392 DBUS_AUTH_NAME (auth), 01393 _dbus_string_get_const_data (&decoded)); 01394 <font class="preprocessor">#endif</font> 01395 <font class="preprocessor"></font> 01396 <font class="keywordflow">if</font> (!(* data_func) (auth, &decoded)) 01397 { 01398 _dbus_string_free (&decoded); 01399 <font class="keywordflow">return</font> FALSE; 01400 } 01401 01402 _dbus_string_free (&decoded); 01403 <font class="keywordflow">return</font> TRUE; 01404 } 01405 01406 <font class="keyword">static</font> dbus_bool_t 01407 handle_auth (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01408 { 01409 <font class="keywordflow">if</font> (_dbus_string_get_length (args) == 0) 01410 { 01411 <font class="comment">/* No args to the auth, send mechanisms */</font> 01412 <font class="keywordflow">if</font> (!send_rejected (auth)) 01413 <font class="keywordflow">return</font> FALSE; 01414 01415 <font class="keywordflow">return</font> TRUE; 01416 } 01417 <font class="keywordflow">else</font> 01418 { 01419 <font class="keywordtype">int</font> i; 01420 <a class="code" href="structDBusString.html">DBusString</a> mech; 01421 <a class="code" href="structDBusString.html">DBusString</a> hex_response; 01422 01423 _dbus_string_find_blank (args, 0, &i); 01424 01425 <font class="keywordflow">if</font> (!_dbus_string_init (&mech)) 01426 <font class="keywordflow">return</font> FALSE; 01427 01428 <font class="keywordflow">if</font> (!_dbus_string_init (&hex_response)) 01429 { 01430 _dbus_string_free (&mech); 01431 <font class="keywordflow">return</font> FALSE; 01432 } 01433 01434 <font class="keywordflow">if</font> (!_dbus_string_copy_len (args, 0, i, &mech, 0)) 01435 <font class="keywordflow">goto</font> failed; 01436 01437 _dbus_string_skip_blank (args, i, &i); 01438 <font class="keywordflow">if</font> (!_dbus_string_copy (args, i, &hex_response, 0)) 01439 <font class="keywordflow">goto</font> failed; 01440 01441 auth-><a class="code" href="structDBusAuth.html#m5">mech</a> = find_mech (&mech, auth-><a class="code" href="structDBusAuth.html#m14">allowed_mechs</a>); 01442 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m5">mech</a> != NULL) 01443 { 01444 _dbus_verbose (<font class="stringliteral">"%s: Trying mechanism %s\n"</font>, 01445 DBUS_AUTH_NAME (auth), 01446 auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>); 01447 01448 <font class="keywordflow">if</font> (!process_data (auth, &hex_response, 01449 auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m1">server_data_func</a>)) 01450 <font class="keywordflow">goto</font> failed; 01451 } 01452 <font class="keywordflow">else</font> 01453 { 01454 <font class="comment">/* Unsupported mechanism */</font> 01455 _dbus_verbose (<font class="stringliteral">"%s: Unsupported mechanism %s\n"</font>, 01456 DBUS_AUTH_NAME (auth), 01457 _dbus_string_get_const_data (&mech)); 01458 01459 <font class="keywordflow">if</font> (!send_rejected (auth)) 01460 <font class="keywordflow">goto</font> failed; 01461 } 01462 01463 _dbus_string_free (&mech); 01464 _dbus_string_free (&hex_response); 01465 01466 <font class="keywordflow">return</font> TRUE; 01467 01468 failed: 01469 auth-><a class="code" href="structDBusAuth.html#m5">mech</a> = NULL; 01470 _dbus_string_free (&mech); 01471 _dbus_string_free (&hex_response); 01472 <font class="keywordflow">return</font> FALSE; 01473 } 01474 } 01475 01476 <font class="keyword">static</font> dbus_bool_t 01477 handle_server_state_waiting_for_auth (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01478 DBusAuthCommand command, 01479 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01480 { 01481 <font class="keywordflow">switch</font> (command) 01482 { 01483 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_AUTH: 01484 <font class="keywordflow">return</font> handle_auth (auth, args); 01485 01486 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_CANCEL: 01487 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_DATA: 01488 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Not currently in an auth conversation"</font>); 01489 01490 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_BEGIN: 01491 goto_state (auth, &common_state_need_disconnect); 01492 <font class="keywordflow">return</font> TRUE; 01493 01494 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_ERROR: 01495 <font class="keywordflow">return</font> send_rejected (auth); 01496 01497 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_REJECTED: 01498 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_OK: 01499 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_UNKNOWN: 01500 <font class="keywordflow">default</font>: 01501 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Unknown command"</font>); 01502 } 01503 } 01504 01505 <font class="keyword">static</font> dbus_bool_t 01506 handle_server_state_waiting_for_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01507 DBusAuthCommand command, 01508 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01509 { 01510 <font class="keywordflow">switch</font> (command) 01511 { 01512 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_AUTH: 01513 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Sent AUTH while another AUTH in progress"</font>); 01514 01515 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_CANCEL: 01516 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_ERROR: 01517 <font class="keywordflow">return</font> send_rejected (auth); 01518 01519 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_DATA: 01520 <font class="keywordflow">return</font> process_data (auth, args, auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m1">server_data_func</a>); 01521 01522 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_BEGIN: 01523 goto_state (auth, &common_state_need_disconnect); 01524 <font class="keywordflow">return</font> TRUE; 01525 01526 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_REJECTED: 01527 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_OK: 01528 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_UNKNOWN: 01529 <font class="keywordflow">default</font>: 01530 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Unknown command"</font>); 01531 } 01532 } 01533 01534 <font class="keyword">static</font> dbus_bool_t 01535 handle_server_state_waiting_for_begin (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01536 DBusAuthCommand command, 01537 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01538 { 01539 <font class="keywordflow">switch</font> (command) 01540 { 01541 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_AUTH: 01542 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Sent AUTH while expecting BEGIN"</font>); 01543 01544 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_DATA: 01545 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Sent DATA while expecting BEGIN"</font>); 01546 01547 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_BEGIN: 01548 goto_state (auth, &common_state_authenticated); 01549 <font class="keywordflow">return</font> TRUE; 01550 01551 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_REJECTED: 01552 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_OK: 01553 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_UNKNOWN: 01554 <font class="keywordflow">default</font>: 01555 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Unknown command"</font>); 01556 01557 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_CANCEL: 01558 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_ERROR: 01559 <font class="keywordflow">return</font> send_rejected (auth); 01560 } 01561 } 01562 01563 <font class="comment">/* return FALSE if no memory, TRUE if all OK */</font> 01564 <font class="keyword">static</font> dbus_bool_t 01565 get_word (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *str, 01566 <font class="keywordtype">int</font> *start, 01567 <a class="code" href="structDBusString.html">DBusString</a> *word) 01568 { 01569 <font class="keywordtype">int</font> i; 01570 01571 _dbus_string_skip_blank (str, *start, start); 01572 _dbus_string_find_blank (str, *start, &i); 01573 01574 <font class="keywordflow">if</font> (i > *start) 01575 { 01576 <font class="keywordflow">if</font> (!_dbus_string_copy_len (str, *start, i - *start, word, 0)) 01577 <font class="keywordflow">return</font> FALSE; 01578 01579 *start = i; 01580 } 01581 01582 <font class="keywordflow">return</font> TRUE; 01583 } 01584 01585 <font class="keyword">static</font> dbus_bool_t 01586 record_mechanisms (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01587 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01588 { 01589 <font class="keywordtype">int</font> next; 01590 <font class="keywordtype">int</font> len; 01591 01592 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m16">already_got_mechanisms</a>) 01593 <font class="keywordflow">return</font> TRUE; 01594 01595 len = _dbus_string_get_length (args); 01596 01597 next = 0; 01598 <font class="keywordflow">while</font> (next < len) 01599 { 01600 <a class="code" href="structDBusString.html">DBusString</a> m; 01601 <font class="keyword">const</font> <a class="code" href="structDBusAuthMechanismHandler.html">DBusAuthMechanismHandler</a> *mech; 01602 01603 <font class="keywordflow">if</font> (!_dbus_string_init (&m)) 01604 <font class="keywordflow">goto</font> nomem; 01605 01606 <font class="keywordflow">if</font> (!get_word (args, &next, &m)) 01607 { 01608 _dbus_string_free (&m); 01609 <font class="keywordflow">goto</font> nomem; 01610 } 01611 01612 mech = find_mech (&m, auth-><a class="code" href="structDBusAuth.html#m14">allowed_mechs</a>); 01613 01614 <font class="keywordflow">if</font> (mech != NULL) 01615 { 01616 <font class="comment">/* FIXME right now we try mechanisms in the order</font> 01617 <font class="comment"> * the server lists them; should we do them in</font> 01618 <font class="comment"> * some more deterministic order?</font> 01619 <font class="comment"> *</font> 01620 <font class="comment"> * Probably in all_mechanisms order, our order of</font> 01621 <font class="comment"> * preference. Of course when the server is us,</font> 01622 <font class="comment"> * it lists things in that order anyhow.</font> 01623 <font class="comment"> */</font> 01624 01625 _dbus_verbose (<font class="stringliteral">"%s: Adding mechanism %s to list we will try\n"</font>, 01626 DBUS_AUTH_NAME (auth), mech-><a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>); 01627 01628 <font class="keywordflow">if</font> (!_dbus_list_append (& DBUS_AUTH_CLIENT (auth)->mechs_to_try, 01629 (<font class="keywordtype">void</font>*) mech)) 01630 { 01631 _dbus_string_free (&m); 01632 <font class="keywordflow">goto</font> nomem; 01633 } 01634 } 01635 <font class="keywordflow">else</font> 01636 { 01637 _dbus_verbose (<font class="stringliteral">"%s: Server offered mechanism \"%s\" that we don't know how to use\n"</font>, 01638 DBUS_AUTH_NAME (auth), 01639 _dbus_string_get_const_data (&m)); 01640 } 01641 01642 _dbus_string_free (&m); 01643 } 01644 01645 auth-><a class="code" href="structDBusAuth.html#m16">already_got_mechanisms</a> = TRUE; 01646 01647 <font class="keywordflow">return</font> TRUE; 01648 01649 nomem: 01650 _dbus_list_clear (& DBUS_AUTH_CLIENT (auth)->mechs_to_try); 01651 01652 <font class="keywordflow">return</font> FALSE; 01653 } 01654 01655 <font class="keyword">static</font> dbus_bool_t 01656 process_rejected (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01657 { 01658 <font class="keyword">const</font> <a class="code" href="structDBusAuthMechanismHandler.html">DBusAuthMechanismHandler</a> *mech; 01659 <a class="code" href="structDBusAuthClient.html">DBusAuthClient</a> *client; 01660 01661 client = DBUS_AUTH_CLIENT (auth); 01662 01663 <font class="keywordflow">if</font> (!auth-><a class="code" href="structDBusAuth.html#m16">already_got_mechanisms</a>) 01664 { 01665 <font class="keywordflow">if</font> (!record_mechanisms (auth, args)) 01666 <font class="keywordflow">return</font> FALSE; 01667 } 01668 01669 <font class="keywordflow">if</font> (DBUS_AUTH_CLIENT (auth)->mechs_to_try != NULL) 01670 { 01671 mech = client-><a class="code" href="structDBusAuthClient.html#m1">mechs_to_try</a>-><a class="code" href="structDBusList.html#m2">data</a>; 01672 01673 <font class="keywordflow">if</font> (!send_auth (auth, mech)) 01674 <font class="keywordflow">return</font> FALSE; 01675 01676 _dbus_list_pop_first (&client-><a class="code" href="structDBusAuthClient.html#m1">mechs_to_try</a>); 01677 01678 _dbus_verbose (<font class="stringliteral">"%s: Trying mechanism %s\n"</font>, 01679 DBUS_AUTH_NAME (auth), 01680 mech-><a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>); 01681 } 01682 <font class="keywordflow">else</font> 01683 { 01684 <font class="comment">/* Give up */</font> 01685 _dbus_verbose (<font class="stringliteral">"%s: Disconnecting because we are out of mechanisms to try using\n"</font>, 01686 DBUS_AUTH_NAME (auth)); 01687 goto_state (auth, &common_state_need_disconnect); 01688 } 01689 01690 <font class="keywordflow">return</font> TRUE; 01691 } 01692 01693 01694 <font class="keyword">static</font> dbus_bool_t 01695 handle_client_state_waiting_for_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01696 DBusAuthCommand command, 01697 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01698 { 01699 _dbus_assert (auth-><a class="code" href="structDBusAuth.html#m5">mech</a> != NULL); 01700 01701 <font class="keywordflow">switch</font> (command) 01702 { 01703 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_DATA: 01704 <font class="keywordflow">return</font> process_data (auth, args, auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m6">client_data_func</a>); 01705 01706 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_REJECTED: 01707 <font class="keywordflow">return</font> process_rejected (auth, args); 01708 01709 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_OK: 01710 <font class="keywordflow">return</font> send_begin (auth); 01711 01712 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_ERROR: 01713 <font class="keywordflow">return</font> send_cancel (auth); 01714 01715 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_AUTH: 01716 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_CANCEL: 01717 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_BEGIN: 01718 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_UNKNOWN: 01719 <font class="keywordflow">default</font>: 01720 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Unknown command"</font>); 01721 } 01722 } 01723 01724 <font class="keyword">static</font> dbus_bool_t 01725 handle_client_state_waiting_for_ok (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01726 DBusAuthCommand command, 01727 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01728 { 01729 <font class="keywordflow">switch</font> (command) 01730 { 01731 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_REJECTED: 01732 <font class="keywordflow">return</font> process_rejected (auth, args); 01733 01734 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_OK: 01735 <font class="keywordflow">return</font> send_begin (auth); 01736 01737 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_DATA: 01738 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_ERROR: 01739 <font class="keywordflow">return</font> send_cancel (auth); 01740 01741 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_AUTH: 01742 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_CANCEL: 01743 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_BEGIN: 01744 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_UNKNOWN: 01745 <font class="keywordflow">default</font>: 01746 <font class="keywordflow">return</font> send_error (auth, <font class="stringliteral">"Unknown command"</font>); 01747 } 01748 } 01749 01750 <font class="keyword">static</font> dbus_bool_t 01751 handle_client_state_waiting_for_reject (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 01752 DBusAuthCommand command, 01753 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *args) 01754 { 01755 <font class="keywordflow">switch</font> (command) 01756 { 01757 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_REJECTED: 01758 <font class="keywordflow">return</font> process_rejected (auth, args); 01759 01760 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_AUTH: 01761 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_CANCEL: 01762 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_DATA: 01763 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_BEGIN: 01764 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_OK: 01765 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_ERROR: 01766 <font class="keywordflow">case</font> DBUS_AUTH_COMMAND_UNKNOWN: 01767 <font class="keywordflow">default</font>: 01768 goto_state (auth, &common_state_need_disconnect); 01769 <font class="keywordflow">return</font> TRUE; 01770 } 01771 } 01772 <a name="l01776"></a><a class="code" href="structDBusAuthCommandName.html">01776</a> <font class="keyword">typedef</font> <font class="keyword">struct </font>{ <a name="l01777"></a><a class="code" href="structDBusAuthCommandName.html#m0">01777</a> <font class="keyword">const</font> <font class="keywordtype">char</font> *name; <a name="l01778"></a><a class="code" href="structDBusAuthCommandName.html#m1">01778</a> DBusAuthCommand command; 01779 } <a class="code" href="structDBusAuthCommandName.html">DBusAuthCommandName</a>; 01780 01781 <font class="keyword">static</font> <a class="code" href="structDBusAuthCommandName.html">DBusAuthCommandName</a> auth_command_names[] = { 01782 { <font class="stringliteral">"AUTH"</font>, DBUS_AUTH_COMMAND_AUTH }, 01783 { <font class="stringliteral">"CANCEL"</font>, DBUS_AUTH_COMMAND_CANCEL }, 01784 { <font class="stringliteral">"DATA"</font>, DBUS_AUTH_COMMAND_DATA }, 01785 { <font class="stringliteral">"BEGIN"</font>, DBUS_AUTH_COMMAND_BEGIN }, 01786 { <font class="stringliteral">"REJECTED"</font>, DBUS_AUTH_COMMAND_REJECTED }, 01787 { <font class="stringliteral">"OK"</font>, DBUS_AUTH_COMMAND_OK }, 01788 { <font class="stringliteral">"ERROR"</font>, DBUS_AUTH_COMMAND_ERROR } 01789 }; 01790 01791 <font class="keyword">static</font> DBusAuthCommand 01792 lookup_command_from_name (<a class="code" href="structDBusString.html">DBusString</a> *command) 01793 { 01794 <font class="keywordtype">int</font> i; 01795 01796 <font class="keywordflow">for</font> (i = 0; i < _DBUS_N_ELEMENTS (auth_command_names); i++) 01797 { 01798 <font class="keywordflow">if</font> (_dbus_string_equal_c_str (command, 01799 auth_command_names[i].name)) 01800 <font class="keywordflow">return</font> auth_command_names[i].<a class="code" href="structDBusAuthCommandName.html#m1">command</a>; 01801 } 01802 01803 <font class="keywordflow">return</font> DBUS_AUTH_COMMAND_UNKNOWN; 01804 } 01805 01806 <font class="keyword">static</font> <font class="keywordtype">void</font> 01807 goto_state (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, <font class="keyword">const</font> <a class="code" href="structDBusAuthStateData.html">DBusAuthStateData</a> *state) 01808 { 01809 _dbus_verbose (<font class="stringliteral">"%s: going from state %s to state %s\n"</font>, 01810 DBUS_AUTH_NAME (auth), 01811 auth-><a class="code" href="structDBusAuth.html#m4">state</a>-><a class="code" href="structDBusAuthStateData.html#m0">name</a>, 01812 state-><a class="code" href="structDBusAuthStateData.html#m0">name</a>); 01813 01814 auth-><a class="code" href="structDBusAuth.html#m4">state</a> = state; 01815 } 01816 01817 <font class="comment">/* returns whether to call it again right away */</font> 01818 <font class="keyword">static</font> dbus_bool_t 01819 process_command (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01820 { 01821 DBusAuthCommand command; 01822 <a class="code" href="structDBusString.html">DBusString</a> line; 01823 <a class="code" href="structDBusString.html">DBusString</a> args; 01824 <font class="keywordtype">int</font> eol; 01825 <font class="keywordtype">int</font> i, j; 01826 dbus_bool_t retval; 01827 01828 <font class="comment">/* _dbus_verbose ("%s: trying process_command()\n"); */</font> 01829 01830 retval = FALSE; 01831 01832 eol = 0; 01833 <font class="keywordflow">if</font> (!_dbus_string_find (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>, 0, <font class="stringliteral">"\r\n"</font>, &eol)) 01834 <font class="keywordflow">return</font> FALSE; 01835 01836 <font class="keywordflow">if</font> (!_dbus_string_init (&line)) 01837 { 01838 auth-><a class="code" href="structDBusAuth.html#m15">needed_memory</a> = TRUE; 01839 <font class="keywordflow">return</font> FALSE; 01840 } 01841 01842 <font class="keywordflow">if</font> (!_dbus_string_init (&args)) 01843 { 01844 _dbus_string_free (&line); 01845 auth-><a class="code" href="structDBusAuth.html#m15">needed_memory</a> = TRUE; 01846 <font class="keywordflow">return</font> FALSE; 01847 } 01848 01849 <font class="keywordflow">if</font> (!_dbus_string_copy_len (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>, 0, eol, &line, 0)) 01850 <font class="keywordflow">goto</font> out; 01851 01852 <font class="keywordflow">if</font> (!_dbus_string_validate_ascii (&line, 0, 01853 _dbus_string_get_length (&line))) 01854 { 01855 _dbus_verbose (<font class="stringliteral">"%s: Command contained non-ASCII chars or embedded nul\n"</font>, 01856 DBUS_AUTH_NAME (auth)); 01857 <font class="keywordflow">if</font> (!send_error (auth, <font class="stringliteral">"Command contained non-ASCII"</font>)) 01858 <font class="keywordflow">goto</font> out; 01859 <font class="keywordflow">else</font> 01860 <font class="keywordflow">goto</font> next_command; 01861 } 01862 01863 _dbus_verbose (<font class="stringliteral">"%s: got command \"%s\"\n"</font>, 01864 DBUS_AUTH_NAME (auth), 01865 _dbus_string_get_const_data (&line)); 01866 01867 _dbus_string_find_blank (&line, 0, &i); 01868 _dbus_string_skip_blank (&line, i, &j); 01869 01870 <font class="keywordflow">if</font> (j > i) 01871 _dbus_string_delete (&line, i, j - i); 01872 01873 <font class="keywordflow">if</font> (!_dbus_string_move (&line, i, &args, 0)) 01874 <font class="keywordflow">goto</font> out; 01875 01876 command = lookup_command_from_name (&line); 01877 <font class="keywordflow">if</font> (!(* auth-><a class="code" href="structDBusAuth.html#m4">state</a>-><a class="code" href="structDBusAuthStateData.html#m1">handler</a>) (auth, command, &args)) 01878 <font class="keywordflow">goto</font> out; 01879 01880 next_command: 01881 01882 <font class="comment">/* We've succeeded in processing the whole command so drop it out</font> 01883 <font class="comment"> * of the incoming buffer and return TRUE to try another command.</font> 01884 <font class="comment"> */</font> 01885 01886 _dbus_string_delete (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>, 0, eol); 01887 01888 <font class="comment">/* kill the \r\n */</font> 01889 _dbus_string_delete (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>, 0, 2); 01890 01891 retval = TRUE; 01892 01893 out: 01894 _dbus_string_free (&args); 01895 _dbus_string_free (&line); 01896 01897 <font class="keywordflow">if</font> (!retval) 01898 auth-><a class="code" href="structDBusAuth.html#m15">needed_memory</a> = TRUE; 01899 <font class="keywordflow">else</font> 01900 auth-><a class="code" href="structDBusAuth.html#m15">needed_memory</a> = FALSE; 01901 01902 <font class="keywordflow">return</font> retval; 01903 } 01904 01905 01920 <a class="code" href="structDBusAuth.html">DBusAuth</a>* <a name="l01921"></a><a class="code" href="group__DBusAuth.html#a0">01921</a> _dbus_auth_server_new (<font class="keywordtype">void</font>) 01922 { 01923 <a class="code" href="structDBusAuth.html">DBusAuth</a> *auth; 01924 <a class="code" href="structDBusAuthServer.html">DBusAuthServer</a> *server_auth; 01925 01926 auth = _dbus_auth_new (<font class="keyword">sizeof</font> (<a class="code" href="structDBusAuthServer.html">DBusAuthServer</a>)); 01927 <font class="keywordflow">if</font> (auth == NULL) 01928 <font class="keywordflow">return</font> NULL; 01929 01930 auth-><a class="code" href="structDBusAuth.html#m1">side</a> = auth_side_server; 01931 auth-><a class="code" href="structDBusAuth.html#m4">state</a> = &server_state_waiting_for_auth; 01932 01933 server_auth = DBUS_AUTH_SERVER (auth); 01934 01935 <font class="comment">/* perhaps this should be per-mechanism with a lower</font> 01936 <font class="comment"> * max</font> 01937 <font class="comment"> */</font> 01938 server_auth-><a class="code" href="structDBusAuthServer.html#m1">failures</a> = 0; 01939 server_auth-><a class="code" href="structDBusAuthServer.html#m2">max_failures</a> = 6; 01940 01941 <font class="keywordflow">return</font> auth; 01942 } 01943 01951 <a class="code" href="structDBusAuth.html">DBusAuth</a>* <a name="l01952"></a><a class="code" href="group__DBusAuth.html#a1">01952</a> _dbus_auth_client_new (<font class="keywordtype">void</font>) 01953 { 01954 <a class="code" href="structDBusAuth.html">DBusAuth</a> *auth; 01955 01956 auth = _dbus_auth_new (<font class="keyword">sizeof</font> (<a class="code" href="structDBusAuthClient.html">DBusAuthClient</a>)); 01957 <font class="keywordflow">if</font> (auth == NULL) 01958 <font class="keywordflow">return</font> NULL; 01959 01960 auth-><a class="code" href="structDBusAuth.html#m1">side</a> = auth_side_client; 01961 auth-><a class="code" href="structDBusAuth.html#m4">state</a> = &client_state_need_send_auth; 01962 01963 <font class="comment">/* Start the auth conversation by sending AUTH for our default</font> 01964 <font class="comment"> * mechanism */</font> 01965 <font class="keywordflow">if</font> (!send_auth (auth, &all_mechanisms[0])) 01966 { 01967 _dbus_auth_unref (auth); 01968 <font class="keywordflow">return</font> NULL; 01969 } 01970 01971 <font class="keywordflow">return</font> auth; 01972 } 01973 01980 <a class="code" href="structDBusAuth.html">DBusAuth</a> * <a name="l01981"></a><a class="code" href="group__DBusAuth.html#a2">01981</a> _dbus_auth_ref (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01982 { 01983 _dbus_assert (auth != NULL); 01984 01985 auth-><a class="code" href="structDBusAuth.html#m0">refcount</a> += 1; 01986 01987 <font class="keywordflow">return</font> auth; 01988 } 01989 01995 <font class="keywordtype">void</font> <a name="l01996"></a><a class="code" href="group__DBusAuth.html#a3">01996</a> _dbus_auth_unref (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 01997 { 01998 _dbus_assert (auth != NULL); 01999 _dbus_assert (auth-><a class="code" href="structDBusAuth.html#m0">refcount</a> > 0); 02000 02001 auth-><a class="code" href="structDBusAuth.html#m0">refcount</a> -= 1; 02002 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m0">refcount</a> == 0) 02003 { 02004 shutdown_mech (auth); 02005 02006 <font class="keywordflow">if</font> (DBUS_AUTH_IS_CLIENT (auth)) 02007 { 02008 _dbus_list_clear (& DBUS_AUTH_CLIENT (auth)->mechs_to_try); 02009 } 02010 02011 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a>) 02012 _dbus_keyring_unref (auth-><a class="code" href="structDBusAuth.html#m11">keyring</a>); 02013 02014 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m10">context</a>); 02015 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m13">challenge</a>); 02016 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m6">identity</a>); 02017 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>); 02018 _dbus_string_free (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>); 02019 02020 dbus_free_string_array (auth-><a class="code" href="structDBusAuth.html#m14">allowed_mechs</a>); 02021 02022 dbus_free (auth); 02023 } 02024 } 02025 02034 dbus_bool_t <a name="l02035"></a><a class="code" href="group__DBusAuth.html#a4">02035</a> _dbus_auth_set_mechanisms (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02036 <font class="keyword">const</font> <font class="keywordtype">char</font> **mechanisms) 02037 { 02038 <font class="keywordtype">char</font> **copy; 02039 02040 <font class="keywordflow">if</font> (mechanisms != NULL) 02041 { 02042 copy = _dbus_dup_string_array (mechanisms); 02043 <font class="keywordflow">if</font> (copy == NULL) 02044 <font class="keywordflow">return</font> FALSE; 02045 } 02046 <font class="keywordflow">else</font> 02047 copy = NULL; 02048 02049 dbus_free_string_array (auth-><a class="code" href="structDBusAuth.html#m14">allowed_mechs</a>); 02050 02051 auth-><a class="code" href="structDBusAuth.html#m14">allowed_mechs</a> = copy; 02052 02053 <font class="keywordflow">return</font> TRUE; 02054 } 02055 <a name="l02060"></a><a class="code" href="group__DBusAuth.html#a19">02060</a> <font class="preprocessor">#define DBUS_AUTH_IN_END_STATE(auth) ((auth)->state->handler == NULL)</font> 02061 <font class="preprocessor"></font> 02069 DBusAuthState <a name="l02070"></a><a class="code" href="group__DBusAuth.html#a5">02070</a> _dbus_auth_do_work (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 02071 { 02072 auth-><a class="code" href="structDBusAuth.html#m15">needed_memory</a> = FALSE; 02073 02074 <font class="comment">/* Max amount we'll buffer up before deciding someone's on crack */</font> 02075 <font class="preprocessor">#define MAX_BUFFER (16 * _DBUS_ONE_KILOBYTE)</font> 02076 <font class="preprocessor"></font> 02077 <font class="keywordflow">do</font> 02078 { 02079 <font class="keywordflow">if</font> (DBUS_AUTH_IN_END_STATE (auth)) 02080 <font class="keywordflow">break</font>; 02081 02082 <font class="keywordflow">if</font> (_dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>) > MAX_BUFFER || 02083 _dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>) > MAX_BUFFER) 02084 { 02085 goto_state (auth, &common_state_need_disconnect); 02086 _dbus_verbose (<font class="stringliteral">"%s: Disconnecting due to excessive data buffered in auth phase\n"</font>, 02087 DBUS_AUTH_NAME (auth)); 02088 <font class="keywordflow">break</font>; 02089 } 02090 } 02091 <font class="keywordflow">while</font> (process_command (auth)); 02092 02093 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m15">needed_memory</a>) 02094 <font class="keywordflow">return</font> DBUS_AUTH_STATE_WAITING_FOR_MEMORY; 02095 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (_dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>) > 0) 02096 <font class="keywordflow">return</font> DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND; 02097 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m4">state</a> == &common_state_need_disconnect) 02098 <font class="keywordflow">return</font> DBUS_AUTH_STATE_NEED_DISCONNECT; 02099 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m4">state</a> == &common_state_authenticated) 02100 <font class="keywordflow">return</font> DBUS_AUTH_STATE_AUTHENTICATED; 02101 <font class="keywordflow">else</font> <font class="keywordflow">return</font> DBUS_AUTH_STATE_WAITING_FOR_INPUT; 02102 } 02103 02113 dbus_bool_t <a name="l02114"></a><a class="code" href="group__DBusAuth.html#a6">02114</a> _dbus_auth_get_bytes_to_send (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02115 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> **str) 02116 { 02117 _dbus_assert (auth != NULL); 02118 _dbus_assert (str != NULL); 02119 02120 *str = NULL; 02121 02122 <font class="keywordflow">if</font> (_dbus_string_get_length (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>) == 0) 02123 <font class="keywordflow">return</font> FALSE; 02124 02125 *str = &auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>; 02126 02127 <font class="keywordflow">return</font> TRUE; 02128 } 02129 02138 <font class="keywordtype">void</font> <a name="l02139"></a><a class="code" href="group__DBusAuth.html#a7">02139</a> _dbus_auth_bytes_sent (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02140 <font class="keywordtype">int</font> bytes_sent) 02141 { 02142 _dbus_verbose (<font class="stringliteral">"%s: Sent %d bytes of: %s\n"</font>, 02143 DBUS_AUTH_NAME (auth), 02144 bytes_sent, 02145 _dbus_string_get_const_data (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>)); 02146 02147 _dbus_string_delete (&auth-><a class="code" href="structDBusAuth.html#m3">outgoing</a>, 02148 0, bytes_sent); 02149 } 02150 02158 <font class="keywordtype">void</font> <a name="l02159"></a><a class="code" href="group__DBusAuth.html#a8">02159</a> _dbus_auth_get_buffer (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02160 <a class="code" href="structDBusString.html">DBusString</a> **buffer) 02161 { 02162 _dbus_assert (auth != NULL); 02163 _dbus_assert (!auth-><a class="code" href="structDBusAuth.html#m18">buffer_outstanding</a>); 02164 02165 *buffer = &auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>; 02166 02167 auth-><a class="code" href="structDBusAuth.html#m18">buffer_outstanding</a> = TRUE; 02168 } 02169 02177 <font class="keywordtype">void</font> <a name="l02178"></a><a class="code" href="group__DBusAuth.html#a9">02178</a> _dbus_auth_return_buffer (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02179 <a class="code" href="structDBusString.html">DBusString</a> *buffer, 02180 <font class="keywordtype">int</font> bytes_read) 02181 { 02182 _dbus_assert (buffer == &auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>); 02183 _dbus_assert (auth-><a class="code" href="structDBusAuth.html#m18">buffer_outstanding</a>); 02184 02185 auth-><a class="code" href="structDBusAuth.html#m18">buffer_outstanding</a> = FALSE; 02186 } 02187 02197 <font class="keywordtype">void</font> <a name="l02198"></a><a class="code" href="group__DBusAuth.html#a10">02198</a> _dbus_auth_get_unused_bytes (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02199 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> **str) 02200 { 02201 <font class="keywordflow">if</font> (!DBUS_AUTH_IN_END_STATE (auth)) 02202 <font class="keywordflow">return</font>; 02203 02204 *str = &auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>; 02205 } 02206 02207 02214 <font class="keywordtype">void</font> <a name="l02215"></a><a class="code" href="group__DBusAuth.html#a11">02215</a> _dbus_auth_delete_unused_bytes (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 02216 { 02217 <font class="keywordflow">if</font> (!DBUS_AUTH_IN_END_STATE (auth)) 02218 <font class="keywordflow">return</font>; 02219 02220 _dbus_string_set_length (&auth-><a class="code" href="structDBusAuth.html#m2">incoming</a>, 0); 02221 } 02222 02231 dbus_bool_t <a name="l02232"></a><a class="code" href="group__DBusAuth.html#a12">02232</a> _dbus_auth_needs_encoding (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 02233 { 02234 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m4">state</a> != &common_state_authenticated) 02235 <font class="keywordflow">return</font> FALSE; 02236 02237 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m5">mech</a> != NULL) 02238 { 02239 <font class="keywordflow">if</font> (DBUS_AUTH_IS_CLIENT (auth)) 02240 <font class="keywordflow">return</font> auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m7">client_encode_func</a> != NULL; 02241 <font class="keywordflow">else</font> 02242 <font class="keywordflow">return</font> auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m2">server_encode_func</a> != NULL; 02243 } 02244 <font class="keywordflow">else</font> 02245 <font class="keywordflow">return</font> FALSE; 02246 } 02247 02258 dbus_bool_t <a name="l02259"></a><a class="code" href="group__DBusAuth.html#a13">02259</a> _dbus_auth_encode_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02260 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *plaintext, 02261 <a class="code" href="structDBusString.html">DBusString</a> *encoded) 02262 { 02263 _dbus_assert (plaintext != encoded); 02264 02265 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m4">state</a> != &common_state_authenticated) 02266 <font class="keywordflow">return</font> FALSE; 02267 02268 <font class="keywordflow">if</font> (_dbus_auth_needs_encoding (auth)) 02269 { 02270 <font class="keywordflow">if</font> (DBUS_AUTH_IS_CLIENT (auth)) 02271 <font class="keywordflow">return</font> (* auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m7">client_encode_func</a>) (auth, plaintext, encoded); 02272 <font class="keywordflow">else</font> 02273 <font class="keywordflow">return</font> (* auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m2">server_encode_func</a>) (auth, plaintext, encoded); 02274 } 02275 <font class="keywordflow">else</font> 02276 { 02277 <font class="keywordflow">return</font> _dbus_string_copy (plaintext, 0, encoded, 02278 _dbus_string_get_length (encoded)); 02279 } 02280 } 02281 02290 dbus_bool_t <a name="l02291"></a><a class="code" href="group__DBusAuth.html#a14">02291</a> _dbus_auth_needs_decoding (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth) 02292 { 02293 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m4">state</a> != &common_state_authenticated) 02294 <font class="keywordflow">return</font> FALSE; 02295 02296 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m5">mech</a> != NULL) 02297 { 02298 <font class="keywordflow">if</font> (DBUS_AUTH_IS_CLIENT (auth)) 02299 <font class="keywordflow">return</font> auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m8">client_decode_func</a> != NULL; 02300 <font class="keywordflow">else</font> 02301 <font class="keywordflow">return</font> auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m3">server_decode_func</a> != NULL; 02302 } 02303 <font class="keywordflow">else</font> 02304 <font class="keywordflow">return</font> FALSE; 02305 } 02306 02307 02321 dbus_bool_t <a name="l02322"></a><a class="code" href="group__DBusAuth.html#a15">02322</a> _dbus_auth_decode_data (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02323 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *encoded, 02324 <a class="code" href="structDBusString.html">DBusString</a> *plaintext) 02325 { 02326 _dbus_assert (plaintext != encoded); 02327 02328 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m4">state</a> != &common_state_authenticated) 02329 <font class="keywordflow">return</font> FALSE; 02330 02331 <font class="keywordflow">if</font> (_dbus_auth_needs_decoding (auth)) 02332 { 02333 <font class="keywordflow">if</font> (DBUS_AUTH_IS_CLIENT (auth)) 02334 <font class="keywordflow">return</font> (* auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m8">client_decode_func</a>) (auth, encoded, plaintext); 02335 <font class="keywordflow">else</font> 02336 <font class="keywordflow">return</font> (* auth-><a class="code" href="structDBusAuth.html#m5">mech</a>-><a class="code" href="structDBusAuthMechanismHandler.html#m3">server_decode_func</a>) (auth, encoded, plaintext); 02337 } 02338 <font class="keywordflow">else</font> 02339 { 02340 <font class="keywordflow">return</font> _dbus_string_copy (encoded, 0, plaintext, 02341 _dbus_string_get_length (plaintext)); 02342 } 02343 } 02344 02352 <font class="keywordtype">void</font> <a name="l02353"></a><a class="code" href="group__DBusAuth.html#a16">02353</a> _dbus_auth_set_credentials (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02354 <font class="keyword">const</font> <a class="code" href="structDBusCredentials.html">DBusCredentials</a> *credentials) 02355 { 02356 auth-><a class="code" href="structDBusAuth.html#m7">credentials</a> = *credentials; 02357 } 02358 02366 <font class="keywordtype">void</font> <a name="l02367"></a><a class="code" href="group__DBusAuth.html#a17">02367</a> _dbus_auth_get_identity (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02368 <a class="code" href="structDBusCredentials.html">DBusCredentials</a> *credentials) 02369 { 02370 <font class="keywordflow">if</font> (auth-><a class="code" href="structDBusAuth.html#m4">state</a> == &common_state_authenticated) 02371 *credentials = auth-><a class="code" href="structDBusAuth.html#m8">authorized_identity</a>; 02372 <font class="keywordflow">else</font> 02373 _dbus_credentials_clear (credentials); 02374 } 02375 02384 dbus_bool_t <a name="l02385"></a><a class="code" href="group__DBusAuth.html#a18">02385</a> _dbus_auth_set_context (<a class="code" href="structDBusAuth.html">DBusAuth</a> *auth, 02386 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *context) 02387 { 02388 <font class="keywordflow">return</font> _dbus_string_replace_len (context, 0, _dbus_string_get_length (context), 02389 &auth-><a class="code" href="structDBusAuth.html#m10">context</a>, 0, _dbus_string_get_length (context)); 02390 } 02391 02394 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font> 02395 <font class="preprocessor"></font><font class="preprocessor">#include "dbus-test.h"</font> 02396 <font class="preprocessor">#include "dbus-auth-script.h"</font> 02397 <font class="preprocessor">#include <stdio.h></font> 02398 02399 <font class="keyword">static</font> dbus_bool_t 02400 process_test_subdir (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_base_dir, 02401 <font class="keyword">const</font> <font class="keywordtype">char</font> *subdir) 02402 { 02403 <a class="code" href="structDBusString.html">DBusString</a> test_directory; 02404 <a class="code" href="structDBusString.html">DBusString</a> filename; 02405 <a class="code" href="structDBusDirIter.html">DBusDirIter</a> *dir; 02406 dbus_bool_t retval; 02407 <a class="code" href="structDBusError.html">DBusError</a> error; 02408 02409 retval = FALSE; 02410 dir = NULL; 02411 02412 <font class="keywordflow">if</font> (!_dbus_string_init (&test_directory)) 02413 _dbus_assert_not_reached (<font class="stringliteral">"didn't allocate test_directory\n"</font>); 02414 02415 _dbus_string_init_const (&filename, subdir); 02416 02417 <font class="keywordflow">if</font> (!_dbus_string_copy (test_base_dir, 0, 02418 &test_directory, 0)) 02419 _dbus_assert_not_reached (<font class="stringliteral">"couldn't copy test_base_dir to test_directory"</font>); 02420 02421 <font class="keywordflow">if</font> (!_dbus_concat_dir_and_file (&test_directory, &filename)) 02422 _dbus_assert_not_reached (<font class="stringliteral">"couldn't allocate full path"</font>); 02423 02424 _dbus_string_free (&filename); 02425 <font class="keywordflow">if</font> (!_dbus_string_init (&filename)) 02426 _dbus_assert_not_reached (<font class="stringliteral">"didn't allocate filename string\n"</font>); 02427 02428 dbus_error_init (&error); 02429 dir = _dbus_directory_open (&test_directory, &error); 02430 <font class="keywordflow">if</font> (dir == NULL) 02431 { 02432 _dbus_warn (<font class="stringliteral">"Could not open %s: %s\n"</font>, 02433 _dbus_string_get_const_data (&test_directory), 02434 error.<a class="code" href="structDBusError.html#m1">message</a>); 02435 dbus_error_free (&error); 02436 <font class="keywordflow">goto</font> failed; 02437 } 02438 02439 printf (<font class="stringliteral">"Testing %s:\n"</font>, subdir); 02440 02441 next: 02442 <font class="keywordflow">while</font> (_dbus_directory_get_next_file (dir, &filename, &error)) 02443 { 02444 <a class="code" href="structDBusString.html">DBusString</a> full_path; 02445 02446 <font class="keywordflow">if</font> (!_dbus_string_init (&full_path)) 02447 _dbus_assert_not_reached (<font class="stringliteral">"couldn't init string"</font>); 02448 02449 <font class="keywordflow">if</font> (!_dbus_string_copy (&test_directory, 0, &full_path, 0)) 02450 _dbus_assert_not_reached (<font class="stringliteral">"couldn't copy dir to full_path"</font>); 02451 02452 <font class="keywordflow">if</font> (!_dbus_concat_dir_and_file (&full_path, &filename)) 02453 _dbus_assert_not_reached (<font class="stringliteral">"couldn't concat file to dir"</font>); 02454 02455 <font class="keywordflow">if</font> (!_dbus_string_ends_with_c_str (&filename, <font class="stringliteral">".auth-script"</font>)) 02456 { 02457 _dbus_verbose (<font class="stringliteral">"Skipping non-.auth-script file %s\n"</font>, 02458 _dbus_string_get_const_data (&filename)); 02459 _dbus_string_free (&full_path); 02460 <font class="keywordflow">goto</font> next; 02461 } 02462 02463 printf (<font class="stringliteral">" %s\n"</font>, _dbus_string_get_const_data (&filename)); 02464 02465 <font class="keywordflow">if</font> (!_dbus_auth_script_run (&full_path)) 02466 { 02467 _dbus_string_free (&full_path); 02468 <font class="keywordflow">goto</font> failed; 02469 } 02470 <font class="keywordflow">else</font> 02471 _dbus_string_free (&full_path); 02472 } 02473 02474 <font class="keywordflow">if</font> (dbus_error_is_set (&error)) 02475 { 02476 _dbus_warn (<font class="stringliteral">"Could not get next file in %s: %s\n"</font>, 02477 _dbus_string_get_const_data (&test_directory), error.<a class="code" href="structDBusError.html#m1">message</a>); 02478 dbus_error_free (&error); 02479 <font class="keywordflow">goto</font> failed; 02480 } 02481 02482 retval = TRUE; 02483 02484 failed: 02485 02486 <font class="keywordflow">if</font> (dir) 02487 _dbus_directory_close (dir); 02488 _dbus_string_free (&test_directory); 02489 _dbus_string_free (&filename); 02490 02491 <font class="keywordflow">return</font> retval; 02492 } 02493 02494 <font class="keyword">static</font> dbus_bool_t 02495 process_test_dirs (<font class="keyword">const</font> <font class="keywordtype">char</font> *test_data_dir) 02496 { 02497 <a class="code" href="structDBusString.html">DBusString</a> test_directory; 02498 dbus_bool_t retval; 02499 02500 retval = FALSE; 02501 02502 _dbus_string_init_const (&test_directory, test_data_dir); 02503 02504 <font class="keywordflow">if</font> (!process_test_subdir (&test_directory, <font class="stringliteral">"auth"</font>)) 02505 <font class="keywordflow">goto</font> failed; 02506 02507 retval = TRUE; 02508 02509 failed: 02510 02511 _dbus_string_free (&test_directory); 02512 02513 <font class="keywordflow">return</font> retval; 02514 } 02515 02516 dbus_bool_t 02517 _dbus_auth_test (<font class="keyword">const</font> <font class="keywordtype">char</font> *test_data_dir) 02518 { 02519 02520 <font class="keywordflow">if</font> (test_data_dir == NULL) 02521 <font class="keywordflow">return</font> TRUE; 02522 02523 <font class="keywordflow">if</font> (!process_test_dirs (test_data_dir)) 02524 <font class="keywordflow">return</font> FALSE; 02525 02526 <font class="keywordflow">return</font> TRUE; 02527 } 02528 02529 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font> </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>