1 /*
2  *  DriverConnect.c
3  *
4  *  $Id$
5  *
6  *  SQLDriverConnect trace functions
7  *
8  *  The iODBC driver manager.
9  *
10  *  Copyright (C) 1996-2021 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  */
86 static void
_trace_connstr_hidepwd(SQLCHAR * str)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 
143 static void
_trace_connstr(SQLCHAR * str,SQLSMALLINT len,SQLSMALLINT * lenptr,int output)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 
193 static void
_trace_connstr_w(SQLWCHAR * str,SQLSMALLINT len,SQLSMALLINT * lenptr,int output)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 
233 static void
_trace_drvcn_completion(SQLUSMALLINT fDriverCompletion)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 
251 void
trace_SQLDriverConnect(int trace_leave,int retcode,SQLHDBC hdbc,SQLHWND hwnd,SQLCHAR * szConnStrIn,SQLSMALLINT cbConnStrIn,SQLCHAR * szConnStrOut,SQLSMALLINT cbConnStrOutMax,SQLSMALLINT * pcbConnStrOut,SQLUSMALLINT fDriverCompletion)252 trace_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
279 void
trace_SQLDriverConnectW(int trace_leave,int retcode,SQLHDBC hdbc,SQLHWND hwnd,SQLWCHAR * szConnStrIn,SQLSMALLINT cbConnStrIn,SQLWCHAR * szConnStrOut,SQLSMALLINT cbConnStrOutMax,SQLSMALLINT * pcbConnStrOut,SQLUSMALLINT fDriverCompletion)280 trace_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