1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
|
#
#
# 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 {.final.}
ssl: PSSL
bio: PBIO
proc connect*(sock: var TSecureSocket, address: string,
port: int): Int =
## Connects to the specified `address` on the specified `port`.
## Returns the result of the certificate validation.
SslLoadErrorStrings()
ERR_load_BIO_strings()
if SSL_library_init() != 1:
OSError()
var ctx = SSL_CTX_new(SSLv23_client_method())
if ctx == nil:
ERR_print_errors_fp(stderr)
OSError()
#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)
if BIO_get_ssl(sock.bio, addr(sock.ssl)) == 0:
OSError()
if BIO_set_conn_hostname(sock.bio, address & ":" & $port) != 1:
OSError()
if BIO_do_connect(sock.bio) <= 0:
ERR_print_errors_fp(stderr)
OSError()
result = 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
|