Exemplo n.º 1
0
/* return true if filename can be opened for read */
bool
test_file (const char *filename)
{
  bool ret = false;
  if (filename)
    {
      FILE *fp = platform_fopen (filename, "r");
      if (fp)
	{
	  fclose (fp);
	  ret = true;
	}
      else
	{
	  if( openvpn_errno () == EACCES ) {
	    msg( M_WARN | M_ERRNO, "Could not access file '%s'", filename);
	  }
	}
    }

  dmsg (D_TEST_FILE, "TEST FILE '%s' [%d]",
       filename ? filename : "UNDEF",
       ret);

  return ret;
}
Exemplo n.º 2
0
int initialize_ifstream(struct ifstream *self, const char *filename)
{
	FILE *fp = platform_fopen(filename, "rb");
	if (!fp)
		return -1;
	setup_ifstream(self, fp, 0, 1);
	return 0;
}
Exemplo n.º 3
0
int initialize_ofstream(struct ofstream *self, const char *filename)
{
	FILE *fp = platform_fopen(filename, "wb");
	if (fp == NULL)
		return -1;
	self->ostream.ops = &ofstream_ops;
	self->is_owner = 1;
	self->fp = fp;
	return 0;
}
Exemplo n.º 4
0
/* Write our PID to a file */
void
write_pid (const char *filename)
{
  if (filename)
    {
      unsigned int pid = 0;
      FILE *fp = platform_fopen (filename, "w");
      if (!fp)
	msg (M_ERR, "Open error on pid file %s", filename);

      pid = platform_getpid ();
      fprintf(fp, "%u\n", pid);
      if (fclose (fp))
	msg (M_ERR, "Close error on pid file %s", filename);
    }
}
Exemplo n.º 5
0
struct buffer_list *
buffer_list_file (const char *fn, int max_line_len)
{
  FILE *fp = platform_fopen (fn, "r");
  struct buffer_list *bl = NULL;

  if (fp)
    {
      char *line = (char *) malloc (max_line_len);
      if (line)
	{
	  bl = buffer_list_new (0);
	  while (fgets (line, max_line_len, fp) != NULL)
	    buffer_list_push (bl, (unsigned char *)line);
	  free (line);
	}
      fclose (fp);
    }
  return bl;
}
Exemplo n.º 6
0
int
tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
    const char *pkcs12_file_inline,
    bool load_ca_file
    )
{
  FILE *fp;
  EVP_PKEY *pkey;
  X509 *cert;
  STACK_OF(X509) *ca = NULL;
  PKCS12 *p12;
  int i;
  char password[256];

  ASSERT(NULL != ctx);

  if (!strcmp (pkcs12_file, INLINE_FILE_TAG) && pkcs12_file_inline)
    {
      BIO *b64 = BIO_new(BIO_f_base64());
      BIO *bio = BIO_new_mem_buf((void *) pkcs12_file_inline,
	  (int) strlen(pkcs12_file_inline));
      ASSERT(b64 && bio);
      BIO_push(b64, bio);
      p12 = d2i_PKCS12_bio(b64, NULL);
      if (!p12)
	msg(M_SSLERR, "Error reading inline PKCS#12 file");
      BIO_free(b64);
      BIO_free(bio);
    }
  else
    {
      /* Load the PKCS #12 file */
      if (!(fp = platform_fopen(pkcs12_file, "rb")))
	msg(M_SSLERR, "Error opening file %s", pkcs12_file);
      p12 = d2i_PKCS12_fp(fp, NULL);
      fclose(fp);
      if (!p12)
	msg(M_SSLERR, "Error reading PKCS#12 file %s", pkcs12_file);
    }

  /* Parse the PKCS #12 file */
  if (!PKCS12_parse(p12, "", &pkey, &cert, &ca))
   {
     pem_password_callback (password, sizeof(password) - 1, 0, NULL);
     /* Reparse the PKCS #12 file with password */
     ca = NULL;
     if (!PKCS12_parse(p12, password, &pkey, &cert, &ca))
      {
#ifdef ENABLE_MANAGEMENT
	      if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE))
		management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
#endif
	PKCS12_free(p12);
	return 1;
      }
   }
  PKCS12_free(p12);

  /* Load Certificate */
  if (!SSL_CTX_use_certificate (ctx->ctx, cert))
   msg (M_SSLERR, "Cannot use certificate");

  /* Load Private Key */
  if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey))
   msg (M_SSLERR, "Cannot use private key");
  warn_if_group_others_accessible (pkcs12_file);

  /* Check Private Key */
  if (!SSL_CTX_check_private_key (ctx->ctx))
   msg (M_SSLERR, "Private key does not match the certificate");

  /* Set Certificate Verification chain */
  if (load_ca_file)
   {
     if (ca && sk_X509_num(ca))
      {
	for (i = 0; i < sk_X509_num(ca); i++)
	  {
	      if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i)))
	      msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)");
	    if (!SSL_CTX_add_client_CA(ctx->ctx, sk_X509_value(ca, i)))
	      msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
	  }
      }
   }
  return 0;
}
Exemplo n.º 7
0
bool
get_user_pass_cr (struct user_pass *up,
		  const char *auth_file,
		  const char *prefix,
		  const unsigned int flags,
		  const char *auth_challenge)
{
  struct gc_arena gc = gc_new ();

  if (!up->defined)
    {
      const bool from_stdin = (!auth_file || !strcmp (auth_file, "stdin"));

      if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
	msg (M_WARN, "Note: previous '%s' credentials failed", prefix);

#ifdef ENABLE_MANAGEMENT
      /*
       * Get username/password from management interface?
       */
      if (management
	  && ((auth_file && streq (auth_file, "management")) || (from_stdin && (flags & GET_USER_PASS_MANAGEMENT)))
	  && management_query_user_pass_enabled (management))
	{
	  const char *sc = NULL;

	  if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
	    management_auth_failure (management, prefix, "previous auth credentials failed");

#ifdef ENABLE_CLIENT_CR
	  if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
	    sc = auth_challenge;
#endif
	  if (!management_query_user_pass (management, up, prefix, flags, sc))
	    {
	      if ((flags & GET_USER_PASS_NOFATAL) != 0)
		return false;
	      else
		msg (M_FATAL, "ERROR: could not read %s username/password/ok/string from management interface", prefix);
	    }
	}
      else
#endif
      /*
       * Get NEED_OK confirmation from the console
       */
      if (flags & GET_USER_PASS_NEED_OK)
	{
	  struct buffer user_prompt = alloc_buf_gc (128, &gc);

	  buf_printf (&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
	  
	  if (!get_console_input (BSTR (&user_prompt), true, up->password, USER_PASS_LEN))
	    msg (M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
	  
	  if (!strlen (up->password))
	    strcpy (up->password, "ok");
	}
	  
      /*
       * Get username/password from standard input?
       */
      else if (from_stdin)
	{
#ifndef WIN32
	  /* did we --daemon'ize before asking for passwords? */
	  if ( !isatty(0) && !isatty(2) )
	    { msg(M_FATAL, "neither stdin nor stderr are a tty device, can't ask for %s password.  If you used --daemon, you need to use --askpass to make passphrase-protected keys work, and you can not use --auth-nocache.", prefix ); }
#endif

#ifdef ENABLE_CLIENT_CR
	  if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
	    {
	      struct auth_challenge_info *ac = get_auth_challenge (auth_challenge, &gc);
	      if (ac)
		{
		  char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc);
		  struct buffer packed_resp;

		  buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN);
		  msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", ac->challenge_text);
		  if (!get_console_input ("Response:", BOOL_CAST(ac->flags&CR_ECHO), response, USER_PASS_LEN))
		    msg (M_FATAL, "ERROR: could not read challenge response from stdin");
		  strncpynt (up->username, ac->user, USER_PASS_LEN);
		  buf_printf (&packed_resp, "CRV1::%s::%s", ac->state_id, response);
		}
	      else
		{
		  msg (M_FATAL, "ERROR: received malformed challenge request from server");
		}
	    }
	  else
#endif
	    {
	      struct buffer user_prompt = alloc_buf_gc (128, &gc);
	      struct buffer pass_prompt = alloc_buf_gc (128, &gc);

	      buf_printf (&user_prompt, "Enter %s Username:"******"Enter %s Password:"******"ERROR: could not read %s username from stdin", prefix);
		  if (strlen (up->username) == 0)
		    msg (M_FATAL, "ERROR: %s username is empty", prefix);
		}

	      if (!get_console_input (BSTR (&pass_prompt), false, up->password, USER_PASS_LEN))
		msg (M_FATAL, "ERROR: could not not read %s password from stdin", prefix);

#ifdef ENABLE_CLIENT_CR
	      if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
		{
		  char *response = (char *) gc_malloc (USER_PASS_LEN, false, &gc);
		  struct buffer packed_resp;
		  char *pw64=NULL, *resp64=NULL;

		  msg (M_INFO|M_NOPREFIX, "CHALLENGE: %s", auth_challenge);
		  if (!get_console_input ("Response:", BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO), response, USER_PASS_LEN))
		    msg (M_FATAL, "ERROR: could not read static challenge response from stdin");
		  if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
		      || openvpn_base64_encode(response, strlen(response), &resp64) == -1)
		    msg (M_FATAL, "ERROR: could not base64-encode password/static_response");
		  buf_set_write (&packed_resp, (uint8_t*)up->password, USER_PASS_LEN);
		  buf_printf (&packed_resp, "SCRV1:%s:%s", pw64, resp64);
		  string_clear(pw64);
		  free(pw64);
		  string_clear(resp64);
		  free(resp64);
		}
#endif
	    }
	}
      else
	{
	  /*
	   * Get username/password from a file.
	   */
	  FILE *fp;
      
#ifndef ENABLE_PASSWORD_SAVE
	  /*
	   * Unless ENABLE_PASSWORD_SAVE is defined, don't allow sensitive passwords
	   * to be read from a file.
	   */
	  if (flags & GET_USER_PASS_SENSITIVE)
	    msg (M_FATAL, "Sorry, '%s' password cannot be read from a file", prefix);
#endif

	  warn_if_group_others_accessible (auth_file);

	  fp = platform_fopen (auth_file, "r");
	  if (!fp)
	    msg (M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);

	  if (flags & GET_USER_PASS_PASSWORD_ONLY)
	    {
	      if (fgets (up->password, USER_PASS_LEN, fp) == NULL)
		msg (M_FATAL, "Error reading password from %s authfile: %s",
		     prefix,
		     auth_file);
	    }
	  else
	    {
	      if (fgets (up->username, USER_PASS_LEN, fp) == NULL
		  || fgets (up->password, USER_PASS_LEN, fp) == NULL)
		msg (M_FATAL, "Error reading username and password (must be on two consecutive lines) from %s authfile: %s",
		     prefix,
		     auth_file);
	    }
      
	  fclose (fp);
      
	  chomp (up->username);
	  chomp (up->password);
      
	  if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen (up->username) == 0)
	    msg (M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file);
	}

      string_mod (up->username, CC_PRINT, CC_CRLF, 0);
      string_mod (up->password, CC_PRINT, CC_CRLF, 0);

      up->defined = true;
    }

