~ubuntu-branches/ubuntu/intrepid/wpasupplicant/intrepid

« back to all changes in this revision

Viewing changes to ctrl_iface_named_pipe.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2007-04-01 10:53:37 UTC
  • Revision ID: james.westby@ubuntu.com-20070401105337-3dd89n3g8ecdhjsl
Tags: 0.5.7-0ubuntu2
Apply patch from upstream after private email discussion:
http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=commitdiff;h=33673d3f43da6f5ec0f0aa5a8245a1617b6eb2fd#patch1
Fixes LP: #98895, #98925

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
        int errors;
75
75
        char req_buf[REQUEST_BUFSIZE];
76
76
        char *rsp_buf;
77
 
        int used;
78
77
};
79
78
 
80
79
 
86
85
};
87
86
 
88
87
 
89
 
static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
90
 
                                           int level, const char *buf,
91
 
                                           size_t len);
92
 
 
93
88
static void ctrl_close_pipe(struct wpa_ctrl_dst *dst);
94
89
static void wpa_supplicant_ctrl_iface_receive(void *, void *);
95
90
static VOID WINAPI ctrl_iface_read_completed(DWORD err, DWORD bytes,
103
98
                                               LPOVERLAPPED overlap);
104
99
 
105
100
 
106
 
static int ctrl_broken_pipe(HANDLE pipe, int used)
 
101
static int ctrl_broken_pipe(HANDLE pipe)
107
102
{
108
103
        DWORD err;
109
104
 
111
106
                return 0;
112
107
 
113
108
        err = GetLastError();
114
 
        if (err == ERROR_BROKEN_PIPE || (err == ERROR_BAD_PIPE && used))
 
109
        if (err == ERROR_BAD_PIPE || err == ERROR_BROKEN_PIPE)
115
110
                return 1;
116
111
        return 0;
117
112
}
125
120
 
126
121
        while (dst) {
127
122
                next = dst->next;
128
 
                if (ctrl_broken_pipe(dst->pipe, dst->used)) {
 
123
                if (ctrl_broken_pipe(dst->pipe)) {
129
124
                        wpa_printf(MSG_DEBUG, "CTRL: closing broken pipe %p",
130
125
                                   dst);
131
126
                        ctrl_close_pipe(dst);
141
136
        DWORD err;
142
137
        TCHAR name[256];
143
138
 
144
 
        dst = os_zalloc(sizeof(*dst));
 
139
        ctrl_flush_broken_pipes(priv);
 
140
        dst = wpa_zalloc(sizeof(*dst));
145
141
        if (dst == NULL)
146
142
                return -1;
147
143
        wpa_printf(MSG_DEBUG, "CTRL: Open pipe %p", dst);
153
149
        dst->overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
154
150
        if (dst->overlap.hEvent == NULL) {
155
151
                wpa_printf(MSG_ERROR, "CTRL: CreateEvent failed: %d",
156
 
                           (int) GetLastError());
 
152
                           (int) GetLastError()); 
157
153
                goto fail;
158
154
        }
159
155
 
165
161
        _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"),
166
162
                   priv->wpa_s->ifname);
167
163
#else /* UNICODE */
168
 
        os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s",
169
 
                    priv->wpa_s->ifname);
 
164
        snprintf(name, 256, NAMED_PIPE_PREFIX "-%s",
 
165
                 priv->wpa_s->ifname);
170
166
#endif /* UNICODE */
171
167
 
172
168
        /* TODO: add support for configuring access list for the pipe */
180
176
                                    priv->sec_attr_set ? &priv->attr : NULL);
181
177
        if (dst->pipe == INVALID_HANDLE_VALUE) {
182
178
                wpa_printf(MSG_ERROR, "CTRL: CreateNamedPipe failed: %d",
183
 
                           (int) GetLastError());
 
179
                           (int) GetLastError()); 
184
180
                goto fail;
185
181
        }
186
182
 
188
184
                wpa_printf(MSG_ERROR, "CTRL: ConnectNamedPipe failed: %d",
189
185
                           (int) GetLastError());
