Sophie

Sophie

distrib > Mandriva > 2007.0 > x86_64 > media > main-release > by-pkgid > 926d2d1e3111287cee1b0a4fad4fb4f6 > files > 52

lib64dbus-1_3-devel-0.92-6mdv2007.0.x86_64.rpm

<!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> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; <a class="qindex" href="annotated.html">Data Structures</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Data Fields</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </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)-&gt;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)-&gt;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)-&gt;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-&gt;<a class="code" href="structDBusAuth.html#m0">refcount</a> = 1;
00332 
00333   _dbus_credentials_clear (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m7">credentials</a>);
00334   _dbus_credentials_clear (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m8">authorized_identity</a>);
00335   _dbus_credentials_clear (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>);
00336   
00337   auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> = NULL;
00338   auth-&gt;<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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m13">challenge</a>);
00371  enomem_4:
00372   _dbus_string_free (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m10">context</a>);
00373  enomem_3:
00374   _dbus_string_free (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m6">identity</a>);
00375  enomem_2:
00376   _dbus_string_free (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>);
00377  enomem_1:
00378   _dbus_string_free (&amp;auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m17">already_asked_for_initial_response</a> = FALSE;
00389   _dbus_string_set_length (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m6">identity</a>, 0);
00390 
00391   _dbus_credentials_clear (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m8">authorized_identity</a>);
00392   _dbus_credentials_clear (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>);
00393   
00394   <font class="keywordflow">if</font> (auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>);
00398       
00399       <font class="keywordflow">if</font> (DBUS_AUTH_IS_CLIENT (auth))
00400         (* auth-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<a class="code" href="structDBusAuthMechanismHandler.html#m9">client_shutdown_func</a>) (auth);
00401       <font class="keywordflow">else</font>
00402         (* auth-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<a class="code" href="structDBusAuthMechanismHandler.html#m4">server_shutdown_func</a>) (auth);
00403       
00404       auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> != NULL);
00424 
00425   retval = FALSE;
00426   
00427   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;cookie))
00428     <font class="keywordflow">return</font> FALSE;
00429 
00430   <font class="keywordflow">if</font> (!_dbus_keyring_get_hex_key (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a>, cookie_id,
00431                                   &amp;cookie))
00432     <font class="keywordflow">goto</font> out_0;
00433 
00434   <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;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 (&amp;to_hash))
00441     <font class="keywordflow">goto</font> out_0;
00442   
00443   <font class="keywordflow">if</font> (!_dbus_string_copy (server_challenge, 0,
00444                           &amp;to_hash, _dbus_string_get_length (&amp;to_hash)))
00445     <font class="keywordflow">goto</font> out_1;
00446 
00447   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;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                           &amp;to_hash, _dbus_string_get_length (&amp;to_hash)))
00452     <font class="keywordflow">goto</font> out_1;
00453 
00454   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;to_hash, <font class="stringliteral">":"</font>))
00455     <font class="keywordflow">goto</font> out_1;
00456 
00457   <font class="keywordflow">if</font> (!_dbus_string_copy (&amp;cookie, 0,
00458                           &amp;to_hash, _dbus_string_get_length (&amp;to_hash)))
00459     <font class="keywordflow">goto</font> out_1;
00460 
00461   <font class="keywordflow">if</font> (!_dbus_sha_compute (&amp;to_hash, hash))
00462     <font class="keywordflow">goto</font> out_1;
00463   
00464   retval = TRUE;
00465 
00466  out_1:
00467   _dbus_string_zero (&amp;to_hash);
00468   _dbus_string_free (&amp;to_hash);
00469  out_0:
00470   _dbus_string_zero (&amp;cookie);
00471   _dbus_string_free (&amp;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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m13">challenge</a>, 0);
00496   
00497   <font class="keywordflow">if</font> (_dbus_string_get_length (data) &gt; 0)
00498     {
00499       <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m6">identity</a>) &gt; 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, &amp;auth-&gt;<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, &amp;auth-&gt;<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 (&amp;tmp))
00522     <font class="keywordflow">return</font> FALSE;
00523 
00524   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;tmp2))
00525     {
00526       _dbus_string_free (&amp;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-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> &amp;&amp;
00535       !_dbus_keyring_is_for_user (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a>,
00536                                   data))
00537     {
00538       _dbus_keyring_unref (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a>);
00539       auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> = NULL;
00540     }
00541   
00542   <font class="keywordflow">if</font> (auth-&gt;<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 (&amp;error);
00547       auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> = _dbus_keyring_new_homedir (data,
00548                                                  &amp;auth-&gt;<a class="code" href="structDBusAuth.html#m10">context</a>,
00549                                                  &amp;error);
00550 
00551       <font class="keywordflow">if</font> (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> == NULL)
00552         {
00553           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error,
00554                                    DBUS_ERROR_NO_MEMORY))
00555             {
00556               dbus_error_free (&amp;error);
00557               <font class="keywordflow">goto</font> out;
00558             }
00559           <font class="keywordflow">else</font>
00560             {
00561               _DBUS_ASSERT_ERROR_IS_SET (&amp;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 (&amp;error);
00567               <font class="keywordflow">goto</font> out;
00568             }
00569         }
00570       <font class="keywordflow">else</font>
00571         {
00572           _dbus_assert (!dbus_error_is_set (&amp;error));
00573         }
00574     }
00575 
00576   _dbus_assert (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> != NULL);
00577 
00578   dbus_error_init (&amp;error);
00579   auth-&gt;<a class="code" href="structDBusAuth.html#m12">cookie_id</a> = _dbus_keyring_get_best_key (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a>, &amp;error);
00580   <font class="keywordflow">if</font> (auth-&gt;<a class="code" href="structDBusAuth.html#m12">cookie_id</a> &lt; 0)
00581     {
00582       _DBUS_ASSERT_ERROR_IS_SET (&amp;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 (&amp;error);
00588       <font class="keywordflow">goto</font> out;
00589     }
00590   <font class="keywordflow">else</font>
00591     {
00592       _dbus_assert (!dbus_error_is_set (&amp;error));
00593     }
00594 
00595   <font class="keywordflow">if</font> (!_dbus_string_copy (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m10">context</a>, 0,
00596                           &amp;tmp2, _dbus_string_get_length (&amp;tmp2)))
00597     <font class="keywordflow">goto</font> out;
00598 
00599   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;tmp2, <font class="stringliteral">" "</font>))
00600     <font class="keywordflow">goto</font> out;
00601 
00602   <font class="keywordflow">if</font> (!_dbus_string_append_int (&amp;tmp2, auth-&gt;<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 (&amp;tmp2, <font class="stringliteral">" "</font>))
00606     <font class="keywordflow">goto</font> out;  
00607   
00608   <font class="keywordflow">if</font> (!_dbus_generate_random_bytes (&amp;tmp, N_CHALLENGE_BYTES))
00609     <font class="keywordflow">goto</font> out;
00610 
00611   _dbus_string_set_length (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m13">challenge</a>, 0);
00612   <font class="keywordflow">if</font> (!_dbus_string_hex_encode (&amp;tmp, 0, &amp;auth-&gt;<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 (&amp;tmp, 0, &amp;tmp2,
00616                                 _dbus_string_get_length (&amp;tmp2)))
00617     <font class="keywordflow">goto</font> out;
00618 
00619   <font class="keywordflow">if</font> (!send_data (auth, &amp;tmp2))
00620     <font class="keywordflow">goto</font> out;
00621       
00622   goto_state (auth, &amp;server_state_waiting_for_data);
00623   retval = TRUE;
00624   
00625  out:
00626   _dbus_string_zero (&amp;tmp);
00627   _dbus_string_free (&amp;tmp);
00628   _dbus_string_zero (&amp;tmp2);
00629   _dbus_string_free (&amp;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, &amp;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 (&amp;client_challenge))
00659     <font class="keywordflow">goto</font> out_0;
00660 
00661   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;client_hash))
00662     <font class="keywordflow">goto</font> out_1;  
00663 
00664   <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, 0, i, &amp;client_challenge,
00665                               0))
00666     <font class="keywordflow">goto</font> out_2;
00667 
00668   _dbus_string_skip_blank (data, i, &amp;i);
00669   
00670   <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, i,
00671                               _dbus_string_get_length (data) - i,
00672                               &amp;client_hash,
00673                               0))
00674     <font class="keywordflow">goto</font> out_2;
00675 
00676   <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;client_challenge) == 0 ||
00677       _dbus_string_get_length (&amp;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 (&amp;correct_hash))
00687     <font class="keywordflow">goto</font> out_2;
00688 
00689   <font class="keywordflow">if</font> (!sha1_compute_hash (auth, auth-&gt;<a class="code" href="structDBusAuth.html#m12">cookie_id</a>,
00690                           &amp;auth-&gt;<a class="code" href="structDBusAuth.html#m13">challenge</a>, 
00691                           &amp;client_challenge,
00692                           &amp;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 (&amp;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 (&amp;client_hash, &amp;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-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>);
00715   
00716   auth-&gt;<a class="code" href="structDBusAuth.html#m8">authorized_identity</a> = auth-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>;
00717   retval = TRUE;
00718   
00719  out_3:
00720   _dbus_string_zero (&amp;correct_hash);
00721   _dbus_string_free (&amp;correct_hash);
00722  out_2:
00723   _dbus_string_zero (&amp;client_hash);
00724   _dbus_string_free (&amp;client_hash);
00725  out_1:
00726   _dbus_string_free (&amp;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-&gt;<a class="code" href="structDBusAuth.html#m12">cookie_id</a> &lt; 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-&gt;<a class="code" href="structDBusAuth.html#m12">cookie_id</a> = -1;  
00745   _dbus_string_set_length (&amp;auth-&gt;<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 (&amp;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, &amp;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 (&amp;context))
00800     <font class="keywordflow">goto</font> out_0;
00801 
00802   <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, 0, i,
00803                               &amp;context, 0))
00804     <font class="keywordflow">goto</font> out_1;
00805   
00806   _dbus_string_skip_blank (data, i, &amp;i);
00807   <font class="keywordflow">if</font> (!_dbus_string_find_blank (data, i, &amp;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 (&amp;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                               &amp;cookie_id_str, 0))
00820     <font class="keywordflow">goto</font> out_2;  
00821 
00822   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;server_challenge))
00823     <font class="keywordflow">goto</font> out_2;
00824 
00825   i = j;
00826   _dbus_string_skip_blank (data, i, &amp;i);
00827   j = _dbus_string_get_length (data);
00828 
00829   <font class="keywordflow">if</font> (!_dbus_string_copy_len (data, i, j - i,
00830                               &amp;server_challenge, 0))
00831     <font class="keywordflow">goto</font> out_3;
00832 
00833   <font class="keywordflow">if</font> (!_dbus_keyring_validate_context (&amp;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 (&amp;cookie_id_str, 0, &amp;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 (&amp;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-&gt;<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 (&amp;error);
00859       auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> = _dbus_keyring_new_homedir (NULL,
00860                                                  &amp;context,
00861                                                  &amp;error);
00862 
00863       <font class="keywordflow">if</font> (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> == NULL)
00864         {
00865           <font class="keywordflow">if</font> (dbus_error_has_name (&amp;error,
00866                                    DBUS_ERROR_NO_MEMORY))
00867             {
00868               dbus_error_free (&amp;error);
00869               <font class="keywordflow">goto</font> out_3;
00870             }
00871           <font class="keywordflow">else</font>
00872             {
00873               _DBUS_ASSERT_ERROR_IS_SET (&amp;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 (&amp;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 (&amp;error));
00888         }
00889     }
00890   
00891   _dbus_assert (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a> != NULL);
00892   
00893   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;tmp))
00894     <font class="keywordflow">goto</font> out_3;
00895   
00896   <font class="keywordflow">if</font> (!_dbus_generate_random_bytes (&amp;tmp, N_CHALLENGE_BYTES))
00897     <font class="keywordflow">goto</font> out_4;
00898 
00899   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;client_challenge))
00900     <font class="keywordflow">goto</font> out_4;
00901 
00902   <font class="keywordflow">if</font> (!_dbus_string_hex_encode (&amp;tmp, 0, &amp;client_challenge, 0))
00903     <font class="keywordflow">goto</font> out_5;
00904 
00905   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;correct_hash))
00906     <font class="keywordflow">goto</font> out_5;
00907   
00908   <font class="keywordflow">if</font> (!sha1_compute_hash (auth, val,
00909                           &amp;server_challenge,
00910                           &amp;client_challenge,
00911                           &amp;correct_hash))
00912     <font class="keywordflow">goto</font> out_6;
00913 
00914   <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;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 (&amp;tmp, 0);
00923   
00924   <font class="keywordflow">if</font> (!_dbus_string_copy (&amp;client_challenge, 0, &amp;tmp,
00925                           _dbus_string_get_length (&amp;tmp)))
00926     <font class="keywordflow">goto</font> out_6;
00927 
00928   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;tmp, <font class="stringliteral">" "</font>))
00929     <font class="keywordflow">goto</font> out_6;
00930 
00931   <font class="keywordflow">if</font> (!_dbus_string_copy (&amp;correct_hash, 0, &amp;tmp,
00932                           _dbus_string_get_length (&amp;tmp)))
00933     <font class="keywordflow">goto</font> out_6;
00934 
00935   <font class="keywordflow">if</font> (!send_data (auth, &amp;tmp))
00936     <font class="keywordflow">goto</font> out_6;
00937 
00938   retval = TRUE;
00939 
00940  out_6:
00941   _dbus_string_zero (&amp;correct_hash);
00942   _dbus_string_free (&amp;correct_hash);
00943  out_5:
00944   _dbus_string_free (&amp;client_challenge);
00945  out_4:
00946   _dbus_string_zero (&amp;tmp);
00947   _dbus_string_free (&amp;tmp);
00948  out_3:
00949   _dbus_string_free (&amp;server_challenge);
00950  out_2:
00951   _dbus_string_free (&amp;cookie_id_str);
00952  out_1:
00953   _dbus_string_free (&amp;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-&gt;<a class="code" href="structDBusAuth.html#m12">cookie_id</a> = -1;  
00962   _dbus_string_set_length (&amp;auth-&gt;<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-&gt;<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) &gt; 0)
00977     {
00978       <font class="keywordflow">if</font> (_dbus_string_get_length (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m6">identity</a>) &gt; 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, &amp;auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m6">identity</a>) == 0 &amp;&amp;
00995       !auth-&gt;<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-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>);
01009   
01010   <font class="comment">/* If auth-&gt;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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m6">identity</a>) == 0)
01016     {
01017       auth-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a> = auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m6">identity</a>,
01022                                   &amp;auth-&gt;<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-&gt;<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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>,
01039                                &amp;auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>,
01049                      auth-&gt;<a class="code" href="structDBusAuth.html#m7">credentials</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>);
01050       
01051       auth-&gt;<a class="code" href="structDBusAuth.html#m8">authorized_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a> = auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m7">credentials</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>, auth-&gt;<a class="code" href="structDBusAuth.html#m7">credentials</a>.<a class="code" href="structDBusCredentials.html#m2">gid</a>,
01063                      auth-&gt;<a class="code" href="structDBusAuth.html#m9">desired_identity</a>.<a class="code" href="structDBusCredentials.html#m1">uid</a>, auth-&gt;<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 (&amp;plaintext))
01086     <font class="keywordflow">return</font> FALSE;
01087   
01088   <font class="keywordflow">if</font> (!_dbus_string_append_uint (&amp;plaintext,
01089                                  _dbus_getuid ()))
01090     <font class="keywordflow">goto</font> failed;
01091 
01092   <font class="keywordflow">if</font> (!_dbus_string_hex_encode (&amp;plaintext, 0,
01093                                 response,
01094                                 _dbus_string_get_length (response)))
01095     <font class="keywordflow">goto</font> failed;
01096 
01097   _dbus_string_free (&amp;plaintext);
01098   
01099   <font class="keywordflow">return</font> TRUE;
01100 
01101  failed:
01102   _dbus_string_free (&amp;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 &amp;&amp;
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> &amp;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 (&amp;auth_command))
01181     <font class="keywordflow">return</font> FALSE;
01182       
01183   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;auth_command,
01184                             <font class="stringliteral">"AUTH "</font>))
01185     {
01186       _dbus_string_free (&amp;auth_command);
01187       <font class="keywordflow">return</font> FALSE;
01188     }  
01189   
01190   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;auth_command,
01191                             mech-&gt;<a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>))
01192     {
01193       _dbus_string_free (&amp;auth_command);
01194       <font class="keywordflow">return</font> FALSE;
01195     }
01196 
01197   <font class="keywordflow">if</font> (mech-&gt;<a class="code" href="structDBusAuthMechanismHandler.html#m5">client_initial_response_func</a> != NULL)
01198     {
01199       <font class="keywordflow">if</font> (!_dbus_string_append (&amp;auth_command, <font class="stringliteral">" "</font>))
01200         {
01201           _dbus_string_free (&amp;auth_command);
01202           <font class="keywordflow">return</font> FALSE;
01203         }
01204       
01205       <font class="keywordflow">if</font> (!(* mech-&gt;<a class="code" href="structDBusAuthMechanismHandler.html#m5">client_initial_response_func</a>) (auth, &amp;auth_command))
01206         {
01207           _dbus_string_free (&amp;auth_command);
01208           <font class="keywordflow">return</font> FALSE;
01209         }
01210     }
01211   
01212   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;auth_command,
01213                             <font class="stringliteral">"\r\n"</font>))
01214     {
01215       _dbus_string_free (&amp;auth_command);
01216       <font class="keywordflow">return</font> FALSE;
01217     }
01218 
01219   <font class="keywordflow">if</font> (!_dbus_string_copy (&amp;auth_command, 0,
01220                           &amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>,
01221                           _dbus_string_get_length (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>)))
01222     {
01223       _dbus_string_free (&amp;auth_command);
01224       <font class="keywordflow">return</font> FALSE;
01225     }
01226 
01227   _dbus_string_free (&amp;auth_command);
01228   shutdown_mech (auth);
01229   auth-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a> = mech;      
01230   goto_state (auth, &amp;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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>);
01245       <font class="keywordflow">if</font> (!_dbus_string_append (&amp;auth-&gt;<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, &amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>,
01249                                     _dbus_string_get_length (&amp;auth-&gt;<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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<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 (&amp;command))
01272     <font class="keywordflow">return</font> FALSE;
01273   
01274   <font class="keywordflow">if</font> (!_dbus_string_append (&amp;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 (&amp;command,
01282                                 <font class="stringliteral">" "</font>))
01283         <font class="keywordflow">goto</font> nomem;
01284 
01285       <font class="keywordflow">if</font> (!_dbus_string_append (&amp;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 (&amp;command, <font class="stringliteral">"\r\n"</font>))
01293     <font class="keywordflow">goto</font> nomem;
01294 
01295   <font class="keywordflow">if</font> (!_dbus_string_copy (&amp;command, 0, &amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>,
01296                           _dbus_string_get_length (&amp;auth-&gt;<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-&gt;<a class="code" href="structDBusAuthServer.html#m1">failures</a> += 1;
01304 
01305   <font class="keywordflow">if</font> (server_auth-&gt;<a class="code" href="structDBusAuthServer.html#m1">failures</a> &gt;= server_auth-&gt;<a class="code" href="structDBusAuthServer.html#m2">max_failures</a>)
01306     goto_state (auth, &amp;common_state_need_disconnect);
01307   <font class="keywordflow">else</font>
01308     goto_state (auth, &amp;server_state_waiting_for_auth);
01309 
01310   _dbus_string_free (&amp;command);
01311   
01312   <font class="keywordflow">return</font> TRUE;
01313 
01314  nomem:
01315   _dbus_string_free (&amp;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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"OK\r\n"</font>))
01330     {
01331       goto_state (auth, &amp;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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"BEGIN\r\n"</font>))
01342     {
01343       goto_state (auth, &amp;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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>, <font class="stringliteral">"CANCEL\r\n"</font>))
01354     {
01355       goto_state (auth, &amp;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 (&amp;decoded))
01371     <font class="keywordflow">return</font> FALSE;
01372 
01373   <font class="keywordflow">if</font> (!_dbus_string_hex_decode (args, 0, &amp;end, &amp;decoded, 0))
01374     {
01375       _dbus_string_free (&amp;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 (&amp;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 (&amp;decoded, 0,
01390                                    _dbus_string_get_length (&amp;decoded)))
01391     _dbus_verbose (<font class="stringliteral">"%s: data: '%s'\n"</font>,
01392                    DBUS_AUTH_NAME (auth),
01393                    _dbus_string_get_const_data (&amp;decoded));
01394 <font class="preprocessor">#endif</font>
01395 <font class="preprocessor"></font>      
01396   <font class="keywordflow">if</font> (!(* data_func) (auth, &amp;decoded))
01397     {
01398       _dbus_string_free (&amp;decoded);
01399       <font class="keywordflow">return</font> FALSE;
01400     }
01401 
01402   _dbus_string_free (&amp;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, &amp;i);
01424 
01425       <font class="keywordflow">if</font> (!_dbus_string_init (&amp;mech))
01426         <font class="keywordflow">return</font> FALSE;
01427 
01428       <font class="keywordflow">if</font> (!_dbus_string_init (&amp;hex_response))
01429         {
01430           _dbus_string_free (&amp;mech);
01431           <font class="keywordflow">return</font> FALSE;
01432         }
01433       
01434       <font class="keywordflow">if</font> (!_dbus_string_copy_len (args, 0, i, &amp;mech, 0))
01435         <font class="keywordflow">goto</font> failed;
01436 
01437       _dbus_string_skip_blank (args, i, &amp;i);
01438       <font class="keywordflow">if</font> (!_dbus_string_copy (args, i, &amp;hex_response, 0))
01439         <font class="keywordflow">goto</font> failed;
01440      
01441       auth-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a> = find_mech (&amp;mech, auth-&gt;<a class="code" href="structDBusAuth.html#m14">allowed_mechs</a>);
01442       <font class="keywordflow">if</font> (auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>);
01447           
01448           <font class="keywordflow">if</font> (!process_data (auth, &amp;hex_response,
01449                              auth-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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 (&amp;mech));
01458           
01459           <font class="keywordflow">if</font> (!send_rejected (auth))
01460             <font class="keywordflow">goto</font> failed;
01461         }
01462 
01463       _dbus_string_free (&amp;mech);      
01464       _dbus_string_free (&amp;hex_response);
01465 
01466       <font class="keywordflow">return</font> TRUE;
01467       
01468     failed:
01469       auth-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a> = NULL;
01470       _dbus_string_free (&amp;mech);
01471       _dbus_string_free (&amp;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, &amp;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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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, &amp;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, &amp;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, &amp;i);
01573   
01574   <font class="keywordflow">if</font> (i &gt; *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-&gt;<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 &lt; 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 (&amp;m))
01604         <font class="keywordflow">goto</font> nomem;
01605       
01606       <font class="keywordflow">if</font> (!get_word (args, &amp;next, &amp;m))
01607         {
01608           _dbus_string_free (&amp;m);
01609           <font class="keywordflow">goto</font> nomem;
01610         }
01611 
01612       mech = find_mech (&amp;m, auth-&gt;<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-&gt;<a class="code" href="structDBusAuthMechanismHandler.html#m0">mechanism</a>);
01627           
01628           <font class="keywordflow">if</font> (!_dbus_list_append (&amp; DBUS_AUTH_CLIENT (auth)-&gt;mechs_to_try,
01629                                   (<font class="keywordtype">void</font>*) mech))
01630             {
01631               _dbus_string_free (&amp;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 (&amp;m));
01640         }
01641 
01642       _dbus_string_free (&amp;m);
01643     }
01644   
01645   auth-&gt;<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 (&amp; DBUS_AUTH_CLIENT (auth)-&gt;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-&gt;<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)-&gt;mechs_to_try != NULL)
01670     {
01671       mech = client-&gt;<a class="code" href="structDBusAuthClient.html#m1">mechs_to_try</a>-&gt;<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 (&amp;client-&gt;<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-&gt;<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, &amp;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-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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, &amp;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 &lt; _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-&gt;<a class="code" href="structDBusAuth.html#m4">state</a>-&gt;<a class="code" href="structDBusAuthStateData.html#m0">name</a>,
01812                  state-&gt;<a class="code" href="structDBusAuthStateData.html#m0">name</a>);
01813 
01814   auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m2">incoming</a>, 0, <font class="stringliteral">"\r\n"</font>, &amp;eol))
01834     <font class="keywordflow">return</font> FALSE;
01835   
01836   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;line))
01837     {
01838       auth-&gt;<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 (&amp;args))
01843     {
01844       _dbus_string_free (&amp;line);
01845       auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m2">incoming</a>, 0, eol, &amp;line, 0))
01850     <font class="keywordflow">goto</font> out;
01851 
01852   <font class="keywordflow">if</font> (!_dbus_string_validate_ascii (&amp;line, 0,
01853                                     _dbus_string_get_length (&amp;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 (&amp;line));
01866   
01867   _dbus_string_find_blank (&amp;line, 0, &amp;i);
01868   _dbus_string_skip_blank (&amp;line, i, &amp;j);
01869 
01870   <font class="keywordflow">if</font> (j &gt; i)
01871     _dbus_string_delete (&amp;line, i, j - i);
01872   
01873   <font class="keywordflow">if</font> (!_dbus_string_move (&amp;line, i, &amp;args, 0))
01874     <font class="keywordflow">goto</font> out;
01875   
01876   command = lookup_command_from_name (&amp;line);
01877   <font class="keywordflow">if</font> (!(* auth-&gt;<a class="code" href="structDBusAuth.html#m4">state</a>-&gt;<a class="code" href="structDBusAuthStateData.html#m1">handler</a>) (auth, command, &amp;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 (&amp;auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m2">incoming</a>, 0, 2);
01890 
01891   retval = TRUE;
01892   
01893  out:
01894   _dbus_string_free (&amp;args);
01895   _dbus_string_free (&amp;line);
01896 
01897   <font class="keywordflow">if</font> (!retval)
01898     auth-&gt;<a class="code" href="structDBusAuth.html#m15">needed_memory</a> = TRUE;
01899   <font class="keywordflow">else</font>
01900     auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m1">side</a> = auth_side_server;
01931   auth-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> = &amp;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-&gt;<a class="code" href="structDBusAuthServer.html#m1">failures</a> = 0;
01939   server_auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m1">side</a> = auth_side_client;
01961   auth-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> = &amp;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, &amp;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-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m0">refcount</a> &gt; 0);
02000 
02001   auth-&gt;<a class="code" href="structDBusAuth.html#m0">refcount</a> -= 1;
02002   <font class="keywordflow">if</font> (auth-&gt;<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 (&amp; DBUS_AUTH_CLIENT (auth)-&gt;mechs_to_try);
02009         }
02010 
02011       <font class="keywordflow">if</font> (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a>)
02012         _dbus_keyring_unref (auth-&gt;<a class="code" href="structDBusAuth.html#m11">keyring</a>);
02013 
02014       _dbus_string_free (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m10">context</a>);
02015       _dbus_string_free (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m13">challenge</a>);
02016       _dbus_string_free (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m6">identity</a>);
02017       _dbus_string_free (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m2">incoming</a>);
02018       _dbus_string_free (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>);
02019 
02020       dbus_free_string_array (auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m14">allowed_mechs</a>);
02050 
02051   auth-&gt;<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)-&gt;state-&gt;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-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m2">incoming</a>) &gt; MAX_BUFFER ||
02083           _dbus_string_get_length (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>) &gt; MAX_BUFFER)
02084         {
02085           goto_state (auth, &amp;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-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>) &gt; 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-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> == &amp;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-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> == &amp;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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>) == 0)
02123     <font class="keywordflow">return</font> FALSE;
02124 
02125   *str = &amp;auth-&gt;<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 (&amp;auth-&gt;<a class="code" href="structDBusAuth.html#m3">outgoing</a>));
02146   
02147   _dbus_string_delete (&amp;auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m18">buffer_outstanding</a>);
02164   
02165   *buffer = &amp;auth-&gt;<a class="code" href="structDBusAuth.html#m2">incoming</a>;
02166 
02167   auth-&gt;<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 == &amp;auth-&gt;<a class="code" href="structDBusAuth.html#m2">incoming</a>);
02183   _dbus_assert (auth-&gt;<a class="code" href="structDBusAuth.html#m18">buffer_outstanding</a>);
02184 
02185   auth-&gt;<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 = &amp;auth-&gt;<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 (&amp;auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> != &amp;common_state_authenticated)
02235     <font class="keywordflow">return</font> FALSE;
02236   
02237   <font class="keywordflow">if</font> (auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> != &amp;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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> != &amp;common_state_authenticated)
02294     <font class="keywordflow">return</font> FALSE;
02295     
02296   <font class="keywordflow">if</font> (auth-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> != &amp;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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m5">mech</a>-&gt;<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-&gt;<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-&gt;<a class="code" href="structDBusAuth.html#m4">state</a> == &amp;common_state_authenticated)
02371     *credentials = auth-&gt;<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                                    &amp;auth-&gt;<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 &lt;stdio.h&gt;</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 (&amp;test_directory))
02413     _dbus_assert_not_reached (<font class="stringliteral">"didn't allocate test_directory\n"</font>);
02414 
02415   _dbus_string_init_const (&amp;filename, subdir);
02416   
02417   <font class="keywordflow">if</font> (!_dbus_string_copy (test_base_dir, 0,
02418                           &amp;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 (&amp;test_directory, &amp;filename))    
02422     _dbus_assert_not_reached (<font class="stringliteral">"couldn't allocate full path"</font>);
02423 
02424   _dbus_string_free (&amp;filename);
02425   <font class="keywordflow">if</font> (!_dbus_string_init (&amp;filename))
02426     _dbus_assert_not_reached (<font class="stringliteral">"didn't allocate filename string\n"</font>);
02427 
02428   dbus_error_init (&amp;error);
02429   dir = _dbus_directory_open (&amp;test_directory, &amp;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 (&amp;test_directory),
02434                   error.<a class="code" href="structDBusError.html#m1">message</a>);
02435       dbus_error_free (&amp;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, &amp;filename, &amp;error))
02443     {
02444       <a class="code" href="structDBusString.html">DBusString</a> full_path;
02445       
02446       <font class="keywordflow">if</font> (!_dbus_string_init (&amp;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 (&amp;test_directory, 0, &amp;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 (&amp;full_path, &amp;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 (&amp;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 (&amp;filename));
02459           _dbus_string_free (&amp;full_path);
02460           <font class="keywordflow">goto</font> next;
02461         }
02462 
02463       printf (<font class="stringliteral">"    %s\n"</font>, _dbus_string_get_const_data (&amp;filename));
02464       
02465       <font class="keywordflow">if</font> (!_dbus_auth_script_run (&amp;full_path))
02466         {
02467           _dbus_string_free (&amp;full_path);
02468           <font class="keywordflow">goto</font> failed;
02469         }
02470       <font class="keywordflow">else</font>
02471         _dbus_string_free (&amp;full_path);
02472     }
02473 
02474   <font class="keywordflow">if</font> (dbus_error_is_set (&amp;error))
02475     {
02476       _dbus_warn (<font class="stringliteral">"Could not get next file in %s: %s\n"</font>,
02477                   _dbus_string_get_const_data (&amp;test_directory), error.<a class="code" href="structDBusError.html#m1">message</a>);
02478       dbus_error_free (&amp;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 (&amp;test_directory);
02489   _dbus_string_free (&amp;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 (&amp;test_directory, test_data_dir);
02503 
02504   <font class="keywordflow">if</font> (!process_test_subdir (&amp;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 (&amp;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>