#if 0
  msg (M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password);
#endif

  gc_free (&gc);

  return true;
}
Exemplo n.º 8
0
bool
get_user_pass_cr(struct user_pass *up,
                 const char *auth_file,
                 const char *prefix,
                 const unsigned int flags,
                 const char *auth_challenge)
{
    struct gc_arena gc = gc_new();

    if (!up->defined)
    {
        bool from_authfile = (auth_file && !streq(auth_file, "stdin"));
        bool username_from_stdin = false;
        bool password_from_stdin = false;
        bool response_from_stdin = true;

        if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
        {
            msg(M_WARN, "Note: previous '%s' credentials failed", prefix);
        }

#ifdef ENABLE_MANAGEMENT
        /*
         * Get username/password from management interface?
         */
        if (management
            && (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT))
            && management_query_user_pass_enabled(management))
        {
            const char *sc = NULL;
            response_from_stdin = false;

            if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED)
            {
                management_auth_failure(management, prefix, "previous auth credentials failed");
            }

#ifdef ENABLE_CLIENT_CR
            if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE))
            {
                sc = auth_challenge;
            }
#endif
            if (!management_query_user_pass(management, up, prefix, flags, sc))
            {
                if ((flags & GET_USER_PASS_NOFATAL) != 0)
                {
                    return false;
                }
                else
                {
                    msg(M_FATAL, "ERROR: could not read %s username/password/ok/string from management interface", prefix);
                }
            }
        }
        else
