1/*
2 *  DriverConnect.c
3 *
4 *  $Id: DriverConnect.c,v 1.6 2006/01/20 15:58:35 source Exp $
5 *
6 *  SQLDriverConnect trace functions
7 *
8 *  The iODBC driver manager.
9 *
10 *  Copyright (C) 1996-2006 by OpenLink Software <iodbc@openlinksw.com>
11 *  All Rights Reserved.
12 *
13 *  This software is released under the terms of either of the following
14 *  licenses:
15 *
16 *      - GNU Library General Public License (see LICENSE.LGPL)
17 *      - The BSD License (see LICENSE.BSD).
18 *
19 *  Note that the only valid version of the LGPL license as far as this
20 *  project is concerned is the original GNU Library General Public License
21 *  Version 2, dated June 1991.
22 *
23 *  While not mandated by the BSD license, any patches you make to the
24 *  iODBC source code may be contributed back into the iODBC project
25 *  at your discretion. Contributions will benefit the Open Source and
26 *  Data Access community as a whole. Submissions may be made at:
27 *
28 *      http://www.iodbc.org
29 *
30 *
31 *  GNU Library Generic Public License Version 2
32 *  ============================================
33 *  This library is free software; you can redistribute it and/or
34 *  modify it under the terms of the GNU Library General Public
35 *  License as published by the Free Software Foundation; only
36 *  Version 2 of the License dated June 1991.
37 *
38 *  This library is distributed in the hope that it will be useful,
39 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
40 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
41 *  Library General Public License for more details.
42 *
43 *  You should have received a copy of the GNU Library General Public
44 *  License along with this library; if not, write to the Free
45 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
46 *
47 *
48 *  The BSD License
49 *  ===============
50 *  Redistribution and use in source and binary forms, with or without
51 *  modification, are permitted provided that the following conditions
52 *  are met:
53 *
54 *  1. Redistributions of source code must retain the above copyright
55 *     notice, this list of conditions and the following disclaimer.
56 *  2. Redistributions in binary form must reproduce the above copyright
57 *     notice, this list of conditions and the following disclaimer in
58 *     the documentation and/or other materials provided with the
59 *     distribution.
60 *  3. Neither the name of OpenLink Software Inc. nor the names of its
61 *     contributors may be used to endorse or promote products derived
62 *     from this software without specific prior written permission.
63 *
64 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
65 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
66 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
67 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR
68 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
69 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
70 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
71 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
72 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
73 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75 */
76
77#include "trace.h"
78
79
80/*
81 *  Never print plaintext passwords
82 *
83 *  NOTE: This function modifies the original string
84 *
85 */
86static void
87_trace_connstr_hidepwd (SQLCHAR *str)
88{
89  SQLCHAR *ptr;
90  int state = 0;
91
92  for (ptr = str; *ptr;)
93    {
94      switch (state)
95	{
96	case -1:
97	  if (strchr ("\'\"}", *ptr))
98	    state = 0;
99	  break;
100
101	case 0:
102	  if (toupper(*ptr) == 'P')
103	    state = 1;
104	  else if (strchr ("\'\"{", *ptr))
105	    state = -1;		/* in string */
106	  break;
107
108	case 1:
109	  if (toupper(*ptr) == 'W')
110	    state = 2;
111	  else
112	    state = 0;
113	  break;
114
115	case 2:
116	  if (toupper(*ptr) == 'D')
117	    state = 3;
118	  else
119	    state = 0;
120	  break;
121
122	case 3:
123	  if (*ptr == '=')
124	    state = 4;		/* goto password mode */
125	  else
126	    state = 0;
127	  break;
128
129	case 4:
130	  if (*ptr == ';')
131	    {
132	      state = 0;	/* go back to normal mode */
133	    }
134	  else
135	    *ptr = '*';
136	  break;
137	}
138      ptr++;
139    }
140}
141
142
143static void
144_trace_connstr (
145  SQLCHAR		* str,
146  SQLSMALLINT		  len,
147  SQLSMALLINT		* lenptr,
148  int 			  output)
149{
150  SQLCHAR *dup;
151  ssize_t length;
152
153  if (!str)
154    {
155      trace_emit ("\t\t%-15.15s * 0x0\n", "SQLCHAR");
156      return;
157    }
158
159  trace_emit ("\t\t%-15.15s * %p\n", "SQLCHAR", str);
160
161  if (!output)
162    return;
163
164  /*
165   *  Calculate string length
166   */
167  if (lenptr )
168    length = *lenptr;
169  else
170    length = len;
171
172  if (length == SQL_NTS)
173    length = STRLEN (str);
174
175
176  /*
177   *  Make a copy of the string
178   */
179  if ((dup = (SQLCHAR *) malloc (length + 1)) == NULL)
180    return;
181  memcpy (dup, str, length);
182  dup[length] = '\0';
183
184  /*
185   *  Emit the string
186   */
187  _trace_connstr_hidepwd (dup);
188  trace_emit_string (dup, length, 0);
189  free (dup);
190}
191
192
193static void
194_trace_connstr_w (
195  SQLWCHAR		* str,
196  SQLSMALLINT		  len,
197  SQLSMALLINT		* lenptr,
198  int 			  output)
199{
200  SQLCHAR *dup;
201  long length;
202
203  if (!str)
204    {
205      trace_emit ("\t\t%-15.15s * 0x0\n", "SQLWCHAR");
206      return;
207    }
208
209  trace_emit ("\t\t%-15.15s * %p\n", "SQLWCHAR", str);
210
211  if (!output)
212    return;
213
214  /*
215   *  Calculate string length
216   */
217  if (lenptr)
218    length = *lenptr;
219  else
220    length = len;
221
222  /*
223   * Emit the string
224   */
225  dup = dm_SQL_W2A (str, length);
226  _trace_connstr_hidepwd (dup);
227  trace_emit_string (dup, SQL_NTS, 1);
228  free (dup);
229}
230
231
232
233static void
234_trace_drvcn_completion(SQLUSMALLINT fDriverCompletion)
235{
236  char *ptr = "invalid completion value";
237
238  switch (fDriverCompletion)
239    {
240      _S (SQL_DRIVER_PROMPT);
241      _S (SQL_DRIVER_COMPLETE);
242      _S (SQL_DRIVER_COMPLETE_REQUIRED);
243      _S (SQL_DRIVER_NOPROMPT);
244    }
245
246  trace_emit ("\t\t%-15.15s   %d (%s)\n",
247  	"SQLUSMALLINT", (int) fDriverCompletion, ptr);
248}
249
250
251void
252trace_SQLDriverConnect (int trace_leave, int retcode,
253  SQLHDBC		  hdbc,
254  SQLHWND		  hwnd,
255  SQLCHAR		* szConnStrIn,
256  SQLSMALLINT		  cbConnStrIn,
257  SQLCHAR 		* szConnStrOut,
258  SQLSMALLINT		  cbConnStrOutMax,
259  SQLSMALLINT 	 	* pcbConnStrOut,
260  SQLUSMALLINT		  fDriverCompletion)
261{
262  /* Trace function */
263  _trace_print_function (en_DriverConnect, trace_leave, retcode);
264
265  /* Trace Arguments */
266  _trace_handle (SQL_HANDLE_DBC, hdbc);
267  _trace_pointer (hwnd);
268  _trace_connstr (szConnStrIn, cbConnStrIn, NULL, TRACE_INPUT);
269  _trace_stringlen ("SQLSMALLINT", cbConnStrIn);
270  _trace_connstr (szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
271      TRACE_OUTPUT_SUCCESS);
272  _trace_stringlen ("SQLSMALLINT", cbConnStrOutMax);
273  _trace_smallint_p (pcbConnStrOut, TRACE_OUTPUT_SUCCESS);
274  _trace_drvcn_completion (fDriverCompletion);
275}
276
277
278#if ODBCVER >= 0x0300
279void
280trace_SQLDriverConnectW (int trace_leave, int retcode,
281  SQLHDBC		  hdbc,
282  SQLHWND		  hwnd,
283  SQLWCHAR 		* szConnStrIn,
284  SQLSMALLINT		  cbConnStrIn,
285  SQLWCHAR 		* szConnStrOut,
286  SQLSMALLINT		  cbConnStrOutMax,
287  SQLSMALLINT 	 	* pcbConnStrOut,
288  SQLUSMALLINT		  fDriverCompletion)
289{
290  /* Trace function */
291  _trace_print_function (en_DriverConnectW, trace_leave, retcode);
292
293  /* Trace Arguments */
294  _trace_handle (SQL_HANDLE_DBC, hdbc);
295  _trace_pointer (hwnd);
296  _trace_connstr_w (szConnStrIn, cbConnStrIn, NULL, TRACE_INPUT);
297  _trace_stringlen ("SQLSMALLINT", cbConnStrIn);
298  _trace_connstr_w (szConnStrOut, cbConnStrOutMax, pcbConnStrOut,
299      TRACE_OUTPUT_SUCCESS);
300  _trace_stringlen ("SQLSMALLINT", cbConnStrOutMax);
301  _trace_smallint_p (pcbConnStrOut, TRACE_OUTPUT_SUCCESS);
302  _trace_drvcn_completion (fDriverCompletion);
303}
304#endif
305