"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.

    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