1/* 2 * Copyright (c) 2000, 2013, 2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25 26#ifndef __SCNC_MAIN__ 27#define __SCNC_MAIN__ 28 29#include <net/if.h> 30#include <sys/queue.h> 31#include <netinet/in.h> 32#include <vproc.h> 33#include "../Drivers/L2TP/L2TP-plugin/vpn_control.h" 34#include <CoreFoundation/CFUserNotification.h> 35#include <dns_sd.h> 36#include <IOKit/network/IOEthernetController.h> 37 38#if TARGET_OS_EMBEDDED 39#include <CoreTelephony/CTServerConnectionPriv.h> 40#endif 41#include <sys/types.h> 42 43#include "ne_sm_bridge_private.h" 44 45//#define PRINTF(x) printf x 46#define PRINTF(x) 47 48#define DEBUG 1 49 50#define FAR_FUTURE (60.0 * 60.0 * 24.0 * 365.0 * 1000.0) 51 52#define FLOW_DIVERT_CONTROL_FD_MAX_COUNT 2 53 54 55/* service client, used for arbitration */ 56struct service_client { 57 TAILQ_ENTRY(service_client) next; 58 void *client; 59 int autoclose; 60}; 61 62enum { 63 FLAG_SETUP = 0x1, /* needs to process service setup */ 64 FLAG_FREE = 0x2, /* needs to dispose of the ppp structure */ 65 FLAG_CONNECT = 0x4, /* needs to connect service */ 66 FLAG_CONFIGCHANGEDNOW = 0x8, /* setup has changed, dialondemand needs to rearm with no delay */ 67 FLAG_CONFIGCHANGEDLATER = 0x10, /* setup has changed, dialondemand needs to rearm with delay if applicable */ 68 FLAG_ONTRAFFIC = 0x20, /* is the connection currently in dial-on-traffic mode */ 69 FLAG_ALERTERRORS = 0x40, /* error alerts are enabled */ 70 FLAG_ALERTPASSWORDS = 0x80, /* passwords alerts are enabled */ 71 // FLAG_STARTING = 0x100 /* pppd is started, and hasn't yet updated the phase */ 72 FLAG_DARKWAKE = 0x100, /* system is in dark wake */ 73 FLAG_FIRSTDIAL = 0x200, /* is it the first autodial attempt after major event */ 74 FLAG_ONDEMAND = 0x400, /* is the connection currently in on-demand mode */ 75 FLAG_USECERTIFICATE = 0x800, /* is the connection using cert authentication ? */ 76 FLAG_AUTHEN_EXTERNAL = 0x00001000, /* get credentials externally from vpn authen agent */ 77 78 /* setup keys */ 79 FLAG_SETUP_ONTRAFFIC = 0x00010000, /* is DialOnDemand (onTraffic) set ? ONLY FOR PPP */ 80 FLAG_SETUP_DISCONNECTONLOGOUT = 0x00020000, /* is DisconnectOnLogout set ? */ 81 FLAG_SETUP_DISCONNECTONSLEEP = 0x00040000, /* is DisconnectOnSleep set ? */ 82 FLAG_SETUP_PREVENTIDLESLEEP = 0x00080000, /* is PreventIdleSleep set ? */ 83 FLAG_SETUP_DISCONNECTONFASTUSERSWITCH = 0x00100000, /* is DisconnectOnFastUserSwitch set ? */ 84 FLAG_SETUP_ONDEMAND = 0x00200000, /* is OnDemand set ? VPN OnDemand scheme */ 85 FLAG_SETUP_PERSISTCONNECTION = 0x00400000, /* is ConnectionPersistence enabled ? */ 86 FLAG_SETUP_APP_LAYER = 0x00800000, /* Are there App Rules configured? */ 87 88 FLAG_SETUP_NETWORKDETECTION = 0x01000000, 89 FLAG_CONNECT_ONDEMAND = 0x02000000, 90 FLAG_PROBE_FOUND = 0x04000000, 91 FLAG_SETUP_DISCONNECTONWAKE = 0x08000000 /* is DisconnectOnWake enabled? */ 92}; 93 94enum { 95 TYPE_PPP = 0x0, /* PPP TYPE service */ 96 TYPE_IPSEC = 0x1, /* IPSEC TYPE service */ 97}; 98 99#if TARGET_OS_EMBEDDED 100enum { 101 CELLULAR_BRINGUP_SUCCESS_EVENT, 102 CELLULAR_BRINGUP_FATAL_FAILURE_EVENT, 103 CELLULAR_BRINGUP_NETWORK_FAILURE_EVENT 104}; 105#endif 106 107#ifndef kSCPropNetVPNOnDemandRuleInterfaceTypeMatch 108#define kSCPropNetVPNOnDemandRuleInterfaceTypeMatch CFSTR("InterfaceTypeMatch") 109 110#define kSCValNetVPNOnDemandRuleInterfaceTypeMatchCellular CFSTR("Cellular") 111#define kSCValNetVPNOnDemandRuleInterfaceTypeMatchEthernet CFSTR("Ethernet") 112#define kSCValNetVPNOnDemandRuleInterfaceTypeMatchWiFi CFSTR("WiFi") 113 114#endif 115 116#ifndef kSCNetworkConnectionOnDemandPluginPIDs 117#define kSCNetworkConnectionOnDemandPluginPIDs CFSTR("PluginPIDs") 118#endif 119 120#ifndef kSCNetworkConnectionOnDemandProbeResults 121#define kSCNetworkConnectionOnDemandProbeResults CFSTR("ProbeResults") 122#define kSCPropNetVPNOnDemandRuleActionParameters CFSTR("ActionParameters") 123#define kSCValNetVPNOnDemandRuleActionEvaluateConnection CFSTR("EvaluateConnection") 124#define kSCPropNetVPNOnDemandRuleActionParametersDomainAction CFSTR("DomainAction") 125#define kSCPropNetVPNOnDemandRuleActionParametersDomains CFSTR("Domains") 126#define kSCPropNetVPNOnDemandRuleActionParametersRequiredDNSServers CFSTR("RequiredDNSServers") 127#define kSCPropNetVPNOnDemandRuleActionParametersRequiredURLStringProbe CFSTR("RequiredURLStringProbe") 128#define kSCValNetVPNOnDemandRuleActionParametersDomainActionConnectIfNeeded CFSTR("ConnectIfNeeded") 129#define kSCValNetVPNOnDemandRuleActionParametersDomainActionNeverConnect CFSTR("NeverConnect") 130#endif 131 132enum { 133 PLUGIN_UPDATE_DOWNLOAD_COMPLETE = 0x01, 134 PLUGIN_UPDATE_INSTALL_COMPLETE = 0x02, 135 PLUGIN_UPDATE_FINISHED = 0x03 136}; 137 138#define MDNS_NAT_MAPPING_MAX 4 // num of mappings per service 139 140typedef struct nat_reflexive_addr { 141 u_int32_t addr; 142 u_int16_t port; 143} nat_reflexive_addr_t; 144 145typedef struct mdns_nat_mapping { 146 DNSServiceRef mDNSRef; 147 DNSServiceRef mDNSRef_tmp; 148 int mDNSRef_fd; 149 u_int32_t interfaceIndex; 150 DNSServiceProtocol protocol; 151 uint16_t privatePort; 152 nat_reflexive_addr_t reflexive; 153 int up; 154} mdns_nat_mapping_t; 155 156typedef struct service_route { 157 struct service_route *next; 158 struct in_addr local_address; 159 struct in_addr local_mask; 160 struct in_addr dest_address; 161 struct in_addr dest_mask; 162 struct in_addr gtwy_address; 163 u_int16_t flags; 164 int installed; 165} service_route_t; 166 167/* this struct contains all the information to control a service */ 168 169struct ppp_service { 170 int controlfd[2]; /* pipe for process agent control */ 171 int statusfd[2]; /* pipe for process agent status */ 172 pid_t pid; /* pid of associated process */ 173 CFBundleRef bundleRef; /* bundle */ 174 175 int ndrv_socket; /* ndrv socket to maintain transport device up */ 176 u_int32_t phase; /* where the link is at */ 177 178 u_int32_t laststatus; /* last fail status */ 179 u_int32_t lastdevstatus; /* last device specific fail status */ 180 181 CFDictionaryRef newconnectopts; /* new connect options to use */ 182 uid_t newconnectuid; /* new connect uid */ 183 gid_t newconnectgid; /* new connect gid */ 184 mach_port_t newconnectbootstrap; /* new connect bootstrap */ 185 mach_port_t newconnectausession; /* new connect audit session */ 186 char lower_interface[16]; /* underlying interface name */ 187 u_int32_t lower_interface_media; /* underlying interface media */ 188}; 189 190struct ipsec_service { 191 u_int32_t phase; /* where the link is at */ 192 u_int32_t laststatus; /* last fail status */ 193 u_int32_t asserted; 194 CFMutableDictionaryRef config; /* ipsec config dict */ 195 struct sockaddr_in our_address; /* our side IP address */ 196 struct sockaddr_in peer_address; /* the other side IP address */ 197 CFRunLoopTimerRef timerref ; /* timer ref */ 198 199 /* racoon communication */ 200 int controlfd; /* racoon control socket */ 201 CFSocketRef controlref; /* racoon control socket ref */ 202 int eventfd; /* kernel event socket */ 203 CFSocketRef eventref; /* kernel event socket ref */ 204 u_int8_t *modecfg_msg; // saved modecfg message from client 205 u_int32_t modecfg_msglen; // modecfg message length 206 u_int8_t *msg; // message in pogress from client 207 u_int32_t msglen; // current message length 208 u_int32_t msgtotallen; // total expected len 209 struct vpnctl_hdr msghdr; // message header read 210 int config_applied; // has racoon config been applied ? 211 int policies_installed; // were ipsec policies installed ? 212 /* dynamically installed mode config policies */ 213 int modecfg_installed; 214 int modecfg_policies_installed; 215 CFMutableDictionaryRef modecfg_policies; /* mode config policies */ 216 int modecfg_defaultroute; /* is default route intalled for that service ? */ 217 int dummy_ipv6_installed; 218 u_int32_t inner_local_addr; 219 u_int32_t inner_local_mask; 220 int kernctl_sock; /* kernel control socket to the virtual interface */ 221 struct in_addr ping_addr; /* ping address to trigger phase 2 */ 222 int ping_count; /* numer of ping phase 2 left */ 223 u_int16_t xauth_flags; /* fields being requested in xauth */ 224 char lower_interface[16]; /* underlying interface name */ 225 Boolean lower_interface_cellular; 226 struct sockaddr_in lower_gateway; /* lower interface gateway */ 227 CFRunLoopTimerRef interface_timerref ; /* timer ref */ 228 CFStringRef banner; /* banner ref */ 229 230 u_int32_t lower_interface_media; 231 u_int32_t timeout_lower_interface_change; 232 CFRunLoopRef port_mapping_timerrun; 233 CFRunLoopTimerRef port_mapping_timerref; 234 int awaiting_peer_resp; 235 236 /* async dns query */ 237 CFMachPortRef dnsPort; 238 struct timeval dnsQueryStart; 239 CFArrayRef resolvedAddress; /* CFArray[CFData] */ 240 int resolvedAddressError; 241 int next_address; // next address to use in the array 242 Boolean has_displayed_reenroll_alert; 243 /* routes */ 244 service_route_t *routes; 245}; 246 247 248typedef enum { 249 ONDEMAND_PAUSE_STATE_TYPE_OFF = 0, 250 ONDEMAND_PAUSE_STATE_TYPE_UNTIL_REBOOT = 1, 251 ONDEMAND_PAUSE_STATE_TYPE_UNTIL_NETCHANGE = 2, 252} onDemandPauseStateType; 253 254#define MAX_ENV_KEYVALUE_SIZE 256 255typedef char envKeyValue_t[MAX_ENV_KEYVALUE_SIZE]; 256 257struct service { 258 259 /* generic portion of the service */ 260 261 TAILQ_ENTRY(service) next; 262 263 Boolean initialized; /* TRUE if successfully initialized */ 264 265 CFStringRef serviceID; /* service ID in the cache */ 266 CFStringRef typeRef; /* type string */ 267 CFStringRef subtypeRef; /* subtype string */ 268 CFStringRef authSubtypeRef; /* authentication subtype string */ 269 u_char *sid; /* C version of the servceID */ 270 // type/subtype/unit will make the reference number 271 u_int16_t type; /* type of link (PPP or IPSEC or VPN) */ 272 u_int16_t subtype; /* subtype of link */ 273 u_int16_t unit; /* ref number in the interfaces managed by this Controller */ 274 275 276 // status information frequently used 277 u_int32_t flags; /* action flags */ 278 CFStringRef device; /* transport device (en0, en1,...) */ 279 uid_t uid; /* uid of the user who started the connection */ 280 gid_t gid; /* gid of the user who started the connection */ 281 mach_port_t bootstrap; /* bootstrap of the user who started the connection */ 282 mach_port_t au_session; /* audit session of the user who started the connection */ 283 char if_name[16]; /* virtual interface name (e.g ppp0, utun0, ...) */ 284 int if_index; /* virtual index, as returned by if_nametoindex(ifname) */ 285 286 CFDictionaryRef connectopts; /* connect options in use */ 287 CFDictionaryRef systemprefs; /* system prefs */ 288#if TARGET_OS_EMBEDDED 289 CFStringRef profileIdentifier; /* profile Identifier in the prefs */ 290 /* Cellular context */ 291 CTServerConnectionRef cellularConnection; 292 CFRunLoopTimerRef cellular_timerref; 293#endif 294 295 CFUserNotificationRef userNotificationRef; /* user notification */ 296 CFRunLoopSourceRef userNotificationRLS; /* user notification rls */ 297 298#if !TARGET_OS_EMBEDDED 299 vproc_transaction_t vt; /* opaque handle used to track outstanding transactions, used by instant off */ 300#endif 301 u_int32_t connecttime; /* time when connection occured */ 302 u_int32_t establishtime; /* time when connection established */ 303 u_int32_t connectionslepttime; /* amount of time connection slept for */ 304 u_int32_t sleepwaketimeout; /* disconnect if sleep-wake duration is longer than this */ 305 mdns_nat_mapping_t nat_mapping[MDNS_NAT_MAPPING_MAX]; 306 u_int32_t nat_mapping_cnt; 307 u_int32_t was_running; 308 u_int32_t persist_connect; 309 u_int32_t persist_connect_status; 310 u_int32_t persist_connect_devstatus; 311 u_int32_t ondemand_paused; 312 CFStringRef ondemandAction; 313 CFPropertyListRef ondemandActionParameters; 314 CFDictionaryRef ondemandDNSTriggeringDicts; /* Dynamic store service DNS dicts to set supplemental match domains when not connected */ 315 Boolean ondemandDNSTriggeringDictsArePublished; 316 CFDictionaryRef ondemandProbeResults; 317 CFDictionaryRef ondemandSavedDns; 318 CFDictionaryRef persist_connect_opts; 319 CFStringRef connection_nid; 320 CFStringRef connection_nap; 321 Boolean dnsRedirectDetected; 322 CFDictionaryRef dnsRedirectedAddresses; 323 CFDictionaryRef routeCache; 324#if !TARGET_OS_EMBEDDED 325 void *connection_nap_monitor; 326#endif 327 envKeyValue_t *envKeys; 328 envKeyValue_t *envValues; 329 int envCount; 330 331 SCNetworkReachabilityRef remote_address_reachability; 332 SCNetworkReachabilityFlags remote_address_reach_flags; 333 int remote_address_reach_ifindex; 334 335 CFRunLoopTimerRef ondemand_pause_timerref; /* ondemand pause end timer to resume VOD */ 336 u_int32_t ondemand_pause_type_on_timer_expire; /* ondemand pause type to set when timer expires */ 337 338 // list of clients for this service. used to arbitrate connection/disconnection 339 TAILQ_HEAD(, service_client) client_head; 340 341 ne_sm_bridge_t ne_sm_bridge; 342 343 /* specific portion of the service */ 344 union { 345 struct ppp_service ppp; 346 struct ipsec_service ipsec; 347 } u; 348 349}; 350 351 352#ifndef kSCValNetInterfaceTypeIPSec 353#define kSCValNetInterfaceTypeIPSec CFSTR("IPSec") 354#endif 355 356 357extern CFURLRef gBundleURLRef; 358extern CFBundleRef gBundleRef; 359extern CFStringRef gBundleDir; 360extern CFURLRef gIconURLRef; 361extern CFStringRef gIconDir; 362extern CFStringRef gPluginsDir; 363extern CFURLRef gPluginsURLRef; 364extern CFStringRef gResourcesDir; 365 366extern SCDynamicStoreRef gDynamicStore; 367extern CFStringRef gLoggedInUser; 368extern uid_t gLoggedInUserUID; 369 370extern int gSleeping; 371extern time_t gSleptAt; 372extern time_t gWokeAt; 373extern uint64_t gWakeUpTime; 374extern double gSleepWakeTimeout; 375extern double gTimeScaleSeconds; 376extern CFRunLoopSourceRef gStopRls; 377 378extern char *gIPSecAppVersion; 379 380extern int gSCNCVerbose; 381extern int gSCNCDebug; 382 383extern CFStringRef gOndemand_key; 384 385#if TARGET_OS_EMBEDDED 386extern int gNattKeepAliveInterval; 387#endif 388 389int client_gone(void *client); 390 391int allow_sleep(); 392int allow_stop(); 393int allow_dispose(struct service *serv); 394void service_started(struct service *serv); 395void service_ended(struct service *serv); 396void phase_changed(struct service *serv, int phase); 397void disable_ondemand(struct service *serv); 398void application_installed(CFDictionaryRef appInfo); 399void application_removed(CFDictionaryRef appInfo); 400#if TARGET_OS_EMBEDDED 401int start_profile_janitor(struct service *serv); 402int bringup_cellular(struct service *serv); 403#endif 404int check_interface_captive_and_not_ready(SCDynamicStoreRef dynamicStoreRef, char *interface_name); 405 406 407void user_notification_callback(CFUserNotificationRef userNotification, CFOptionFlags responseFlags); 408 409void scnc_bootstrap_dealloc(struct service *serv); 410void scnc_bootstrap_retain(struct service *serv, mach_port_t bootstrap); 411void scnc_ausession_dealloc(struct service *serv); 412void scnc_ausession_retain(struct service *serv, mach_port_t au_session); 413 414int scnc_stop(struct service *serv, void *client, int signal, int scnc_reason); 415int scnc_start(struct service *serv, CFDictionaryRef options, void *client, int autoclose, uid_t uid, gid_t gid, int pid, mach_port_t bootstrap, mach_port_t au_session); 416int scnc_getstatus(struct service *serv); 417int scnc_copyextendedstatus(struct service *serv, void **reply, u_int16_t *replylen); 418int scnc_copystatistics(struct service *serv, void **reply, u_int16_t *replylen); 419int scnc_getconnectdata(struct service *serv, void **reply, u_int16_t *replylen, int all); 420int scnc_getconnectsystemdata(struct service *serv, void **reply, u_int16_t *replylen); 421#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR 422double scnc_getsleepwaketimeout (struct service *serv); 423#endif 424void scnc_idle_disconnect (struct service *serv); 425int scnc_suspend(struct service *serv); 426int scnc_resume(struct service *serv); 427int scnc_sendmsg(struct service *serv, uint32_t msg_type, CFDataRef cfdata, uid_t uid, gid_t gid, int pid, mach_port_t bootstrap, mach_port_t au_session); 428struct service *findbyserviceID(CFStringRef serviceID); 429struct service *findbypid(pid_t pid); 430struct service *findbysid(u_char *data, int len); 431struct service *findbyref(u_int16_t type, u_int32_t ref); 432u_int32_t makeref(struct service *serv); 433 434int scnc_disconnectifoverslept(const char *function, struct service *serv, char *if_name); 435void nat_port_mapping_set(struct service *serv); 436void nat_port_mapping_clear(struct service *serv); 437void check_network_refresh(void); 438void ondemand_set_pause(struct service *serv, uint32_t pauseflag, Boolean update_store); 439Boolean set_ondemand_pause_timer(struct service *serv, uint32_t timeout, uint32_t pause_type, uint32_t pause_type_on_expire); 440void clear_ondemand_pause_timer(struct service *serv); 441void ondemand_clear_pause_all(onDemandPauseStateType type_to_clear); 442Boolean ondemand_unpublish_dns_triggering_dicts (struct service *serv); 443int ondemand_add_service(struct service *serv, Boolean update_configuration); 444void scnc_init_resources(CFBundleRef bundle); 445 446u_short findfreeunit(u_short type, u_short subtype); 447 448#define DISCONNECT_VPN_IFOVERSLEPT(f,s,i) scnc_disconnectifoverslept(f,s,i) 449 450#define SET_VPN_PORTMAPPING(s) 451 452#define CLEAR_VPN_PORTMAPPING(s) 453 454#define TRACK_VPN_LOCATION(s) 455 456#define STOP_TRACKING_VPN_LOCATION(s) 457 458#define DISCONNECT_VPN_IFLOCATIONCHANGED(s) 0 459 460#define DID_VPN_LOCATIONCHANGE(s) 0 461 462#endif 463