int BIO_fd_should_retry(int i)
#endif
	{
	int err;

	if ((i == 0) || (i == -1))
		{
#ifndef BIO_FD
		err=get_last_socket_error();
#else
		err=get_last_sys_error();
#endif

#if defined(WINDOWS) && 0 /* more microsoft stupidity? perhaps not? Ben 4/1/99 */
		if ((i == -1) && (err == 0))
			return(1);
#endif

#ifndef BIO_FD
		return(BIO_sock_non_fatal_error(err));
#else
		return(BIO_fd_non_fatal_error(err));
#endif
		}
	return(0);
	}
Beispiel #2
0
BIO *BIO_new_file(const char *filename, const char *mode)
{
    BIO  *ret;
    FILE *file = openssl_fopen(filename, mode);
    int fp_flags = BIO_CLOSE;

    if (strchr(mode, 'b') == NULL)
        fp_flags |= BIO_FP_TEXT;

    if (file == NULL) {
        SYSerr(SYS_F_FOPEN, get_last_sys_error());
        ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
        if (errno == ENOENT
# ifdef ENXIO
            || errno == ENXIO
# endif
            )
            BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
        else
            BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
        return NULL;
    }
    if ((ret = BIO_new(BIO_s_file())) == NULL) {
        fclose(file);
        return NULL;
    }

    BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
                                             * UPLINK */
    BIO_set_fp(ret, file, fp_flags);
    return ret;
}
Beispiel #3
0
BIO *BIO_new_file(const char *filename, const char *mode)
	{
	BIO *ret;
	FILE *file;

	if ((file=fopen(filename,mode)) == NULL)
		{
		SYSerr(SYS_F_FOPEN,get_last_sys_error());
		ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
		if (errno == ENOENT)
			BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
		else
			BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
		return(NULL);
		}
	if ((ret=BIO_new(BIO_s_file_internal())) == NULL)
		{
		fclose(file);
		return(NULL);
		}

	BIO_clear_flags(ret,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
	BIO_set_fp(ret,file,BIO_CLOSE);
	return(ret);
	}
Beispiel #4
0
/*
 * err_shelve_state returns the current thread local error state
 * and freezes the error module until err_unshelve_state is called.
 */
int err_shelve_state(void **state)
{
    int saveerrno = get_last_sys_error();

    /*
     * Note, at present our only caller is OPENSSL_init_crypto(), indirectly
     * via ossl_init_load_crypto_nodelete(), by which point the requested
     * "base" initialization has already been performed, so the below call is a
     * NOOP, that re-enters OPENSSL_init_crypto() only to quickly return.
     *
     * If are no other valid callers of this function, the call below can be
     * removed, avoiding the re-entry into OPENSSL_init_crypto().  If there are
     * potential uses that are not from inside OPENSSL_init_crypto(), then this
     * call is needed, but some care is required to make sure that the re-entry
     * remains a NOOP.
     */
    if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL))
        return 0;

    if (!RUN_ONCE(&err_init, err_do_init))
        return 0;

    *state = CRYPTO_THREAD_get_local(&err_thread_local);
    if (!CRYPTO_THREAD_set_local(&err_thread_local, (ERR_STATE*)-1))
        return 0;

    set_sys_error(saveerrno);
    return 1;
}
Beispiel #5
0
static void build_SYS_str_reasons(void)
{
    /* OPENSSL_malloc cannot be used here, use static storage instead */
    static char strerror_pool[SPACE_SYS_STR_REASONS];
    char *cur = strerror_pool;
    size_t cnt = 0;
    static int init = 1;
    int i;
    int saveerrno = get_last_sys_error();

    CRYPTO_THREAD_write_lock(err_string_lock);
    if (!init) {
        CRYPTO_THREAD_unlock(err_string_lock);
        return;
    }

    for (i = 1; i <= NUM_SYS_STR_REASONS; i++) {
        ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];

        str->error = ERR_PACK(ERR_LIB_SYS, 0, i);
        if (str->string == NULL) {
            if (openssl_strerror_r(i, cur, sizeof(strerror_pool) - cnt)) {
                size_t l = strlen(cur);

                str->string = cur;
                cnt += l;
                if (cnt > sizeof(strerror_pool))
                    cnt = sizeof(strerror_pool);
                cur += l;

                /*
                 * VMS has an unusual quirk of adding spaces at the end of
                 * some (most? all?) messages.  Lets trim them off.
                 */
                while (ossl_isspace(cur[-1])) {
                    cur--;
                    cnt--;
                }
                *cur++ = '\0';
                cnt++;
            }
        }
        if (str->string == NULL)
            str->string = "unknown";
    }

    /*
     * Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, as
     * required by ERR_load_strings.
     */

    init = 0;

    CRYPTO_THREAD_unlock(err_string_lock);
    /* openssl_strerror_r could change errno, but we want to preserve it */
    set_sys_error(saveerrno);
    err_load_strings(SYS_str_reasons);
}
Beispiel #6
0
int BIO_fd_should_retry(int i)
{
    int err;

    if ((i == 0) || (i == -1)) {
        err = get_last_sys_error();

        return (BIO_fd_non_fatal_error(err));
    }
    return (0);
}
Beispiel #7
0
int BIO_fd_should_retry(int i)
{
    int err;

    if ((i == 0) || (i == -1)) {
        err = get_last_sys_error();

# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps
                                       * not? Ben 4/1/99 */
        if ((i == -1) && (err == 0))
            return (1);
# endif

        return (BIO_fd_non_fatal_error(err));
    }
static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
{
    int ret=0;

    if (b->init && (out != NULL))
    {
        ret=fread(out,1,(int)outl,(FILE *)b->ptr);
        if(ret == 0 && ferror((FILE *)b->ptr))
        {
            SYSerr(SYS_F_FREAD,get_last_sys_error());
            BIOerr(BIO_F_FILE_READ,ERR_R_SYS_LIB);
            ret=-1;
        }
    }
    return(ret);
}
Beispiel #9
0
BIO *BIO_new_file(const char *filename, const char *mode)
	{
	BIO *ret;
	FILE *file;

	if ((file=fopen(filename,mode)) == NULL)
		{
		SYSerr(SYS_F_FOPEN,get_last_sys_error());
		ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
		BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
		return(NULL);
		}
	if ((ret=BIO_new(BIO_s_file_internal())) == NULL)
		return(NULL);

	BIO_set_fp(ret,file,BIO_CLOSE);
	return(ret);
	}
Beispiel #10
0
static int file_read(BIO *b, char *out, int outl)
{
    int ret = 0;

    if (b->init && (out != NULL)) {
        if (b->flags & BIO_FLAGS_UPLINK)
            ret = UP_fread(out, 1, (int)outl, b->ptr);
        else
            ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
        if (ret == 0
            && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
                                               ferror((FILE *)b->ptr)) {
            SYSerr(SYS_F_FREAD, get_last_sys_error());
            BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
            ret = -1;
        }
    }
    return ret;
}
Beispiel #11
0
ERR_STATE *ERR_get_state(void)
{
    ERR_STATE *state;
    int saveerrno = get_last_sys_error();

    if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL))
        return NULL;

    if (!RUN_ONCE(&err_init, err_do_init))
        return NULL;

    state = CRYPTO_THREAD_get_local(&err_thread_local);
    if (state == (ERR_STATE*)-1)
        return NULL;

    if (state == NULL) {
        if (!CRYPTO_THREAD_set_local(&err_thread_local, (ERR_STATE*)-1))
            return NULL;

        if ((state = OPENSSL_zalloc(sizeof(*state))) == NULL) {
            CRYPTO_THREAD_set_local(&err_thread_local, NULL);
            return NULL;
        }

        if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE)
                || !CRYPTO_THREAD_set_local(&err_thread_local, state)) {
            ERR_STATE_free(state);
            CRYPTO_THREAD_set_local(&err_thread_local, NULL);
            return NULL;
        }

        /* Ignore failures from these */
        OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
    }

    set_sys_error(saveerrno);
    return state;
}
Beispiel #12
0
static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
{
    long ret = 1;
    FILE *fp = (FILE *)b->ptr;
    FILE **fpp;
    char p[4];

    switch (cmd) {
    case BIO_C_FILE_SEEK:
    case BIO_CTRL_RESET:
        if (b->flags & BIO_FLAGS_UPLINK)
            ret = (long)UP_fseek(b->ptr, num, 0);
        else
            ret = (long)fseek(fp, num, 0);
        break;
    case BIO_CTRL_EOF:
        if (b->flags & BIO_FLAGS_UPLINK)
            ret = (long)UP_feof(fp);
        else
            ret = (long)feof(fp);
        break;
    case BIO_C_FILE_TELL:
    case BIO_CTRL_INFO:
        if (b->flags & BIO_FLAGS_UPLINK)
            ret = UP_ftell(b->ptr);
        else
            ret = ftell(fp);
        break;
    case BIO_C_SET_FILE_PTR:
        file_free(b);
        b->shutdown = (int)num & BIO_CLOSE;
        b->ptr = ptr;
        b->init = 1;
#  if BIO_FLAGS_UPLINK!=0
#   if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
#    define _IOB_ENTRIES 20
#   endif
#   if defined(_IOB_ENTRIES)
        /* Safety net to catch purely internal BIO_set_fp calls */
        if ((size_t)ptr >= (size_t)stdin &&
            (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
            BIO_clear_flags(b, BIO_FLAGS_UPLINK);
#   endif
#  endif
#  ifdef UP_fsetmod
        if (b->flags & BIO_FLAGS_UPLINK)
            UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b'));
        else
#  endif
        {
#  if defined(OPENSSL_SYS_WINDOWS)
            int fd = _fileno((FILE *)ptr);
            if (num & BIO_FP_TEXT)
                _setmode(fd, _O_TEXT);
            else
                _setmode(fd, _O_BINARY);
#  elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
            int fd = fileno((FILE *)ptr);
            /* Under CLib there are differences in file modes */
            if (num & BIO_FP_TEXT)
                setmode(fd, O_TEXT);
            else
                setmode(fd, O_BINARY);
#  elif defined(OPENSSL_SYS_MSDOS)
            int fd = fileno((FILE *)ptr);
            /* Set correct text/binary mode */
            if (num & BIO_FP_TEXT)
                _setmode(fd, _O_TEXT);
            /* Dangerous to set stdin/stdout to raw (unless redirected) */
            else {
                if (fd == STDIN_FILENO || fd == STDOUT_FILENO) {
                    if (isatty(fd) <= 0)
                        _setmode(fd, _O_BINARY);
                } else
                    _setmode(fd, _O_BINARY);
            }
#  elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
            int fd = fileno((FILE *)ptr);
            if (num & BIO_FP_TEXT)
                setmode(fd, O_TEXT);
            else
                setmode(fd, O_BINARY);
#  endif
        }
        break;
    case BIO_C_SET_FILENAME:
        file_free(b);
        b->shutdown = (int)num & BIO_CLOSE;
        if (num & BIO_FP_APPEND) {
            if (num & BIO_FP_READ)
                BUF_strlcpy(p, "a+", sizeof p);
            else
                BUF_strlcpy(p, "a", sizeof p);
        } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
            BUF_strlcpy(p, "r+", sizeof p);
        else if (num & BIO_FP_WRITE)
            BUF_strlcpy(p, "w", sizeof p);
        else if (num & BIO_FP_READ)
            BUF_strlcpy(p, "r", sizeof p);
        else {
            BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
            ret = 0;
            break;
        }
#  if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
        if (!(num & BIO_FP_TEXT))
            strcat(p, "b");
        else
            strcat(p, "t");
#  endif
#  if defined(OPENSSL_SYS_NETWARE)
        if (!(num & BIO_FP_TEXT))
            strcat(p, "b");
        else
            strcat(p, "t");
#  endif
        fp = fopen(ptr, p);
        if (fp == NULL) {
            SYSerr(SYS_F_FOPEN, get_last_sys_error());
            ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
            BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
            ret = 0;
            break;
        }
        b->ptr = fp;
        b->init = 1;
        BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
                                               * UPLINK */
        break;
    case BIO_C_GET_FILE_PTR:
        /* the ptr parameter is actually a FILE ** in this case. */
        if (ptr != NULL) {
            fpp = (FILE **)ptr;
            *fpp = (FILE *)b->ptr;
        }
        break;
    case BIO_CTRL_GET_CLOSE:
        ret = (long)b->shutdown;
        break;
    case BIO_CTRL_SET_CLOSE:
        b->shutdown = (int)num;
        break;
    case BIO_CTRL_FLUSH:
        if (b->flags & BIO_FLAGS_UPLINK)
            UP_fflush(b->ptr);
        else
            fflush((FILE *)b->ptr);
        break;
    case BIO_CTRL_DUP:
        ret = 1;
        break;

    case BIO_CTRL_WPENDING:
    case BIO_CTRL_PENDING:
    case BIO_CTRL_PUSH:
    case BIO_CTRL_POP:
    default:
        ret = 0;
        break;
    }
    return (ret);
}
Beispiel #13
0
BIO *BIO_new_file(const char *filename, const char *mode)
{
    BIO *ret;
    FILE *file = NULL;

#  if defined(_WIN32) && defined(CP_UTF8)
    int sz, len_0 = (int)strlen(filename) + 1;
    DWORD flags;

    /*
     * Basically there are three cases to cover: a) filename is
     * pure ASCII string; b) actual UTF-8 encoded string and
     * c) locale-ized string, i.e. one containing 8-bit
     * characters that are meaningful in current system locale.
     * If filename is pure ASCII or real UTF-8 encoded string,
     * MultiByteToWideChar succeeds and _wfopen works. If
     * filename is locale-ized string, chances are that
     * MultiByteToWideChar fails reporting
     * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
     * back to fopen...
     */
    if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS),
                                  filename, len_0, NULL, 0)) > 0 ||
        (GetLastError() == ERROR_INVALID_FLAGS &&
         (sz = MultiByteToWideChar(CP_UTF8, (flags = 0),
                                   filename, len_0, NULL, 0)) > 0)
        ) {
        WCHAR wmode[8];
        WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));

        if (MultiByteToWideChar(CP_UTF8, flags,
                                filename, len_0, wfilename, sz) &&
            MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1,
                                wmode, sizeof(wmode) / sizeof(wmode[0])) &&
            (file = _wfopen(wfilename, wmode)) == NULL &&
            (errno == ENOENT || errno == EBADF)
            ) {
            /*
             * UTF-8 decode succeeded, but no file, filename
             * could still have been locale-ized...
             */
            file = fopen(filename, mode);
        }
    } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
        file = fopen(filename, mode);
    }