#endif /* ifdef ENABLE_MANAGEMENT */
        /*
         * Get NEED_OK confirmation from the console
         */
        if (flags & GET_USER_PASS_NEED_OK)
        {
            struct buffer user_prompt = alloc_buf_gc(128, &gc);

            buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
            if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
                                   up->password, USER_PASS_LEN, false))
            {
                msg(M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
            }

            if (!strlen(up->password))
            {
                strcpy(up->password, "ok");
            }
        }
        else if (flags & GET_USER_PASS_INLINE_CREDS)
        {
            struct buffer buf;
            buf_set_read(&buf, (uint8_t *) auth_file, strlen(auth_file) + 1);
            if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
            {
                buf_parse(&buf, '\n', up->username, USER_PASS_LEN);
            }
            buf_parse(&buf, '\n', up->password, USER_PASS_LEN);
        }
        /*
         * Read from auth file unless this is a dynamic challenge request.
         */
        else if (from_authfile && !(flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
        {
            /*
             * Try to get username/password from a file.
             */
            FILE *fp;
            char password_buf[USER_PASS_LEN] = { '\0' };

            fp = platform_fopen(auth_file, "r");
            if (!fp)
            {
                msg(M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
            }

            if ((flags & GET_USER_PASS_PASSWORD_ONLY) == 0)
            {
                /* Read username first */
                if (fgets(up->username, USER_PASS_LEN, fp) == NULL)
                {
                    msg(M_FATAL, "Error reading username from %s authfile: %s",
                        prefix,
                        auth_file);
                }
            }
            chomp(up->username);

            if (fgets(password_buf, USER_PASS_LEN, fp) != NULL)
            {
                chomp(password_buf);
            }

            if (flags & GET_USER_PASS_PASSWORD_ONLY && !password_buf[0])
            {
                msg(M_FATAL, "Error reading password from %s authfile: %s", prefix, auth_file);
            }

            if (password_buf[0])
            {
                strncpy(up->password, password_buf, USER_PASS_LEN);
            }
            else
            {
                password_from_stdin = 1;
            }

            fclose(fp);

            if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen(up->username) == 0)
            {
                msg(M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file);
            }
        }
        else
        {
            username_from_stdin = true;
            password_from_stdin = true;
        }

        /*
         * Get username/password from standard input?
         */
        if (username_from_stdin || password_from_stdin || response_from_stdin)
        {
#ifdef ENABLE_CLIENT_CR
            if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE) && response_from_stdin)
            {
                struct auth_challenge_info *ac = get_auth_challenge(auth_challenge, &gc);
                if (ac)
                {
                    char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
                    struct buffer packed_resp, challenge;

                    challenge = alloc_buf_gc(14+strlen(ac->challenge_text), &gc);
                    buf_printf(&challenge, "CHALLENGE: %s", ac->challenge_text);
                    buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);

                    if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
                                           response, USER_PASS_LEN, BOOL_CAST(ac->flags&CR_ECHO)))
                    {
                        msg(M_FATAL, "ERROR: could not read challenge response from stdin");
                    }
                    strncpynt(up->username, ac->user, USER_PASS_LEN);
                    buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id, response);
                }
                else
                {
                    msg(M_FATAL, "ERROR: received malformed challenge request from server");
                }
            }
            else
