pike.git / lib / modules / SSL.pmod / Connection.pike

version» Context lines:

pike.git/lib/modules/SSL.pmod/Connection.pike:68:   .Cipher.KeyExchange ke;      ProtocolVersion version;   ProtocolVersion client_version; /* Used to check for version roll-back attacks. */      //! Random cookies, sent and received with the hello-messages.   string(0..255) client_random;   string(0..255) server_random;      #define Packet .Packet + #define Alert .Alert    - .Alert Alert(int(1..2) level, int(0..255) description, string|void message) + Alert alert(int(1..2) level, int(0..255) description, +  string|void message)   { -  // NB: We are always inherited by SSL.connection. +     return context->alert_factory(this, level, description, version,    message);   }      string(8bit) get_signature_algorithms()   {    ADT.struct sign_algs = ADT.struct();    foreach(sort(indices(HASH_lookup)), int h) {    sign_algs->put_uint(h, 1);    sign_algs->put_uint(SIGNATURE_rsa, 1);
pike.git/lib/modules/SSL.pmod/Connection.pike:335:   int sent;   int dying;   int closing; // Bitfield: 1 if a close is sent, 2 of one is received.      function(object,int|object,string:void) alert_callback;      constant PRI_alert = 1;   constant PRI_urgent = 2;   constant PRI_application = 3;    - protected ADT.Queue alert = ADT.Queue(); - protected ADT.Queue urgent = ADT.Queue(); - protected ADT.Queue application = ADT.Queue(); + protected ADT.Queue alert_q = ADT.Queue(); + protected ADT.Queue urgent_q = ADT.Queue(); + protected ADT.Queue application_q = ADT.Queue();      //! Called with alert object, sequence number of bad packet,   //! and raw data as arguments, if a bad packet is received.   //!   //! Can be used to support a fallback redirect https->http.   void set_alert_callback(function(object,int|object,string:void) callback)   {    alert_callback = callback;   }   
pike.git/lib/modules/SSL.pmod/Connection.pike:409:    PACKET_heartbeat : PRI_urgent,    PACKET_application_data : PRI_application ])[packet->content_type];    SSL3_DEBUG_MSG("SSL.connection->send_packet: type %d, desc %d, pri %d, %O\n",    packet->content_type, packet->description, priority,    packet->fragment[..5]);    switch (priority)    {    default:    error( "Internal error\n" );    case PRI_alert: -  alert->put(packet); +  alert_q->put(packet);    break;    case PRI_urgent: -  urgent->put(packet); +  urgent_q->put(packet);    break;    case PRI_application: -  application->put(packet); +  application_q->put(packet);    break;    }      }      //! Extracts data from the packet queues. Returns a string of data   //! to be written, "" if there are no pending packets, 1 of the   //! connection is being closed politely, and -1 if the connection   //! died unexpectedly.   //!   //! This function is intended to be called from an i/o write callback.   string|int to_write()   {    if (dying)    return -1;    -  Packet packet = [object(Packet)](alert->get() || urgent->get() || -  application->get()); +  Packet packet = [object(Packet)](alert_q->get() || urgent_q->get() || +  application_q->get());    if (!packet) {    return closing ? 1 : "";    }       SSL3_DEBUG_MSG("SSL.connection: writing packet of type %d, %O\n",    packet->content_type, packet->fragment[..6]);    if (packet->content_type == PACKET_alert)    {    if (packet->level == ALERT_fatal) {    dying = 1;
pike.git/lib/modules/SSL.pmod/Connection.pike:464:    }    string res = current_write_state->encrypt_packet(packet, version)->send();    if (packet->content_type == PACKET_change_cipher_spec)    current_write_state = pending_write_state;    return res;   }      //! Initiate close.   void send_close()   { -  send_packet(Alert(ALERT_warning, ALERT_close_notify, +  send_packet(alert(ALERT_warning, ALERT_close_notify,    "Closing connection.\n"), PRI_application);   }      //! Send an application data packet. If the data block is too large   //! then as much as possible of the beginning of it is sent. The size   //! of the sent data is returned.   int send_streaming_data (string(8bit) data)   {    if (!sizeof(data)) return 0;    Packet packet = Packet();
pike.git/lib/modules/SSL.pmod/Connection.pike:509:    return size;   }      protected int handle_alert(string s)   {    // sizeof(s)==2, checked at caller.    int level = s[0];    int description = s[1];    if (! (ALERT_levels[level] && ALERT_descriptions[description]))    { -  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, +  send_packet(alert(ALERT_fatal, ALERT_unexpected_message,    "invalid alert\n"));    return -1;    }    if (level == ALERT_fatal)    {    SSL3_DEBUG_MSG("SSL.connection: Fatal alert %d\n", description);    return -1;    }    if (description == ALERT_close_notify)    {
pike.git/lib/modules/SSL.pmod/Connection.pike:533:    }    if (description == ALERT_no_certificate)    {    SSL3_DEBUG_MSG("SSL.connection: No certificate alert %d\n", description);       if ((certificate_state == CERT_requested) && (context->auth_level == AUTHLEVEL_ask))    {    certificate_state = CERT_no_certificate;    return 0;    } else { -  send_packet(Alert(ALERT_fatal, +  send_packet(alert(ALERT_fatal,    ((certificate_state == CERT_requested)    ? ALERT_handshake_failure    : ALERT_unexpected_message),    "Certificate required.\n"));    return -1;    }    }   #ifdef SSL3_DEBUG    else    werror("SSL.connection: Received warning alert %d\n", description);   #endif    return 0;   }      int handle_change_cipher(int c)   {    if (!expect_change_cipher || (c != 1))    {    SSL3_DEBUG_MSG("SSL.connection: handle_change_cipher: Unexcepted message!"); -  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, +  send_packet(alert(ALERT_fatal, ALERT_unexpected_message,    "Unexpected change cipher!\n"));    return -1;    }    else    {    current_read_state = pending_read_state;    expect_change_cipher = 0;    return 0;    }   }
pike.git/lib/modules/SSL.pmod/Connection.pike:641:    // RFC 6520 4:    // If a received HeartbeatResponse message does not contain the    // expected payload, the message MUST be discarded silently.    if ((sizeof(payload) == 16) && heartbeat_decode) {    hb_msg = ADT.struct(heartbeat_decode->crypt(payload));    int a = hb_msg->get_uint(8);    int b = hb_msg->get_uint(8);    if (a != b) {    if (!b) {    // Heartbleed probe response. -  send_packet(Alert(ALERT_fatal, ALERT_insufficient_security, +  send_packet(alert(ALERT_fatal, ALERT_insufficient_security,    "Peer suffers from a bleeding heart.\n"));    }    break;    }   #ifdef SSL3_DEBUG    int delta = gethrtime() - a;    SSL3_DEBUG_MSG("SSL.connection: Heartbeat roundtrip: %dus\n", delta);   #endif    }    break;
pike.git/lib/modules/SSL.pmod/Connection.pike:748:    }    case PACKET_handshake:    {    SSL3_DEBUG_MSG("SSL.connection: HANDSHAKE\n");       if (handshake_finished && !secure_renegotiation) {    // Don't allow renegotiation in unsecure mode, to address    // http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-3555.    // For details see: http://www.g-sec.lu/practicaltls.pdf and    // RFC 5746. -  send_packet(Alert(ALERT_warning, ALERT_no_renegotiation, +  send_packet(alert(ALERT_warning, ALERT_no_renegotiation,    "Renegotiation not supported in unsecure mode.\n"));    return -1;    }    if (expect_change_cipher)    {    /* No change_cipher message was received */    // FIXME: There's a bug somewhere since expect_change_cipher often    // remains set after the handshake is completed. The effect is that    // renegotiation doesn't work all the time.    //    // A side effect is that we are partly invulnerable to the    // renegotiation vulnerability mentioned above. It is however not    // safe to assume that, since there might be routes past this,    // maybe through the use of a version 2 hello message below. -  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, +  send_packet(alert(ALERT_fatal, ALERT_unexpected_message,    "Expected change cipher.\n"));    return -1;    }    int err, len;    handshake_buffer += packet->fragment;       while (sizeof(handshake_buffer) >= 4)    {    sscanf(handshake_buffer, "%*c%3c", len);    if (sizeof(handshake_buffer) < (len + 4))
pike.git/lib/modules/SSL.pmod/Connection.pike:785:    mixed exception = catch {    err = handle_handshake(handshake_buffer[0],    handshake_buffer[4..len + 3],    handshake_buffer[.. len + 3]);    };    if( exception )    {    if( objectp(exception) && ([object]exception)->ADT_struct )    {    Error.Generic e = [object(Error.Generic)]exception; -  send_packet(Alert(ALERT_fatal, ALERT_decode_error, +  send_packet(alert(ALERT_fatal, ALERT_decode_error,    e->message()));    return -1;    }    throw(exception);    }    handshake_buffer = handshake_buffer[len + 4..];    if (err < 0)    return err;    if (err > 0) {    handshake_finished = 1;    }    }    break;    }    case PACKET_application_data:    SSL3_DEBUG_MSG("SSL.connection: APPLICATION_DATA\n");       if (!handshake_finished)    { -  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, +  send_packet(alert(ALERT_fatal, ALERT_unexpected_message,    "Handshake not finished yet!\n"));    return -1;    }    res += packet->fragment;    break;    case PACKET_heartbeat:    {    // RFC 6520.    SSL3_DEBUG_MSG("SSL.connection: Heartbeat.\n");    if (!handshake_finished) {
pike.git/lib/modules/SSL.pmod/Connection.pike:827:    // The receiving peer SHOULD discard the message silently,    // if it arrives during the handshake.    break;    }    if (!session->heartbeat_mode) {    // RFC 6520 2:    // If an endpoint that has indicated peer_not_allowed_to_send    // receives a HeartbeatRequest message, the endpoint SHOULD    // drop the message silently and MAY send an unexpected_message    // Alert message. -  send_packet(Alert(ALERT_warning, ALERT_unexpected_message, +  send_packet(alert(ALERT_warning, ALERT_unexpected_message,    "Heart beat mode not enabled.\n"));    break;    }       mixed exception = catch {    handle_heartbeat(packet->fragment);    };    if( exception )    {    if( objectp(exception) && ([object]exception)->ADT_struct )    {    Error.Generic e = [object(Error.Generic)]exception; -  send_packet(Alert(ALERT_fatal, ALERT_decode_error, +  send_packet(alert(ALERT_fatal, ALERT_decode_error,    e->message()));    return -1;    }    throw(exception);    }       }    break;    default:    if (!handshake_finished)    { -  send_packet(Alert(ALERT_fatal, ALERT_unexpected_message, +  send_packet(alert(ALERT_fatal, ALERT_unexpected_message,    "Unexpected message during handshake!\n"));    return -1;    }    // RFC 4346 6:    // If a TLS implementation receives a record type it does not    // understand, it SHOULD just ignore it.    SSL3_DEBUG_MSG("SSL.connection: Ignoring packet of type %s\n",    fmt_constant(packet->content_type, "PACKET"));    break;    }    }    }    return closing & 2 ? 1 : res;   }