#  else
    file = fopen(filename, mode);
#  endif
    if (file == NULL) {
        SYSerr(SYS_F_FOPEN, get_last_sys_error());
        ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
        if (errno == ENOENT)
            BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
        else
            BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
        return (NULL);
    }
    if ((ret = BIO_new(BIO_s_file())) == NULL) {
        fclose(file);
        return (NULL);
    }

    BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
                                             * UPLINK */
    BIO_set_fp(ret, file, BIO_CLOSE);
    return (ret);
}
Beispiel #14
0
static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
	{
	long ret=1;
	FILE *fp=(FILE *)b->ptr;
	FILE **fpp;
	char p[4];

	switch (cmd)
		{
	case BIO_C_FILE_SEEK:
	case BIO_CTRL_RESET:
		ret=(long)fseek(fp,num,0);
		break;
	case BIO_CTRL_EOF:
		ret=(long)feof(fp);
		break;
	case BIO_C_FILE_TELL:
	case BIO_CTRL_INFO:
		ret=ftell(fp);
		break;
	case BIO_C_SET_FILE_PTR:
		file_free(b);
		b->shutdown=(int)num&BIO_CLOSE;
		b->ptr=(char *)ptr;
		b->init=1;
#if defined(MSDOS) || defined(WINDOWS)
		/* Set correct text/binary mode */
		if (num & BIO_FP_TEXT)
			_setmode(fileno((FILE *)ptr),_O_TEXT);
		else
			_setmode(fileno((FILE *)ptr),_O_BINARY);
#endif
		break;
	case BIO_C_SET_FILENAME:
		file_free(b);
		b->shutdown=(int)num&BIO_CLOSE;
		if (num & BIO_FP_APPEND)
			{
			if (num & BIO_FP_READ)
				strcpy(p,"a+");
			else	strcpy(p,"a");
			}
		else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
			strcpy(p,"r+");
		else if (num & BIO_FP_WRITE)
			strcpy(p,"w");
		else if (num & BIO_FP_READ)
			strcpy(p,"r");
		else
			{
			BIOerr(BIO_F_FILE_CTRL,BIO_R_BAD_FOPEN_MODE);
			ret=0;
			break;
			}
#if defined(MSDOS) || defined(WINDOWS)
		if (!(num & BIO_FP_TEXT))
			strcat(p,"b");
		else
			strcat(p,"t");
#endif
		fp=fopen(ptr,p);
		if (fp == NULL)
			{
			SYSerr(SYS_F_FOPEN,get_last_sys_error());
			ERR_add_error_data(5,"fopen('",ptr,"','",p,"')");
			BIOerr(BIO_F_FILE_CTRL,ERR_R_SYS_LIB);
			ret=0;
			break;
			}
		b->ptr=(char *)fp;
		b->init=1;
		break;
	case BIO_C_GET_FILE_PTR:
		/* the ptr parameter is actually a FILE ** in this case. */
		if (ptr != NULL)
			{
			fpp=(FILE **)ptr;
			*fpp=(FILE *)b->ptr;
			}
		break;
	case BIO_CTRL_GET_CLOSE:
		ret=(long)b->shutdown;
		break;
	case BIO_CTRL_SET_CLOSE:
		b->shutdown=(int)num;
		break;
	case BIO_CTRL_FLUSH:
		fflush((FILE *)b->ptr);
		break;
	case BIO_CTRL_DUP:
		ret=1;
		break;

	case BIO_CTRL_WPENDING:
	case BIO_CTRL_PENDING:
	case BIO_CTRL_PUSH:
	case BIO_CTRL_POP:
	default:
		ret=0;
		break;
		}
	return(ret);
	}