Пример #1
0
bool
ssl_connect_wget (int fd, const char *hostname)
{
  SSL *conn;
  struct scwt_context scwt_ctx;
  struct openssl_transport_context *ctx;

  DEBUGP (("Initiating SSL handshake.\n"));

  assert (ssl_ctx != NULL);
  conn = SSL_new (ssl_ctx);
  if (!conn)
    goto error;
#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
  /* If the SSL library was build with support for ServerNameIndication
     then use it whenever we have a hostname.  If not, don't, ever. */
  if (! is_valid_ip_address (hostname))
    {
      if (! SSL_set_tlsext_host_name (conn, hostname))
        {
          DEBUGP (("Failed to set TLS server-name indication."));
          goto error;
        }
    }
#endif

#ifndef FD_TO_SOCKET
# define FD_TO_SOCKET(X) (X)
#endif
  if (!SSL_set_fd (conn, FD_TO_SOCKET (fd)))
    goto error;
  SSL_set_connect_state (conn);

  scwt_ctx.ssl = conn;
  if (run_with_timeout(opt.read_timeout, ssl_connect_with_timeout_callback,
                       &scwt_ctx)) {
    DEBUGP (("SSL handshake timed out.\n"));
    goto timeout;
  }
  if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK)
    goto error;

  ctx = xnew0 (struct openssl_transport_context);
  ctx->conn = conn;

  /* Register FD with Wget's transport layer, i.e. arrange that our
     functions are used for reading, writing, and polling.  */
  fd_register_transport (fd, &openssl_transport, ctx);
  DEBUGP (("Handshake successful; connected socket %d to SSL handle 0x%0*lx\n",
           fd, PTR_FORMAT (conn)));
  return true;

 error:
  DEBUGP (("SSL handshake failed.\n"));
  print_errors ();
 timeout:
  if (conn)
    SSL_free (conn);
  return false;
}
Пример #2
0
/**
   Validate an IP host address
   @param[in] addr_str pointer to string containing address to be validated
   @param[in] addr pointer to 32-bit memory for returning valid IP address,
   in network byte-order, if this function returns TRUE
   @return TRUE if the address in addr_str is valid, FALSE otherwise
*/
boolean is_valid_ip_host_addr (char *addr_str, uint32_t *addr)
{
    uint32_t d[IP_ADDR_PARTS];
    uint32_t temp_addr; 
    int      i;
    /*
     * Validate input args
     */
    if ((addr == NULL) || (addr_str == NULL)) {
	return (FALSE);
    }

    if (is_valid_ip_address(addr_str)) {
        i = sscanf(addr_str, "%u.%u.%u.%u", &d[0], &d[1], &d[2], &d[3]);
        if ( i < 4) {
            /* Something is really wrong because we have already check */
            /* this condition */
            return (FALSE);
        }

        /*
         * Cannot be in multicast range (Class D), experimental or bcast
         * (Class E).  These ranges are 
         *    multicast:    [224.0.0.0 - 239.255.255.255] Class D
         *    experimental: [240.0.0.0 - 254.255.255.255] Class E
         *    broadcast:    [255.0.0.0 - 255.255.255.255] Class E
         */
        if (d[0] > 223) {
            return (FALSE);            
        }

        temp_addr = d[0] << 24 | d[1] << 16 | d[2] << 8 | d[3];
        
        if (temp_addr == INADDR_NONE) {
            return (FALSE);            
        }

        if (temp_addr == INADDR_ANY) {
            return (FALSE);            
        }

        /* 
         * Return IP Address, in network byte-order
         */ 
        *addr = htonl(temp_addr);

        return (TRUE);
    }
    else {
        return (FALSE);
    }
}
Пример #3
0
/* Configuring IPv6 default gateway on management interface.
 * On success, returns CMD_SUCCESS. On failure, returns CMD_OVSDB_FAILURE.
 */
static int
mgmt_intf_set_default_gw_ipv6(bool set, const char *gw_v6)
{
    const struct ovsrec_system *row = NULL;
    struct smap smap = SMAP_INITIALIZER(&smap);
    const char *cfg_gw = NULL;
    struct ovsdb_idl_txn* status_txn = NULL;
    enum ovsdb_idl_txn_status status;

    if (!is_valid_ip_address(gw_v6))
    {
        vty_out(vty, "  %s %s", OVSDB_INVALID_IPV4_IPV6_ERROR,VTY_NEWLINE);
        return CMD_SUCCESS;
    }

    status_txn = cli_do_config_start();
    if (NULL == status_txn)
    {
        VLOG_ERR(OVSDB_TXN_CREATE_ERROR);
        cli_do_config_abort(status_txn);
        return CMD_OVSDB_FAILURE;
    }

    row = ovsrec_system_first(idl);

    if (!row)
    {
        VLOG_ERR(OVSDB_ROW_FETCH_ERROR);
        cli_do_config_abort(status_txn);
        return CMD_OVSDB_FAILURE;
    }

    if (!is_mode_static(row))
    {
        vty_out(vty, "  %s %s", OVSDB_MODE_ERROR, VTY_NEWLINE);
        cli_do_config_abort(status_txn);
        return CMD_SUCCESS;
    }

    smap_clone(&smap, &row->mgmt_intf);

    if(!smap_get(&smap, SYSTEM_MGMT_INTF_MAP_IPV6))
    {
        vty_out(vty, "  %s %s", OVSDB_NO_IP_ERROR, VTY_NEWLINE);
        cli_do_config_abort(status_txn);
        smap_destroy(&smap);
        return CMD_SUCCESS;
    }

    if (set)
    {
        smap_replace(&smap, SYSTEM_MGMT_INTF_MAP_DEFAULT_GATEWAY_V6, gw_v6);
    }
    else
    {
        cfg_gw = smap_get(&smap, SYSTEM_MGMT_INTF_MAP_DEFAULT_GATEWAY_V6);
        if (!cfg_gw || strcmp(gw_v6, cfg_gw) != 0)
        {
            vty_out(vty, "  %s %s", OVSDB_INVALID_VALUE_ERROR, VTY_NEWLINE);
            cli_do_config_abort(status_txn);
            smap_destroy(&smap);
            return CMD_SUCCESS;
        }

        smap_replace(&smap, SYSTEM_MGMT_INTF_MAP_DEFAULT_GATEWAY_V6,
                                            MGMT_INTF_DEFAULT_IPV6);

    }

    ovsrec_system_set_mgmt_intf(row, &smap);

    smap_destroy(&smap);

    status = cli_do_config_finish(status_txn);
    if (TXN_SUCCESS == status || TXN_UNCHANGED == status)
    {
        return CMD_SUCCESS;
    }
    else
    {
        VLOG_ERR(OVSDB_TXN_COMMIT_ERROR);
        return CMD_OVSDB_FAILURE;
    }
}
Пример #4
0
/* Configuring static ip on management interface.
 * On success, returns CMD_SUCCESS. On failure, returns CMD_OVSDB_FAILURE.
 */
