67 // done |
67 // done |
68 return SUCCESS; |
68 return SUCCESS; |
69 } |
69 } |
70 |
70 |
71 |
71 |
72 // XXX: errors |
72 err_t sock_gnutls_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err) |
73 struct sock_stream *sock_ssl_connect (const char *host, const char *service) |
|
74 { |
73 { |
75 int _err; |
74 struct sock_gnutls *sock = NULL; |
76 struct sock_gnutls *sock; |
|
77 struct sock_gnutls_client_ctx *ctx = &_sock_gnutls_client_ctx; |
75 struct sock_gnutls_client_ctx *ctx = &_sock_gnutls_client_ctx; |
78 |
76 |
79 // alloc |
77 // alloc |
80 if ((sock = calloc(1, sizeof(*sock))) == NULL) |
78 if ((sock = calloc(1, sizeof(*sock))) == NULL) |
81 errx(1, "calloc"); |
79 return SET_ERROR(err, ERR_CALLOC); |
82 |
80 |
83 // initialize |
81 // initialize base |
84 sock->base_tcp.base.type = &sock_gnutls_type; |
82 sock_stream_init(SOCK_GNUTLS_BASE(sock), &sock_gnutls_type); |
85 |
83 |
86 // initialize client session |
84 // initialize client session |
87 if ((_err = gnutls_init(&sock->session, GNUTLS_CLIENT)) < 0) |
85 if ((ERROR_EXTRA(err) = gnutls_init(&sock->session, GNUTLS_CLIENT)) < 0) |
88 errx(1, "gnutls_init: %s", gnutls_strerror(_err)); |
86 JUMP_SET_ERROR(err, ERR_GNUTLS_INIT); |
89 |
87 |
90 // ...default priority stuff |
88 // ...default priority stuff |
91 gnutls_set_default_priority(sock->session); |
89 if ((ERROR_EXTRA(err) = gnutls_set_default_priority(sock->session))) |
|
90 JUMP_SET_ERROR(err, ERR_GNUTLS_SET_DEFAULT_PRIORITY); |
92 |
91 |
93 // bind anon credentials |
92 // bind anon credentials |
94 gnutls_credentials_set(sock->session, GNUTLS_CRD_CERTIFICATE, ctx->xcred); |
93 if ((ERROR_EXTRA(err) = gnutls_credentials_set(sock->session, GNUTLS_CRD_CERTIFICATE, ctx->xcred))) |
|
94 JUMP_SET_ERROR(err, ERR_GNUTLS_CRED_SET); |
95 |
95 |
96 // TCP connect |
96 // TCP connect |
97 sock_tcp_init_connect(SOCK_GNUTLS_TCP(sock), host, service); |
97 if (sock_tcp_init_connect(SOCK_GNUTLS_TCP(sock), host, service)) |
|
98 JUMP_SET_ERROR_INFO(err, SOCK_GNUTLS_ERR(sock)); |
98 |
99 |
99 // bind default transport functions (recv/send) to use the TCP fd |
100 // bind default transport functions (recv/send) to use the TCP fd |
100 gnutls_transport_set_ptr(sock->session, (gnutls_transport_ptr_t) sock->base_tcp.fd); |
101 gnutls_transport_set_ptr(sock->session, (gnutls_transport_ptr_t) sock->base_tcp.fd); |
101 |
102 |
102 // perform the handshake |
103 // perform the handshake |
103 if ((_err = gnutls_handshake(sock->session)) < 0) |
104 if ((ERROR_EXTRA(err) = gnutls_handshake(sock->session)) < 0) |
104 _sock_gnutls_error(sock, "gnutls_handshake", _err); |
105 JUMP_SET_ERROR(err, ERR_GNUTLS_HANDSHAKE); |
105 |
106 |
106 // done |
107 // done |
107 return SOCK_GNUTLS_BASE(sock); |
108 *sock_ptr = SOCK_GNUTLS_BASE(sock); |
|
109 |
|
110 return SUCCESS; |
|
111 |
|
112 error: |
|
113 // XXX: cleanup |
|
114 |
|
115 return ERROR_CODE(err); |
108 } |
116 } |
109 |
117 |