是不是需要实现ntlm的用户验证?
这个方面有没有相关的代码或者资料,谢谢

解决方案 »

  1.   

    以下代码片段摘自OpenVPN源码,支持BASIC、NTLM两种验证方式想详细了解可以下载完整代码  /* format HTTP CONNECT message */
      openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s\r\n"
      "Host: %s:%d\r\n",
        host,
        port,
        p->options.http_version,
    host,
    port);  msg (D_PROXY, "Send to HTTP proxy: 'CONNECT %s:%d HTTP/%s'", host, port, p->options.http_version);  /* send HTTP CONNECT message to proxy */
      if (!send_line_crlf (sd, buf))
        goto error;
    #if 0
      /* send User-Agent string if provided */
      if (p->options.user_agent)
        {
          openvpn_snprintf (buf, sizeof(buf), "User-Agent: %s",
    p->options.user_agent);
          if (!send_line_crlf (sd, buf))
    goto error;
        }  /* auth specified? */
      switch (p->auth_method)
        {
        case HTTP_AUTH_NONE:
          break;    case HTTP_AUTH_BASIC:
          openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: Basic %s",
    username_password_as_base64 (p, &gc));
          msg (D_PROXY, "Attempting Basic Proxy-Authorization");
          dmsg (D_SHOW_KEYS, "Send to HTTP proxy: '%s'", buf);
          openvpn_sleep (1);
          if (!send_line_crlf (sd, buf))
    goto error;
          break;#if NTLM
        case HTTP_AUTH_NTLM:
          openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s",
    ntlm_phase_1 (p, &gc));
          msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 1");
          dmsg (D_SHOW_KEYS, "Send to HTTP proxy: '%s'", buf);
          openvpn_sleep (1);
          if (!send_line_crlf (sd, buf))
    goto error;
          break;
    #endif    default:
          ASSERT (0);
        }
      /* send empty CR, LF */
      openvpn_sleep (1);
      if (!send_crlf (sd))
        goto error;
    #endif
      
      /* receive reply from proxy */
      if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
        goto error;  /* remove trailing CR, LF */
      chomp (buf);  msg (D_PROXY, "HTTP proxy returned: '%s'", buf);  /* parse return string */
      nparms = sscanf (buf, "%*s %d", &status);  /* check for a "407 Proxy Authentication Required" response */
      if (nparms >= 1 && status == 407)
        {
          msg (D_PROXY, "Proxy requires authentication");      /* check for NTLM */
          if (p->auth_method == HTTP_AUTH_NTLM)
            {
    #if NTLM
              /* look for the phase 2 response */          while (true)
                {
                  if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
                    goto error;
                  chomp (buf);
                  msg (D_PROXY, "HTTP proxy returned: '%s'", buf);              openvpn_snprintf (get, sizeof get, "%%*s NTLM %%%ds", (int) sizeof (buf2) - 1);
                  nparms = sscanf (buf, get, buf2);
                  buf2[127] = 0; /* we only need the beginning - ensure it's null terminated. */              /* check for "Proxy-Authenticate: NTLM TlRM..." */
                  if (nparms == 1)
                    {
                      /* parse buf2 */
                      msg (D_PROXY, "auth string: '%s'", buf2);
                      break;
                    }
                }
              /* if we are here then auth string was got */
              msg (D_PROXY, "Received NTLM Proxy-Authorization phase 2 response");          /* receive and discard everything else */
              while (recv_line (sd, NULL, 0, p->options.timeout, true, NULL, signal_received))
                ;          /* now send the phase 3 reply */          /* format HTTP CONNECT message */
              openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%d HTTP/%s\r\n"
      "Host: %s",
        host,
        port,
        p->options.http_version,
    host);          msg (D_PROXY, "Send to HTTP proxy: 'CONNECT %s:%d HTTP/%s'", host, port, p->options.http_version);          /* send HTTP CONNECT message to proxy */
              if (!send_line_crlf (sd, buf))
                goto error;          /* send HOST etc, */
              openvpn_sleep (1);
              openvpn_snprintf (buf, sizeof(buf), "Host: %s", host);
              msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
              if (!send_line_crlf (sd, buf))
                goto error;          openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s",
        ntlm_phase_3 (p, buf2, &gc));
              msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 3");
              msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
              openvpn_sleep (1);
              if (!send_line_crlf (sd, buf))
        goto error;
              /* ok so far... */
              /* send empty CR, LF */
              openvpn_sleep (1);
              if (!send_crlf (sd))
                goto error;          /* receive reply from proxy */
              if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
                goto error;          /* remove trailing CR, LF */
              chomp (buf);          msg (D_PROXY, "HTTP proxy returned: '%s'", buf);          /* parse return string */
              nparms = sscanf (buf, "%*s %d", &status);
    #else
      ASSERT (0); /* No NTLM support */
    #endif
    }
          else goto error;
        }
      /* check return code, success = 200 */
      if (nparms < 1 || status != 200)
        {
          msg (D_LINK_ERRORS, "HTTP proxy returned bad status");
    #if 0 
          /* DEBUGGING -- show a multi-line HTTP error response */
          while (true)
    {
      if (!recv_line (sd, buf, sizeof (buf), p->options.timeout, true, NULL, signal_received))
        goto error;
      chomp (buf);
      msg (D_PROXY, "HTTP proxy returned: '%s'", buf);
    }
    #endif
          goto error;
        }  /* receive line from proxy and discard */
      if (!recv_line (sd, NULL, 0, p->options.timeout, true, NULL, signal_received))
        goto error;  /*
       * Toss out any extraneous chars, but don't throw away the
       * start of the OpenVPN data stream (put it in lookahead).
       */
      while (recv_line (sd, NULL, 0, 2, false, lookahead, signal_received))
        ;  gc_free (&gc);
      return;
      

  2.   

    一般服务器只是用base64的验证,如果你的帐号和密码没弄对,自然是会出现错误的,而且用户名和密码也是弄成base64格式,以base64验证的格式发送给代理服务器才会验证成功的.