summary refs log tree commit diff stats
path: root/tests/vm/textensionmap.nim
Commit message (Collapse)AuthorAgeFilesLines
* fixes #5237Andreas Rumpf2017-01-191-0/+13
' href='#n28'>28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
discard """
  cmd: "nim $target --threads:on -d:ssl $options $file"
  disabled: "openbsd"
"""

#            Nim - Basic SSL integration tests
#        (c) Copyright 2018 Nim contributors
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#
## Warning: this test performs local networking.
## Test with:
## ./bin/nim c -d:ssl -p:. --threads:on -r tests/stdlib/thttpclient_ssl.nim

when not defined(windows):
  # Disabled on Windows due to old OpenSSL version

  import
    httpclient,
    net,
    openssl,
    os,
    strutils,
    threadpool,
    times,
    unittest

  # bogus self-signed certificate
  const
    certFile = "tests/stdlib/thttpclient_ssl_cert.pem"
    keyFile = "tests/stdlib/thttpclient_ssl_key.pem"

  proc log(msg: string) =
    when defined(ssldebug):
      echo "    [" & $epochTime() & "] " & msg
    # FIXME
    echo "    [" & $epochTime() & "] " & msg
    discard

  proc runServer(port: Port): bool {.thread.} =
    ## Run a trivial HTTPS server in a {.thread.}
    ## Exit after serving one request

    var socket = newSocket()
    socket.setSockOpt(OptReusePort, true)
    socket.bindAddr(port)

    var ctx = newContext(certFile=certFile, keyFile=keyFile)

    ##  Handle one connection
    socket.listen()

    var client: Socket
    var address = ""

    log "server: ready"
    socket.acceptAddr(client, address)
    log "server: incoming connection"

    var ssl: SslPtr = SSL_new(ctx.context)
    discard SSL_set_fd(ssl, client.getFd())
    log "server: accepting connection"
    ErrClearError()
    if SSL_accept(ssl) <= 0:
      ERR_print_errors_fp(stderr)
    else:
      const reply = "HTTP/1.0 200 OK\r\nServer: test\r\nContent-type: text/html\r\nContent-Length: 0\r\n\r\n"
      log "server: sending reply"
      discard SSL_write(ssl, reply.cstring, reply.len)

    log "server: receiving a line"
    let line = client.recvLine()
    log "server: received $# bytes" % $line.len
    log "closing"
    SSL_free(ssl)
    close(client)
    close(socket)
    log "server: exited"


  suite "SSL self signed certificate check":

    test "TCP socket":
      const port = 12347.Port
      let t = spawn runServer(port)
      sleep(100)
      var sock = newSocket()
      var ctx = newContext()
      ctx.wrapSocket(sock)
      try:
        log "client: connect"
        sock.connect("127.0.0.1", port)
        fail()
      except:
        let msg = getCurrentExceptionMsg()
        check(msg.contains("certificate verify failed"))

    test "HttpClient default: no check":
      const port = 12345.Port
      let t = spawn runServer(port)
      sleep(100)

      var client = newHttpClient(sslContext=newContext(verifyMode=CVerifyNone))
      try:
        log "client: connect"
        discard client.getContent("https://127.0.0.1:12345")
      except:
        let msg = getCurrentExceptionMsg()
        log "client: unexpected exception: " & msg
        fail()

    test "HttpClient with CVerifyPeer":
      const port = 12346.Port
      let t = spawn runServer(port)
      sleep(100)

      var client = newHttpClient(sslContext=newContext(verifyMode=CVerifyPeer))
      try:
        log "client: connect"
        discard client.getContent("https://127.0.0.1:12346")
        log "getContent should have raised an exception"
        fail()
      except:
        let msg = getCurrentExceptionMsg()
        log "client: exception: " & msg
        # SSL_shutdown:shutdown while in init
        if not (msg.contains("alert number 48") or
          msg.contains("certificate verify failed")):
          echo "CVerifyPeer exception: " & msg
          check(false)

    test "HttpClient with CVerifyPeerUseEnvVars":
      const port = 12346.Port
      let t = spawn runServer(port)
      sleep(100)

      putEnv("SSL_CERT_FILE", getCurrentDir() / certFile)
      var client = newHttpClient(sslContext=newContext(verifyMode=CVerifyPeerUseEnvVars))
      try:
        log "client: connect"
        discard client.getContent("https://127.0.0.1:12346")
      except:
        let msg = getCurrentExceptionMsg()
        log "client: exception: " & msg
        log "getContent should not have raised an exception"
        fail()