Skip to content

Instantly share code, notes, and snippets.

@tiffany352
Created December 13, 2011 22:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tiffany352/1474150 to your computer and use it in GitHub Desktop.
Save tiffany352/1474150 to your computer and use it in GitHub Desktop.
/* Title: std.ssl
Binds GnuTLS for easy interface with std.socket */
module std.ssl;
import std.string, c.unistd, c.sys.socket, c.netdb, c.string, c.errno, c.gnutls.gnutls, std.socket;
pragma(lib,"gnutls");
enum AuthType {
Client,
Server,
AnonymousClient,
AnonymousServer
}
class GnuTLSSocket : Socket {
gnutls_session_t session;
AuthType auth;
string priorities;
void *cred;
void close() {
gnutls_bye(session,GNUTLS_SHUT_RDWR); // https://www.gnu.org/software/gnutls/manual/html_node/Core-TLS-API.html#gnutls_005finit
c.unistd.close(sockfd);
gnutls_deinit(session);
if auth==AuthType.AnonymousClient
gnutls_anon_free_client_credentials ( *(gnutls_anon_client_credentials_t*:cred) );
}
// init() not needed
// reuse not needed ?
/*Function: setup
Initialises the TLS connection.*/
void setup(AuthType a = AuthType.AnonymousClient, string p = "NORMAL") {
auth = a;
priorities = p;
}
void open(TcpAddress ta) {
// initialise socket
gnutls_init(&session,GNUTLS_CLIENT);
// set priorities
char *err;
gnutls_priority_set_direct(session,toStringz priorities,&err);
if err
raise new Error "gnutls_priority_set_direct failed: $(CToString err)";
// set up authentication
if auth == AuthType.AnonymousClient {
gnutls_anon_client_credentials_t anoncred;
cred = &anoncred;
gnutls_anon_allocate_client_credentials (&anoncred);
gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
}
// connect socket
auto res = c.sys.socket.connect (sockfd, sockaddr*:&ta.saddr, size-of type-of ta.saddr);
// bind gnutls to socket
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sockfd);
// handshake
res = gnutls_handshake (session);
}
int recv(byte[] buf) {
auto res = gnutls_record_recv(session, buf.ptr, buf.length);
if res <= 0
close;
return res;
}
int send(byte[] buf) {
auto res = gnutls_record_send(session, buf.ptr, buf.length);
if res<=0
close;
return res;
}
// sendAll not needed
void bind(Address addr) {
boundAddr = addr;
auto err = .bind(sockfd, addr.getAddrHandle());
if (err == -1)
raise new Error "While binding to $addr: $(CToString strerror errno)";
gnutls_init(&session,GNUTLS_SERVER);
}
void listen(int backlog = 4) {
}
Socket accept() using new Socket {
}
}
void gnutlsGlobalInit () {
int res=gnutls_global_init();
if res!=0
raise new Error "gnutls_global_init failed: $res";
}
void gnutlsGlobalExit () {
gnutls_global_deinit();
}
module test63;
import std.socket, std.ssl;
void main() {
gnutlsGlobalInit;
writeln "Connecting.";
GnuTLSSocket s = new GnuTLSSocket;
s.setup();
s.open(new TcpAddress("physibots.info",443));
byte[] p=new byte[] 1024;
writeln "receive: $(s.recv(p))";
writeln "======================================================";
writeln string:p;
s.close;
gnutlsGlobalExit;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment