diff options
Diffstat (limited to 'lib/impure/ssl.nim')
-rw-r--r-- | lib/impure/ssl.nim | 81 |
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 + |