예제 #1
0
파일: a_mbstr.c 프로젝트: Ana06/openssl
static int traverse_string(const unsigned char *p, int len, int inform,
                           int (*rfunc) (unsigned long value, void *in),
                           void *arg)
{
    unsigned long value;
    int ret;
    while (len) {
        if (inform == MBSTRING_ASC) {
            value = *p++;
            len--;
        } else if (inform == MBSTRING_BMP) {
            value = *p++ << 8;
            value |= *p++;
            len -= 2;
        } else if (inform == MBSTRING_UNIV) {
            value = ((unsigned long)*p++) << 24;
            value |= ((unsigned long)*p++) << 16;
            value |= *p++ << 8;
            value |= *p++;
            len -= 4;
        } else {
            ret = UTF8_getc(p, len, &value);
            if (ret < 0)
                return -1;
            len -= ret;
            p += ret;
        }
        if (rfunc) {
            ret = rfunc(value, arg);
            if (ret <= 0)
                return ret;
        }
    }
    return 1;
}
예제 #2
0
파일: eval.c 프로젝트: doly/femtoutil
void rec_cal(int fc)
{
	int rec_num = g_fa[fc].rec_num;
	int shared_mem_id;
	int *shared_mem_ptr;
	int *ans;
	int ans_count;
	shared_mem_id = shmget(IPC_PRIVATE, rec_num * sizeof(int), IPC_CREAT);
	if ((shared_mem_ptr = shmat(shared_mem_id, NULL, 0)) == (void*)-1) {
		return;
	}

	ans = (int*)shared_mem_ptr;

	for (ans_count = 0; ans_count < rec_num; ans_count++) {
		pid_t child_pid;
		child_pid = fork();
		if (child_pid == 0) {
			*(ans + ans_count) = rfunc(g_fa[fc].rec_locate[ans_count]);
//			printf("%d\n",*(ans + ans_count));
			exit(0);
		}
	}

	for (ans_count = 0; ans_count < rec_num; ans_count++) {
		wait(NULL);
	}

	for (ans_count = 0; ans_count < rec_num; ans_count++) {
		g_fa[fc].rec_locate[ans_count]->type = CHILD_ANS;
		g_fa[fc].rec_locate[ans_count]->result = *(ans + ans_count);
//		printf("ans %d\n", *(ans + ans_count));
	}
}
예제 #3
0
파일: a_mbstr.c 프로젝트: MiKTeX/miktex
static int
traverse_string(const unsigned char *p, int len, int inform,
    int (*rfunc)(unsigned long value, void *in), void *arg)
{
	unsigned long value;
	int ret;

	while (len) {
		switch (inform) {
		case MBSTRING_ASC:
			value = *p++;
			len--;
			break;
		case MBSTRING_BMP:
			value = *p++ << 8;
			value |= *p++;
			/* BMP is explictly defined to not support surrogates */
			if (UNICODE_IS_SURROGATE(value))
				return -1;
			len -= 2;
			break;
		case MBSTRING_UNIV:
			value = (unsigned long)*p++ << 24;
			value |= *p++ << 16;
			value |= *p++ << 8;
			value |= *p++;
			if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value))
				return -1;
			len -= 4;
			break;
		default:
			ret = UTF8_getc(p, len, &value);
			if (ret < 0)
				return -1;
			len -= ret;
			p += ret;
			break;
		}
		if (rfunc) {
			ret = rfunc(value, arg);
			if (ret <= 0)
				return ret;
		}
	}
	return 1;
}
예제 #4
0
파일: tls_bio_ops.c 프로젝트: 10jschen/acl
int     tls_bio(ACL_SOCKET fd, int timeout, TLS_SESS_STATE *TLScontext,
	int (*hsfunc) (SSL *),
	int (*rfunc) (SSL *, void *, int),
	int (*wfunc) (SSL *, const void *, int),
	void *buf, int num)
{
    const char *myname = "tls_bio";
    int     status = 0;
    int     err;
    int     retval = 0;
    int     biop_retval;
    int     done;

    /*
     * If necessary, retry the SSL handshake or read/write operation after
     * handling any pending network I/O.
     */
    for (done = 0; done == 0; /* void */ ) {
	if (hsfunc) {
#if 1
	    status = hsfunc(TLScontext->con);
#else
	    status = SSL_do_handshake(TLScontext->con);
#endif
	} else if (rfunc)
	    status = rfunc(TLScontext->con, buf, num);
	else if (wfunc)
	    status = wfunc(TLScontext->con, buf, num);
	else
	    acl_msg_panic("%s: nothing to do here", myname);
	err = SSL_get_error(TLScontext->con, status);

#if (OPENSSL_VERSION_NUMBER <= 0x0090581fL)

	/*
	 * There is a bug up to and including OpenSSL-0.9.5a: if an error
	 * occurs while checking the peers certificate due to some
	 * certificate error (e.g. as happend with a RSA-padding error), the
	 * error is put onto the error stack. If verification is not
	 * enforced, this error should be ignored, but the error-queue is not
	 * cleared, so we can find this error here. The bug has been fixed on
	 * May 28, 2000.
	 * 
	 * This bug so far has only manifested as 4800:error:0407006A:rsa
	 * routines:RSA_padding_check_PKCS1_type_1:block type is not
	 * 01:rsa_pk1.c:100: 4800:error:04067072:rsa
	 * routines:RSA_EAY_PUBLIC_DECRYPT:padding check
	 * failed:rsa_eay.c:396: 4800:error:0D079006:asn1 encoding
	 * routines:ASN1_verify:bad get asn1 object call:a_verify.c:109: so
	 * that we specifically test for this error. We print the errors to
	 * the logfile and automatically clear the error queue. Then we retry
	 * to get another error code. We cannot do better, since we can only
	 * retrieve the last entry of the error-queue without actually
	 * cleaning it on the way.
	 * 
	 * This workaround is secure, as verify_result is set to "failed"
	 * anyway.
	 */
	if (err == SSL_ERROR_SSL) {
	    if (ERR_peek_error() == 0x0407006AL) {
		tls_print_errors();
		acl_msg_info("OpenSSL <= 0.9.5a workaround called: certificate errors ignored");
		err = SSL_get_error(TLScontext->con, status);
	    }
	}
#endif

	/*
	 * Find out if we must retry the operation and/or if there is pending
	 * network I/O.
	 * 
	 * XXX If we're the first to invoke SSL_shutdown(), then the operation
	 * isn't really complete when the call returns. We could hide that
	 * anomaly here and repeat the call.
	 */
	switch (err) {
	case SSL_ERROR_NONE:			/* success */
	    retval = status;
	    done = 1;
	    /* FALLTHROUGH */
	case SSL_ERROR_WANT_WRITE:		/* flush/update buffers */
	case SSL_ERROR_WANT_READ:
	    biop_retval = network_biopair_interop(fd, timeout, TLScontext->network_bio);
	    if (biop_retval < 0)
		return (-1);		/* network read/write error */
	    break;

	    /*
	     * With tls_timed_read() and tls_timed_write() the caller is the
	     * VSTREAM library module which is unaware of TLS, so we log the
	     * TLS error stack here. In a better world, each VSTREAM I/O
	     * object would provide an error reporting method in addition to
	     * the timed_read and timed_write methods, so that we would not
	     * need to have ad-hoc code like this.
	     */
	case SSL_ERROR_SSL:
	    if (rfunc || wfunc)
		tls_print_errors();
	    /* FALLTHROUGH */
	default:
	    retval = status;
	    done = 1;
	    break;
	}
    }
    return (retval);
}
예제 #5
0
파일: wswrapper.c 프로젝트: bartuer/noVNC
ssize_t _WS_recv(int recvf, int sockfd, const void *buf,
                 size_t len, int flags)
{
    int rawcount, deccount, left, rawlen, retlen, decodelen;
    int sockflags;
    int i;
    char * fstart, * fend, * cstart;

    static void * (*rfunc)(), * (*rfunc2)();
    if (!rfunc) rfunc = (void *(*)()) dlsym(RTLD_NEXT, "recv");
    if (!rfunc2) rfunc2 = (void *(*)()) dlsym(RTLD_NEXT, "read");

    if (len == 0) {
        return 0;
    }

    if ((_WS_sockfd == 0) || (_WS_sockfd != sockfd)) {
        // Not our file descriptor, just pass through
        if (recvf) {
            return (ssize_t) rfunc(sockfd, buf, len, flags);
        } else {
            return (ssize_t) rfunc2(sockfd, buf, len);
        }
    }
    DEBUG("_WS_recv(%d, _, %d) called\n", sockfd, len);

    sockflags = fcntl(sockfd, F_GETFL, 0);
    left = len;
    retlen = 0;

    // first copy in any carry-over bytes
    if (_WS_rcarry_cnt) {
        if (_WS_rcarry_cnt == 1) {
            DEBUG("Using carry byte: %u (", _WS_rcarry[0]);
        } else if (_WS_rcarry_cnt == 2) {
            DEBUG("Using carry bytes: %u,%u (", _WS_rcarry[0],
                    _WS_rcarry[1]);
        } else {
            RET_ERROR(EIO, "Too many carry-over bytes\n");
        }
        if (len <= _WS_rcarry_cnt) {
            DEBUG("final)\n");
            memcpy((char *) buf, _WS_rcarry, len);
            _WS_rcarry_cnt -= len;
            return len;
        } else {
            DEBUG("prepending)\n");
            memcpy((char *) buf, _WS_rcarry, _WS_rcarry_cnt);
            retlen += _WS_rcarry_cnt;
            left -= _WS_rcarry_cnt;
            _WS_rcarry_cnt = 0;
        }
    }

    // Determine the number of base64 encoded bytes needed
    rawcount = (left * 4) / 3 + 3;
    rawcount -= rawcount%4;

    if (rawcount > _WS_bufsize - 1) {
        RET_ERROR(ENOMEM, "recv of %d bytes is larger than buffer\n", rawcount);
    }

    i = 0;
    while (1) {
        // Peek at everything available
        rawlen = (int) rfunc(sockfd, _WS_rbuf, _WS_bufsize-1,
                            flags | MSG_PEEK);
        if (rawlen <= 0) {
            DEBUG("_WS_recv: returning because rawlen %d\n", rawlen);
            return (ssize_t) rawlen;
        }
        fstart = _WS_rbuf;

        /*
        while (rawlen >= 2 && fstart[0] == '\x00' && fstart[1] == '\xff') {
            fstart += 2;
            rawlen -= 2;
        }
        */
        if (rawlen >= 2 && fstart[0] == '\x00' && fstart[1] == '\xff') {
            rawlen = (int) rfunc(sockfd, _WS_rbuf, 2, flags);
            if (rawlen != 2) {
                RET_ERROR(EIO, "Could not strip empty frame headers\n");
            }
            continue;
        }

        fstart[rawlen] = '\x00';

        if (rawlen - _WS_newframe >= 4) {
            // We have enough to base64 decode at least 1 byte
            break;
        }
        // Not enough to base64 decode
        if (sockflags & O_NONBLOCK) {
            // Just tell the caller to call again
            DEBUG("_WS_recv: returning because O_NONBLOCK, rawlen %d\n", rawlen);
            errno = EAGAIN;
            return -1;
        }
        // Repeat until at least 1 byte (4 raw bytes) to decode
        i++;
        if (i > 1000000) { 
            MSG("Could not send final part of frame\n");
        }
    }

    /*
    DEBUG("_WS_recv, left: %d, len: %d, rawlen: %d, newframe: %d, raw: ",
          left, len, rawlen, _WS_newframe);
    for (i = 0; i < rawlen; i++) {
        DEBUG("%u,", (unsigned char) ((char *) fstart)[i]);
    }
    DEBUG("\n");
    */

    if (_WS_newframe) {
        if (fstart[0] != '\x00') {
            RET_ERROR(EPROTO, "Missing frame start\n");
        }
        fstart++;
        rawlen--;
        _WS_newframe = 0;
    }

    fend = memchr(fstart, '\xff', rawlen);

    if (fend) {
        _WS_newframe = 1;
        if ((fend - fstart) % 4) {
            RET_ERROR(EPROTO, "Frame length is not multiple of 4\n");
        }
    } else {
        fend = fstart + rawlen - (rawlen % 4);
        if (fend - fstart < 4) {
            RET_ERROR(EPROTO, "Frame too short\n");
        }
    }

    // How much should we consume
    if (rawcount < fend - fstart) {
        _WS_newframe = 0;
        deccount = rawcount;
    } else {
        deccount = fend - fstart;
    }

    // Now consume what we processed
    if (flags & MSG_PEEK) {
        MSG("*** Got MSG_PEEK ***\n");
    } else {
        rfunc(sockfd, _WS_rbuf, fstart - _WS_rbuf + deccount + _WS_newframe, flags);
    }

    fstart[deccount] = '\x00'; // base64 terminator

    // Do direct base64 decode, instead of decode()
    decodelen = b64_pton(fstart, (char *) buf + retlen, deccount);
    if (decodelen <= 0) {
        RET_ERROR(EPROTO, "Base64 decode error\n");
    }

    if (decodelen <= left) {
        retlen += decodelen;
    } else {
        retlen += left;

        if (! (flags & MSG_PEEK)) {
            // Add anything left over to the carry-over
            _WS_rcarry_cnt = decodelen - left;
            if (_WS_rcarry_cnt > 2) {
                RET_ERROR(EPROTO, "Got too much base64 data\n");
            }
            memcpy(_WS_rcarry, buf + retlen, _WS_rcarry_cnt);
            if (_WS_rcarry_cnt == 1) {
                DEBUG("Saving carry byte: %u\n", _WS_rcarry[0]);
            } else if (_WS_rcarry_cnt == 2) {
                DEBUG("Saving carry bytes: %u,%u\n", _WS_rcarry[0],
                        _WS_rcarry[1]);
            } else {
                MSG("Waah2!\n");
            }
        }
    }
    ((char *) buf)[retlen] = '\x00';

    /*
    DEBUG("*** recv %s as ", fstart);
    for (i = 0; i < retlen; i++) {
        DEBUG("%u,", (unsigned char) ((char *) buf)[i]);
    }
    DEBUG(" (%d -> %d): %d\n", deccount, decodelen, retlen);
    */
    return retlen;
}
예제 #6
0
파일: wswrapper.c 프로젝트: bartuer/noVNC
int _WS_handshake(int sockfd)
{
    int sz = 0, len, idx;
    int ret = -1, save_errno = EPROTO;
    char *last, *start, *end;
    long flags;
    char handshake[4096], response[4096],
         path[1024], prefix[5] = "", scheme[10] = "ws", host[1024],
         origin[1024], key1[100], key2[100], key3[9], chksum[17];

    static void * (*rfunc)(), * (*wfunc)();
    if (!rfunc) rfunc = (void *(*)()) dlsym(RTLD_NEXT, "recv");
    if (!wfunc) wfunc = (void *(*)()) dlsym(RTLD_NEXT, "send");
    DEBUG("_WS_handshake starting\n");

    /* Disable NONBLOCK if set */
    flags = fcntl(sockfd, F_GETFL, 0);
    if (flags & O_NONBLOCK) {
        fcntl(sockfd, F_SETFL, flags^O_NONBLOCK);
    }

    while (1) {
        len = (int) rfunc(sockfd, handshake+sz, 4095, 0);
        if (len < 1) {
            ret = len;
            save_errno = errno;
            break;
        }
        sz += len;
        handshake[sz] = '\x00';
        if (sz < 4) {
            // Not enough yet
            continue;
        }
        if (strstr(handshake, "GET ") != handshake) {
            // We got something but it wasn't a WebSockets client
            break;
        }
        last = strstr(handshake, "\r\n\r\n");
        if (! last) {
            continue;
        }
        if (! strstr(handshake, "Upgrade: WebSocket\r\n")) {
            MSG("Invalid WebSockets handshake\n");
            break;
        }

        // Now parse out the data
        start = handshake+4;
        end = strstr(start, " HTTP/1.1");
        if (!end) { break; }
        snprintf(path, end-start+1, "%s", start);

        start = strstr(handshake, "\r\nHost: ");
        if (!start) { break; }
        start += 8;
        end = strstr(start, "\r\n");
        snprintf(host, end-start+1, "%s", start);

        start = strstr(handshake, "\r\nOrigin: ");
        if (!start) { break; }
        start += 10;
        end = strstr(start, "\r\n");
        snprintf(origin, end-start+1, "%s", start);

        start = strstr(handshake, "\r\n\r\n") + 4;
        if (strlen(start) == 8) {
            sprintf(prefix, "Sec-");

            snprintf(key3, 8+1, "%s", start);

            start = strstr(handshake, "\r\nSec-WebSocket-Key1: ");
            if (!start) { break; }
            start += 22;
            end = strstr(start, "\r\n");
            snprintf(key1, end-start+1, "%s", start);

            start = strstr(handshake, "\r\nSec-WebSocket-Key2: ");
            if (!start) { break; }
            start += 22;
            end = strstr(start, "\r\n");
            snprintf(key2, end-start+1, "%s", start);

            _WS_gen_md5(key1, key2, key3, chksum);

            //DEBUG("Got handshake (v76): %s\n", handshake);
            MSG("Got handshake (v76)\n");

        } else {
            sprintf(prefix, "");
            sprintf(key1, "");
            sprintf(key2, "");
            sprintf(key3, "");
            sprintf(chksum, "");

            //DEBUG("Got handshake (v75): %s\n", handshake);
            MSG("Got handshake (v75)\n");
        }
        sprintf(response, _WS_response, prefix, origin, prefix, scheme,
                host, path, prefix, chksum);
        //DEBUG("Handshake response: %s\n", response);
        wfunc(sockfd, response, strlen(response), 0);
        save_errno = 0;
        ret = 0;
        break;
    }

    /* Re-enable NONBLOCK if it was set */
    if (flags & O_NONBLOCK) {
        fcntl(sockfd, F_SETFL, flags);
    }
    errno = save_errno;
    return ret;
}
예제 #7
0
int     tls_bio(int fd, int timeout, TLS_SESS_STATE *TLScontext,
                int (*hsfunc) (SSL *),
                int (*rfunc) (SSL *, void *, int),
                int (*wfunc) (SSL *, const void *, int),
                void *buf, int num)
{
    const char *myname = "tls_bio";
    int     status;
    int     err;
    int     enable_deadline;
    struct timeval time_left;		/* amount of time left */
    struct timeval time_deadline;	/* time of deadline */
    struct timeval time_now;		/* time after SSL_mumble() call */

    /*
     * Compensation for interface mis-match: With VSTREAMs, timeout <= 0
     * means wait forever; with the read/write_wait() calls below, we need to
     * specify timeout < 0 instead.
     *
     * Safety: no time limit means no deadline.
     */
    if (timeout <= 0) {
        timeout = -1;
        enable_deadline = 0;
    }

    /*
     * Deadline management is simpler than with VSTREAMs, because we don't
     * need to decrement a per-stream time limit. We just work within the
     * budget that is available for this tls_bio() call.
     */
    else {
        enable_deadline =
            vstream_fstat(TLScontext->stream, VSTREAM_FLAG_DEADLINE);
        if (enable_deadline) {
            GETTIMEOFDAY(&time_deadline);
            time_deadline.tv_sec += timeout;
        }
    }

    /*
     * If necessary, retry the SSL handshake or read/write operation after
     * handling any pending network I/O.
     */
    for (;;) {
        if (hsfunc)
            status = hsfunc(TLScontext->con);
        else if (rfunc)
            status = rfunc(TLScontext->con, buf, num);
        else if (wfunc)
            status = wfunc(TLScontext->con, buf, num);
        else
            msg_panic("%s: nothing to do here", myname);
        err = SSL_get_error(TLScontext->con, status);

#if (OPENSSL_VERSION_NUMBER <= 0x0090581fL)

        /*
         * There is a bug up to and including OpenSSL-0.9.5a: if an error
         * occurs while checking the peers certificate due to some
         * certificate error (e.g. as happend with a RSA-padding error), the
         * error is put onto the error stack. If verification is not
         * enforced, this error should be ignored, but the error-queue is not
         * cleared, so we can find this error here. The bug has been fixed on
         * May 28, 2000.
         *
         * This bug so far has only manifested as 4800:error:0407006A:rsa
         * routines:RSA_padding_check_PKCS1_type_1:block type is not
         * 01:rsa_pk1.c:100: 4800:error:04067072:rsa
         * routines:RSA_EAY_PUBLIC_DECRYPT:padding check
         * failed:rsa_eay.c:396: 4800:error:0D079006:asn1 encoding
         * routines:ASN1_verify:bad get asn1 object call:a_verify.c:109: so
         * that we specifically test for this error. We print the errors to
         * the logfile and automatically clear the error queue. Then we retry
         * to get another error code. We cannot do better, since we can only
         * retrieve the last entry of the error-queue without actually
         * cleaning it on the way.
         *
         * This workaround is secure, as verify_result is set to "failed"
         * anyway.
         */
        if (err == SSL_ERROR_SSL) {
            if (ERR_peek_error() == 0x0407006AL) {
                tls_print_errors();
                msg_info("OpenSSL <= 0.9.5a workaround called: certificate errors ignored");
                err = SSL_get_error(TLScontext->con, status);
            }
        }
#endif

        /*
         * Correspondence between SSL_ERROR_* error codes and tls_bio_(read,
         * write, accept, connect, shutdown) return values (for brevity:
         * retval).
         *
         * SSL_ERROR_NONE corresponds with retval > 0. With SSL_(read, write)
         * this is the number of plaintext bytes sent or received. With
         * SSL_(accept, connect, shutdown) this means that the operation was
         * completed successfully.
         *
         * SSL_ERROR_WANT_(WRITE, READ) start a new loop iteration, or force
         * (retval = -1, errno = ETIMEDOUT) when the time limit is exceeded.
         *
         * All other SSL_ERROR_* cases correspond with retval <= 0. With
         * SSL_(read, write, accept, connect) retval == 0 means that the
         * remote party either closed the network connection or that it
         * requested TLS shutdown; with SSL_shutdown() retval == 0 means that
         * our own shutdown request is in progress. With all operations
         * retval < 0 means that there was an error. In the latter case,
         * SSL_ERROR_SYSCALL means that error details are returned via the
         * errno value.
         *
         * Find out if we must retry the operation and/or if there is pending
         * network I/O.
         *
         * XXX If we're the first to invoke SSL_shutdown(), then the operation
         * isn't really complete when the call returns. We could hide that
         * anomaly here and repeat the call.
         */
        switch (err) {
        case SSL_ERROR_WANT_WRITE:
        case SSL_ERROR_WANT_READ:
            if (enable_deadline) {
                GETTIMEOFDAY(&time_now);
                timersub(&time_deadline, &time_now, &time_left);
                timeout = time_left.tv_sec + (time_left.tv_usec > 0);
                if (timeout <= 0) {
                    errno = ETIMEDOUT;
                    return (-1);
                }
            }
            if (err == SSL_ERROR_WANT_WRITE) {
                if (write_wait(fd, timeout) < 0)
                    return (-1);		/* timeout error */
            } else {
                if (read_wait(fd, timeout) < 0)
                    return (-1);		/* timeout error */
            }
            break;

        /*
         * Unhandled cases: SSL_ERROR_WANT_(ACCEPT, CONNECT, X509_LOOKUP)
         * etc. Historically, Postfix silently treated these as ordinary
         * I/O errors so we don't really know how common they are. For
         * now, we just log a warning.
         */
        default:
            msg_warn("%s: unexpected SSL_ERROR code %d", myname, err);
        /* FALLTHROUGH */

        /*
         * With tls_timed_read() and tls_timed_write() the caller is the
         * VSTREAM library module which is unaware of TLS, so we log the
         * TLS error stack here. In a better world, each VSTREAM I/O
         * object would provide an error reporting method in addition to
         * the timed_read and timed_write methods, so that we would not
         * need to have ad-hoc code like this.
         */
        case SSL_ERROR_SSL:
            if (rfunc || wfunc)
                tls_print_errors();
        /* FALLTHROUGH */
        case SSL_ERROR_ZERO_RETURN:
        case SSL_ERROR_NONE:
            errno = 0;				/* avoid bogus warnings */
        /* FALLTHROUGH */
        case SSL_ERROR_SYSCALL:
            return (status);
        }
    }
}