1 /* 2 * Copyright 1995-2020 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_local.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 else if (ret == 0) 127 b->flags |= BIO_FLAGS_IN_EOF; 128 } 129 } 130 return ret; 131 } 132 133 static int fd_write(BIO *b, const char *in, int inl) 134 { 135 int ret; 136 clear_sys_error(); 137 ret = UP_write(b->num, in, inl); 138 BIO_clear_retry_flags(b); 139 if (ret <= 0) { 140 if (BIO_fd_should_retry(ret)) 141 BIO_set_retry_write(b); 142 } 143 return ret; 144 } 145 146 static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) 147 { 148 long ret = 1; 149 int *ip; 150 151 switch (cmd) { 152 case BIO_CTRL_RESET: 153 num = 0; 154 /* fall thru */ 155 case BIO_C_FILE_SEEK: 156 ret = (long)UP_lseek(b->num, num, 0); 157 break; 158 case BIO_C_FILE_TELL: 159 case BIO_CTRL_INFO: 160 ret = (long)UP_lseek(b->num, 0, 1); 161 break; 162 case BIO_C_SET_FD: 163 fd_free(b); 164 b->num = *((int *)ptr); 165 b->shutdown = (int)num; 166 b->init = 1; 167 break; 168 case BIO_C_GET_FD: 169 if (b->init) { 170 ip = (int *)ptr; 171 if (ip != NULL) 172 *ip = b->num; 173 ret = b->num; 174 } else 175 ret = -1; 176 break; 177 case BIO_CTRL_GET_CLOSE: 178 ret = b->shutdown; 179 break; 180 case BIO_CTRL_SET_CLOSE: 181 b->shutdown = (int)num; 182 break; 183 case BIO_CTRL_PENDING: 184 case BIO_CTRL_WPENDING: 185 ret = 0; 186 break; 187 case BIO_CTRL_DUP: 188 case BIO_CTRL_FLUSH: 189 ret = 1; 190 break; 191 case BIO_CTRL_EOF: 192 ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; 193 break; 194 default: 195 ret = 0; 196 break; 197 } 198 return ret; 199 } 200 201 static int fd_puts(BIO *bp, const char *str) 202 { 203 int n, ret; 204 205 n = strlen(str); 206 ret = fd_write(bp, str, n); 207 return ret; 208 } 209 210 static int fd_gets(BIO *bp, char *buf, int size) 211 { 212 int ret = 0; 213 char *ptr = buf; 214 char *end = buf + size - 1; 215 216 while (ptr < end && fd_read(bp, ptr, 1) > 0) { 217 if (*ptr++ == '\n') 218 break; 219 } 220 221 ptr[0] = '\0'; 222 223 if (buf[0] != '\0') 224 ret = strlen(buf); 225 return ret; 226 } 227 228 int BIO_fd_should_retry(int i) 229 { 230 int err; 231 232 if ((i == 0) || (i == -1)) { 233 err = get_last_sys_error(); 234 235 return BIO_fd_non_fatal_error(err); 236 } 237 return 0; 238 } 239 240 int BIO_fd_non_fatal_error(int err) 241 { 242 switch (err) { 243 244 # ifdef EWOULDBLOCK 245 # ifdef WSAEWOULDBLOCK 246 # if WSAEWOULDBLOCK != EWOULDBLOCK 247 case EWOULDBLOCK: 248 # endif 249 # else 250 case EWOULDBLOCK: 251 # endif 252 # endif 253 254 # if defined(ENOTCONN) 255 case ENOTCONN: 256 # endif 257 258 # ifdef EINTR 259 case EINTR: 260 # endif 261 262 # ifdef EAGAIN 263 # if EWOULDBLOCK != EAGAIN 264 case EAGAIN: 265 # endif 266 # endif 267 268 # ifdef EPROTO 269 case EPROTO: 270 # endif 271 272 # ifdef EINPROGRESS 273 case EINPROGRESS: 274 # endif 275 276 # ifdef EALREADY 277 case EALREADY: 278 # endif 279 return 1; 280 default: 281 break; 282 } 283 return 0; 284 } 285 #endif 286