Exemple #1
0
static const char *
parse_windows_proxy_setting (const char *str, struct auto_proxy_info_entry *e, struct gc_arena *gc)
{
  char buf[128];
  const char *ret = NULL;
  struct buffer in;

  CLEAR (*e);

  buf_set_read (&in, (const uint8_t *)str, strlen (str));

  if (strchr (str, '=') != NULL)
    {
      if (buf_parse (&in, '=', buf, sizeof (buf)))
	ret = string_alloc (buf, gc);
    }
	
  if (buf_parse (&in, ':', buf, sizeof (buf)))
    e->server = string_alloc (buf, gc);

  if (e->server && buf_parse (&in, '\0', buf, sizeof (buf)))
    e->port = atoi (buf);

  return ret;
}
Exemple #2
0
void
ifconfig_pool_read(struct ifconfig_pool_persist *persist, struct ifconfig_pool *pool)
{
    const int buf_size = 128;

    update_time();
    if (persist && persist->file && pool)
    {
        struct gc_arena gc = gc_new();
        struct buffer in = alloc_buf_gc(256, &gc);
        char *cn_buf;
        char *ip_buf;
        int line = 0;

        ALLOC_ARRAY_CLEAR_GC(cn_buf, char, buf_size, &gc);
        ALLOC_ARRAY_CLEAR_GC(ip_buf, char, buf_size, &gc);

        while (true)
        {
            ASSERT(buf_init(&in, 0));
            if (!status_read(persist->file, &in))
            {
                break;
            }
            ++line;
            if (BLEN(&in))
            {
                int c = *BSTR(&in);
                if (c == '#' || c == ';')
                {
                    continue;
                }
                msg( M_INFO, "ifconfig_pool_read(), in='%s', TODO: IPv6",
                     BSTR(&in) );

                if (buf_parse(&in, ',', cn_buf, buf_size)
                    && buf_parse(&in, ',', ip_buf, buf_size))
                {
                    bool succeeded;
                    const in_addr_t addr = getaddr(GETADDR_HOST_ORDER, ip_buf, 0, &succeeded, NULL);
                    if (succeeded)
                    {
                        msg( M_INFO, "succeeded -> ifconfig_pool_set()");
                        ifconfig_pool_set(pool, cn_buf, addr, persist->fixed);
                    }
                }
            }
        }

        ifconfig_pool_msg(pool, D_IFCONFIG_POOL);

        gc_free(&gc);
    }
}
Exemple #3
0
/*
 * See management/management-notes.txt for more info on the
 * the dynamic challenge/response protocol implemented here.
 */
struct auth_challenge_info *
get_auth_challenge (const char *auth_challenge, struct gc_arena *gc)
{
  if (auth_challenge)
    {
      struct auth_challenge_info *ac;
      const int len = strlen (auth_challenge);
      char *work = (char *) gc_malloc (len+1, false, gc);
      char *cp;

      struct buffer b;
      buf_set_read (&b, (const uint8_t *)auth_challenge, len);

      ALLOC_OBJ_CLEAR_GC (ac, struct auth_challenge_info, gc);

      /* parse prefix */
      if (!buf_parse(&b, ':', work, len))
	return NULL;
      if (strcmp(work, "CRV1"))
	return NULL;

      /* parse flags */
      if (!buf_parse(&b, ':', work, len))
	return NULL;
      for (cp = work; *cp != '\0'; ++cp)
	{
	  const char c = *cp;
	  if (c == 'E')
	    ac->flags |= CR_ECHO;
	  else if (c == 'R')
	    ac->flags |= CR_RESPONSE;
	}
      
      /* parse state ID */
      if (!buf_parse(&b, ':', work, len))
	return NULL;
      ac->state_id = string_alloc(work, gc);

      /* parse user name */
      if (!buf_parse(&b, ':', work, len))
	return NULL;
      ac->user = (char *) gc_malloc (strlen(work)+1, true, gc);
      openvpn_base64_decode(work, (void*)ac->user, -1);

      /* parse challenge text */
      ac->challenge_text = string_alloc(BSTR(&b), gc);

      return ac;
    }
  else
    return NULL;
}
Exemple #4
0
static bool
in_src_get (const struct in_src *is, char *line, const int size)
{
	if (is->type == IS_TYPE_FP)
	{
		return BOOL_CAST (fgets (line, size, is->u.fp));
	}
	else if (is->type == IS_TYPE_BUF)
	{
		bool status = buf_parse (is->u.multiline, '\n', line, size);
		if ((int) strlen (line) + 1 < size)
			strcat (line, "\n");
		return status;
	}
	else
	{
		return false;
	}
}
Exemple #5
0
static void
push_update_digest(md_ctx_t *ctx, struct buffer *buf, const struct options *opt)
{
    char line[OPTION_PARM_SIZE];
    while (buf_parse(buf, ',', line, sizeof(line)))
    {
        /* peer-id might change on restart and this should not trigger reopening tun */
        if (strprefix(line, "peer-id "))
        {
            continue;
        }
        /* tun reopen only needed if cipher change can change tun MTU */
        if (strprefix(line, "cipher ") && !opt->ce.tun_mtu_defined)
        {
            continue;
        }
        md_ctx_update(ctx, (const uint8_t *) line, strlen(line)+1);
    }
}
Exemple #6
0
static void
parse_windows_proxy_setting_list (const char *str, const char *type, struct auto_proxy_info_entry *e, struct gc_arena *gc)
{
  struct gc_arena gc_local = gc_new ();
  struct auto_proxy_info_entry el;

  CLEAR (*e);
  if (type)
    {
      char buf[128];
      struct buffer in;

      buf_set_read (&in, (const uint8_t *)str, strlen (str));
      if (strchr (str, '=') != NULL)
	{
	  while (buf_parse (&in, ' ', buf, sizeof (buf)))
	    {
	      const char *t = parse_windows_proxy_setting (buf, &el, &gc_local);
	      if (t && !strcmp (t, type))
		goto found;
	    }
	}
    }
  else
    {
      if (!parse_windows_proxy_setting (str, &el, &gc_local))
	goto found;
    }
  goto done;

 found:
  if (el.server && el.port > 0)
    {
      e->server = string_alloc (el.server, gc);
      e->port = el.port;
    }

 done:
  gc_free (&gc_local);
}
Exemple #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)
    {
        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;
}