static int
mgmt_intf_set_static(bool set, const char *ip, enum ip_type type)
{
    const struct ovsrec_system *row = NULL;
    struct smap smap = SMAP_INITIALIZER(&smap);
    struct ovsdb_idl_txn* status_txn = NULL;
    enum ovsdb_idl_txn_status status;

    const char *subnet = NULL;
    const char *ip_addr = NULL;
    unsigned short subnet_in = 0;
    char buf[MAX_IPV4_OR_IPV6_SUBNET_CIDR_STR_LEN];

    if (!is_valid_ip_address(ip))
    {
        vty_out(vty, "  %s %s", OVSDB_INVALID_IPV4_IPV6_ERROR, VTY_NEWLINE);
        return CMD_SUCCESS;
    }

    memset(buf, 0, MAX_IPV4_OR_IPV6_SUBNET_CIDR_STR_LEN);
    strncpy(buf, ip, MAX_IPV4_OR_IPV6_SUBNET_CIDR_STR_LEN);
    ip_addr   = strtok(buf, "/");
    subnet    = strtok(NULL, "\0");
    subnet_in = atoi(subnet);

    if (IPV4 == type)
    {
        if (IS_INVALID_IPV4_SUBNET(subnet_in))
        {
            vty_out(vty, "  %s %s", OVSDB_INVALID_SUBNET_ERROR, VTY_NEWLINE);
            return CMD_SUCCESS;
        }
    }else if (IPV6 == type) {
        if (IS_INVALID_IPV6_SUBNET(subnet_in))
        {
            vty_out(vty, "  %s %s", OVSDB_INVALID_SUBNET_ERROR, VTY_NEWLINE);
            return CMD_SUCCESS;
        }
    }


    status_txn = cli_do_config_start();
    if (NULL == status_txn)
    {
        VLOG_ERR(OVSDB_TXN_CREATE_ERROR);
        cli_do_config_abort(status_txn);
        return CMD_OVSDB_FAILURE;
    }

    row = ovsrec_system_first(idl);

    if (!row)
    {
        VLOG_ERR(OVSDB_ROW_FETCH_ERROR);
        cli_do_config_abort(status_txn);
        return CMD_OVSDB_FAILURE;
    }

    smap_clone(&smap, &row->mgmt_intf);

    if (set)
        smap_replace(&smap, SYSTEM_MGMT_INTF_MAP_MODE,
                            SYSTEM_MGMT_INTF_MAP_MODE_STATIC);

    if (IPV4 == type) {
        if (set)
        {
            smap_replace(&smap, SYSTEM_MGMT_INTF_MAP_IP, ip_addr);
            smap_replace(&smap, SYSTEM_MGMT_INTF_MAP_SUBNET_MASK, subnet);
        }
        else
        {
            if (mgmt_intf_remove_static_ipv4_address(&smap, ip_addr, subnet)
                                                               != CMD_SUCCESS)
            {
                cli_do_config_abort(status_txn);
                smap_destroy(&smap);
                return CMD_SUCCESS;
            }
        }
    }else if (IPV6 == type) {
        if (set)
            smap_replace(&smap, SYSTEM_MGMT_INTF_MAP_IPV6, ip);
        else
        {
            if (mgmt_intf_remove_static_ipv6_address(&smap, ip) != CMD_SUCCESS)
            {
                cli_do_config_abort(status_txn);
                smap_destroy(&smap);
                return CMD_SUCCESS;
            }
        }
    }

    ovsrec_system_set_mgmt_intf(row, &smap);

    smap_destroy(&smap);

    status = cli_do_config_finish(status_txn);
    if (TXN_SUCCESS == status || TXN_UNCHANGED == status)
    {
        return CMD_SUCCESS;
    }
    else
    {
        VLOG_ERR(OVSDB_TXN_COMMIT_ERROR);
        return CMD_OVSDB_FAILURE;
    }
}
Пример #5
0
Файл: main.c Проект: 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;
        }
    }
}