gnutls: rearrange some code to avoid a warning
[platform/upstream/glib-networking.git] / tls / gnutls / gtlsserverconnection-gnutls.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2010 Red Hat, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22 #include "glib.h"
23
24 #include <errno.h>
25 #include <gnutls/gnutls.h>
26 #include <gnutls/x509.h>
27
28 #include "gtlsserverconnection-gnutls.h"
29 #include "gtlscertificate-gnutls.h"
30 #include <glib/gi18n-lib.h>
31
32 enum
33 {
34   PROP_0,
35   PROP_AUTHENTICATION_MODE
36 };
37
38 static void g_tls_server_connection_gnutls_get_property (GObject    *object,
39                                                          guint       prop_id,
40                                                          GValue     *value,
41                                                          GParamSpec *pspec);
42 static void g_tls_server_connection_gnutls_set_property (GObject      *object,
43                                                          guint         prop_id,
44                                                          const GValue *value,
45                                                          GParamSpec   *pspec);
46
47 static void     g_tls_server_connection_gnutls_begin_handshake  (GTlsConnectionGnutls  *conn);
48 static gboolean g_tls_server_connection_gnutls_verify_peer      (GTlsConnectionGnutls  *gnutls,
49                                                                  GTlsCertificate       *peer_certificate,
50                                                                  GTlsCertificateFlags  *errors);
51 static void     g_tls_server_connection_gnutls_finish_handshake (GTlsConnectionGnutls  *conn,
52                                                                  GError               **inout_error);
53
54 static void g_tls_server_connection_gnutls_server_connection_interface_init (GTlsServerConnectionInterface *iface);
55
56 static int g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t  session,
57                                                              gnutls_retr_st   *st);
58
59 G_DEFINE_TYPE_WITH_CODE (GTlsServerConnectionGnutls, g_tls_server_connection_gnutls, G_TYPE_TLS_CONNECTION_GNUTLS,
60                          G_IMPLEMENT_INTERFACE (G_TYPE_TLS_SERVER_CONNECTION,
61                                                 g_tls_server_connection_gnutls_server_connection_interface_init))
62
63 struct _GTlsServerConnectionGnutlsPrivate
64 {
65   GTlsAuthenticationMode authentication_mode;
66 };
67
68 static void
69 g_tls_server_connection_gnutls_class_init (GTlsServerConnectionGnutlsClass *klass)
70 {
71   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
72   GTlsConnectionGnutlsClass *connection_gnutls_class = G_TLS_CONNECTION_GNUTLS_CLASS (klass);
73
74   g_type_class_add_private (klass, sizeof (GTlsServerConnectionGnutlsPrivate));
75
76   gobject_class->get_property = g_tls_server_connection_gnutls_get_property;
77   gobject_class->set_property = g_tls_server_connection_gnutls_set_property;
78
79   connection_gnutls_class->begin_handshake  = g_tls_server_connection_gnutls_begin_handshake;
80   connection_gnutls_class->verify_peer      = g_tls_server_connection_gnutls_verify_peer;
81   connection_gnutls_class->finish_handshake = g_tls_server_connection_gnutls_finish_handshake;
82
83   g_object_class_override_property (gobject_class, PROP_AUTHENTICATION_MODE, "authentication-mode");
84 }
85
86 static void
87 g_tls_server_connection_gnutls_server_connection_interface_init (GTlsServerConnectionInterface *iface)
88 {
89 }
90
91 static void
92 g_tls_server_connection_gnutls_init (GTlsServerConnectionGnutls *gnutls)
93 {
94   gnutls_certificate_credentials_t creds;
95
96   gnutls->priv = G_TYPE_INSTANCE_GET_PRIVATE (gnutls, G_TYPE_TLS_SERVER_CONNECTION_GNUTLS, GTlsServerConnectionGnutlsPrivate);
97
98   creds = g_tls_connection_gnutls_get_credentials (G_TLS_CONNECTION_GNUTLS (gnutls));
99   gnutls_certificate_server_set_retrieve_function (creds, g_tls_server_connection_gnutls_retrieve_function);
100 }
101
102 static void
103 g_tls_server_connection_gnutls_get_property (GObject    *object,
104                                              guint       prop_id,
105                                              GValue     *value,
106                                              GParamSpec *pspec)
107 {
108   GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (object);
109
110   switch (prop_id)
111     {
112     case PROP_AUTHENTICATION_MODE:
113       g_value_set_enum (value, gnutls->priv->authentication_mode);
114       break;
115       
116     default:
117       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
118     }
119 }
120
121 static void
122 g_tls_server_connection_gnutls_set_property (GObject      *object,
123                                              guint         prop_id,
124                                              const GValue *value,
125                                              GParamSpec   *pspec)
126 {
127   GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (object);
128
129   switch (prop_id)
130     {
131     case PROP_AUTHENTICATION_MODE:
132       gnutls->priv->authentication_mode = g_value_get_enum (value);
133       break;
134
135     default:
136       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
137     }
138 }
139
140 static int
141 g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t  session,
142                                                   gnutls_retr_st   *st)
143 {
144   g_tls_connection_gnutls_get_certificate (gnutls_transport_get_ptr (session), st);
145   return 0;
146 }
147
148 static void
149 g_tls_server_connection_gnutls_begin_handshake (GTlsConnectionGnutls *conn)
150 {
151   GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (conn);
152   gnutls_session_t session;
153   gnutls_certificate_request_t req_mode;
154
155   switch (gnutls->priv->authentication_mode)
156     {
157     case G_TLS_AUTHENTICATION_REQUESTED:
158       req_mode = GNUTLS_CERT_REQUEST;
159       break;
160     case G_TLS_AUTHENTICATION_REQUIRED:
161       req_mode = GNUTLS_CERT_REQUIRE;
162       break;
163     default:
164       req_mode = GNUTLS_CERT_IGNORE;
165       break;
166     }
167
168   session = g_tls_connection_gnutls_get_session (conn);
169   gnutls_certificate_server_set_request (session, req_mode);
170 }
171
172 static gboolean
173 g_tls_server_connection_gnutls_verify_peer (GTlsConnectionGnutls  *gnutls,
174                                             GTlsCertificate       *peer_certificate,
175                                             GTlsCertificateFlags  *errors)
176 {
177   return g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
178                                                    peer_certificate, *errors);
179 }
180
181 static void
182 g_tls_server_connection_gnutls_finish_handshake (GTlsConnectionGnutls  *gnutls,
183                                                  GError               **inout_error)
184 {
185 }