Example #1
0
static void pipe_flush_event(void * x) {
    ChannelPIPE * c = (ChannelPIPE *)x;
    assert(c->magic == CHANNEL_MAGIC);
    if (--c->out_flush_cnt == 0) {
        int congestion_level = c->chan->congestion_level;
        if (congestion_level > 0) usleep(congestion_level * 2500);
        pipe_flush(c);
        pipe_unlock(c->chan);
    }
}
Example #2
0
/**
 * \fn pipe_close
 * \brief Update reference count and if necessary clean up
 */
static int pipe_close(struct pipe* pipe)
{
    if (pipe == NULL)
        return -E_NULL_PTR;

    if (atomic_dec(&pipe->ref_cnt) == 0)
    {
        pipe_flush(pipe);
        kfree(pipe);
    }

    return -E_SUCCESS;
}
Example #3
0
static void pipe_write_stream(OutputStream * out, int byte) {
    ChannelPIPE * c = channel2pipe(out2channel(out));
    assert(c->magic == CHANNEL_MAGIC);
    if (c->chan->state == ChannelStateDisconnected) return;
    if (c->chan->out.cur == c->chan->out.end) pipe_flush(c);
    if (byte < 0 || byte == ESC) {
        char esc = 0;
        *c->chan->out.cur++ = ESC;
        if (byte == ESC) esc = 0;
        else if (byte == MARKER_EOM) esc = 1;
        else if (byte == MARKER_EOS) esc = 2;
        else assert(0);
        if (c->chan->state == ChannelStateDisconnected) return;
        if (c->chan->out.cur == c->chan->out.end) pipe_flush(c);
        *c->chan->out.cur++ = esc;
        if (byte == MARKER_EOM && c->out_flush_cnt < 2) {
            if (c->out_flush_cnt++ == 0) pipe_lock(c->chan);
            post_event_with_delay(pipe_flush_event, c, 0);
        }
        return;
    }
    *c->chan->out.cur++ = (char)byte;
}
Example #4
0
static void pipe_write_block_stream(OutputStream * out, const char * bytes, size_t size) {
    size_t cnt = 0;
    ChannelPIPE * c = channel2pipe(out2channel(out));

    if (out->supports_zero_copy && size > 32) {
        /* Send the binary data escape seq */
        size_t n = size;
        if (c->chan->out.cur >= c->chan->out.end - 8) pipe_flush(c);
        *c->chan->out.cur++ = ESC;
        *c->chan->out.cur++ = 3;
        for (;;) {
            if (n <= 0x7fu) {
                *c->chan->out.cur++ = (char)n;
                break;
            }
            *c->chan->out.cur++ = (n & 0x7fu) | 0x80u;
            n = n >> 7;
        }
        /* We need to flush the buffer then send our data */
        pipe_flush(c);

        create_write_request(c, bytes, size);
        return;
    }
Example #5
0
File: main.c Project: fyra/fribid
/**
 * Called when a command is being sent from the plugin.
 */
void pipeCommand(PipeCommand command, const char *url, const char *hostname,
                 const char *ip) {
    switch (command) {
        case PC_GetVersion: {
            char *versionString = bankid_getVersion();
            
            pipe_sendString(stdout, versionString);
            free(versionString);
            pipe_flush(stdout);
            
            platform_leaveMainloop();
            break;
        }
        case PC_Authenticate:
        case PC_Sign: {
            char *challenge = pipe_readString(stdin);
            int32_t serverTime = pipe_readInt(stdin);
            free(pipe_readOptionalString(stdin)); // Just ignore the policies list for now
            char *subjectFilter = pipe_readOptionalString(stdin);
            char *messageEncoding = NULL, *message = NULL,
                 *invisibleMessage = NULL;
            if (command == PC_Sign) {
                messageEncoding = pipe_readString(stdin);
                message = pipe_readString(stdin);
                invisibleMessage = pipe_readOptionalString(stdin);
            }
            
            // Validate input
            BankIDError error = BIDERR_OK;
            
            if (!is_https_url(url)) {
                error = BIDERR_NotSSL;
            } else if (!is_canonical_base64(challenge) ||
                       !is_valid_hostname(hostname) ||
                       !is_valid_ip_address(ip) ||
                       (command == PC_Sign && (
                           !is_canonical_base64(message) ||
                           (invisibleMessage && !is_canonical_base64(invisibleMessage))
                       ))) {
                error = BIDERR_InternalError;
            }
            
            if (error != BIDERR_OK) {
                pipe_sendInt(stdout, error);
                pipe_sendString(stdout, "");
                pipe_flush(stdout);
                
                platform_leaveMainloop();
                return;
            }
            
            if (subjectFilter && !is_canonical_base64(subjectFilter)) {
                // The subject filter is invalid. Ignore it
                free(subjectFilter);
                subjectFilter = NULL;
            }
            
            Token *token;
            char *password = NULL;
            long password_maxsize = 0;
            char *signature = NULL;
            char *decodedSubjectFilter = NULL;
            error = BIDERR_UserCancel;

            // Allocate a secure page for the password
            password = secmem_get_page(&password_maxsize);
            if (!password || !password_maxsize) {
                pipe_sendInt(stdout, BIDERR_InternalError);
                pipe_sendString(stdout, "");
                pipe_flush(stdout);
                
                platform_leaveMainloop();
                return;
            }

            if (subjectFilter) {
                decodedSubjectFilter = base64_decode(subjectFilter);
                free(subjectFilter);
            }
            
            // Pass all parameters to the user interface
            platform_startSign(url, hostname, ip, browserWindowId);
            BackendNotifier *notifier = backend_createNotifier(
                decodedSubjectFilter,
                (command == PC_Sign ?
                    KeyUsage_Signing : KeyUsage_Authentication),
                notifyCallback);
            platform_setNotifier(notifier);
            platform_addKeyDirectories();
            backend_scanTokens(notifier);
            free(decodedSubjectFilter);
            
            if (command == PC_Sign) {
                if (!message) abort();
                char *decodedMessage = base64_decode(message);
                platform_setMessage(decodedMessage);
                free(decodedMessage);
            }

            while (platform_sign(&token, password, password_maxsize)) {
                // Set the password (not used by all backends)
                token_usePassword(token, password);
                
                // Try to authenticate/sign
                if (command == PC_Authenticate) {
                    error = bankid_authenticate(token, challenge, serverTime,
                                                hostname, ip, &signature);
                } else {
                    error = bankid_sign(token, challenge, serverTime,
                                        hostname, ip, messageEncoding,
                                        message, invisibleMessage,
                                        &signature);
                }
                
                guaranteed_memset(password, 0, password_maxsize);
                
                if (error == BIDERR_OK) break;
                
                // An error occurred
                const TokenError tokenError = token_getLastError(token);
                platform_showError(tokenError);
                if (tokenError == TokenError_BadPassword || tokenError == TokenError_BadPin) {
                    platform_focusPassword(); // also removes focus from the Sign button
                }
                error = BIDERR_UserCancel;
            }

            secmem_free_page(password);

            platform_endSign();
            
            backend_freeNotifier(notifier);
            free(messageEncoding);
            free(message);
            free(invisibleMessage);
            free(challenge);
            
            pipe_sendInt(stdout, error);
            pipe_sendString(stdout, (signature ? signature : ""));
            pipe_flush(stdout);
            
            free(signature);
            platform_leaveMainloop();
            break;
        }
        case PC_CreateRequest: {
            char *request = NULL;
            BankIDError error = BIDERR_InternalError;
            long password_maxsize = 0;
            char *name = NULL;
            char *password = NULL;
            
            // Read input
            RegutilInfo input;
            memset(&input, 0, sizeof(input));
            
            input.minPasswordLength = pipe_readInt(stdin);
            input.minPasswordNonDigits = pipe_readInt(stdin);
            input.minPasswordDigits = pipe_readInt(stdin);
            
            while (pipe_readInt(stdin) == PLS_MoreData) {
                // PKCS10
                RegutilPKCS10 *pkcs10 = malloc(sizeof(RegutilPKCS10));
                pkcs10->keyUsage = pipe_readInt(stdin);
                pkcs10->keySize = pipe_readInt(stdin);
                pkcs10->subjectDN = pipe_readString(stdin);
                pkcs10->includeFullDN = pipe_readInt(stdin);
                
                pkcs10->next = input.pkcs10;
                input.pkcs10 = pkcs10;
            }
            
            // CMC
            input.cmc.oneTimePassword = pipe_readString(stdin);
            input.cmc.rfc2729cmcoid = pipe_readString(stdin);
            
            // Check for broken pipe
            if (feof(stdin)) goto createReq_end;
            
            // Check input
            if (!input.pkcs10) goto createReq_end;
            
            // Get name to display
            name = bankid_getRequestDisplayName(&input);
            if (!name) goto createReq_end;
            
            // Allocate a secure page for the password
            password = secmem_get_page(&password_maxsize);
            if (!password || !password_maxsize) goto createReq_end;
            
            platform_startChoosePassword(name, browserWindowId);
            platform_setPasswordPolicy(input.minPasswordLength,
                                       input.minPasswordNonDigits,
                                       input.minPasswordDigits);
            
            for (;;) {
                error = RUERR_UserCancel;
                // Ask for a password
                if (!platform_choosePassword(password, password_maxsize))
                    break;
                
                // Try to authenticate/sign
                // Generate key pair and construct the request
                TokenError tokenError;
                error = bankid_createRequest(&input, hostname, password,
                                             &request, &tokenError);
                
                guaranteed_memset(password, 0, password_maxsize);
                
                if (error == BIDERR_OK) break;
                
                platform_showError(tokenError);
            }
            
            platform_endChoosePassword();
            
            // Send result
          createReq_end:
            secmem_free_page(password);
            pipe_sendInt(stdout, error);
            
            if (!request) pipe_sendString(stdout, "");
            else {
                pipe_sendString(stdout, request);
                free(request);
            }
            
            pipe_flush(stdout);
            platform_leaveMainloop();
            break;
        }
        case PC_StoreCertificates: {
            char *certs = pipe_readString(stdin);
            
            TokenError tokenError;
            BankIDError error = bankid_storeCertificates(certs, hostname,
                                                         &tokenError);
            if (error != BIDERR_OK) {
                if (prefs_debug_dump) {
                    certutil_dumpCertsP7(certs);
                }
                platform_showError(tokenError);
            }
            
            pipe_sendInt(stdout, error);
            pipe_flush(stdout);
            
            platform_leaveMainloop();
            break;
        }
        default: {
            fprintf(stderr, BINNAME ": invalid command from pipe\n");
            platform_leaveMainloop();
            break;
        }
    }
}
Example #6
0
File: slip.c Project: OPSF/uClinux
int slip_set_addrs()
{
    char buf[128];
    char type[30];
    char addr[30];
    int res;

    if (waiting_for_bootp && (!have_local || !have_remote)) {
	int i;
	char *buf, *tail;
	buf = tail = bootp_pipe.buf;
	i = pipe_read(&bootp_pipe);
	if (i <= 0) return 0;
	while (i--) {
	   if (*tail == '\n') {
		*tail = 0;
		/* Got a line, deal with it */
		if (sscanf(buf,"%[^=]=%s\n",type,addr) == 2) {
		    if (strcmp(type,"SERVER")==0) {
			have_remote = 1;
			remote_ip = strdup(addr);
		    } else if (strcmp(type,"IPADDR")==0) {
			have_local = 1;
			local_ip = strdup(addr);
		    }
		}
		buf = tail+1;
	   }
	   tail++;
	}
	pipe_flush(&bootp_pipe,buf-bootp_pipe.buf);
    }

    if (waiting_for_bootp && (!have_local || !have_remote))
        return 0;

    if (waiting_for_bootp) {
        pclose(bootpfp);
	syslog(LOG_INFO,"New addresses: local %s, remote %s.",
	    local_ip,remote_ip);
    	waiting_for_bootp = 0;
    }

    if (route_wait) {
	/* set the initial rx counter once the link is up */
	if (rx_count == -1) rx_count = slip_rx_count();

	/* check if we got the routing packet yet */
	if (slip_rx_count() == rx_count) return 0;
    }

    /* redo the interface marking and the routing since BOOTP will change it */
    if (netmask) {
        sprintf(buf,"%s sl%d %s pointopoint %s netmask %s mtu %d up",
	    PATH_IFCONFIG,link_iface,local_ip,remote_ip,netmask,mtu);
    } else {
        sprintf(buf,"%s sl%d %s pointopoint %s mtu %d up",
	    PATH_IFCONFIG,link_iface,local_ip,remote_ip,mtu);
    }
    res = system(buf);
    report_system_result(res,buf);

    /* Set the routing for the new slip interface */
    set_ptp("sl",link_iface,remote_ip,metric);

    if (dynamic_addrs || force_dynamic) {
	local_addr = inet_addr(local_ip);
	/* have to reset the proxy if we won't be rerouting... */
	if (!do_reroute) {
	    proxy_config(local_ip,remote_ip);
    	    set_ptp("sl",proxy_iface,remote_ip,metric+1);
	    add_routes("sl",proxy_iface,local_ip,remote_ip,drmetric+1);
	}
    }

    if (do_reroute)
        add_routes("sl",link_iface,local_ip,remote_ip,drmetric);

    return 1;
}