Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
func tlsTimedHandshake(tc *tls.Conn) error {
	tc.SetDeadline(time.Now().Add(tlsHandshakeTimeout))
	defer tc.SetDeadline(time.Time{})
	return tc.Handshake()
}