190
186
                CloseHandle(dst->pipe);
191
 
                os_free(dst);
 
187
                free(dst);
192
188
                return -1;
193
189
        }
194
190
 
208
204
                wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe error: %d",
209
205
                           (int) err);
210
206
                CloseHandle(dst->pipe);
211
 
                os_free(dst);
 
207
                free(dst);
212
208
                return -1;
213
209
        }
214
210
 
252
248
        if (dst->next)
253
249
                dst->next->prev = dst->prev;
254
250
 
255
 
        os_free(dst->rsp_buf);
256
 
        os_free(dst);
 
251
        free(dst->rsp_buf);
 
252
        free(dst);
257
253
}
258
254
 
259
255
 
268
264
                return;
269
265
        }
270
266
 
271
 
        os_free(dst->rsp_buf);
 
267
        free(dst->rsp_buf);
272
268
        dst->rsp_buf = NULL;
273
269
 
274
270
        if (!ReadFileEx(dst->pipe, dst->req_buf, sizeof(dst->req_buf),
276
272
                wpa_printf(MSG_DEBUG, "CTRL: ReadFileEx failed: %d",
277
273
                           (int) GetLastError());
278
274
                ctrl_close_pipe(dst);
279
 
                return;
280
275
        }
281
276
        wpa_printf(MSG_DEBUG, "CTRL: Overlapped read started for %p", dst);
282
277
}
290
285
        int new_attached = 0;
291
286
        char *buf = dst->req_buf;
292
287
 
293
 
        dst->used = 1;
294
288
        if (len >= REQUEST_BUFSIZE)
295
289
                len = REQUEST_BUFSIZE - 1;
296
290
        buf[len] = '\0';
297
291
 
298
 
        if (os_strcmp(buf, "ATTACH") == 0) {
 
292
        if (strcmp(buf, "ATTACH") == 0) {
299
293
                dst->attached = 1;
300
294
                wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor attached");
301
295
                new_attached = 1;
302
296
                reply_len = 2;
303
 
        } else if (os_strcmp(buf, "DETACH") == 0) {
 
297
        } else if (strcmp(buf, "DETACH") == 0) {
304
298
                dst->attached = 0;
305
299
                wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached");
306
300
                reply_len = 2;
307
 
        } else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
 
301
        } else if (strncmp(buf, "LEVEL ", 6) == 0) {
308
302
                wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", buf + 6);
309
303
                dst->debug_level = atoi(buf + 6);
310
304
                reply_len = 2;
324
318
                send_len = 5;
325
319
        }
326
320
 
327
 
        os_free(dst->rsp_buf);
328
 
        dst->rsp_buf = os_malloc(send_len);
 
321
        free(dst->rsp_buf);
 
322
        dst->rsp_buf = malloc(send_len);
329
323
        if (dst->rsp_buf == NULL) {
330
324
                ctrl_close_pipe(dst);
331
 
                os_free(reply);
 
325
                free(reply);
332
326
                return;
333
327
        }
334
 
        os_memcpy(dst->rsp_buf, send_buf, send_len);
335
 
        os_free(reply);
 
328
        memcpy(dst->rsp_buf, send_buf, send_len);
 
329
        free(reply);
336
330
 
337
331
        if (!WriteFileEx(dst->pipe, dst->rsp_buf, send_len, &dst->overlap,
338
332
                         ctrl_iface_write_completed)) {
339
333
                wpa_printf(MSG_DEBUG, "CTRL: WriteFileEx failed: %d",
340
334
                           (int) GetLastError());
341
335
                ctrl_close_pipe(dst);
342
 
        } else {
343
 
                wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p",
344
 
                           dst);
345
336
        }
 
337
        wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p", dst);
346
338
 
347
339
        if (new_attached)
348
340
                eapol_sm_notify_ctrl_attached(wpa_s->eapol);
378
370
                   "connected");
379
371
 
380
372
        /* Open a new named pipe for the next client. */
