1 /* 2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <errno.h> 12 13 #include "bio_lcl.h" 14 15 #if defined(OPENSSL_NO_POSIX_IO) 16 /* 17 * Dummy placeholder for BIO_s_fd... 18 */ 19 BIO *BIO_new_fd(int fd, int close_flag) 20 { 21 return NULL; 22 } 23 24 int BIO_fd_non_fatal_error(int err) 25 { 26 return 0; 27 } 28 29 int BIO_fd_should_retry(int i) 30 { 31 return 0; 32 } 33 34 const BIO_METHOD *BIO_s_fd(void) 35 { 36 return NULL; 37 } 38 #else 39 /* 40 * As for unconditional usage of "UPLINK" interface in this module. 41 * Trouble is that unlike Unix file descriptors [which are indexes 42 * in kernel-side per-process table], corresponding descriptors on 43 * platforms which require "UPLINK" interface seem to be indexes 44 * in a user-land, non-global table. Well, in fact they are indexes 45 * in stdio _iob[], and recall that _iob[] was the very reason why 46 * "UPLINK" interface was introduced in first place. But one way on 47 * another. Neither libcrypto or libssl use this BIO meaning that 48 * file descriptors can only be provided by application. Therefore 49 * "UPLINK" calls are due... 50 */ 51 static int fd_write(BIO *h, const char *buf, int num); 52 static int fd_read(BIO *h, char *buf, int size); 53 static int fd_puts(BIO *h, const char *str); 54 static int fd_gets(BIO *h, char *buf, int size); 55 static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); 56 static int fd_new(BIO *h); 57 static int fd_free(BIO *data); 58 int BIO_fd_should_retry(int s); 59 60 static const BIO_METHOD methods_fdp = { 61 BIO_TYPE_FD, 62 "file descriptor", 63 /* TODO: Convert to new style write function */ 64 bwrite_conv, 65 fd_write, 66 /* TODO: Convert to new style read function */ 67 bread_conv, 68 fd_read, 69 fd_puts, 70 fd_gets, 71 fd_ctrl, 72 fd_new, 73 fd_free, 74 NULL, /* fd_callback_ctrl */ 75 }; 76 77 const BIO_METHOD *BIO_s_fd(void) 78 { 79 return &methods_fdp; 80 } 81 82 BIO *BIO_new_fd(int fd, int close_flag) 83 { 84 BIO *ret; 85 ret = BIO_new(BIO_s_fd()); 86 if (ret == NULL) 87 return NULL; 88 BIO_set_fd(ret, fd, close_flag); 89 return ret; 90 } 91 92 static int fd_new(BIO *bi) 93 { 94 bi->init = 0; 95 bi->num = -1; 96 bi->ptr = NULL; 97 bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */ 98 return 1; 99 } 100 101 static int fd_free(BIO *a) 102 { 103 if (a == NULL) 104 return 0; 105 if (a->shutdown) { 106 if (a->init) { 107 UP_close(a->num); 108 } 109 a->init = 0; 110 a->flags = BIO_FLAGS_UPLINK; 111 } 112 return 1; 113 } 114 115 static int fd_read(BIO *b, char *out, int outl) 116 { 117 int ret = 0; 118 119 if (out != NULL) { 120 clear_sys_error(); 121 ret = UP_read(b->num, out, outl); 122 BIO_clear_retry_flags(b); 123 if (ret <= 0) { 124 if (BIO_fd_should_retry(ret)) 125 BIO_set_retry_read(b); 126 } 127 } 128 return ret; 129 } 130 131 static int fd_write(BIO *b, const char *in, int inl) 132 { 133 int ret; 134 clear_sys_error(); 135 ret = UP_write(b->num, in, inl); 136 BIO_clear_retry_flags(b); 137 if (ret <= 0) { 138 if (BIO_fd_should_retry(ret)) 139 BIO_set_retry_write(b); 140 } 141 return ret; 142 } 143 144 static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) 145 { 146 long ret = 1; 147 int *ip; 148 149 switch (cmd) { 150 case BIO_CTRL_RESET: 151 num = 0; 152 /* fall thru */ 153 case BIO_C_FILE_SEEK: 154 ret = (long)UP_lseek(b->num, num, 0); 155 break; 156 case BIO_C_FILE_TELL: 157 case BIO_CTRL_INFO: 158 ret = (long)UP_lseek(b->num, 0, 1); 159 break; 160 case BIO_C_SET_FD: 161 fd_free(b); 162 b->num = *((int *)ptr); 163 b->shutdown = (int)num; 164 b->init = 1; 165 break; 166 case BIO_C_GET_FD: 167 if (b->init) { 168 ip = (int *)ptr; 169 if (ip != NULL) 170 *ip = b->num; 171 ret = b->num; 172 } else 173 ret = -1; 174 break; 175 case BIO_CTRL_GET_CLOSE: 176 ret = b->shutdown; 177 break; 178 case BIO_CTRL_SET_CLOSE: 179 b->shutdown = (int)num; 180 break; 181 case BIO_CTRL_PENDING: 182 case BIO_CTRL_WPENDING: 183 ret = 0; 184 break; 185 case BIO_CTRL_DUP: 186 case BIO_CTRL_FLUSH: 187 ret = 1; 188 break; 189 default: 190 ret = 0; 191 break; 192 } 193 return ret; 194 } 195 196 static int fd_puts(BIO *bp, const char *str) 197 { 198 int n, ret; 199 200 n = strlen(str); 201 ret = fd_write(bp, str, n); 202 return ret; 203 } 204 205 static int fd_gets(BIO *bp, char *buf, int size) 206 { 207 int ret = 0; 208 char *ptr = buf; 209 char *end = buf + size - 1; 210 211 while (ptr < end && fd_read(bp, ptr, 1) > 0) { 212 if (*ptr++ == '\n') 213 break; 214 } 215 216 ptr[0] = '\0'; 217 218 if (buf[0] != '\0') 219 ret = strlen(buf); 220 return ret; 221 } 222 223 int BIO_fd_should_retry(int i) 224 { 225 int err; 226 227 if ((i == 0) || (i == -1)) { 228 err = get_last_sys_error(); 229 230 return BIO_fd_non_fatal_error(err); 231 } 232 return 0; 233 } 234 235 int BIO_fd_non_fatal_error(int err) 236 { 237 switch (err) { 238 239 # ifdef EWOULDBLOCK 240 # ifdef WSAEWOULDBLOCK 241 # if WSAEWOULDBLOCK != EWOULDBLOCK 242 case EWOULDBLOCK: 243 # endif 244 # else 245 case EWOULDBLOCK: 246 # endif 247 # endif 248 249 # if defined(ENOTCONN) 250 case ENOTCONN: 251 # endif 252 253 # ifdef EINTR 254 case EINTR: 255 # endif 256 257 # ifdef EAGAIN 258 # if EWOULDBLOCK != EAGAIN 259 case EAGAIN: 260 # endif 261 # endif 262 263 # ifdef EPROTO 264 case EPROTO: 265 # endif 266 267 # ifdef EINPROGRESS 268 case EINPROGRESS: 269 # endif 270 271 # ifdef EALREADY 272 case EALREADY: 273 # endif 274 return 1; 275 default: 276 break; 277 } 278 return 0; 279 } 280 #endif 281