LCOV - code coverage report
Current view: top level - src/tds - sec_negotiate.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 0 53 0.0 %
Date: 2025-01-18 11:50:39 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2             :  * Copyright (C) 2015  Frediano Ziglio
       3             :  *
       4             :  * This library is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU Library General Public
       6             :  * License as published by the Free Software Foundation; either
       7             :  * version 2 of the License, or (at your option) any later version.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             :  * Library General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU Library General Public
      15             :  * License along with this library; if not, write to the
      16             :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      17             :  * Boston, MA 02111-1307, USA.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : 
      22             : #if HAVE_STDLIB_H
      23             : #include <stdlib.h>
      24             : #endif /* HAVE_STDLIB_H */
      25             : 
      26             : #if HAVE_STDDEF_H
      27             : #include <stddef.h>
      28             : #endif /* HAVE_STDDEF_H */
      29             : 
      30             : #include <ctype.h>
      31             : 
      32             : #if HAVE_STRING_H
      33             : #include <string.h>
      34             : #endif /* HAVE_STRING_H */
      35             : 
      36             : #include <freetds/time.h>
      37             : #include <freetds/tds.h>
      38             : #include <freetds/bytes.h>
      39             : #include <freetds/utils/string.h>
      40             : #include <freetds/replacements.h>
      41             : 
      42             : #ifdef HAVE_GNUTLS
      43             : #  include "sec_negotiate_gnutls.h"
      44             : #elif defined(HAVE_OPENSSL)
      45             : #  include "sec_negotiate_openssl.h"
      46             : #endif
      47             : 
      48             : 
      49             : /**
      50             :  * \ingroup libtds
      51             :  * \defgroup auth Authentication
      52             :  * Functions for handling authentication.
      53             :  */
      54             : 
      55             : /**
      56             :  * \addtogroup auth
      57             :  * @{
      58             :  */
      59             : 
      60             : #if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
      61             : 
      62             : typedef struct tds5_negotiate
      63             : {
      64             :         TDSAUTHENTICATION tds_auth;
      65             : } TDS5NEGOTIATE;
      66             : 
      67             : static TDSRET
      68           0 : tds5_negotiate_free(TDSCONNECTION * conn TDS_UNUSED, TDSAUTHENTICATION * tds_auth)
      69             : {
      70           0 :         TDS5NEGOTIATE *auth = (TDS5NEGOTIATE *) tds_auth;
      71             : 
      72           0 :         free(auth->tds_auth.packet);
      73           0 :         free(auth);
      74             : 
      75           0 :         return TDS_SUCCESS;
      76             : }
      77             : 
      78             : static void
      79           0 : tds5_send_msg(TDSSOCKET *tds, uint16_t msg_type)
      80             : {
      81           0 :         tds_put_tinyint(tds, TDS_MSG_TOKEN);
      82           0 :         tds_put_tinyint(tds, 3); /* length */
      83           0 :         tds_put_tinyint(tds, 1); /* status, 1=has params */
      84           0 :         tds_put_smallint(tds, msg_type);
      85           0 : }
      86             : 
      87             : static TDSRET
      88           0 : tds5_negotiate_handle_next(TDSSOCKET * tds, TDSAUTHENTICATION * tds_auth, size_t len TDS_UNUSED)
      89             : {
      90             :         TDSPARAMINFO *info;
      91           0 :         void *rsa, *nonce = NULL;
      92           0 :         size_t rsa_len, nonce_len = 0;
      93             :         void *em;
      94             :         size_t em_size;
      95           0 :         TDSRET rc = TDS_FAIL;
      96             : 
      97             :         /* send next data for authentication */
      98             : 
      99           0 :         if (!tds->login)
     100             :                 goto error;
     101             : 
     102             :         /* we only support RSA authentication, we should have send 2/3 parameters:
     103             :          * 1- integer, cipher suite. 1 for RSA
     104             :          * 2- binary, rsa public key in PEM format
     105             :          * 3- binary, nonce (optional)
     106             :          */
     107             : 
     108             :         /* message not supported */
     109           0 :         if (tds_auth->msg_type != TDS5_MSG_SEC_ENCRYPT3)
     110             :                 goto error;
     111             : 
     112           0 :         info = tds->param_info;
     113           0 :         if (!info || info->num_cols < 2)
     114             :                 goto error;
     115             : 
     116           0 :         if (info->columns[1]->column_type != SYBLONGBINARY)
     117             :                 goto error;
     118           0 :         if (info->num_cols >= 3 && info->columns[2]->column_type != SYBLONGBINARY)
     119             :                 goto error;
     120           0 :         rsa = ((TDSBLOB*) info->columns[1]->column_data)->textvalue;
     121           0 :         rsa_len = info->columns[1]->column_size;
     122           0 :         if (info->num_cols >= 3) {
     123           0 :                 nonce = ((TDSBLOB*) info->columns[2]->column_data)->textvalue;
     124           0 :                 nonce_len = info->columns[2]->column_size;
     125             :         }
     126             : 
     127           0 :         em = tds5_rsa_encrypt(rsa, rsa_len, nonce, nonce_len, tds_dstr_cstr(&tds->login->password), &em_size);
     128           0 :         if (!em)
     129             :                 goto error;
     130             : 
     131           0 :         tds->out_flag = TDS_NORMAL;
     132             : 
     133             :         /* password */
     134           0 :         tds5_send_msg(tds, TDS5_MSG_SEC_LOGPWD3);
     135           0 :         tds_put_n(tds, "\xec\x0e\x00\x01\x00\x00\x00\x00\x00\x00\x00\xe1\xff\xff\xff\x7f\x00", 0x11);
     136           0 :         tds_put_byte(tds, TDS5_PARAMS_TOKEN);
     137           0 :         tds_put_int(tds, em_size);
     138           0 :         tds_put_n(tds, em, em_size);
     139             : 
     140             :         /* remote password */
     141           0 :         tds5_send_msg(tds, TDS5_MSG_SEC_REMPWD3);
     142           0 :         tds_put_n(tds, "\xec\x17\x00\x02\x00\x00\x00\x00\x00\x00\x00\x27\xff\x00\x00\x00\x00\x00\x00\x00\xe1\xff\xff\xff\x7f\x00", 0x1a);
     143           0 :         tds_put_byte(tds, TDS5_PARAMS_TOKEN);
     144           0 :         tds_put_byte(tds, 0);
     145           0 :         tds_put_int(tds, em_size);
     146           0 :         tds_put_n(tds, em, em_size);
     147             : 
     148           0 :         free(em);
     149             : 
     150           0 :         rc = tds_flush_packet(tds);
     151             : 
     152           0 : error:
     153           0 :         tds5_negotiate_free(tds->conn, tds_auth);
     154           0 :         tds->conn->authentication = NULL;
     155             : 
     156           0 :         return rc;
     157             : }
     158             : 
     159             : /**
     160             :  * Initialize Sybase negotiate handling
     161             :  * @param tds     A pointer to the TDSSOCKET structure managing a client/server operation.
     162             :  * @return authentication info
     163             :  */
     164             : TDSAUTHENTICATION *
     165           0 : tds5_negotiate_get_auth(TDSSOCKET * tds)
     166             : {
     167             :         TDS5NEGOTIATE *auth;
     168             : 
     169           0 :         if (!tds->login)
     170             :                 return NULL;
     171             : 
     172           0 :         auth = tds_new0(TDS5NEGOTIATE, 1);
     173           0 :         if (!auth)
     174             :                 return NULL;
     175             : 
     176           0 :         auth->tds_auth.free = tds5_negotiate_free;
     177           0 :         auth->tds_auth.handle_next = tds5_negotiate_handle_next;
     178             : 
     179           0 :         return (TDSAUTHENTICATION *) auth;
     180             : }
     181             : 
     182             : #else /* not HAVE_GNUTLS or HAVE_OPENSSL */
     183             : 
     184             : TDSAUTHENTICATION *
     185             : tds5_negotiate_get_auth(TDSSOCKET * tds TDS_UNUSED)
     186             : {
     187             :         tdsdump_log(TDS_DBG_ERROR,
     188             :                 "Sybase authentication not supported if GnuTLS or OpenSSL are not present\n");
     189             : 
     190             :         return NULL;
     191             : }
     192             : 
     193             : #endif
     194             : 
     195             : /** @} */
     196             : 

Generated by: LCOV version 1.13