381
 
        ctrl_open_pipe(priv);
 
373
        ctrl_open_pipe(priv); 
382
374
 
383
375
        /* Use write completion function to start reading a command */
384
376
        ctrl_iface_write_completed(0, 0, &dst->overlap);
385
 
 
386
 
        ctrl_flush_broken_pipes(priv);
387
377
}
388
378
 
389
379
 
392
382
        const char *sddl = NULL;
393
383
        TCHAR *t_sddl;
394
384
 
395
 
        if (os_strncmp(params, "SDDL=", 5) == 0)
 
385
        if (strncmp(params, "SDDL=", 5) == 0)
396
386
                sddl = params + 5;
397
387
        if (!sddl) {
398
 
                sddl = os_strstr(params, " SDDL=");
 
388
                sddl = strstr(params, " SDDL=");
399
389
                if (sddl)
400
390
                        sddl += 6;
401
391
        }
404
394
                return 0;
405
395
 
406
396
        wpa_printf(MSG_DEBUG, "CTRL: SDDL='%s'", sddl);
407
 
        os_memset(&priv->attr, 0, sizeof(priv->attr));
 
397
        memset(&priv->attr, 0, sizeof(priv->attr));
408
398
        priv->attr.nLength = sizeof(priv->attr);
409
399
        priv->attr.bInheritHandle = FALSE;
410
400
        t_sddl = wpa_strdup_tchar(sddl);
411
 
        if (t_sddl == NULL)
412
 
                return -1;
413
401
        if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
414
402
                    t_sddl, SDDL_REVISION_1,
415
403
                    (PSECURITY_DESCRIPTOR *) &priv->attr.lpSecurityDescriptor,
416
404
                    NULL)) {
417
 
                os_free(t_sddl);
 
405
                free(t_sddl);
418
406
                wpa_printf(MSG_ERROR, "CTRL: SDDL='%s' - could not convert to "
419
407
                           "security descriptor: %d",
420
408
                           sddl, (int) GetLastError());
421
409
                return -1;
422
410
        }
423
 
        os_free(t_sddl);
 
411
        free(t_sddl);
424
412
 
425
413
        priv->sec_attr_set = 1;
426
414
 
428
416
}
429
417
 
430
418
 
431
 
static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
432
 
                                             const char *txt, size_t len)
433
 
{
434
 
        struct wpa_supplicant *wpa_s = ctx;
435
 
        if (wpa_s == NULL || wpa_s->ctrl_iface == NULL)
436
 
                return;
437
 
        wpa_supplicant_ctrl_iface_send(wpa_s->ctrl_iface, level, txt, len);
438
 
}
439
 
 
440
 
 
441
419
struct ctrl_iface_priv *
442
420
wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
443
421
{
444
422
        struct ctrl_iface_priv *priv;
445
423
 
446
 
        priv = os_zalloc(sizeof(*priv));
 
424
        priv = wpa_zalloc(sizeof(*priv));
447
425
        if (priv == NULL)
448
426
                return NULL;
449
427
        priv->wpa_s = wpa_s;
452
430
                return priv;
453
431
 
454
432
        if (ctrl_iface_parse(priv, wpa_s->conf->ctrl_interface) < 0) {
455
 
                os_free(priv);
 
433
                free(priv);
456
434
                return NULL;
457
435
        }
458
436
 
459
437
        if (ctrl_open_pipe(priv) < 0) {
460
 
                os_free(priv);
 
438
                free(priv);
461
439
                return NULL;
462
440
        }
463
441
 
464
 
        wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
465
 
 
466
442
        return priv;
467
443
}
468
444
 
473
449
                ctrl_close_pipe(priv->ctrl_dst);
474
450
        if (priv->sec_attr_set)
475
451
                LocalFree(priv->attr.lpSecurityDescriptor);
476
 
        os_free(priv);
 
452
        free(priv);
477
453
}
478
454
 
479
455
 
480
 
static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
481
 
                                           int level, const char *buf,
