summary refs log blame commit diff stats
path: root/lib/impure/ssl.nim
blob: 5b0e899f631d6ef087fdae1d92a67ccf25091057 (plain) (tree)
1
2
3
4
5
6
7
8
9

 
                                  
                                           




                                                   
                                                    
                                        


                                                                            
 
              
 


                            
                        

               
                                             
 
                                                      
                     
                                                                 
                                                      

                        
 
                             
                               
 


                                               
                               

                                        
                                                        

                                         
 
                                     
                                                
                               
 
                                                                 
                               
 

                                   
                               
 
                                          
 
                                                                   


                                                                       
                        
             
                            
                                                  
                           
                    
                                                
                                
                   
                  

                                  
                          

 
                                              
                                 
                                                   
                               
 
                                 


                               
                               
 
                                           
                     
                                        
 


                                         
 
                         
             
                 
 
#
#
#            Nim's Runtime Library
#        (c) Copyright 2012 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
## nim interface to the OpenSSL library.
##
## **Warning:** This module is deprecated, use the SSL procedures defined in
## the ``net`` module instead.

{.deprecated.}

import openssl, strutils, os

type
  SecureSocket* = object
    ssl: SslPtr
    bio: BIO
{.deprecated: [TSecureSocket: SecureSocket].}

proc connect*(sock: var SecureSocket, 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:
    raiseOSError(osLastError())

  var ctx = SSL_CTX_new(SSLv23_client_method())
  if ctx == nil:
    ERR_print_errors_fp(stderr)
    raiseOSError(osLastError())

  #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:
    raiseOSError(osLastError())

  if BIO_set_conn_hostname(sock.bio, address & ":" & $port) != 1:
    raiseOSError(osLastError())

  if BIO_do_connect(sock.bio) <= 0:
    ERR_print_errors_fp(stderr)
    raiseOSError(osLastError())

  result = SSL_get_verify_result(sock.ssl)

proc recvLine*(sock: SecureSocket, line: var TaintedString): 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.string, 0)
  while true:
    var c: array[0..0, char]
    var n = BIO_read(sock.bio, addr c, c.len.cint)
    if n <= 0: return false
    if c[0] == '\r':
      n = BIO_read(sock.bio, addr c, c.len.cint)
      if n > 0 and c[0] == '\L':
        return true
      elif n <= 0:
        return false
    elif c[0] == '\L': return true
    add(line.string, c[0])


proc send*(sock: SecureSocket, data: string) =
  ## Writes `data` to the socket.
  if BIO_write(sock.bio, data, data.len.cint) <= 0:
    raiseOSError(osLastError())

proc close*(sock: SecureSocket) =
  ## Closes the socket
  if BIO_free(sock.bio) <= 0:
    ERR_print_errors_fp(stderr)
    raiseOSError(osLastError())

when not defined(testing) and isMainModule:
  var s: SecureSocket
  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