sijms / go-ora

Pure go oracle client
MIT License
805 stars 175 forks source link

Allow for tls connection without certificate (one-way TLS) #372

Closed victorien-a closed 1 year ago

victorien-a commented 1 year ago

This prevents certificate errors when trying to connect via TLS without a wallet. Options that worked for me:

import (
    go_ora "github.com/sijms/go-ora/v2"

    oracle "github.com/godoes/gorm-oracle" // Only needed for GORM
    "gorm.io/gorm" // Only needed for GORM
)

    urlOptions := map[string]string{
        //"TRACE FILE": "trace.log",
        "AUTH TYPE":  "TCPS",
        "SSL":        "TRUE",
        "SSL VERIFY": "TRUE",
    }

Then I used JDBC string since "connStr" was the only this I was sure was correct.

    jdbc := "(description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1521)(host=" + ORACLE_SERVER + "))(connect_data=(service_name=" + ORACLE_SERVICE + "))(security=(ssl_server_dn_match=yes)))"
    cleanJDBC := go_ora.BuildJDBC( ORACLE_USER ,  ORACLE_PASS), jdbc, urlOptions)

Using normal go-ora:

    conn, err := go_ora.NewConnection(cleanJDBC)
    if err != nil {
        log.Fatalln("Could not login: " + err.Error())
    }

    // check for error
    err = conn.Open()
    if err != nil {
        log.Fatalln("Could not login: " + err.Error())
    }
    // check for error
    defer conn.Close()

Using gorm:

    oracle.New(oracle.Config{})
    db, err := gorm.Open(oracle.Open(cleanJDBC), &gorm.Config{})
    if err != nil {
        log.Fatalln("Could not login: " + err.Error())
    }

To explain:

Basically this change the tlsConfig object from:

 &tls.Config{
        Certificates: session.SSL.tlsCertificates,
        RootCAs:      session.SSL.roots,
        ServerName:   host.Addr,
    }

To

 &tls.Config{
        ServerName: host.Addr,
    }

Having nil RootCAs enable to use host root CA set :

(From TLS pkg) 
    // RootCAs defines the set of root certificate authorities
    // that clients use when verifying server certificates.
    // If RootCAs is nil, TLS uses the host's root CA set.
    RootCAs *x509.CertPool

And leaving the AuthType nil we can use the default "NoClientCert" method:

(From TLS ClientAuthType)
        // NoClientCert indicates that no client certificate should be requested
    // during the handshake, and if any certificates are sent they will not
    // be verified.
    NoClientCert ClientAuthType = iota

And we leave the InsecureSkipVerify to FALSE based on the parameters.

if !connOption.SSLVerify {
        config.InsecureSkipVerify = true
    }