482
 
                                           size_t len)
 
456
void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, int level,
 
457
                                    const char *buf, size_t len)
483
458
{
484
459
        struct wpa_ctrl_dst *dst, *next;
485
460
        char levelstr[10];
492
467
        if (dst == NULL)
493
468
                return;
494
469
 
495
 
        os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
 
470
        snprintf(levelstr, sizeof(levelstr), "<%d>", level);
496
471
 
497
 
        llen = os_strlen(levelstr);
498
 
        sbuf = os_malloc(llen + len);
 
472
        llen = strlen(levelstr);
 
473
        sbuf = malloc(llen + len);
499
474
        if (sbuf == NULL)
500
475
                return;
501
476
 
502
 
        os_memcpy(sbuf, levelstr, llen);
503
 
        os_memcpy(sbuf + llen, buf, len);
 
477
        memcpy(sbuf, levelstr, llen);
 
478
        memcpy(sbuf + llen, buf, len);
504
479
 
505
480
        idx = 0;
506
481
        while (dst) {
522
497
                idx++;
523
498
                dst = next;
524
499
        }
525
 
        os_free(sbuf);
 
500
        free(sbuf);
526
501
}
527
502
 
528
503
 
549
524
        HANDLE pipe;
550
525
        char req_buf[REQUEST_BUFSIZE];
551
526
        char *rsp_buf;
552
 
        int used;
553
527
};
554
528
 
555
529
struct ctrl_iface_global_priv {
566
540
 
567
541
        while (dst) {
568
542
                next = dst->next;
569
 
                if (ctrl_broken_pipe(dst->pipe, dst->used)) {
 
543
                if (ctrl_broken_pipe(dst->pipe)) {
570
544
                        wpa_printf(MSG_DEBUG, "CTRL: closing broken pipe %p",
571
545
                                   dst);
572
546
                        global_close_pipe(dst);
581
555
        struct wpa_global_dst *dst;
582
556
        DWORD err;
583
557
 
584
 
        dst = os_zalloc(sizeof(*dst));
 
558
        global_flush_broken_pipes(priv);
 
559
        dst = wpa_zalloc(sizeof(*dst));
585
560
        if (dst == NULL)
586
561
                return -1;
587
562
        wpa_printf(MSG_DEBUG, "CTRL: Open pipe %p", dst);
592
567
        dst->overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
593
568
        if (dst->overlap.hEvent == NULL) {
594
569
                wpa_printf(MSG_ERROR, "CTRL: CreateEvent failed: %d",
595
 
                           (int) GetLastError());
 
570
                           (int) GetLastError()); 
596
571
                goto fail;
597
572
        }
598
573
 
610
585
                                    1000, NULL);
611
586
        if (dst->pipe == INVALID_HANDLE_VALUE) {
612
587
                wpa_printf(MSG_ERROR, "CTRL: CreateNamedPipe failed: %d",
613
 
                           (int) GetLastError());
 
588
                           (int) GetLastError()); 
614
589
                goto fail;
615
590
        }
616
591
 
618
593
                wpa_printf(MSG_ERROR, "CTRL: ConnectNamedPipe failed: %d",
619
594
                           (int) GetLastError());
620
595
                CloseHandle(dst->pipe);
621
 
                os_free(dst);
 
596
                free(dst);
622
597
                return -1;
623
598
        }
624
599
 
638
613
                wpa_printf(MSG_DEBUG, "CTRL: ConnectNamedPipe error: %d",
639
614
                           (int) err);
640
615
                CloseHandle(dst->pipe);
641
 
                os_free(dst);
 
616
                free(dst);
642
617
                return -1;
643
618
        }
644
619
 
682
657
        if (dst->next)
683
658
                dst->next->prev = dst->prev;
684
659
 
685
 
        os_free(dst->rsp_buf);
686
 
        os_free(dst);
 
660
        free(dst->rsp_buf);
 
661
        free(dst);
687
662
}
688
663
 
689
664
 
698
673
                return;
699
674
        }
700
675
 
