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 /*- 11 * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout 12 * with binary data (e.g. asn1parse -inform DER < xxx) under 13 * Windows 14 */ 15 16 #ifndef HEADER_BSS_FILE_C 17 # define HEADER_BSS_FILE_C 18 19 # if defined(__linux) || defined(__sun) || defined(__hpux) 20 /* 21 * Following definition aliases fopen to fopen64 on above mentioned 22 * platforms. This makes it possible to open and sequentially access files 23 * larger than 2GB from 32-bit application. It does not allow to traverse 24 * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit 25 * platform permits that, not with fseek/ftell. Not to mention that breaking 26 * 2GB limit for seeking would require surgery to *our* API. But sequential 27 * access suffices for practical cases when you can run into large files, 28 * such as fingerprinting, so we can let API alone. For reference, the list 29 * of 32-bit platforms which allow for sequential access of large files 30 * without extra "magic" comprise *BSD, Darwin, IRIX... 31 */ 32 # ifndef _FILE_OFFSET_BITS 33 # define _FILE_OFFSET_BITS 64 34 # endif 35 # endif 36 37 # include <stdio.h> 38 # include <errno.h> 39 # include "bio_lcl.h" 40 # include <openssl/err.h> 41 42 # if !defined(OPENSSL_NO_STDIO) 43 44 static int file_write(BIO *h, const char *buf, int num); 45 static int file_read(BIO *h, char *buf, int size); 46 static int file_puts(BIO *h, const char *str); 47 static int file_gets(BIO *h, char *str, int size); 48 static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2); 49 static int file_new(BIO *h); 50 static int file_free(BIO *data); 51 static const BIO_METHOD methods_filep = { 52 BIO_TYPE_FILE, 53 "FILE pointer", 54 file_write, 55 file_read, 56 file_puts, 57 file_gets, 58 file_ctrl, 59 file_new, 60 file_free, 61 NULL, /* file_callback_ctrl */ 62 }; 63 64 BIO *BIO_new_file(const char *filename, const char *mode) 65 { 66 BIO *ret; 67 FILE *file = openssl_fopen(filename, mode); 68 int fp_flags = BIO_CLOSE; 69 70 if (strchr(mode, 'b') == NULL) 71 fp_flags |= BIO_FP_TEXT; 72 73 if (file == NULL) { 74 SYSerr(SYS_F_FOPEN, get_last_sys_error()); 75 ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); 76 if (errno == ENOENT 77 # ifdef ENXIO 78 || errno == ENXIO 79 # endif 80 ) 81 BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); 82 else 83 BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB); 84 return (NULL); 85 } 86 if ((ret = BIO_new(BIO_s_file())) == NULL) { 87 fclose(file); 88 return (NULL); 89 } 90 91 BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage 92 * UPLINK */ 93 BIO_set_fp(ret, file, fp_flags); 94 return (ret); 95 } 96 97 BIO *BIO_new_fp(FILE *stream, int close_flag) 98 { 99 BIO *ret; 100 101 if ((ret = BIO_new(BIO_s_file())) == NULL) 102 return (NULL); 103 104 /* redundant flag, left for documentation purposes */ 105 BIO_set_flags(ret, BIO_FLAGS_UPLINK); 106 BIO_set_fp(ret, stream, close_flag); 107 return (ret); 108 } 109 110 const BIO_METHOD *BIO_s_file(void) 111 { 112 return (&methods_filep); 113 } 114 115 static int file_new(BIO *bi) 116 { 117 bi->init = 0; 118 bi->num = 0; 119 bi->ptr = NULL; 120 bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */ 121 return (1); 122 } 123 124 static int file_free(BIO *a) 125 { 126 if (a == NULL) 127 return (0); 128 if (a->shutdown) { 129 if ((a->init) && (a->ptr != NULL)) { 130 if (a->flags & BIO_FLAGS_UPLINK) 131 UP_fclose(a->ptr); 132 else 133 fclose(a->ptr); 134 a->ptr = NULL; 135 a->flags = BIO_FLAGS_UPLINK; 136 } 137 a->init = 0; 138 } 139 return (1); 140 } 141 142 static int file_read(BIO *b, char *out, int outl) 143 { 144 int ret = 0; 145 146 if (b->init && (out != NULL)) { 147 if (b->flags & BIO_FLAGS_UPLINK) 148 ret = UP_fread(out, 1, (int)outl, b->ptr); 149 else 150 ret = fread(out, 1, (int)outl, (FILE *)b->ptr); 151 if (ret == 0 152 && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) : 153 ferror((FILE *)b->ptr)) { 154 SYSerr(SYS_F_FREAD, get_last_sys_error()); 155 BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); 156 ret = -1; 157 } 158 } 159 return (ret); 160 } 161 162 static int file_write(BIO *b, const char *in, int inl) 163 { 164 int ret = 0; 165 166 if (b->init && (in != NULL)) { 167 if (b->flags & BIO_FLAGS_UPLINK) 168 ret = UP_fwrite(in, (int)inl, 1, b->ptr); 169 else 170 ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr); 171 if (ret) 172 ret = inl; 173 /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */ 174 /* 175 * according to Tim Hudson <tjh@cryptsoft.com>, the commented out 176 * version above can cause 'inl' write calls under some stupid stdio 177 * implementations (VMS) 178 */ 179 } 180 return (ret); 181 } 182 183 static long file_ctrl(BIO *b, int cmd, long num, void *ptr) 184 { 185 long ret = 1; 186 FILE *fp = (FILE *)b->ptr; 187 FILE **fpp; 188 char p[4]; 189 int st; 190 191 switch (cmd) { 192 case BIO_C_FILE_SEEK: 193 case BIO_CTRL_RESET: 194 if (b->flags & BIO_FLAGS_UPLINK) 195 ret = (long)UP_fseek(b->ptr, num, 0); 196 else 197 ret = (long)fseek(fp, num, 0); 198 break; 199 case BIO_CTRL_EOF: 200 if (b->flags & BIO_FLAGS_UPLINK) 201 ret = (long)UP_feof(fp); 202 else 203 ret = (long)feof(fp); 204 break; 205 case BIO_C_FILE_TELL: 206 case BIO_CTRL_INFO: 207 if (b->flags & BIO_FLAGS_UPLINK) 208 ret = UP_ftell(b->ptr); 209 else 210 ret = ftell(fp); 211 break; 212 case BIO_C_SET_FILE_PTR: 213 file_free(b); 214 b->shutdown = (int)num & BIO_CLOSE; 215 b->ptr = ptr; 216 b->init = 1; 217 # if BIO_FLAGS_UPLINK!=0 218 # if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) 219 # define _IOB_ENTRIES 20 220 # endif 221 /* Safety net to catch purely internal BIO_set_fp calls */ 222 # if defined(_MSC_VER) && _MSC_VER>=1900 223 if (ptr == stdin || ptr == stdout || ptr == stderr) 224 BIO_clear_flags(b, BIO_FLAGS_UPLINK); 225 # elif defined(_IOB_ENTRIES) 226 if ((size_t)ptr >= (size_t)stdin && 227 (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) 228 BIO_clear_flags(b, BIO_FLAGS_UPLINK); 229 # endif 230 # endif 231 # ifdef UP_fsetmod 232 if (b->flags & BIO_FLAGS_UPLINK) 233 UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); 234 else 235 # endif 236 { 237 # if defined(OPENSSL_SYS_WINDOWS) 238 int fd = _fileno((FILE *)ptr); 239 if (num & BIO_FP_TEXT) 240 _setmode(fd, _O_TEXT); 241 else 242 _setmode(fd, _O_BINARY); 243 # elif defined(OPENSSL_SYS_MSDOS) 244 int fd = fileno((FILE *)ptr); 245 /* Set correct text/binary mode */ 246 if (num & BIO_FP_TEXT) 247 _setmode(fd, _O_TEXT); 248 /* Dangerous to set stdin/stdout to raw (unless redirected) */ 249 else { 250 if (fd == STDIN_FILENO || fd == STDOUT_FILENO) { 251 if (isatty(fd) <= 0) 252 _setmode(fd, _O_BINARY); 253 } else 254 _setmode(fd, _O_BINARY); 255 } 256 # elif defined(OPENSSL_SYS_WIN32_CYGWIN) 257 int fd = fileno((FILE *)ptr); 258 if (num & BIO_FP_TEXT) 259 setmode(fd, O_TEXT); 260 else 261 setmode(fd, O_BINARY); 262 # endif 263 } 264 break; 265 case BIO_C_SET_FILENAME: 266 file_free(b); 267 b->shutdown = (int)num & BIO_CLOSE; 268 if (num & BIO_FP_APPEND) { 269 if (num & BIO_FP_READ) 270 OPENSSL_strlcpy(p, "a+", sizeof(p)); 271 else 272 OPENSSL_strlcpy(p, "a", sizeof(p)); 273 } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) 274 OPENSSL_strlcpy(p, "r+", sizeof(p)); 275 else if (num & BIO_FP_WRITE) 276 OPENSSL_strlcpy(p, "w", sizeof(p)); 277 else if (num & BIO_FP_READ) 278 OPENSSL_strlcpy(p, "r", sizeof(p)); 279 else { 280 BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE); 281 ret = 0; 282 break; 283 } 284 # if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32_CYGWIN) 285 if (!(num & BIO_FP_TEXT)) 286 strlcat(p, "b", sizeof(p)); 287 else 288 strlcat(p, "t", sizeof(p)); 289 # endif 290 fp = openssl_fopen(ptr, p); 291 if (fp == NULL) { 292 SYSerr(SYS_F_FOPEN, get_last_sys_error()); 293 ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); 294 BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); 295 ret = 0; 296 break; 297 } 298 b->ptr = fp; 299 b->init = 1; 300 BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage 301 * UPLINK */ 302 break; 303 case BIO_C_GET_FILE_PTR: 304 /* the ptr parameter is actually a FILE ** in this case. */ 305 if (ptr != NULL) { 306 fpp = (FILE **)ptr; 307 *fpp = (FILE *)b->ptr; 308 } 309 break; 310 case BIO_CTRL_GET_CLOSE: 311 ret = (long)b->shutdown; 312 break; 313 case BIO_CTRL_SET_CLOSE: 314 b->shutdown = (int)num; 315 break; 316 case BIO_CTRL_FLUSH: 317 st = b->flags & BIO_FLAGS_UPLINK 318 ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr); 319 if (st == EOF) { 320 SYSerr(SYS_F_FFLUSH, get_last_sys_error()); 321 ERR_add_error_data(1, "fflush()"); 322 BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); 323 ret = 0; 324 } 325 break; 326 case BIO_CTRL_DUP: 327 ret = 1; 328 break; 329 330 case BIO_CTRL_WPENDING: 331 case BIO_CTRL_PENDING: 332 case BIO_CTRL_PUSH: 333 case BIO_CTRL_POP: 334 default: 335 ret = 0; 336 break; 337 } 338 return (ret); 339 } 340 341 static int file_gets(BIO *bp, char *buf, int size) 342 { 343 int ret = 0; 344 345 buf[0] = '\0'; 346 if (bp->flags & BIO_FLAGS_UPLINK) { 347 if (!UP_fgets(buf, size, bp->ptr)) 348 goto err; 349 } else { 350 if (!fgets(buf, size, (FILE *)bp->ptr)) 351 goto err; 352 } 353 if (buf[0] != '\0') 354 ret = strlen(buf); 355 err: 356 return (ret); 357 } 358 359 static int file_puts(BIO *bp, const char *str) 360 { 361 int n, ret; 362 363 n = strlen(str); 364 ret = file_write(bp, str, n); 365 return (ret); 366 } 367 368 #else 369 370 static int file_write(BIO *b, const char *in, int inl) 371 { 372 return -1; 373 } 374 static int file_read(BIO *b, char *out, int outl) 375 { 376 return -1; 377 } 378 static int file_puts(BIO *bp, const char *str) 379 { 380 return -1; 381 } 382 static int file_gets(BIO *bp, char *buf, int size) 383 { 384 return 0; 385 } 386 static long file_ctrl(BIO *b, int cmd, long num, void *ptr) 387 { 388 return 0; 389 } 390 static int file_new(BIO *bi) 391 { 392 return 0; 393 } 394 static int file_free(BIO *a) 395 { 396 return 0; 397 } 398 399 static const BIO_METHOD methods_filep = { 400 BIO_TYPE_FILE, 401 "FILE pointer", 402 file_write, 403 file_read, 404 file_puts, 405 file_gets, 406 file_ctrl, 407 file_new, 408 file_free, 409 NULL, /* file_callback_ctrl */ 410 }; 411 412 const BIO_METHOD *BIO_s_file(void) 413 { 414 return (&methods_filep); 415 } 416 417 BIO *BIO_new_file(const char *filename, const char *mode) 418 { 419 return NULL; 420 } 421 422 # endif /* OPENSSL_NO_STDIO */ 423 424 #endif /* HEADER_BSS_FILE_C */ 425