1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * WPA Supplicant / Windows Named Pipe -based control interface 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eloop.h" 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "config.h" 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eapol_supp/eapol_supp_sm.h" 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "wpa_supplicant_i.h" 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "ctrl_iface.h" 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "wpa_ctrl.h" 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef __MINGW32_VERSION 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* mingw-w32api v3.1 does not yet include sddl.h, so define needed parts here 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define SDDL_REVISION_1 1 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA( 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPCSTR, DWORD, PSECURITY_DESCRIPTOR *, PULONG); 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtBOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW( 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPCWSTR, DWORD, PSECURITY_DESCRIPTOR *, PULONG); 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef UNICODE 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define ConvertStringSecurityDescriptorToSecurityDescriptor \ 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtConvertStringSecurityDescriptorToSecurityDescriptorW 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define ConvertStringSecurityDescriptorToSecurityDescriptor \ 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtConvertStringSecurityDescriptorToSecurityDescriptorA 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* __MINGW32_VERSION */ 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef _WIN32_WINNT 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define _WIN32_WINNT 0x0500 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <sddl.h> 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* __MINGW32_VERSION */ 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WPA_SUPPLICANT_NAMED_PIPE 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant" 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE) 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* Per-interface ctrl_iface */ 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define REQUEST_BUFSIZE 256 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define REPLY_BUFSIZE 4096 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ctrl_iface_priv; 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * struct wpa_ctrl_dst - Internal data structure of control interface clients 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This structure is used to store information about registered control 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * interface monitors into struct wpa_supplicant. This data is private to 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * ctrl_iface_named_pipe.c and should not be touched directly from other files. 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct wpa_ctrl_dst { 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Note: OVERLAPPED must be the first member of struct wpa_ctrl_dst */ 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OVERLAPPED overlap; 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ctrl_dst *next, *prev; 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_priv *priv; 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HANDLE pipe; 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int attached; 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int debug_level; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int errors; 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char req_buf[REQUEST_BUFSIZE]; 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *rsp_buf; 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int used; 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ctrl_iface_priv { 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_supplicant *wpa_s; 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ctrl_dst *ctrl_dst; 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_ATTRIBUTES attr; 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int sec_attr_set; 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int level, const char *buf, 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len); 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ctrl_close_pipe(struct wpa_ctrl_dst *dst); 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_ctrl_iface_receive(void *, void *); 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic VOID WINAPI ctrl_iface_read_completed(DWORD err, DWORD bytes, 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPOVERLAPPED overlap); 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct wpa_global_dst; 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void global_close_pipe(struct wpa_global_dst *dst); 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_global_iface_receive(void *eloop_data, 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_ctx); 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic VOID WINAPI global_iface_read_completed(DWORD err, DWORD bytes, 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPOVERLAPPED overlap); 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int ctrl_broken_pipe(HANDLE pipe, int used) 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD err; 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (PeekNamedPipe(pipe, NULL, 0, NULL, NULL, NULL)) 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = GetLastError(); 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err == ERROR_BROKEN_PIPE || (err == ERROR_BAD_PIPE && used)) 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 1; 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ctrl_flush_broken_pipes(struct ctrl_iface_priv *priv) 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ctrl_dst *dst, *next; 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst = priv->ctrl_dst; 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (dst) { 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = dst->next; 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ctrl_broken_pipe(dst->pipe, dst->used)) { 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: closing broken pipe %p", 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst); 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_close_pipe(dst); 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst = next; 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int ctrl_open_pipe(struct ctrl_iface_priv *priv) 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ctrl_dst *dst; 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD err; 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TCHAR name[256]; 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst = os_zalloc(sizeof(*dst)); 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst == NULL) 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Open pipe %p", dst); 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->priv = priv; 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->debug_level = MSG_INFO; 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->pipe = INVALID_HANDLE_VALUE; 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->overlap.hEvent == NULL) { 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CTRL: CreateEvent failed: %d", 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto fail; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_event(dst->overlap.hEvent, 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(dst->overlap.hEvent), 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_ctrl_iface_receive, dst, NULL); 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef UNICODE 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"), 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->wpa_s->ifname); 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* UNICODE */ 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s", 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->wpa_s->ifname); 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* UNICODE */ 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: add support for configuring access list for the pipe */ 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->pipe = CreateNamedPipe(name, 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PIPE_TYPE_MESSAGE | 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PIPE_READMODE_MESSAGE | 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PIPE_WAIT, 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15, REPLY_BUFSIZE, REQUEST_BUFSIZE, 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1000, 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->sec_attr_set ? &priv->attr : NULL); 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->pipe == INVALID_HANDLE_VALUE) { 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CTRL: CreateNamedPipe failed: %d", 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto fail; 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ConnectNamedPipe(dst->pipe, &dst->overlap)) { 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CTRL: ConnectNamedPipe failed: %d", 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(dst->pipe); 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst); 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = GetLastError(); 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (err) { 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case ERROR_IO_PENDING: 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: connection in " 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "progress"); 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case ERROR_PIPE_CONNECTED: 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: already " 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "connected"); 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (SetEvent(dst->overlap.hEvent)) 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* fall through */ 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe error: %d", 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) err); 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(dst->pipe); 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst); 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->next = priv->ctrl_dst; 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->next) 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->next->prev = dst; 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->ctrl_dst = dst; 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtfail: 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_close_pipe(dst); 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ctrl_close_pipe(struct wpa_ctrl_dst *dst) 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: close pipe %p", dst); 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->overlap.hEvent) { 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_unregister_event(dst->overlap.hEvent, 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(dst->overlap.hEvent)); 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(dst->overlap.hEvent); 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->pipe != INVALID_HANDLE_VALUE) { 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Could use FlushFileBuffers() here to guarantee that all data 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * gets delivered to the client, but that can block, so let's 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * not do this for now. 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * FlushFileBuffers(dst->pipe); 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(dst->pipe); 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->prev) 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->prev->next = dst->next; 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->priv->ctrl_dst = dst->next; 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->next) 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->next->prev = dst->prev; 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst->rsp_buf); 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst); 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic VOID WINAPI ctrl_iface_write_completed(DWORD err, DWORD bytes, 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPOVERLAPPED overlap) 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ctrl_dst *dst = (struct wpa_ctrl_dst *) overlap; 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Overlapped write completed: dst=%p " 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "err=%d bytes=%d", dst, (int) err, (int) bytes); 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err) { 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_close_pipe(dst); 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst->rsp_buf); 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->rsp_buf = NULL; 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!ReadFileEx(dst->pipe, dst->req_buf, sizeof(dst->req_buf), 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &dst->overlap, ctrl_iface_read_completed)) { 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: ReadFileEx failed: %d", 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_close_pipe(dst); 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Overlapped read started for %p", dst); 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_ctrl_iface_rx(struct wpa_ctrl_dst *dst, size_t len) 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_supplicant *wpa_s = dst->priv->wpa_s; 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *reply = NULL, *send_buf; 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t reply_len = 0, send_len; 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int new_attached = 0; 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *buf = dst->req_buf; 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->used = 1; 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (len >= REQUEST_BUFSIZE) 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = REQUEST_BUFSIZE - 1; 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf[len] = '\0'; 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_strcmp(buf, "ATTACH") == 0) { 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->attached = 1; 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached"); 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt new_attached = 1; 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply_len = 2; 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (os_strcmp(buf, "DETACH") == 0) { 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->attached = 0; 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached"); 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply_len = 2; 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (os_strncmp(buf, "LEVEL ", 6) == 0) { 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", buf + 6); 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->debug_level = atoi(buf + 6); 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply_len = 2; 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf, 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &reply_len); 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (reply) { 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_buf = reply; 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_len = reply_len; 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (reply_len == 2) { 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_buf = "OK\n"; 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_len = 3; 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_buf = "FAIL\n"; 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_len = 5; 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst->rsp_buf); 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->rsp_buf = os_malloc(send_len); 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->rsp_buf == NULL) { 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_close_pipe(dst); 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(reply); 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(dst->rsp_buf, send_buf, send_len); 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(reply); 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!WriteFileEx(dst->pipe, dst->rsp_buf, send_len, &dst->overlap, 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_iface_write_completed)) { 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: WriteFileEx failed: %d", 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_close_pipe(dst); 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p", 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst); 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (new_attached) 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eapol_sm_notify_ctrl_attached(wpa_s->eapol); 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic VOID WINAPI ctrl_iface_read_completed(DWORD err, DWORD bytes, 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPOVERLAPPED overlap) 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ctrl_dst *dst = (struct wpa_ctrl_dst *) overlap; 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Overlapped read completed: dst=%p err=%d " 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "bytes=%d", dst, (int) err, (int) bytes); 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err == 0 && bytes > 0) 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_ctrl_iface_rx(dst, bytes); 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_ctrl_iface_receive(void *eloop_data, void *user_ctx) 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ctrl_dst *dst = eloop_data; 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_priv *priv = dst->priv; 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD bytes; 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: wpa_supplicant_ctrl_iface_receive"); 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ResetEvent(dst->overlap.hEvent); 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!GetOverlappedResult(dst->pipe, &dst->overlap, &bytes, FALSE)) { 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult failed: %d", 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult: New client " 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "connected"); 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Open a new named pipe for the next client. */ 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_open_pipe(priv); 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Use write completion function to start reading a command */ 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_iface_write_completed(0, 0, &dst->overlap); 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_flush_broken_pipes(priv); 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int ctrl_iface_parse(struct ctrl_iface_priv *priv, const char *params) 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *sddl = NULL; 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TCHAR *t_sddl; 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_strncmp(params, "SDDL=", 5) == 0) 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sddl = params + 5; 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!sddl) { 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sddl = os_strstr(params, " SDDL="); 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sddl) 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sddl += 6; 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!sddl) 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: SDDL='%s'", sddl); 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&priv->attr, 0, sizeof(priv->attr)); 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->attr.nLength = sizeof(priv->attr); 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->attr.bInheritHandle = FALSE; 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t_sddl = wpa_strdup_tchar(sddl); 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (t_sddl == NULL) 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!ConvertStringSecurityDescriptorToSecurityDescriptor( 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t_sddl, SDDL_REVISION_1, 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (PSECURITY_DESCRIPTOR *) (void *) 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &priv->attr.lpSecurityDescriptor, 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL)) { 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(t_sddl); 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CTRL: SDDL='%s' - could not convert to " 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "security descriptor: %d", 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sddl, (int) GetLastError()); 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(t_sddl); 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->sec_attr_set = 1; 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *txt, size_t len) 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_supplicant *wpa_s = ctx; 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_s == NULL || wpa_s->ctrl_iface == NULL) 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_ctrl_iface_send(wpa_s->ctrl_iface, level, txt, len); 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ctrl_iface_priv * 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtwpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_priv *priv; 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv = os_zalloc(sizeof(*priv)); 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (priv == NULL) 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->wpa_s = wpa_s; 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_s->conf->ctrl_interface == NULL) 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return priv; 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ctrl_iface_parse(priv, wpa_s->conf->ctrl_interface) < 0) { 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(priv); 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ctrl_open_pipe(priv) < 0) { 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(priv); 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return priv; 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (priv->ctrl_dst) 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_close_pipe(priv->ctrl_dst); 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (priv->sec_attr_set) 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LocalFree(priv->attr.lpSecurityDescriptor); 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(priv); 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int level, const char *buf, 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len) 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ctrl_dst *dst, *next; 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char levelstr[10]; 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int idx; 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *sbuf; 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int llen; 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD written; 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst = priv->ctrl_dst; 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst == NULL) 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt llen = os_strlen(levelstr); 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sbuf = os_malloc(llen + len); 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sbuf == NULL) 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(sbuf, levelstr, llen); 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(sbuf + llen, buf, len); 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt idx = 0; 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (dst) { 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = dst->next; 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->attached && level >= dst->debug_level) { 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor send %p", 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst); 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!WriteFile(dst->pipe, sbuf, llen + len, &written, 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL)) { 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: WriteFile to dst " 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "%p failed: %d", 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst, (int) GetLastError()); 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->errors++; 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->errors > 10) 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_close_pipe(dst); 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->errors = 0; 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt idx++; 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst = next; 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(sbuf); 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv) 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor", 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->wpa_s->ifname); 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (priv->ctrl_dst == NULL) 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WaitForSingleObject(priv->ctrl_dst->pipe, INFINITE); 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* Global ctrl_iface */ 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ctrl_iface_global_priv; 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct wpa_global_dst { 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Note: OVERLAPPED must be the first member of struct wpa_global_dst 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt OVERLAPPED overlap; 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global_dst *next, *prev; 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_global_priv *priv; 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HANDLE pipe; 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char req_buf[REQUEST_BUFSIZE]; 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *rsp_buf; 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int used; 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ctrl_iface_global_priv { 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global *global; 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global_dst *ctrl_dst; 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void global_flush_broken_pipes(struct ctrl_iface_global_priv *priv) 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global_dst *dst, *next; 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst = priv->ctrl_dst; 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (dst) { 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = dst->next; 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ctrl_broken_pipe(dst->pipe, dst->used)) { 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: closing broken pipe %p", 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst); 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_close_pipe(dst); 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst = next; 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int global_open_pipe(struct ctrl_iface_global_priv *priv) 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global_dst *dst; 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD err; 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst = os_zalloc(sizeof(*dst)); 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst == NULL) 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Open pipe %p", dst); 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->priv = priv; 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->pipe = INVALID_HANDLE_VALUE; 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->overlap.hEvent == NULL) { 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CTRL: CreateEvent failed: %d", 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto fail; 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_event(dst->overlap.hEvent, 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(dst->overlap.hEvent), 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_global_iface_receive, dst, NULL); 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: add support for configuring access list for the pipe */ 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->pipe = CreateNamedPipe(NAMED_PIPE_PREFIX, 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PIPE_TYPE_MESSAGE | 608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PIPE_READMODE_MESSAGE | 609526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PIPE_WAIT, 610526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 10, REPLY_BUFSIZE, REQUEST_BUFSIZE, 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1000, NULL); 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->pipe == INVALID_HANDLE_VALUE) { 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CTRL: CreateNamedPipe failed: %d", 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto fail; 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ConnectNamedPipe(dst->pipe, &dst->overlap)) { 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CTRL: ConnectNamedPipe failed: %d", 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(dst->pipe); 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst); 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt err = GetLastError(); 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (err) { 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case ERROR_IO_PENDING: 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: connection in " 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "progress"); 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case ERROR_PIPE_CONNECTED: 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe: already " 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "connected"); 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (SetEvent(dst->overlap.hEvent)) 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* fall through */ 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe error: %d", 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) err); 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(dst->pipe); 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst); 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->next = priv->ctrl_dst; 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->next) 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->next->prev = dst; 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->ctrl_dst = dst; 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtfail: 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_close_pipe(dst); 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void global_close_pipe(struct wpa_global_dst *dst) 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: close pipe %p", dst); 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->overlap.hEvent) { 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_unregister_event(dst->overlap.hEvent, 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(dst->overlap.hEvent)); 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(dst->overlap.hEvent); 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->pipe != INVALID_HANDLE_VALUE) { 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Could use FlushFileBuffers() here to guarantee that all data 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * gets delivered to the client, but that can block, so let's 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * not do this for now. 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * FlushFileBuffers(dst->pipe); 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(dst->pipe); 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->prev) 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->prev->next = dst->next; 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->priv->ctrl_dst = dst->next; 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->next) 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->next->prev = dst->prev; 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst->rsp_buf); 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst); 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic VOID WINAPI global_iface_write_completed(DWORD err, DWORD bytes, 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPOVERLAPPED overlap) 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global_dst *dst = (struct wpa_global_dst *) overlap; 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Overlapped write completed: dst=%p " 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "err=%d bytes=%d", dst, (int) err, (int) bytes); 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err) { 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_close_pipe(dst); 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst->rsp_buf); 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->rsp_buf = NULL; 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!ReadFileEx(dst->pipe, dst->req_buf, sizeof(dst->req_buf), 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &dst->overlap, global_iface_read_completed)) { 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: ReadFileEx failed: %d", 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_close_pipe(dst); 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* FIX: if this was the pipe waiting for new global 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * connections, at this point there are no open global pipes.. 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Should try to open a new pipe.. */ 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Overlapped read started for %p", dst); 716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_global_iface_rx(struct wpa_global_dst *dst, 720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len) 721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global *global = dst->priv->global; 723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *reply = NULL, *send_buf; 724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t reply_len = 0, send_len; 725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *buf = dst->req_buf; 726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->used = 1; 728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (len >= REQUEST_BUFSIZE) 729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = REQUEST_BUFSIZE - 1; 730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf[len] = '\0'; 731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpa_supplicant_global_ctrl_iface_process(global, buf, 733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &reply_len); 734526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (reply) { 735526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_buf = reply; 736526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_len = reply_len; 737526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (reply_len) { 738526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_buf = "FAIL\n"; 739526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt send_len = 5; 740526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 741526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst->rsp_buf); 742526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->rsp_buf = NULL; 743526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 744526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 745526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 746526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(dst->rsp_buf); 747526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst->rsp_buf = os_malloc(send_len); 748526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dst->rsp_buf == NULL) { 749526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_close_pipe(dst); 750526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(reply); 751526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 752526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 753526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(dst->rsp_buf, send_buf, send_len); 754526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(reply); 755526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 756526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!WriteFileEx(dst->pipe, dst->rsp_buf, send_len, &dst->overlap, 757526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_iface_write_completed)) { 758526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: WriteFileEx failed: %d", 759526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 760526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_close_pipe(dst); 761526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 762526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p", 763526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dst); 764526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 765526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 766526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 767526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 768526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic VOID WINAPI global_iface_read_completed(DWORD err, DWORD bytes, 769526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPOVERLAPPED overlap) 770526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 771526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global_dst *dst = (struct wpa_global_dst *) overlap; 772526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: Overlapped read completed: dst=%p err=%d " 773526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "bytes=%d", dst, (int) err, (int) bytes); 774526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (err == 0 && bytes > 0) 775526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_global_iface_rx(dst, bytes); 776526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 777526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 778526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 779526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_supplicant_global_iface_receive(void *eloop_data, 780526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_ctx) 781526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 782526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global_dst *dst = eloop_data; 783526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_global_priv *priv = dst->priv; 784526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD bytes; 785526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 786526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: wpa_supplicant_global_iface_receive"); 787526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ResetEvent(dst->overlap.hEvent); 788526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 789526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!GetOverlappedResult(dst->pipe, &dst->overlap, &bytes, FALSE)) { 790526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult failed: %d", 791526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 792526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 793526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 794526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: GetOverlappedResult: New client " 795526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "connected"); 796526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 797526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Open a new named pipe for the next client. */ 798526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (global_open_pipe(priv) < 0) { 799526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "CTRL: global_open_pipe failed"); 800526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 801526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 802526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 803526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Use write completion function to start reading a command */ 804526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_iface_write_completed(0, 0, &dst->overlap); 805526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 806526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_flush_broken_pipes(priv); 807526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 808526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 809526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 810526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ctrl_iface_global_priv * 811526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtwpa_supplicant_global_ctrl_iface_init(struct wpa_global *global) 812526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 813526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_global_priv *priv; 814526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 815526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv = os_zalloc(sizeof(*priv)); 816526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (priv == NULL) 817526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 818526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt priv->global = global; 819526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 820526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (global_open_pipe(priv) < 0) { 821526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(priv); 822526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 823526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 824526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 825526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return priv; 826526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 827526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 828526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 829526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid 830526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtwpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv) 831526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 832526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (priv->ctrl_dst) 833526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global_close_pipe(priv->ctrl_dst); 834526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(priv); 835526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 836