Postfix3.3.1
tls_session.c
[詳解]
1 /*++
2 /* NAME
3 /* tls_session
4 /* SUMMARY
5 /* TLS client and server session routines
6 /* SYNOPSIS
7 /* #include <tls.h>
8 /*
9 /* void tls_session_stop(ctx, stream, timeout, failure, TLScontext)
10 /* TLS_APPL_STATE *ctx;
11 /* VSTREAM *stream;
12 /* int timeout;
13 /* int failure;
14 /* TLS_SESS_STATE *TLScontext;
15 /*
16 /* VSTRING *tls_session_passivate(session)
17 /* SSL_SESSION *session;
18 /*
19 /* SSL_SESSION *tls_session_activate(session_data, session_data_len)
20 /* char *session_data;
21 /* int session_data_len;
22 /* DESCRIPTION
23 /* tls_session_stop() implements the tls_server_shutdown()
24 /* and the tls_client_shutdown() routines.
25 /*
26 /* tls_session_passivate() converts an SSL_SESSION object to
27 /* VSTRING. The result is a null pointer in case of problems,
28 /* otherwise it should be disposed of with vstring_free().
29 /*
30 /* tls_session_activate() reanimates a passivated SSL_SESSION object.
31 /* The result is a null pointer in case of problems,
32 /* otherwise it should be disposed of with SSL_SESSION_free().
33 /* LICENSE
34 /* .ad
35 /* .fi
36 /* This software is free. You can do with it whatever you want.
37 /* The original author kindly requests that you acknowledge
38 /* the use of his software.
39 /* AUTHOR(S)
40 /* Originally written by:
41 /* Lutz Jaenicke
42 /* BTU Cottbus
43 /* Allgemeine Elektrotechnik
44 /* Universitaetsplatz 3-4
45 /* D-03044 Cottbus, Germany
46 /*
47 /* Updated by:
48 /* Wietse Venema
49 /* IBM T.J. Watson Research
50 /* P.O. Box 704
51 /* Yorktown Heights, NY 10598, USA
52 /*
53 /* Victor Duchovni
54 /* Morgan Stanley
55 /*--*/
56 
57 /* System library. */
58 
59 #include <sys_defs.h>
60 
61 #ifdef USE_TLS
62 
63 /* Utility library. */
64 
65 #include <vstream.h>
66 #include <msg.h>
67 #include <mymalloc.h>
68 
69 /* TLS library. */
70 
71 #define TLS_INTERNAL
72 #include <tls.h>
73 
74 /* Application-specific. */
75 
76 #define STR vstring_str
77 
78 /* tls_session_stop - shut down the TLS connection and reset state */
79 
80 void tls_session_stop(TLS_APPL_STATE *unused_ctx, VSTREAM *stream, int timeout,
81  int failure, TLS_SESS_STATE *TLScontext)
82 {
83  const char *myname = "tls_session_stop";
84  int retval;
85 
86  /*
87  * Sanity check.
88  */
89  if (TLScontext == 0)
90  msg_panic("%s: stream has no active TLS context", myname);
91 
92  /*
93  * Perform SSL_shutdown() twice, as the first attempt will send out the
94  * shutdown alert but it will not wait for the peer's shutdown alert.
95  * Therefore, when we are the first party to send the alert, we must call
96  * SSL_shutdown() again. On failure we don't want to resume the session,
97  * so we will not perform SSL_shutdown() and the session will be removed
98  * as being bad.
99  */
100  if (!failure) {
101  retval = tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext);
102  if (retval == 0)
103  tls_bio_shutdown(vstream_fileno(stream), timeout, TLScontext);
104  }
105  tls_free_context(TLScontext);
106  tls_stream_stop(stream);
107 }
108 
109 /* tls_session_passivate - passivate SSL_SESSION object */
110 
111 VSTRING *tls_session_passivate(SSL_SESSION *session)
112 {
113  const char *myname = "tls_session_passivate";
114  int estimate;
115  int actual_size;
116  VSTRING *session_data;
117  unsigned char *ptr;
118 
119  /*
120  * First, find out how much memory is needed for the passivated
121  * SSL_SESSION object.
122  */
123  estimate = i2d_SSL_SESSION(session, (unsigned char **) 0);
124  if (estimate <= 0) {
125  msg_warn("%s: i2d_SSL_SESSION failed: unable to cache session", myname);
126  return (0);
127  }
128 
129  /*
130  * Passivate the SSL_SESSION object. The use of a VSTRING is slightly
131  * wasteful but is convenient to combine data and length.
132  */
133  session_data = vstring_alloc(estimate);
134  ptr = (unsigned char *) STR(session_data);
135  actual_size = i2d_SSL_SESSION(session, &ptr);
136  if (actual_size != estimate) {
137  msg_warn("%s: i2d_SSL_SESSION failed: unable to cache session", myname);
138  vstring_free(session_data);
139  return (0);
140  }
141  VSTRING_AT_OFFSET(session_data, actual_size); /* XXX not public */
142 
143  return (session_data);
144 }
145 
146 /* tls_session_activate - activate passivated session */
147 
148 SSL_SESSION *tls_session_activate(const char *session_data, int session_data_len)
149 {
150 #if (OPENSSL_VERSION_NUMBER < 0x0090707fL)
151 #define BOGUS_CONST
152 #else
153 #define BOGUS_CONST const
154 #endif
155  SSL_SESSION *session;
156  BOGUS_CONST unsigned char *ptr;
157 
158  /*
159  * Activate the SSL_SESSION object.
160  */
161  ptr = (BOGUS_CONST unsigned char *) session_data;
162  session = d2i_SSL_SESSION((SSL_SESSION **) 0, &ptr, session_data_len);
163  if (!session)
164  tls_print_errors();
165 
166  return (session);
167 }
168 
169 #endif
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define STR(x)
Definition: anvil.c:518
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
#define vstream_fileno(vp)
Definition: vstream.h:115
#define VSTRING_AT_OFFSET(vp, offset)
Definition: vstring.h:92