summary refs log tree commit diff stats
path: root/lib/impure/ssl.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/impure/ssl.nim')
-rw-r--r--lib/impure/ssl.nim81
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim
new file mode 100644
index 000000000..469446daf
--- /dev/null
+++ b/lib/impure/ssl.nim
@@ -0,0 +1,81 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2010 Dominik Picheta
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module provides an easy to use sockets-style nimrod interface to the OpenSSL library.
+
+import openssl, strutils, os
+
+type
+  TSecureSocket* = object
+    ssl: PSSL
+    bio: PBIO
+
+proc connect*(sock: var TSecureSocket, address: string, port: int, certResult: var Int) =
+  ## Connects to the specified `address` on the specified `port`. `certResult` will become the result of the certificate validation.
+  SslLoadErrorStrings()
+  ERR_load_BIO_strings()
+  
+  assert(SSL_library_init() == 1)
+  
+  var ctx = SSL_CTX_new(SSLv23_client_method())
+  if ctx == nil:
+    ERR_print_errors_fp(stderr)
+    assert(False)
+    
+  #if SSL_CTX_load_verify_locations(ctx, "/tmp/openssl-0.9.8e/certs/vsign1.pem", NIL) == 0:
+  #  echo("Failed load verify locations")
+  #  ERR_print_errors_fp(stderr)
+  
+  sock.bio = BIO_new_ssl_connect(ctx)
+  assert(BIO_get_ssl(sock.bio, addr(sock.ssl)) != 0)
+
+  assert(BIO_set_conn_hostname(sock.bio, address & ":" & $port) == 1)
+  
+  if BIO_do_connect(sock.bio) <= 0:
+    ERR_print_errors_fp(stderr)
+    OSError()
+  
+  certResult = SSL_get_verify_result(sock.ssl)
+
+proc recvLine*(sock: TSecureSocket, line: var String): bool =
+  ## Acts in a similar fashion to the `recvLine` in the sockets module.
+  ## Returns false when no data is available to be read.
+  ## `Line` must be initialized and not nil!
+  setLen(line, 0)
+  while True:
+    var c: array[0..0, char]
+    var n = BIO_read(sock.bio, c, c.len)
+    if n <= 0: return False
+    if c[0] == '\r':
+      n = BIO_read(sock.bio, c, c.len)
+      if n > 0 and c[0] == '\L':
+        return True
+      elif n <= 0:
+        return False
+    elif c[0] == '\L': return True
+    add(line, c)
+
+
+proc send*(sock: TSecureSocket, data: string) =
+  ## Writes `data` to the socket.
+  if BIO_write(sock.bio, data, data.len()) <= 0:
+    OSError()
+
+when isMainModule:
+  var s: TSecureSocket
+  echo connect(s, "smtp.gmail.com", 465)
+  
+  #var buffer: array[0..255, char]
+  #echo BIO_read(bio, buffer, buffer.len)
+  var buffer: string = ""
+  
+  echo s.recvLine(buffer)
+  echo buffer 
+  echo buffer.len
+