"Fossies" - the Fresh Open Source Software Archive

Member "freeradius-server-3.0.23/src/main/cb.c" (10 Jun 2021, 5932 Bytes) of package /linux/misc/freeradius-server-3.0.23.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cb.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.0.22_vs_3.0.23.

    1 /*
    2  * cb.c
    3  *
    4  * Version:     $Id: ec8e77aa006ec06a98a9aa8db4c73c7fd087d901 $
    5  *
    6  *   This program is free software; you can redistribute it and/or modify
    7  *   it under the terms of the GNU General Public License as published by
    8  *   the Free Software Foundation; either version 2 of the License, or
    9  *   (at your option) any later version.
   10  *
   11  *   This program is distributed in the hope that it will be useful,
   12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  *   GNU General Public License for more details.
   15  *
   16  *   You should have received a copy of the GNU General Public License
   17  *   along with this program; if not, write to the Free Software
   18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
   19  *
   20  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
   21  * Copyright 2006  The FreeRADIUS server project
   22  */
   23 
   24 RCSID("$Id: ec8e77aa006ec06a98a9aa8db4c73c7fd087d901 $")
   25 USES_APPLE_DEPRECATED_API   /* OpenSSL API has been deprecated by Apple */
   26 
   27 #include <freeradius-devel/radiusd.h>
   28 
   29 #ifdef WITH_TLS
   30 void cbtls_info(SSL const *s, int where, int ret)
   31 {
   32     char const *role, *state;
   33     REQUEST *request = SSL_get_ex_data(s, FR_TLS_EX_INDEX_REQUEST);
   34 
   35     if ((where & ~SSL_ST_MASK) & SSL_ST_CONNECT) {
   36         role = "Client ";
   37     } else if (((where & ~SSL_ST_MASK)) & SSL_ST_ACCEPT) {
   38         role = "Server ";
   39     } else {
   40         role = "";
   41     }
   42 
   43     state = SSL_state_string_long(s);
   44     state = state ? state : "<none>";
   45 
   46     if ((where & SSL_CB_LOOP) || (where & SSL_CB_HANDSHAKE_START) || (where & SSL_CB_HANDSHAKE_DONE)) {
   47         if (RDEBUG_ENABLED3) {
   48             char const *abbrv = SSL_state_string(s);
   49             size_t len;
   50 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
   51             STACK_OF(SSL_CIPHER) *client_ciphers;
   52             STACK_OF(SSL_CIPHER) *server_ciphers;
   53 #endif
   54 
   55             /*
   56              *  Trim crappy OpenSSL state strings...
   57              */
   58             len = strlen(abbrv);
   59             if ((len > 1) && (abbrv[len - 1] == ' ')) len--;
   60 
   61             RDEBUG3("(TLS) Handshake state [%.*s] - %s%s (%d)",
   62                 (int)len, abbrv, role, state, SSL_get_state(s));
   63 
   64             /*
   65              *  After a ClientHello, list all the proposed ciphers from the client
   66              */
   67 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
   68             if (SSL_get_state(s) == TLS_ST_SR_CLNT_HELLO) {
   69                 int i;
   70                 int num_ciphers;
   71                 const SSL_CIPHER *this_cipher;
   72 
   73                 server_ciphers = SSL_get_ciphers(s);
   74                 if (server_ciphers) {
   75                     RDEBUG3("Server preferred ciphers (by priority)");
   76                     num_ciphers = sk_SSL_CIPHER_num(server_ciphers);
   77                     for (i = 0; i < num_ciphers; i++) {
   78                         this_cipher = sk_SSL_CIPHER_value(server_ciphers, i);
   79                         RDEBUG3("(TLS)    [%i] %s", i, SSL_CIPHER_get_name(this_cipher));
   80                     }
   81                 }
   82     
   83                 client_ciphers = SSL_get_client_ciphers(s);
   84                 if (client_ciphers) {
   85                     RDEBUG3("Client preferred ciphers (by priority)");
   86                     num_ciphers = sk_SSL_CIPHER_num(client_ciphers);
   87                     for (i = 0; i < num_ciphers; i++) {
   88                         this_cipher = sk_SSL_CIPHER_value(client_ciphers, i);
   89                         RDEBUG3("(TLS)    [%i] %s", i, SSL_CIPHER_get_name(this_cipher));
   90                     }
   91                 }
   92             }
   93 #endif
   94         } else {
   95             RDEBUG2("(TLS) Handshake state - %s%s", role, state);
   96         }
   97         return;
   98     }
   99 
  100     if (where & SSL_CB_ALERT) {
  101         if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) return;
  102 
  103         RERROR("(TLS) Alert %s:%s:%s", (where & SSL_CB_READ) ? "read": "write",
  104                SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
  105         return;
  106     }
  107 
  108     if (where & SSL_CB_EXIT) {
  109         if (ret == 0) {
  110             RERROR("(TLS) %s: Failed in %s", role, state);
  111             return;
  112         }
  113 
  114         if (ret < 0) {
  115             if (SSL_want_read(s)) {
  116                 RDEBUG2("(TLS) %s: Need to read more data: %s", role, state);
  117                 return;
  118             }
  119             RERROR("(TLS) %s: Error in %s", role, state);
  120         }
  121     }
  122 }
  123 
  124 /*
  125  *  Fill in our 'info' with TLS data.
  126  */
  127 void cbtls_msg(int write_p, int msg_version, int content_type,
  128            void const *inbuf, size_t len,
  129            SSL *ssl UNUSED, void *arg)
  130 {
  131     uint8_t const *buf = inbuf;
  132     tls_session_t *state = (tls_session_t *)arg;
  133 
  134     /*
  135      *  OpenSSL 1.0.2 calls this function with 'pseudo'
  136      *  content types.  Which breaks our tracking of
  137      *  the SSL Session state.
  138      */
  139     if ((msg_version == 0) && (content_type > UINT8_MAX)) {
  140         DEBUG4("(TLS) Ignoring cbtls_msg call with pseudo content type %i, version %i",
  141                content_type, msg_version);
  142         return;
  143     }
  144 
  145     if ((write_p != 0) && (write_p != 1)) {
  146         DEBUG4("(TLS) Ignoring cbtls_msg call with invalid write_p %d", write_p);
  147         return;
  148     }
  149 
  150     /*
  151      *  Work around bug #298, where we may be called with a NULL
  152      *  argument.  We should really log a serious error
  153      */
  154     if (!state) return;
  155 
  156     /*
  157      *  0 - received (from peer)
  158      *  1 - sending (to peer)
  159      */
  160     state->info.origin = write_p;
  161     state->info.content_type = content_type;
  162     state->info.record_len = len;
  163     state->info.version = msg_version;
  164     state->info.initialized = true;
  165 
  166 
  167     if (content_type == SSL3_RT_ALERT) {
  168         state->info.alert_level = buf[0];
  169         state->info.alert_description = buf[1];
  170         state->info.handshake_type = 0x00;
  171 
  172     } else if (content_type == SSL3_RT_HANDSHAKE) {
  173         state->info.handshake_type = buf[0];
  174         state->info.alert_level = 0x00;
  175         state->info.alert_description = 0x00;
  176 
  177 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
  178     } else if (content_type == SSL3_RT_INNER_CONTENT_TYPE && buf[0] == SSL3_RT_APPLICATION_DATA) {
  179         /* let tls_ack_handler set application_data */
  180         state->info.content_type = SSL3_RT_HANDSHAKE;
  181 #endif
  182 
  183 #ifdef SSL3_RT_HEARTBEAT
  184     } else if (content_type == TLS1_RT_HEARTBEAT) {
  185         uint8_t *p = buf;
  186 
  187         if ((len >= 3) && (p[0] == 1)) {
  188             size_t payload_len;
  189 
  190             payload_len = (p[1] << 8) | p[2];
  191 
  192             if ((payload_len + 3) > len) {
  193                 state->invalid_hb_used = true;
  194                 ERROR("OpenSSL Heartbeat attack detected.  Closing connection");
  195                 return;
  196             }
  197         }
  198 #endif
  199     }
  200     tls_session_information(state);
  201 }
  202 
  203 int cbtls_password(char *buf,
  204            int num UNUSED,
  205            int rwflag UNUSED,
  206            void *userdata)
  207 {
  208     strcpy(buf, (char *)userdata);
  209     return(strlen((char *)userdata));
  210 }
  211 
  212 #endif