Added an openssl wrapper, ssl module and smtp module.
This commit is contained in:
parent
56e963b465
commit
d68782cd38
3 changed files with 643 additions and 0 deletions
81
lib/impure/ssl.nim
Normal file
81
lib/impure/ssl.nim
Normal file
|
|
@ -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
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue