spiped 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/ext/spiped/extconf.rb +3 -0
  3. data/ext/spiped/spiped-source/BUILDING +46 -0
  4. data/ext/spiped/spiped-source/CHANGELOG +44 -0
  5. data/ext/spiped/spiped-source/COPYRIGHT +33 -0
  6. data/ext/spiped/spiped-source/Makefile +47 -0
  7. data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
  8. data/ext/spiped/spiped-source/Makefile.inc +20 -0
  9. data/ext/spiped/spiped-source/Makefile.prog +23 -0
  10. data/ext/spiped/spiped-source/POSIX/README +10 -0
  11. data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
  12. data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
  13. data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
  14. data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
  15. data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
  16. data/ext/spiped/spiped-source/README +198 -0
  17. data/ext/spiped/spiped-source/STYLE +151 -0
  18. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
  19. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
  20. data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
  21. data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
  22. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
  23. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
  24. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
  25. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
  26. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
  27. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
  28. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
  29. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
  30. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
  31. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
  32. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
  33. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
  34. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
  35. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
  36. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
  37. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
  38. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
  39. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
  40. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
  41. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
  42. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
  43. data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
  44. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
  45. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
  46. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
  47. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
  48. data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
  49. data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
  50. data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
  51. data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
  52. data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
  53. data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
  54. data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
  55. data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
  56. data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
  57. data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
  58. data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
  59. data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
  60. data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
  61. data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
  62. data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
  63. data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
  64. data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
  65. data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
  66. data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
  67. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
  68. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
  69. data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
  70. data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
  71. data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
  72. data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
  73. data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
  74. data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
  75. data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
  76. data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
  77. data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
  78. data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
  79. data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
  80. data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
  81. data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
  82. data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
  83. data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
  84. data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
  85. data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
  86. data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
  87. data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
  88. data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
  89. data/ext/spiped/spiped-source/spipe/Makefile +90 -0
  90. data/ext/spiped/spiped-source/spipe/README +24 -0
  91. data/ext/spiped/spiped-source/spipe/main.c +178 -0
  92. data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
  93. data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
  94. data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
  95. data/ext/spiped/spiped-source/spiped/Makefile +98 -0
  96. data/ext/spiped/spiped-source/spiped/README +62 -0
  97. data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
  98. data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
  99. data/ext/spiped/spiped-source/spiped/main.c +267 -0
  100. data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
  101. data/lib/spiped.rb +3 -0
  102. metadata +143 -0