#endif /* ifdef ENABLE_CLIENT_CR */
            {
                struct buffer user_prompt = alloc_buf_gc(128, &gc);
                struct buffer pass_prompt = alloc_buf_gc(128, &gc);

                query_user_clear();
                buf_printf(&user_prompt, "Enter %s Username:"******"Enter %s Password:"******"ERROR: Failed retrieving username or password");
                }

                if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
                {
                    if (strlen(up->username) == 0)
                    {
                        msg(M_FATAL, "ERROR: %s username is empty", prefix);
                    }
                }

#ifdef ENABLE_CLIENT_CR
                if (auth_challenge && (flags & GET_USER_PASS_STATIC_CHALLENGE) && response_from_stdin)
                {
                    char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
                    struct buffer packed_resp, challenge;
                    char *pw64 = NULL, *resp64 = NULL;

                    challenge = alloc_buf_gc(14+strlen(auth_challenge), &gc);
                    buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);

                    if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
                                           response, USER_PASS_LEN,
                                           BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
                    {
                        msg(M_FATAL, "ERROR: could not retrieve static challenge response");
                    }
                    if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
                        || openvpn_base64_encode(response, strlen(response), &resp64) == -1)
                    {
                        msg(M_FATAL, "ERROR: could not base64-encode password/static_response");
                    }
                    buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);
                    buf_printf(&packed_resp, "SCRV1:%s:%s", pw64, resp64);
                    string_clear(pw64);
                    free(pw64);
                    string_clear(resp64);
                    free(resp64);
                }
#endif /* ifdef ENABLE_CLIENT_CR */
            }
        }

        string_mod(up->username, CC_PRINT, CC_CRLF, 0);
        string_mod(up->password, CC_PRINT, CC_CRLF, 0);

        up->defined = true;
    }

#if 0
    msg(M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password);
#endif

    gc_free(&gc);

    return true;
}
Exemplo n.º 9
0
fs_file_t *fs_file_open(const char *filename, const char *mode) {
    return (fs_file_t*)platform_fopen(filename, mode);
}