1 /* 2 * ustream-ssl - library for SSL over ustream 3 * 4 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org> 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <string.h> 20 21 #include <libubox/ustream.h> 22 23 #include "ustream-ssl.h" 24 #include "openssl_bio_compat.h" 25 #include "ustream-internal.h" 26 27 static int 28 s_ustream_new(BIO *b) 29 { 30 BIO_set_init(b, 1); 31 BIO_set_data(b, NULL); 32 BIO_clear_flags(b, ~0); 33 return 1; 34 } 35 36 static int 37 s_ustream_free(BIO *b) 38 { 39 struct bio_ctx *ctx; 40 41 if (!b) 42 return 0; 43 44 ctx = (struct bio_ctx *)BIO_get_data(b); 45 if (ctx) 46 free(ctx); 47 48 BIO_set_data(b, NULL); 49 BIO_set_init(b, 0); 50 BIO_clear_flags(b, ~0); 51 return 1; 52 } 53 54 static int 55 s_ustream_read(BIO *b, char *buf, int len) 56 { 57 struct bio_ctx *ctx; 58 char *sbuf; 59 int slen; 60 61 if (!buf || len <= 0) 62 return 0; 63 64 ctx = (struct bio_ctx *)BIO_get_data(b); 65 if (!ctx || !ctx->stream) 66 return 0; 67 68 sbuf = ustream_get_read_buf(ctx->stream, &slen); 69 70 BIO_clear_retry_flags(b); 71 if (!slen) { 72 BIO_set_retry_read(b); 73 return -1; 74 } 75 76 if (slen > len) 77 slen = len; 78 79 memcpy(buf, sbuf, slen); 80 ustream_consume(ctx->stream, slen); 81 82 return slen; 83 } 84 85 static int 86 s_ustream_write(BIO *b, const char *buf, int len) 87 { 88 struct bio_ctx *ctx; 89 90 if (!buf || len <= 0) 91 return 0; 92 93 ctx = (struct bio_ctx *)BIO_get_data(b); 94 if (!ctx || !ctx->stream) 95 return 0; 96 97 if (ctx->stream->write_error) 98 return len; 99 100 return ustream_write(ctx->stream, buf, len, false); 101 } 102 103 static int 104 s_ustream_gets(BIO *b, char *buf, int len) 105 { 106 return -1; 107 } 108 109 static int 110 s_ustream_puts(BIO *b, const char *str) 111 { 112 return s_ustream_write(b, str, strlen(str)); 113 } 114 115 static long s_ustream_ctrl(BIO *b, int cmd, long num, void *ptr) 116 { 117 switch (cmd) { 118 case BIO_CTRL_FLUSH: 119 return 1; 120 default: 121 return 0; 122 }; 123 } 124 125 static BIO_METHOD *ustream_meth(void) 126 { 127 static BIO_METHOD *meth = NULL; 128 129 if (meth) 130 return meth; 131 132 meth = BIO_meth_new(100 | BIO_TYPE_SOURCE_SINK, "ustream"); 133 if (!meth) 134 return NULL; 135 136 BIO_meth_set_write(meth, s_ustream_write); 137 BIO_meth_set_read(meth, s_ustream_read); 138 BIO_meth_set_puts(meth, s_ustream_puts); 139 BIO_meth_set_gets(meth, s_ustream_gets); 140 BIO_meth_set_ctrl(meth, s_ustream_ctrl); 141 BIO_meth_set_create(meth, s_ustream_new); 142 BIO_meth_set_destroy(meth, s_ustream_free); 143 144 return meth; 145 } 146 147 static BIO *ustream_bio_new(struct ustream *s) 148 { 149 BIO_METHOD *meth = ustream_meth(); 150 struct bio_ctx *ctx; 151 BIO *bio; 152 153 if (!meth) 154 return NULL; 155 156 ctx = calloc(1, sizeof(struct bio_ctx)); 157 if (!ctx) 158 return NULL; 159 160 ctx->stream = s; 161 bio = BIO_new(meth); 162 if (!bio) { 163 free(ctx); 164 return NULL; 165 } 166 167 BIO_set_data(bio, ctx); 168 169 return bio; 170 } 171 172 static BIO *fd_bio_new(int fd) 173 { 174 BIO *bio = BIO_new(BIO_s_socket()); 175 176 if (!bio) 177 return NULL; 178 179 BIO_set_fd(bio, fd, BIO_NOCLOSE); 180 181 return bio; 182 } 183 184 __hidden void ustream_set_io(struct ustream_ssl *us) 185 { 186 BIO *bio; 187 188 if (us->conn) 189 bio = ustream_bio_new(us->conn); 190 else 191 bio = fd_bio_new(us->fd.fd); 192 193 if (bio) 194 SSL_set_bio(us->ssl, bio, bio); 195 } 196
This page was automatically generated by LXR 0.3.1. • OpenWrt