func handle_tlsconn(conn *tls.Conn, context *Context) bool { conn.SetDeadline(time.Now().Add(config.TimeoutTLS)) err := conn.Handshake() if err != nil { util.Log(0, "ERROR! [SECURITY] TLS Handshake: %v", err) return false } var no_deadline time.Time conn.SetDeadline(no_deadline) state := conn.ConnectionState() if len(state.PeerCertificates) == 0 { util.Log(0, "ERROR! [SECURITY] TLS peer has no certificate") return false } cert := state.PeerCertificates[0] // docs are unclear about this but I think leaf certificate is the first entry because that's as it is in tls.Certificate if util.LogLevel >= 2 { // because creating the dump is expensive util.Log(2, "DEBUG! [SECURITY] Peer certificate presented by %v:\n%v", conn.RemoteAddr(), CertificateInfo(cert)) } for _, cacert := range config.CACert { err = cert.CheckSignatureFrom(cacert) if err == nil { if string(cacert.RawSubject) != string(cert.RawIssuer) { err = fmt.Errorf("Certificate was issued by wrong CA: \"%v\" instead of \"%v\"", cacert.Subject, cert.Issuer) } else { break // stop checking if we found a match for a CA. err == nil here! } } } if err != nil { util.Log(0, "ERROR! [SECURITY] TLS peer presented certificate not signed by trusted CA: %v", err) return false } for _, e := range cert.Extensions { if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 && e.Id[3] == 17 { parseSANExtension(e.Value, context) } else if len(e.Id) == 9 && e.Id[0] == 1 && e.Id[1] == 3 && e.Id[2] == 6 && e.Id[3] == 1 && e.Id[4] == 4 && e.Id[5] == 1 && e.Id[6] == 45753 && e.Id[7] == 1 { switch e.Id[8] { case 5: err = parseConnectionLimits(e.Value, context) if err != nil { util.Log(0, "ERROR! [SECURITY] GosaConnectionLimits: %v", err) } case 6: //err = parseAccessControl(e.Value, context) //if err != nil { util.Log(0, "ERROR! [SECURITY] GosaAccessControl: %v", err) } } } } context.TLS = true return true }
func Publishv1(input chan []*FileEvent, registrar chan []*FileEvent, config *NetworkConfig) { var buffer bytes.Buffer var socket *tls.Conn var sequence uint32 var err error socket = connect(config) defer socket.Close() for events := range input { buffer.Truncate(0) compressor, _ := zlib.NewWriterLevel(&buffer, 3) for _, event := range events { sequence += 1 writeDataFrame(event, sequence, compressor) } compressor.Flush() compressor.Close() compressed_payload := buffer.Bytes() // Send buffer until we're successful... oops := func(err error) { // TODO(sissel): Track how frequently we timeout and reconnect. If we're // timing out too frequently, there's really no point in timing out since // basically everything is slow or down. We'll want to ratchet up the // timeout value slowly until things improve, then ratchet it down once // things seem healthy. log.Printf("Socket error, will reconnect: %s\n", err) time.Sleep(1 * time.Second) socket.Close() socket = connect(config) } SendPayload: for { // Abort if our whole request takes longer than the configured // network timeout. socket.SetDeadline(time.Now().Add(config.timeout)) // Set the window size to the length of this payload in events. _, err = socket.Write([]byte("1W")) if err != nil { oops(err) continue } binary.Write(socket, binary.BigEndian, uint32(len(events))) if err != nil { oops(err) continue } // Write compressed frame socket.Write([]byte("1C")) if err != nil { oops(err) continue } binary.Write(socket, binary.BigEndian, uint32(len(compressed_payload))) if err != nil { oops(err) continue } _, err = socket.Write(compressed_payload) if err != nil { oops(err) continue } // read ack response := make([]byte, 0, 6) ackbytes := 0 for ackbytes != 6 { n, err := socket.Read(response[len(response):cap(response)]) if err != nil { log.Printf("Read error looking for ack: %s\n", err) socket.Close() socket = connect(config) continue SendPayload // retry sending on new connection } else { ackbytes += n } } // TODO(sissel): verify ack // Success, stop trying to send the payload. break } // Tell the registrar that we've successfully sent these events registrar <- events } /* for each event payload */ } // Publish
func tlsTimedHandshake(tc *tls.Conn) error { tc.SetDeadline(time.Now().Add(tlsHandshakeTimeout)) defer tc.SetDeadline(time.Time{}) return tc.Handshake() }