701
 
        os_free(dst->rsp_buf);
 
676
        free(dst->rsp_buf);
702
677
        dst->rsp_buf = NULL;
703
678
 
704
679
        if (!ReadFileEx(dst->pipe, dst->req_buf, sizeof(dst->req_buf),
706
681
                wpa_printf(MSG_DEBUG, "CTRL: ReadFileEx failed: %d",
707
682
                           (int) GetLastError());
708
683
                global_close_pipe(dst);
709
 
                /* FIX: if this was the pipe waiting for new global
710
 
                 * connections, at this point there are no open global pipes..
711
 
                 * Should try to open a new pipe.. */
712
 
                return;
713
684
        }
714
685
        wpa_printf(MSG_DEBUG, "CTRL: Overlapped read started for %p", dst);
715
686
}
723
694
        size_t reply_len = 0, send_len;
724
695
        char *buf = dst->req_buf;
725
696
 
726
 
        dst->used = 1;
727
697
        if (len >= REQUEST_BUFSIZE)
728
698
                len = REQUEST_BUFSIZE - 1;
729
699
        buf[len] = '\0';
737
707
                send_buf = "FAIL\n";
738
708
                send_len = 5;
739
709
        } else {
740
 
                os_free(dst->rsp_buf);
 
710
                free(dst->rsp_buf);
741
711
                dst->rsp_buf = NULL;
742
712
                return;
743
713
        }
744
714
 
745
 
        os_free(dst->rsp_buf);
746
 
        dst->rsp_buf = os_malloc(send_len);
 
715
        free(dst->rsp_buf);
 
716
        dst->rsp_buf = malloc(send_len);
747
717
        if (dst->rsp_buf == NULL) {
748
718
                global_close_pipe(dst);
749
 
                os_free(reply);
 
719
                free(reply);
750
720
                return;
751
721
        }
752
 
        os_memcpy(dst->rsp_buf, send_buf, send_len);
753
 
        os_free(reply);
 
722
        memcpy(dst->rsp_buf, send_buf, send_len);
 
723
        free(reply);
754
724
 
755
725
        if (!WriteFileEx(dst->pipe, dst->rsp_buf, send_len, &dst->overlap,
756
726
                         global_iface_write_completed)) {
757
727
                wpa_printf(MSG_DEBUG, "CTRL: WriteFileEx failed: %d",
758
728
                           (int) GetLastError());
759
729
                global_close_pipe(dst);
760
 
        } else {
761
 
                wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p",
762
 
                           dst);
763
730
        }
 
731
        wpa_printf(MSG_DEBUG, "CTRL: Overlapped write started for %p", dst);
764
732
}
765
733
 
766
734
 
794
762
                   "connected");
795
763
 
796
764
        /* Open a new named pipe for the next client. */
797
 
        if (global_open_pipe(priv) < 0) {
798
 
                wpa_printf(MSG_DEBUG, "CTRL: global_open_pipe failed");
799
 
                return;
800
 
        }
 
765
        global_open_pipe(priv); 
801
766
 
802
767
        /* Use write completion function to start reading a command */
803
768
        global_iface_write_completed(0, 0, &dst->overlap);
804
 
 
805
 
        global_flush_broken_pipes(priv);
806
769
}
807
770
 
808
771
 
811
774
{
812
775
        struct ctrl_iface_global_priv *priv;
813
776
 
814
 
        priv = os_zalloc(sizeof(*priv));
 
777
        priv = wpa_zalloc(sizeof(*priv));
815
778
        if (priv == NULL)
816
779
                return NULL;
817
780
        priv->global = global;
818
781
 
819
782
        if (global_open_pipe(priv) < 0) {
820
 
                os_free(priv);
 
783
                free(priv);
821
784
                return NULL;
822
785
        }
823
786
 
830
793
{
831
794
        while (priv->ctrl_dst)
832
795
                global_close_pipe(priv->ctrl_dst);
833
 
        os_free(priv);
 
796
        free(priv);
834
797
}