/* * UPnP WPS Device - Web connections * Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2006-2007 Sony Corporation * Copyright (c) 2008-2009 Atheros Communications * Copyright (c) 2009, Jouni Malinen * * See wps_upnp.c for more details on licensing and code history. */ #include "includes.h" #include #include "common.h" #include "base64.h" #include "eloop.h" #include "uuid.h" #include "httpread.h" #include "wps_i.h" #include "wps_upnp.h" #include "wps_upnp_i.h" /*************************************************************************** * Web connections (we serve pages of info about ourselves, handle * requests, etc. etc.). **************************************************************************/ #define WEB_CONNECTION_TIMEOUT_SEC 30 /* Drop web connection after t.o. */ #define WEB_CONNECTION_MAX_READ 8000 /* Max we'll read for TCP request */ #define MAX_WEB_CONNECTIONS 10 /* max simultaneous web connects */ static const char *urn_wfawlanconfig = "urn:schemas-wifialliance-org:service:WFAWLANConfig:1"; static const char *http_server_hdr = "Server: unspecified, UPnP/1.0, unspecified\r\n"; static const char *http_connection_close = "Connection: close\r\n"; /* * Incoming web connections are recorded in this struct. * A web connection is a TCP connection to us, the server; * it is called a "web connection" because we use http and serve * data that looks like web pages. * State information is need to track the connection until we figure * out what they want and what we want to do about it. */ struct web_connection { /* double linked list */ struct web_connection *next; struct web_connection *prev; struct upnp_wps_device_sm *sm; /* parent */ int sd; /* socket to read from */ struct sockaddr_in cli_addr; int sd_registered; /* nonzero if we must cancel registration */ struct httpread *hread; /* state machine for reading socket */ int n_rcvd_data; /* how much data read so far */ int done; /* internal flag, set when we've finished */ }; /* * XML parsing and formatting * * XML is a markup language based on unicode; usually (and in our case, * always!) based on utf-8. utf-8 uses a variable number of bytes per * character. utf-8 has the advantage that all non-ASCII unicode characters are * represented by sequences of non-ascii (high bit set) bytes, whereas ASCII * characters are single ascii bytes, thus we can use typical text processing. * * (One other interesting thing about utf-8 is that it is possible to look at * any random byte and determine if it is the first byte of a character as * versus a continuation byte). * * The base syntax of XML uses a few ASCII punctionation characters; any * characters that would appear in the payload data are rewritten using * sequences, e.g., & for ampersand(&) and < for left angle bracket (<). * Five such escapes total (more can be defined but that does not apply to our * case). Thus we can safely parse for angle brackets etc. * * XML describes tree structures of tagged data, with each element beginning * with an opening tag with * matching label. (There is also a self-closing tag