@@ -0,0 +1,330 @@
1
+ #include <assert.h>
2
+ #include <stdint.h>
3
+ #include <stdlib.h>
4
+ #include <string.h>
5
+
6
+ #include "crypto_entropy.h"
7
+ #include "network.h"
8
+
9
+ #include "proto_crypt.h"
10
+
11
+ #include "proto_handshake.h"
12
+
13
+ struct handshake_cookie {
14
+ int (* callback)(void *, struct proto_keys *, struct proto_keys *);
15
+ void * cookie;
16
+ int s;
17
+ int decr;
18
+ int nofps;
19
+ int requirefps;
20
+ const struct proto_secret * K;
21
+ uint8_t nonce_local[PCRYPT_NONCE_LEN];
22
+ uint8_t nonce_remote[PCRYPT_NONCE_LEN];
23
+ uint8_t dhmac_local[PCRYPT_DHMAC_LEN];
24
+ uint8_t dhmac_remote[PCRYPT_DHMAC_LEN];
25
+ uint8_t x[PCRYPT_X_LEN];
26
+ uint8_t yh_local[PCRYPT_YH_LEN];
27
+ uint8_t yh_remote[PCRYPT_YH_LEN];
28
+ void * read_cookie;
29
+ void * write_cookie;
30
+ };
31
+
32
+ static int callback_nonce_write(void *, ssize_t);
33
+ static int callback_nonce_read(void *, ssize_t);
34
+ static int gotnonces(struct handshake_cookie *);
35
+ static int dhread(struct handshake_cookie *);
36
+ static int callback_dh_read(void *, ssize_t);
37
+ static int dhwrite(struct handshake_cookie *);
38
+ static int callback_dh_write(void *, ssize_t);
39
+ static int handshakedone(struct handshake_cookie *);
40
+
41
+ /* The handshake failed. Call back and clean up. */
42
+ static int
43
+ handshakefail(struct handshake_cookie * H)
44
+ {
45
+ int rc;
46
+
47
+ /* Cancel any pending network read or write. */
48
+ if (H->read_cookie != NULL)
49
+ network_read_cancel(H->read_cookie);
50
+ if (H->write_cookie != NULL)
51
+ network_write_cancel(H->write_cookie);
52
+
53
+ /* Perform the callback. */
54
+ rc = (H->callback)(H->cookie, NULL, NULL);
55
+
56
+ /* Free the cookie. */
57
+ free(H);
58
+
59
+ /* Return status from callback. */
60
+ return (rc);
61
+ }
62
+
63
+ /**
64
+ * proto_handshake(s, decr, nofps, requirefps, K, callback, cookie):
65
+ * Perform a protocol handshake on socket ${s}. If ${decr} is non-zero we are
66
+ * at the receiving end of the connection; otherwise at the sending end. If
67
+ * ${nofps} is non-zero, perform a "weak" handshake without forward perfect
68
+ * secrecy. If ${requirefps} is non-zero, drop the connection if the other
69
+ * end attempts to perform a "weak" handshake. The shared protocol secret is
70
+ * ${K}. Upon completion, invoke ${callback}(${cookie}, f, r), where f
71
+ * contains the keys needed for the forward direction and r contains the keys
72
+ * needed for the reverse direction; or f = r = NULL if the handshake failed.
73
+ * Return a cookie which can be passed to proto_handshake_cancel to cancel the
74
+ * handshake.
75
+
76
+ */
77
+ void *
78
+ proto_handshake(int s, int decr, int nofps, int requirefps,
79
+ const struct proto_secret * K,
80
+ int (* callback)(void *, struct proto_keys *, struct proto_keys *),
81
+ void * cookie)
82
+ {
83
+ struct handshake_cookie * H;
84
+
85
+ /* Bake a cookie. */
86
+ if ((H = malloc(sizeof(struct handshake_cookie))) == NULL)
87
+ goto err0;
88
+ H->callback = callback;
89
+ H->cookie = cookie;
90
+ H->s = s;
91
+ H->decr = decr;
92
+ H->nofps = nofps;
93
+ H->requirefps = requirefps;
94
+ H->K = K;
95
+
96
+ /* Generate a 32-byte connection nonce. */
97
+ if (crypto_entropy_read(H->nonce_local, 32))
98
+ goto err1;
99
+
100
+ /* Send our nonce. */
101
+ if ((H->write_cookie = network_write(s, H->nonce_local, 32, 32,
102
+ callback_nonce_write, H)) == NULL)
103
+ goto err1;
104
+
105
+ /* Read the other party's nonce. */
106
+ if ((H->read_cookie = network_read(s, H->nonce_remote, 32, 32,
107
+ callback_nonce_read, H)) == NULL)
108
+ goto err2;
109
+
110
+ /* Success! */
111
+ return (H);
112
+
113
+ err2:
114
+ network_write_cancel(H->write_cookie);
115
+ err1:
116
+ free(H);
117
+ err0:
118
+ /* Failure! */
119
+ return (NULL);
120
+ }
121
+
122
+ /* We've written our nonce. */
123
+ static int
124
+ callback_nonce_write(void * cookie, ssize_t len)
125
+ {
126
+ struct handshake_cookie * H = cookie;
127
+
128
+ /* This write is no longer pending. */
129
+ H->write_cookie = NULL;
130
+
131
+ /* Did we successfully write? */
132
+ if (len < 32)
133
+ return (handshakefail(H));
134
+
135
+ /* If the nonce read is also done, move on to the next step. */
136
+ if (H->read_cookie == NULL)
137
+ return (gotnonces(H));
138
+
139
+ /* Nothing to do. */
140
+ return (0);
141
+ }
142
+
143
+ /* We've read a nonce. */
144
+ static int
145
+ callback_nonce_read(void * cookie, ssize_t len)
146
+ {
147
+ struct handshake_cookie * H = cookie;
148
+
149
+ /* This read is no longer pending. */
150
+ H->read_cookie = NULL;
151
+
152
+ /* Did we successfully read? */
153
+ if (len < 32)
154
+ return (handshakefail(H));
155
+
156
+ /* If the nonce write is also done, move on to the next step. */
157
+ if (H->write_cookie == NULL)
158
+ return (gotnonces(H));
159
+
160
+ /* Nothing to do. */
161
+ return (0);
162
+ }
163
+
164
+ /* We have two nonces. Start the DH exchange. */
165
+ static int
166
+ gotnonces(struct handshake_cookie * H)
167
+ {
168
+
169
+ /* Compute the diffie-hellman parameter MAC keys. */
170
+ proto_crypt_dhmac(H->K, H->nonce_local, H->nonce_remote,
171
+ H->dhmac_local, H->dhmac_remote, H->decr);
172
+
173
+ /*
174
+ * If we're the server, we need to read the client's diffie-hellman
175
+ * parameter. If we're the client, we need to generate and send our
176
+ * diffie-hellman parameter.
177
+ */
178
+ if (H->decr)
179
+ return (dhread(H));
180
+ else
181
+ return (dhwrite(H));
182
+
183
+ /* NOTREACHED */
184
+ }
185
+
186
+ /* Read a diffie-hellman parameter. */
187
+ static int
188
+ dhread(struct handshake_cookie * H)
189
+ {
190
+
191
+ /* Read the remote signed diffie-hellman parameter. */
192
+ if ((H->read_cookie = network_read(H->s, H->yh_remote, PCRYPT_YH_LEN,
193
+ PCRYPT_YH_LEN, callback_dh_read, H)) == NULL)
194
+ goto err0;
195
+
196
+ /* Success! */
197
+ return (0);
198
+
199
+ err0:
200
+ /* Failure! */
201
+ return (-1);
202
+ }
203
+
204
+ /* We have read a diffie-hellman parameter. */
205
+ static int
206
+ callback_dh_read(void * cookie, ssize_t len)
207
+ {
208
+ struct handshake_cookie * H = cookie;
209
+
210
+ /* This read is no longer pending. */
211
+ H->read_cookie = NULL;
212
+
213
+ /* Did we successfully read? */
214
+ if (len < PCRYPT_YH_LEN)
215
+ return (handshakefail(H));
216
+
217
+ /* Is the value we read valid? */
218
+ if (proto_crypt_dh_validate(H->yh_remote, H->dhmac_remote,
219
+ H->requirefps))
220
+ return (handshakefail(H));
221
+
222
+ /*
223
+ * If we're the server, we need to send our diffie-hellman parameter
224
+ * next. If we're the client, move on to the final computation.
225
+ */
226
+ if (H->decr)
227
+ return (dhwrite(H));
228
+ else
229
+ return (handshakedone(H));
230
+
231
+ /* NOTREACHED */
232
+ }
233
+
234
+ /* Generate and write a diffie-hellman parameter. */
235
+ static int
236
+ dhwrite(struct handshake_cookie * H)
237
+ {
238
+
239
+ /* Generate a signed diffie-hellman parameter. */
240
+ if (proto_crypt_dh_generate(H->yh_local, H->x, H->dhmac_local,
241
+ H->nofps))
242
+ goto err0;
243
+
244
+ /* Write our signed diffie-hellman parameter. */
245
+ if ((H->write_cookie = network_write(H->s, H->yh_local, PCRYPT_YH_LEN,
246
+ PCRYPT_YH_LEN, callback_dh_write, H)) == NULL)
247
+ goto err0;
248
+
249
+ /* Success! */
250
+ return (0);
251
+
252
+ err0:
253
+ /* Failure! */
254
+ return (-1);
255
+ }
256
+
257
+ /* We have written our diffie-hellman parameter. */
258
+ static int
259
+ callback_dh_write(void * cookie, ssize_t len)
260
+ {
261
+ struct handshake_cookie * H = cookie;
262
+
263
+ /* This write is no longer pending. */
264
+ H->write_cookie = NULL;
265
+
266
+ /* Did we successfully write? */
267
+ if (len < PCRYPT_YH_LEN)
268
+ return (handshakefail(H));
269
+
270
+ /*
271
+ * If we're the server, move on to the final computation. If we're
272
+ * the client, we need to read the server's parameter next.
273
+ */
274
+ if (H->decr)
275
+ return (handshakedone(H));
276
+ else
277
+ return (dhread(H));
278
+
279
+ /* NOTREACHED */
280
+ }
281
+
282
+ /* We've got all the bits; do the final computation and callback. */
283
+ static int
284
+ handshakedone(struct handshake_cookie * H)
285
+ {
286
+ struct proto_keys * c;
287
+ struct proto_keys * s;
288
+ int rc;
289
+
290
+ /* Sanity-check: There should be no callbacks in progress. */
291
+ assert(H->read_cookie == NULL);
292
+ assert(H->write_cookie == NULL);
293
+
294
+ /* Perform the final computation. */
295
+ if (proto_crypt_mkkeys(H->K, H->nonce_local, H->nonce_remote,
296
+ H->yh_remote, H->x, H->nofps, H->decr, &c, &s))
297
+ goto err0;
298
+
299
+ /* Perform the callback. */
300
+ rc = (H->callback)(H->cookie, c, s);
301
+
302
+ /* Free the cookie. */
303
+ free(H);
304
+
305
+ /* Return status code from callback. */
306
+ return (rc);
307
+
308
+ err0:
309
+ /* Failure! */
310
+ return (-1);
311
+ }
312
+
313
+ /**
314
+ * proto_handshake_cancel(cookie):
315
+ * Cancel the handshake for which proto_handshake returned ${cookie}.
316
+ */
317
+ void
318
+ proto_handshake_cancel(void * cookie)
319
+ {
320
+ struct handshake_cookie * H = cookie;
321
+
322
+ /* Cancel any in-progress network operations. */
323
+ if (H->read_cookie != NULL)
324
+ network_read_cancel(H->read_cookie);
325
+ if (H->write_cookie != NULL)
326
+ network_write_cancel(H->write_cookie);
327
+
328
+ /* Free the cookie. */
329
+ free(H);
330
+ }
@@ -0,0 +1,30 @@
1
+ #ifndef _PROTO_HANDSHAKE_H_
2
+ #define _PROTO_HANDSHAKE_H_
3
+
4
+ /* Opaque structures. */
5
+ struct proto_keys;
6
+ struct proto_secret;
7
+
8
+ /**
9
+ * proto_handshake(s, decr, nofps, requirefps, K, callback, cookie):
10
+ * Perform a protocol handshake on socket ${s}. If ${decr} is non-zero we are
11
+ * at the receiving end of the connection; otherwise at the sending end. If
12
+ * ${nofps} is non-zero, perform a "weak" handshake without forward perfect
13
+ * secrecy. If ${requirefps} is non-zero, drop the connection if the other
14
+ * end attempts to perform a "weak" handshake. The shared protocol secret is
15
+ * ${K}. Upon completion, invoke ${callback}(${cookie}, f, r), where f
16
+ * contains the keys needed for the forward direction and r contains the keys
17
+ * needed for the reverse direction; or f = r = NULL if the handshake failed.
18
+ * Return a cookie which can be passed to proto_handshake_cancel to cancel the
19
+ * handshake.
20
+ */
21
+ void * proto_handshake(int, int, int, int, const struct proto_secret *,
22
+ int (*)(void *, struct proto_keys *, struct proto_keys *), void *);
23
+
24
+ /**
25
+ * proto_handshake_cancel(cookie):
26
+ * Cancel the handshake for which proto_handshake returned ${cookie}.
27
+ */
28
+ void proto_handshake_cancel(void *);
29
+
30
+ #endif /* !_PROTO_HANDSHAKE_H_ */
@@ -0,0 +1,202 @@
1
+ #include <sys/types.h>
2
+ #include <sys/socket.h>
3
+
4
+ #include <stdint.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <unistd.h>
8
+
9
+ #include "network.h"
10
+
11
+ #include "proto_crypt.h"
12
+
13
+ #include "proto_pipe.h"
14
+
15
+ struct pipe_cookie {
16
+ int (* callback)(void *);
17
+ void * cookie;
18
+ int * status;
19
+ int s_in;
20
+ int s_out;
21
+ int decr;
22
+ struct proto_keys * k;
23
+ uint8_t dbuf[PCRYPT_MAXDSZ];
24
+ uint8_t ebuf[PCRYPT_ESZ];
25
+ void * read_cookie;
26
+ void * write_cookie;
27
+ ssize_t wlen;
28
+ };
29
+
30
+ static int callback_pipe_read(void *, ssize_t);
31
+ static int callback_pipe_write(void *, ssize_t);
32
+
33
+ /**
34
+ * proto_pipe(s_in, s_out, decr, k, status, callback, cookie):
35
+ * Read bytes from ${s_in} and write them to ${s_out}. If ${decr} is non-zero
36
+ * then use ${k} to decrypt the bytes; otherwise use ${k} to encrypt them.
37
+ * If EOF is read, set ${status} to 0, and if an error is encountered set
38
+ * ${status} to -1; in either case, invoke ${callback}(${cookie}). Return a
39
+ * cookie which can be passed to proto_pipe_cancel.
40
+ */
41
+ void *
42
+ proto_pipe(int s_in, int s_out, int decr, struct proto_keys * k,
43
+ int * status, int (* callback)(void *), void * cookie)
44
+ {
45
+ struct pipe_cookie * P;
46
+
47
+ /* Bake a cookie. */
48
+ if ((P = malloc(sizeof(struct pipe_cookie))) == NULL)
49
+ goto err0;
50
+ P->callback = callback;
51
+ P->cookie = cookie;
52
+ P->status = status;
53
+ P->s_in = s_in;
54
+ P->s_out = s_out;
55
+ P->decr = decr;
56
+ P->k = k;
57
+ P->read_cookie = NULL;
58
+ P->write_cookie = NULL;
59
+
60
+ /* Start reading. */
61
+ if (P->decr) {
62
+ if ((P->read_cookie = network_read(P->s_in, P->ebuf,
63
+ PCRYPT_ESZ, PCRYPT_ESZ, callback_pipe_read, P)) == NULL)
64
+ goto err1;
65
+ } else {
66
+ if ((P->read_cookie = network_read(P->s_in, P->dbuf,
67
+ PCRYPT_MAXDSZ, 1, callback_pipe_read, P)) == NULL)
68
+ goto err1;
69
+ }
70
+
71
+ /* Success! */
72
+ return (P);
73
+
74
+ err1:
75
+ free(P);
76
+ err0:
77
+ /* Failure! */
78
+ return (NULL);
79
+ }
80
+
81
+ /* Some data has been read. */
82
+ static int
83
+ callback_pipe_read(void * cookie, ssize_t len)
84
+ {
85
+ struct pipe_cookie * P = cookie;
86
+
87
+ /* This read is no longer in progress. */
88
+ P->read_cookie = NULL;
89
+
90
+ /* Did we read EOF? */
91
+ if (len == 0)
92
+ goto eof;
93
+
94
+ /* Did the read fail? */
95
+ if (len == -1)
96
+ goto fail;
97
+
98
+ /* Did a packet read end prematurely? */
99
+ if ((P->decr) && (len < PCRYPT_ESZ))
100
+ goto fail;
101
+
102
+ /* Encrypt or decrypt the data. */
103
+ if (P->decr) {
104
+ if ((P->wlen = proto_crypt_dec(P->ebuf, P->dbuf, P->k)) == -1)
105
+ goto fail;
106
+ } else {
107
+ proto_crypt_enc(P->dbuf, len, P->ebuf, P->k);
108
+ P->wlen = PCRYPT_ESZ;
109
+ }
110
+
111
+ /* Write the encrypted or decrypted data. */
112
+ if (P->decr) {
113
+ if ((P->write_cookie = network_write(P->s_out, P->dbuf,
114
+ P->wlen, P->wlen, callback_pipe_write, P)) == NULL)
115
+ goto err0;
116
+ } else {
117
+ if ((P->write_cookie = network_write(P->s_out, P->ebuf,
118
+ P->wlen, P->wlen, callback_pipe_write, P)) == NULL)
119
+ goto err0;
120
+ }
121
+
122
+ /* Success! */
123
+ return (0);
124
+
125
+ fail:
126
+ /* Record that this connection is broken. */
127
+ *(P->status) = -1;
128
+
129
+ /* Inform the upstream that our status has changed. */
130
+ return ((P->callback)(P->cookie));
131
+
132
+ eof:
133
+ /* We aren't going to write any more. */
134
+ shutdown(P->s_out, SHUT_WR);
135
+
136
+ /* Record that we have reached EOF. */
137
+ *(P->status) = 0;
138
+
139
+ /* Inform the upstream that our status has changed. */
140
+ return ((P->callback)(P->cookie));
141
+
142
+ err0:
143
+ /* Failure! */
144
+ return (-1);
145
+ }
146
+
147
+ static int
148
+ callback_pipe_write(void * cookie, ssize_t len)
149
+ {
150
+ struct pipe_cookie * P = cookie;
151
+
152
+ /* This write is no longer in progress. */
153
+ P->write_cookie = NULL;
154
+
155
+ /* Did we fail to write everything? */
156
+ if (len < P->wlen)
157
+ goto fail;
158
+
159
+ /* Launch another read. */
160
+ if (P->decr) {
161
+ if ((P->read_cookie = network_read(P->s_in, P->ebuf,
162
+ PCRYPT_ESZ, PCRYPT_ESZ, callback_pipe_read, P)) == NULL)
163
+ goto err0;
164
+ } else {
165
+ if ((P->read_cookie = network_read(P->s_in, P->dbuf,
166
+ PCRYPT_MAXDSZ, 1, callback_pipe_read, P)) == NULL)
167
+ goto err0;
168
+ }
169
+
170
+ /* Success! */
171
+ return (0);
172
+
173
+ fail:
174
+ /* Record that this connection is broken. */
175
+ *(P->status) = -1;
176
+
177
+ /* Inform the upstream that our status has changed. */
178
+ return ((P->callback)(P->cookie));
179
+
180
+ err0:
181
+ /* Failure! */
182
+ return (-1);
183
+ }
184
+
185
+ /**
186
+ * proto_pipe_cancel(cookie):
187
+ * Shut down the pipe created by proto_pipe for which ${cookie} was returned.
188
+ */
189
+ void
190
+ proto_pipe_cancel(void * cookie)
191
+ {
192
+ struct pipe_cookie * P = cookie;
193
+
194
+ /* If a read or write is in progress, cancel it. */
195
+ if (P->read_cookie)
196
+ network_read_cancel(P->read_cookie);
197
+ if (P->write_cookie)
198
+ network_write_cancel(P->write_cookie);
199
+
200
+ /* Free the cookie. */
201
+ free(P);
202
+ }