解析主机时,可移植的本机客户端权限被拒绝

Portable native client Permission denied when resolving host

本文关键字:客户端 本机 权限 拒绝 可移植 主机      更新时间:2023-09-26

我正在编写一个小应用程序来测试和理解PNaCl。

该应用程序的目的是使用PNaCl框架中的HostResolver类来解析主机名和主机的ip。代码似乎工作正常,但我收到了一个拒绝访问错误(返回值-7),因为我没有向用户请求访问套接字层的权限(我想)。问题是我不知道该怎么做。我试图写一个清单文件,但什么也没发生。

注意:此应用程序必须在开放的Web上运行,并且不需要任何安装过程。我不想写Chrome应用程序。

我在网上没有找到任何线索,所以我很感激你的帮助。

hello_utttorial.cc:

#include <stdio.h>
#include <string.h>
#include <sstream>

#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/tcp_socket.h"
#include "ppapi/cpp/host_resolver.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/tcp_socket.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/utility/completion_callback_factory.h"

namespace {
  // exptected string from the browser 
  const char * const kHelloString = "hello"; 
  // the sting sent from the nacl module to the browser
  const char * const kReplyString ="hello from the PNaCl"; 
} 

class HelloTutorialInstance : public pp::Instance {
  pp::CompletionCallbackFactory<HelloTutorialInstance> callback_factory_;
  pp::TCPSocket tcp_socket_;
  pp::HostResolver resolver_;
 public:
  explicit HelloTutorialInstance(PP_Instance instance) : pp::Instance(instance),
      callback_factory_(this)
      {}
  virtual ~HelloTutorialInstance() {}
  virtual void HandleMessage(const pp::Var& var_message) { 
    if (!var_message.is_string())
      return; 
    std::string message = var_message.AsString(); 
    pp::Var var_reply; 
    test_socket_support(); 
     if( message == kHelloString){
      var_reply = pp::Var("So far so good"); 
      PostMessage(var_reply); 
    }
  }
 private:
 void test_socket_support(){
  if (!pp::TCPSocket::IsAvailable()) {
      PostMessage("TCPSocket not available");
      return;
    }
  tcp_socket_ = pp::TCPSocket(this);
  if (tcp_socket_.is_null()) {
      PostMessage("Error creating TCPSocket.");
      return;
   }
  if (!pp::HostResolver::IsAvailable()) {
    PostMessage("HostResolver not available");
    return;
  }
  resolver_ = pp::HostResolver(this);
  if (resolver_.is_null()) {
    PostMessage("Error creating HostResolver.");
    return;
  }

  int port = 80;
  pp::CompletionCallback callback = '
      callback_factory_.NewCallback(&HelloTutorialInstance::OnResolveCompletion);
  PP_HostResolver_Hint hint = { PP_NETADDRESS_FAMILY_UNSPECIFIED, 0 };
  resolver_.Resolve("http://www.google.com", port, hint, callback);
  PostMessage("Resolving ...");
  }
 void OnResolveCompletion(int32_t result) {
  if (result != PP_OK) {
    char str[100] = {0}; 
    sprintf(str, "Resolved failed %d", result);
    PostMessage(str);
    if( result == PP_ERROR_NOACCESS )
        PostMessage("Access denied");
    return;
  }
  pp::NetAddress addr = resolver_.GetNetAddress(0);
  PostMessage(std::string("Resolved: ") +
              addr.DescribeAsString(true).AsString());
  }
}; 
class HelloTutorialModule : public pp::Module {
 public:
  HelloTutorialModule() : pp::Module() {}
  virtual ~HelloTutorialModule() {}
  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new HelloTutorialInstance(instance);
  }
};
namespace pp {
  Module* CreateModule() {
  return new HelloTutorialModule();
  }
}  // namespace pp

Manifest.json:

{
  "name": "hello_tutorial",
  "version": "31.0.1650.57",
  "manifest_version": 2,
  "description": "socket Example",
  "offline_enabled": true,
  "permissions": [
    {
        "socket": [
            "tcp-listen:*:*", 
            "tcp-connect", 
            "resolve-host", 
            "udp-bind:*:*", 
            "udp-send-to:*:*"
        ]
    }
]
}

index.html:

<div id="listener">
  <script type="text/javascript">
    var listener = document.getElementById('listener');
    listener.addEventListener('load', moduleDidLoad, true);
    listener.addEventListener('message', handleMessage, true);
  </script>
  <embed id="hello_tutorial"
         width=0 height=0
         src="hello_tutorial.nmf"
         type="application/x-pnacl" />
</div>

输出:

Resolving ... 
So far so good
Resolved failed -7 
Access denied 

只有来自chrome商店的打包应用程序才能使用socket API。

启动Chrome时,您可以通过设置"--allow-nacl socket-api=foo"标志来访问套接字进行开发。将"foo"替换为加载应用程序的主机名"localhost"(如果您从本地机器加载)。请注意,您应该而不是在"about:flags"上启用"allow nacl socket-api"选项。这会覆盖命令行选项,但不包括授权主机的列表,因此结果是没有主机具有使用套接字API的权限。

pp::HostResolver和其他原始套接字接口只能由Chrome应用程序使用,不能在开放式web上使用。请参见此处。

此外,如果您决定制作Chrome应用程序,请参阅此处的文档。您不能只添加一个manifest.json文件,还必须指定一个启动应用程序的后台脚本。