Destroying client-related data in a multi-client/server system - c++

I will build a multi-client/server system. It's expected to work like this:
The client comunicates with the server using TCP/IP
When the client makes the connection to the server, the client sends a command string. When the server receives the command string, it parses it, do the required work and then sends a response to the client.
When the client closes the TCP connection, the server will destroy the resource related to this client.
The server is a multi-threaded program. The command receive, the command parse, the command deal and the response to the client may each be in a different thread.
Now, I want to define a CmdTcpContext class to contain the data related to the client.
class CmdTcpContext
18 {
19 public:
20 CmdTcpContext(){recv_buff_.SetRecvList(&recv_list_);}
21 ~CmdTcpContext(){}
22
23 CmdRecvBuffer & recv_buff(){return recv_buff_;}
24 SendBuffer & send_buff(){return send_buff_;}
25
26 RecvList<CmdPackage> & recv_list(){return recv_list_;}
27 RecvList<CmdPackage> & send_list(){return send_list_;}
28
29 InetAddr & inet_addr(){return addr_;}
30 SockStream & sock_stream(){return stream_;}
31
32 EventHandler * event_handler(){return handler_;}
33 void event_handler(EventHandler * eh){handler_ = eh;}
34 private:
35 SockStream stream_;
36 InetAddr addr_;
37
38 CmdRecvBuffer recv_buff_;
39 SendBuffer send_buff_;
40
41 RecvList<CmdPackage> recv_list_;
42 RecvList<CmdPackage> send_list_;
43
44 EventHandler *handler_;
45 };
My problem is: how can I destroy the CmdTcpContext object when the client closes the connection?

Related

"queueproxy" : error reverse proxying request; sockstat: sockets TCP: inuse 27 orphan 2 tw 20 alloc 593 mem 52

I've issue with respect to above subject, using
knative v1.2.5
istio 1.12.7
Every 20mins we see below error in the queue proxy,
error: "context canceled"
knative.dev/key: "test-common-service/test-app-0-0-0"
knative.dev/pod: "test-app-0-0-0-deployment-xxxxxxx-xxxxx"
logger: "queueproxy"
message: "error reverse proxying request; sockstat: sockets: used 44
TCP: inuse 27 orphan 2 tw 20 alloc 593 mem 52
UDP: inuse 0 mem 3
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0
Can someone please let me know how can I fix this.
Thank you!
It looks like you may have requests which are hitting request timeouts in the queue proxy. What is your typical request latency, and what is the Revision timeoutSeconds set to?
It's also possible that istio is cancelling (resetting) some of the TCP connections to the queue-proxy, but that seems unlikely.

Using Boost-Beast (Asio) http client with SSL (HTTPS)

I am new to SSL and the Boost-Beast library, and also C++, but that's a different story.
I have a question regarding using HTTPS (SSL) with Beast. I am going to use the library to connect to a REST service and post JSON to a server where I do not control the certificates, the API etc.
And it kind of works.
The thing is that I do not clearly understand HOW it works. In the example that comes with Beast it is referenced to a file example/common/root_certificates.hpp where it is two certificates in base64 format or something like that.
When I tried the example, I got it to work with POST a JSON string to a server, let's call it "exampleserver.com". Connected to both port 80 and 443. Even though I commented out the line where it calls the root certificate function, load_root_certificates(ctx);. No errors from handshaking or anything else showed up. And the server responded correctly.
So, my questions are then:
1) Did the Beast library get the certificate from exampleserver.com or did I already have it installed and that's why it worked? If so what happens when it expires? Do I have to reinstall a new one on every client that uses my application?
I would prefer to not have any hardcoded certificates in my code to check it upon. The certificate says DigiCert Global Root CA -> DigiCert SHA2 Secure Server CA is that a standard certificate maybe that comes with the browser?
2) Did it just use plain HTTP over port 443 (no SSL)? Don know if this is possible at all...
Even though I commented out the line where it calls the root certificate funtion, "load_root_certificates(ctx);"
In that case, openssl uses the systemwide default certificate store (e.g. on linux /etc/ssl/certs), so the "usual" authorities will be trusted (just like e.g. your browser does).
1) Did the Beast library get the certificate from "exampleserver.com" or did I already have it installed and thats why it worked?
Yes.
If so what happens when it expires?
It will fail to verify. Test it, if you want: https://expired.badssl.com/
That site has many excellent SSL tests (https://badssl.com)
The certificate says "DigiCert Global Root CA -> DigiCert SHA2 Secure Server CA" is that a standard certificate maybe that comes with the browser?
The browser's trusted certificates aren't relevant (you're not using the browser). However, you can see openssl's (see above), or you can test using something like
openssl s_client -connect exampleserver.com:443 -verify -showcerts
Which prints something similar to
verify depth is 0
CONNECTED(00000003)
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = US, ST = TX, L = Houston, O = "cPanel, Inc.", CN = "cPanel, Inc. Certification Authority"
verify return:1
depth=0 CN = tradingfleet.com
verify return:1
---
Certificate chain
0 s:/CN=tradingfleet.com
i:/C=US/ST=TX/L=Houston/O=cPanel, Inc./CN=cPanel, Inc. Certification Authority
1 s:/C=US/ST=TX/L=Houston/O=cPanel, Inc./CN=cPanel, Inc. Certification Authority
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFUjCCBDqgAwIBAgIQPI9I0oyjgNMrudesOYyqgDANBgkqhkiG9w0BAQsFADBy
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCVFgxEDAOBgNVBAcTB0hvdXN0b24xFTAT
BgNVBAoTDGNQYW5lbCwgSW5jLjEtMCsGA1UEAxMkY1BhbmVsLCBJbmMuIENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MDIxODAwMDAwMFoXDTE4MDUxOTIzNTk1
OVowGzEZMBcGA1UEAxMQdHJhZGluZ2ZsZWV0LmNvbTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBANe5zu81biDwwIloBMFHWc2OvoiGTNBr2aya8auWrzRm
rmbOfugZOaIAms79jnINCQ7jy0Qk2xwblgCifCg7y/UfSXvv7IWUWcEDywsAoyz/
sUc9myvQbot+kD1DaxVoyN85LnDehaYF5+myDznJISQe1ei01n/aIF8gwOz4k3Gn
R07Zh0sDRBjIiRsAL6ZljrPRk47cul2+8pD0qNJHHN0QX6hz/KPOugTiivI1+ymo
onSeeN29oh5oTtCHP2yj9+RNsCNcPAnbDawy0RAgFi2W5GyHiIo/NkUxBXN8tQxH
2xrPnY+MQJHUcKXJd//DTX6tWoQqo4xisN6Q9iZ3+R8CAwEAAaOCAjkwggI1MB8G
A1UdIwQYMBaAFH4DWmVBa6d+CuG4nQjqHY4dasdlMB0GA1UdDgQWBBQKTFmhmBNx
pS9uBbXjqE1ZjCOiFjAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNV
HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA6BgsrBgEEAbIx
AQICNDArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29tL0NQ
UzAIBgZngQwBAgEwTAYDVR0fBEUwQzBBoD+gPYY7aHR0cDovL2NybC5jb21vZG9j
YS5jb20vY1BhbmVsSW5jQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwfQYIKwYB
BQUHAQEEcTBvMEcGCCsGAQUFBzAChjtodHRwOi8vY3J0LmNvbW9kb2NhLmNvbS9j
UGFuZWxJbmNDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNydDAkBggrBgEFBQcwAYYY
aHR0cDovL29jc3AuY29tb2RvY2EuY29tMIGXBgNVHREEgY8wgYyCEHRyYWRpbmdm
bGVldC5jb22CF2NwYW5lbC50cmFkaW5nZmxlZXQuY29tghVtYWlsLnRyYWRpbmdm
bGVldC5jb22CGHdlYmRpc2sudHJhZGluZ2ZsZWV0LmNvbYIYd2VibWFpbC50cmFk
aW5nZmxlZXQuY29tghR3d3cudHJhZGluZ2ZsZWV0LmNvbTANBgkqhkiG9w0BAQsF
AAOCAQEAPFIZv1oHXm79+uoLnP9Sya2qEghOn/uPpNtappgUSrh2Pb0MueX84C0P
4HRS4yHRO1TD9ZOfCuPsguzXhl+RUB7Asl2iAhwthoZGMLhv6uaUnAUHZbpdkJY3
r/quuWHXDGNoe2quAOxGLPDO7WMvrDh1hFi7x7AGshkRSZ4DREBnCS7iprKzKL6H
BaNqtAlWgoXcSSg1RpnbU2o4bWIv8mZG0ATr7Cc8VSf04SjBLZnLTNeqo6Z+ALQ3
yrFsAytim6857FB231V5NEvLh+iZjSOuBG9xv+4Nw46bVz9z8QxB3czAodrDGXbB
lgH1s5f486lRq45dRn/hGY+DZjJXgg==
-----END CERTIFICATE-----
subject=/CN=tradingfleet.com
issuer=/C=US/ST=TX/L=Houston/O=cPanel, Inc./CN=cPanel, Inc. Certification Authority
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4988 bytes and written 431 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: 24CB439538212A23E0391887F856E369858AB6864B25DA5F1FD618550C41EB92
Session-ID-ctx:
Master-Key: 1B8A3028923478527196B429D10F3584C5FA5DE4175C834CBBEF9EB19013FBFE58E7668CED9C0877E15F4F214A61F80C
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - ca 83 5a 76 c2 51 7b c7-68 15 12 a7 cb c9 f5 35 ..Zv.Q{.h......5
0010 - 0a dc c1 2a 90 fd 61 69-0a d9 89 09 f0 c4 b3 40 ...*..ai.......#
0020 - 79 dc 97 8a c5 0d a1 67-85 5e b4 25 47 94 ed 23 y......g.^.%G..#
0030 - 42 df b2 99 25 ec b1 fa-d7 3e 3e 24 37 ef 67 ef B...%....>>$7.g.
0040 - 56 f4 d2 57 cd 47 48 bd-d7 86 b1 2f b5 76 d6 db V..W.GH..../.v..
0050 - 12 9d 7a d3 94 b0 58 bf-c5 c4 3e 7d 05 98 75 1d ..z...X...>}..u.
0060 - 31 bc 9b 23 4f a7 ce 37-af 77 8a 96 89 20 20 64 1..#O..7.w... d
0070 - 3d bf de 25 b2 09 02 20-49 09 b5 57 a1 c3 75 ed =..%... I..W..u.
0080 - 97 ec 51 d2 46 f7 c6 b7-4a d8 b2 db 95 eb ac d6 ..Q.F...J.......
0090 - be 76 14 80 ca 08 dc b7-b6 cb e9 c9 cc 8b 45 bd .v............E.
00a0 - d7 1d a7 88 9b a4 91 33-aa 23 fe 23 65 b8 e1 d9 .......3.#.#e...
00b0 - 98 f6 55 1e 25 32 97 b5-22 ac d0 58 01 a6 42 60 ..U.%2.."..X..B`
Start Time: 1522150150
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
^C
2) Did it just use plain http over port 443 (no SSL)? Don know if this is possible at all...
No it didn't.
It's possible only given a whacky server config, but usually if your server connects https from a browser, it will be impossible to connect plain:
https://askubuntu.com/questions/860511/is-it-possible-to-set-same-port-work-with-http-and-https
on whacky configs: Nodejs HTTP and HTTPS over same port
As suggested by Vinnie Falco, in the file example/common/root_certificates.hpp, use the following header only library https://github.com/djarek/certify
In your code add the following includes
#include <boost/certify/extensions.hpp>
#include <boost/certify/https_verification.hpp>
And replace the initial code:
// This holds the root certificate used for verification
load_root_certificates(ctx);
// Verify the remote server's certificate
ctx.set_verify_mode(ssl::verify_peer);
by this:
ctx.set_verify_mode(ssl::context::verify_peer );
boost::certify::enable_native_https_server_verification(ctx);
Tested quickly with site badssl.com and sites with good ssl certificate. And it's work like a charm.
Possibly, you already figured it out by now.
I tried the same beast sample (Boost libraries 1.70) and had to make the following change to the ctor of session (I did it there it may be possible to make the change at some other place in code as well):
ws_.next_layer().set_verify_mode(boost::asio::ssl::verify_peer);
ws_.next_layer().set_verify_callback(std::bind(&session::verify_certificate, this, _1, _2));
and added a method (that I copied as is from the Asio client sample):
bool verify_certificate(bool pverified_ok, ssl::verify_context& ctx)
{
char subject_name[256];
X509 *cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
std::cout << "Verifying " << subject_name << std::endl;
return pverified_ok;
}
This change causes the verification to fail (I had removed the hard-coded certificates since I did not want to use those). The callback assists in logging that the server certificate was actually being verified.
Just like the Asio sample adding a CA certificate to the ssl::context e.g.
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
ctx.load_verify_file("ca.pem"); // CA certificate
Causes the verification to pass.
You need to create the self-signed CA certificate and server certificate signed by it and place it in the server code (again from Asio sample) e.g.
context_.use_certificate_chain_file("..\\sample-server1.pem");
context_.use_private_key_file("..\\sample-server1-key.pem", boost::asio::ssl::context::pem);
context_.use_tmp_dh_file("..\\dh2048.pem");

Using JAX-WS in Weblogic 10.3.6 combining 2waySSL and Proxy

I have implemented a connector to different kinds of webservice with JAX-WS in weblogic 10.3.6, the connector can be configured with 2waySSL, proxy and combine both of them.
The implementation to use proxy works properly using ClientProxyFeature.
In the same way with 2waySSL using a custom SSLSocketFactory as Oracle says in the documentation. Persisting the State of a Request over SSL (JAX-WS Only)
((BindingProvider) port).getRequestContext().put(
JAXWSProperties.SSL_SOCKET_FACTORY,
SSLClientUtil.getSSLSocketFactoryFromSysProperties());
The issue occurs when combine both features. The handshake does not happend (ClientHello)
The error is:
ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', READ: TLSv1.2 Alert, length = 64
Padded plaintext after DECRYPTION: len = 64
0000: F0 E5 6E 9F 6F F4 BB 2E 07 29 56 FE 34 0A 10 0B ..n.o....)V.4...
0010: 02 28 7E 75 92 F7 03 4E CD 3A 7E 0B E2 6A 7C 8E .(.u...N.:...j..
0020: 3B F8 4E F5 98 A3 D3 B4 67 76 20 49 1B 77 07 5E ;.N.....gv I.w.^
0030: 9D 66 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D .f..............
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', RECV TLSv1.2 ALERT: fatal, handshake_failure
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)', fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: handshake_failure
<13-sep-2017 09H32' CEST> <Debug> <SecuritySSL> <BEA-000000> <[Thread[[ACTIVE] ExecuteThread: '19' for queue: 'weblogic.kernel.Default (self-tuning)',5,Pooled Threads]]weblogic.security.SSL.jsseadapter: SSLENGINE: Exception occurred during SSLEngine.unwrap(ByteBuffer,ByteBuffer[]).
javax.net.ssl.SSLException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:188)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1614)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1582)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1751)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1043)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:865)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:740)
Debuging and decompiling weblogic source I can see that the HttpsClient when use proxy does not use the custom SSLSocketFactory.
1) In the transport class weblogic.wsee.jaxws.transport.http.client.HttpClientTransport weblogic opens the connection:
protected HttpURLConnection openConnection(Packet paramPacket)
…
localSSLSocketFactory = (javax.net.ssl.SSLSocketFactory)this.context.invocationProperties.get("com.sun.xml.ws.transport.https.client.SSLSocketFactory");
if ((localSSLSocketFactory != null) && ((localSSLSocketFactory instanceof javax.net.ssl.SSLSocketFactory)))
{
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("set (jdk) ssl socketfactory to wls socketfactory");
}
((weblogic.net.http.HttpsURLConnection)localObject3).setSSLSocketFactory(new MySSLSocketFactory((javax.net.ssl.SSLSocketFactory)localSSLSocketFactory));
}
…
As you can see, set the custom SSLSocketFactory.
2) Without a proxy, the weblogic.net.http.HttpsClient uses the custom SSLSocketFactory to create the socket
this.serverSocket = localSocketFactory.createSocket(arrayOfInetAddress[i], paramInt);
The localSocketFactory is the custom SSLSocketFactory.
3) But if uses proxy then create a new SSLSocketFactory
private void makeConnectionUsingProxy(String s, int i, boolean flag)
throws IOException
{
javax.net.ssl.SSLSocketFactory sslsocketfactory;
int j;
SSLContextWrapper sslcontextwrapper = SSLSetup.getSSLContext(sslInfo);
sslcontextwrapper.getHostnameVerifier().setProxyMapping(s, host);
sslcontextwrapper.getTrustManager().setProxyMapping(s, host);
sslsocketfactory = sslcontextwrapper.getSSLSocketFactory();
The sslInfo is an object without the keystore or truststore informed in the SSLSocketFactory. I haven't seen any way to inform the object sslInfo (weblogic.security.SSL.SSLClientInfo)
The variables to start the weblogic are the next:
-Dweblogic.security.SSL.nojce=true -Djavax.net.debug=all -Dssl.debug=true
-Djavax.net.ssl.keyStore=XXXXXs -Djavax.net.ssl.keyStorePassword=XXXXX
-Djdk.tls.enableRC4CipherSuites=true -Djsse.enableSNIExtension=false -Dweblogic.ssl.JSSEEnabled=true -Dweblogic.security.SSL.enableJSSE=true -Dweblogic.security.SSL.nojce=true -Dweblogic.security.SSL.ignoreHostnameVerification=true
The custom SSLSocketFactory is create with this params and with the default trustore. When no proxy is used everything works propertly.
I don't understand why to make the connection with a proxy weblogic does not use the same SSLSocketFactory.
Any ideas?
Oracle people have confirm us that is a "bug" in this implementation, it is only possible to solve with the property -DUseSunHttpHandler=true.
In Oracle 12 you can use the setter method setUseSunHttpHandler of the ClientProxyFeature. But with the weblogic implementation is not possible to solve.

happy base integration not working with hbase

I am able to connect with my hbase
connection = happybase.Connection(host='node-04',port=16000)
table = connection.table('test')
These 2 commands work without any error. but when I run the below cammand i am getting following error
print connection.tables()
error
Traceback (most recent call last)
<ipython-input-49-de0848d7286f> in <module>()
----> 1 print connection.tables()
/root/anaconda2/lib/python2.7/site-packages/happybase/connection.pyc in tables(self)
236 :rtype: List of strings
237 """
--> 238 names = self.client.getTableNames()
239
240 # Filter using prefix, and strip prefix from names
/root/anaconda2/lib/python2.7/site-packages/happybase/hbase/Hbase.pyc in getTableNames(self)
815 #return returns a list of names
816 """
--> 817 self.send_getTableNames()
818 return self.recv_getTableNames()
819
/root/anaconda2/lib/python2.7/site-packages/happybase/hbase/Hbase.pyc in send_getTableNames(self)
823 args.write(self._oprot)
824 self._oprot.writeMessageEnd()
--> 825 self._oprot.trans.flush()
826
827 def recv_getTableNames(self, ):
/root/anaconda2/lib/python2.7/site-packages/thrift/transport/TTransport.pyc in flush(self)
172 # reset wbuf before write/flush to preserve state on underlying failure
173 self.__wbuf = StringIO()
--> 174 self.__trans.write(out)
175 self.__trans.flush()
176
/root/anaconda2/lib/python2.7/site-packages/thrift/transport/TSocket.pyc in write(self, buff)
128 have = len(buff)
129 while sent < have:
--> 130 plus = self.handle.send(buff)
131 if plus == 0:
132 raise TTransportException(type=TTransportException.END_OF_FILE,
error: [Errno 32] Broken pipe
I am usingHbase version:1.1.2.2.3.4.0-3485
Please help if you can suggest any package which i can use to code for hbase using python
happybase requires you to connect to the thrift daemon, which you need to start on your hbase cluster. happybase does not connect to hbase nodes directly.
judging from the port number, you are not connecting to thrift (uses port 9090 by default) but to the hbase master. this is not how happybase works.

How a device registers itself after adding a pass

When I add a pass in a device, I see on the console like this:
Mar 26 14:32:36 CamMobs-iPod4 passd[7128] <Warning>: Card has more than 10 locations. Capping.
Mar 26 14:32:38 CamMobs-iPod4 MobileSafari[7115] <Warning>: Warning: Attempt to dismiss from view controller <BrowserRootViewController: 0x1ed546a0> while a presentation or dismiss is in progress!
Mar 26 14:32:39 CamMobs-iPod4 backboardd[52] <Warning>: CoreAnimation: updates deferred for too long
Mar 26 14:32:39 CamMobs-iPod4 locationd[41] <Notice>: Location icon should now be in state 'Active'
Mar 26 14:32:50 CamMobs-iPod4 locationd[41] <Notice>: Location icon should now be in state 'Inactive'
Mar 26 14:32:52 CamMobs-iPod4 profiled[7122] <Notice>: (Note ) profiled: Idled.
Mar 26 14:32:52 CamMobs-iPod4 profiled[7122] <Notice>: (Note ) profiled: Service stopping.
Mar 26 14:33:31 CamMobs-iPod4 locationd[41] <Warning>: Launch Services: Registering unknown app identifier com.apple.PassKit failed
Mar 26 14:33:31 CamMobs-iPod4 locationd[41] <Warning>: Launch Services: Unable to find app identifier com.apple.PassKit
Mar 26 14:33:33 CamMobs-iPod4 configd[50] <Notice>: network changed: v4(en0:192.168.1.109) DNS Proxy
Mar 26 14:33:53 CamMobs-iPod4 backboardd[52] <Notice>: Posting 'com.apple.iokit.hid.displayStatus' notifyState=0
.....
Why it tries to register to com.apple.PassKit ?
In my server, I use some codes in index.php like the following:
<?php
// Transfer Request URL into array
$request = explode("/", substr(#$_SERVER['REQUEST_URI'], 1));
//$request = explode("/", substr(#$_SERVER['REQUEST_URI'], 1));
print_r($_SERVER['REQUEST_URI']);
if (strtoupper($_SERVER['REQUEST_METHOD']) === "POST"
&& isset($_SERVER['HTTP_AUTHORIZATION'])
&& strpos($_SERVER['HTTP_AUTHORIZATION'], 'ApplePass') === 0
&& $request[2] === "devices"
&& $request[4] === "registrations") {
$auth_key = str_replace('ApplePass ', '', $_SERVER['HTTP_AUTHORIZATION']);
$device_id = $request[3];
$pass_id = $request[5];
$serial = $request[6];
echo $request[3];
//$device_id = $_POST[''];
echo $device_id;
echo $pass_id;
echo $serial ;
// Catch the JSON post and decode it
$dt = #file_get_contents('php://input');
// $dt = #file_get_contents('php://input');
//$device_token = json_decode($dt);
//$device_token = $device_token->pushToken;
$pushtoken=json_decode($dt)->pushToken;
if (!$device_token) die('No Token Found'); // Token wasn't found
$dbhost = 'localhost:8889';
$dbuser = 'root';
$dbpass = 'root';
$dbname = 'passesdb';
$conn = mysql_connect($dbhost, $dbuser, $dbpass)
or die ('Error connecting to mysql'.mysql_error());
mysql_select_db($dbname);
mysql_query("SET NAMES UTF8");
mysql_query($sql,$conn);
$table = 'Devices';
$sql = mysql_query("insert into Devices values('$device_id','$pushtoken')");
mysql_query($sql);
exit;
}
?>
This is what a successful registration looks like in the console:
1. Mar 26 17:00:03 iPhone5 passd[6262] <Warning>: Generating POST request with URL <https:/afr.passk.it/v1/devices/7864dc8fdcfe739273cf7362a0db2b35/registrations/pass.it.passk.developer3/1wqdDAqHydkRURA9YCjbq>
2. Mar 26 17:00:03 iPhone5 passd[6262] <Warning>: Request contains header field <Authorization: ApplePass 5cdddad65324384efa39575a4cf22424>
3. Mar 26 17:00:03 iPhone5 passd[6262] <Warning>: Request contains body dictionary {
pushToken = 0bbe54794500332b789a3ddb69827386d5c9aad1cb035c9f2725761d419950b2;
}
4. Mar 26 17:00:04 iPhone5 passd[6262] <Warning>: Register task (for device 7864dc8fdcfe739273cf7362a0db2b35, pass type pass.it.passk.developer3, serial number 1wqdDAqHydkRURA9YCjbq; with web service url https://afr.passk.it/) got response with code 201
5. Mar 26 17:00:04 iPhone5 passd[6262] <Warning>: Generating GET request with URL <https:/afr.passk.it/v1/devices/7864dc8fdcfe739273cf7362a0db2b35/registrations/pass.it.passk.developer3?passesUpdatedSince=1364287618>
6. Mar 26 17:00:04 iPhone5 passd[6262] <Warning>: Generating GET request with URL <https:/afr.passk.it/v1/passes/pass.it.passk.developer3/1wqdDAqHydkRURA9YCjbq>
7. Mar 26 17:00:04 iPhone5 passd[6262] <Warning>: Request contains header field <If-Modified-Since: Tue, 26 Mar 2013 07:35:33 GMT>
8. Mar 26 17:00:04 iPhone5 passd[6262] <Warning>: Request contains header field <Authorization: ApplePass 5cdddad65324384efa39575a4cf22424>
9. Mar 26 17:00:04 iPhone5 passd[6262] <Warning>: Get serial #s task (for device 7864dc8fdcfe739273cf7362a0db2b35, pass type pass.it.passk.developer3, last updated 1364287618; with web service url https://afr.passk.it/) got response with code 204
10. Mar 26 17:00:04 iPhone5 passd[6262] <Warning>: Get serial numbers task completed with update tag (null), serial numbers (null)
11. Mar 26 17:00:05 iPhone5 passd[6262] <Warning>: Get pass task (pass type pass.it.passk.developer3, serial number 1wqdDAqHydkRURA9YCjbq, if-modified-since Tue, 26 Mar 2013 07:35:33 GMT; with web service url https://afr.passk.it/) got response with code 304
What you have posted above is only the last line of this process, (where passd has picked up that you have more than 10 locations in your pass.json).
If you examine the above you can see the flow of events that your web service needs to respond to:
Row 1: Device sends a POST request to:
https://webserviceURL/v1/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}/{serialNumber}`
Row 2: POST request is sent with the header field:
Authorization: ApplePass {authenticationToken}
Row 3: POST body contains the JSON Dictionary:
{
pushToken = {pushToken};
}
Provided your rewrite rule is correct, your PHP code should analyse the URL and capture the deviceLibraryIdentifier and pushToken and store it in the database, linked to the pass record containing the serialNumber, authenticationToken and passTypeIdentifier.
Then Row 4: Your web service responds to the device with a 201 code to indicate that the registration was successful.
On Row 5: The device then generates a GET request to your web service to check if there is a newer versions pof passes for the same certificate:
https:/webserviceURL/v1/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}?passesUpdatedSince={lastUpdateTag}
On Row 6, 7 and 8: The device generates a GET request to your web service to check if there is a newer version of this specific pass. It provides an If-Modified-Since header containing the date provided in the header of the last downloaded .pkpass bundle (Row 7), and provides another Authorization header containing Applepass {authenticationToken} (Row 8) so that your web service can validate the request against by checking the database record for the serialNumber.
https:/webserviceURL/v1/passes/{passTypeIdentifier}/{serialNumber}
Header: If-Modified-Since: {last modified date}
Header: Authorization: ApplePass {authenticationToken}
On Row 9: the web service responds with a 204 response, indicating that there are no serialNumbers for the passTypeIdentifier that require updating. Row 10 confirms this.
Finally, on Row 11, the device receives a 304 response from your web service, confirming that the pass it has just installed is the latest version of the pass.
The above outlines precisely what your web service will receive and the responses it needs to provide to successfully register a device.