~ubuntu-branches/ubuntu/utopic/squid3/utopic-proposed

« back to all changes in this revision

Viewing changes to helpers/ntlm_auth/smb_lm/smbval/rfcnb-util.c

  • Committer: Package Import Robot
  • Author(s): Yolanda Robla
  • Date: 2013-07-10 17:12:42 UTC
  • mfrom: (21.2.18 sid)
  • Revision ID: package-import@ubuntu.com-20130710171242-2i9v941ikbpnjyqk
Tags: 3.3.4-1ubuntu1
* Merge from Debian unstable (LP: #1199883).  Remaining changes:
  + debian/control:
    - Update maintainer.
    - Suggests apparmor (>= 2.3)
    - Depends on ssl-cert ((>= 1.0-11ubuntu1), autopkgtests
  + debian/squid3.upstart
    - Move ulimit command to script section so that it applies
      to the started squid daemon. Thanks to Timur Irmatov (LP: 986159)
    - Work around squid not handling SIGHUP by adding respawn to
      upstart job. (LP: 978356)
  + debian/NEWS.Debian: Rename NEWS.debian, add note regarding squid3
    transition in 12.04 (LP: 924739)
  + debian/rules
    - Re-enable all hardening options lost in the squid->squid3
      transition (LP: 986314)
  + squid3.resolvconf, debian/squid3.postinst, debian/squid3.postrm,
    debian/squid3.preinst, debian/squid3.prerm:
    - Convert init script to upstart
  + debian/patches/99-ubuntu-ssl-cert-snakeoil:
    - Use snakeoil certificates.
  + debian/logrotate
    - Use sar-reports rather than sarg-maint. (LP: 26616)
  + debian/patches/90-cf.data.ubuntu.dpatch:
    - Add an example refresh pattern for debs.
      (foundations-lucid-local-report spec)
  + Add disabled by default AppArmor profile (LP: 497790)
    - debian/squid3.upstart: load profile in pre-start stanza
    - add debian/usr.sbin.squid3 profile
    - debian/rules:
      + install debian/usr.sbin.squid3, etc/apparmor.d/force-complain and
        etc/apparmor.d/disable into $(INSTALLDIR)
      + use dh_apparmor
    - debian/squid3.install: install etc/apparmor.d/disable, force-complain
      and usr.sbin.squid3
    - debian/squid3.preinst: disable profile on clean install or upgrades
      from earlier than when we shipped the profile
  + debian/tests:
    - Add autopkgtests.

* Dropped:
  - debian/patches: dropped patches, superseded by new release:
    + 98-CVE-2012-5643.patch
    + 99-lp1117517_r12473.patch
  - debian/rules: fix FTBFS, removed --with-cppunit-basedir flag,
    included in Debian.
  - debian/control: Dropped transitional packages from squid, no
    longer required.

* Refreshed patches:
  - 01-cf.data.debian.patch
  - 02-makefile-defaults.patch
  - 15-cachemgr-default-config.patch

* debian/tests/test-squid.py: fixed case problem with ftp test

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
2
 
 *
3
 
 * Version 1.0
4
 
 * RFCNB Utility Routines ...
5
 
 *
6
 
 * Copyright (C) Richard Sharpe 1996
7
 
 *
8
 
 */
9
 
 
10
 
/*
11
 
 * This program is free software; you can redistribute it and/or modify
12
 
 * it under the terms of the GNU General Public License as published by
13
 
 * the Free Software Foundation; either version 2 of the License, or
14
 
 * (at your option) any later version.
15
 
 *
16
 
 * This program is distributed in the hope that it will be useful,
17
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 
 * GNU General Public License for more details.
20
 
 *
21
 
 * You should have received a copy of the GNU General Public License
22
 
 * along with this program; if not, write to the Free Software
23
 
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
 
 */
25
 
 
26
 
#include "config.h"
27
 
 
28
 
#include "std-includes.h"
29
 
#include "rfcnb-priv.h"
30
 
#include "rfcnb-util.h"
31
 
#include <string.h>
32
 
#include <stdlib.h>
33
 
#include "rfcnb-io.h"
34
 
#include <arpa/inet.h>
35
 
 
36
 
#ifndef uint16
37
 
#ifdef u_int16_t
38
 
typedef u_int16_t uint16;
39
 
#else
40
 
typedef unsigned short uint16;
41
 
#endif
42
 
#endif
43
 
 
44
 
extern void (*Prot_Print_Routine) ();   /* Pointer to protocol print routine */
45
 
 
46
 
/* Convert name and pad to 16 chars as needed */
47
 
/* Name 1 is a C string with null termination, name 2 may not be */
48
 
/* If SysName is true, then put a <00> on end, else space>       */
49
 
 
50
 
void
51
 
RFCNB_CvtPad_Name(char *name1, char *name2)
52
 
{
53
 
    char c, c1, c2;
54
 
    int i, len;
55
 
 
56
 
    len = strlen(name1);
57
 
 
58
 
    for (i = 0; i < 16; i++) {
59
 
 
60
 
        if (i >= len) {
61
 
 
62
 
            c1 = 'C';
63
 
            c2 = 'A';           /* CA is a space */
64
 
 
65
 
        } else {
66
 
 
67
 
            c = name1[i];
68
 
            c1 = (char) ((int) c / 16 + (int) 'A');
69
 
            c2 = (char) ((int) c % 16 + (int) 'A');
70
 
        }
71
 
 
72
 
        name2[i * 2] = c1;
73
 
        name2[i * 2 + 1] = c2;
74
 
 
75
 
    }
76
 
 
77
 
    name2[32] = 0;              /* Put in the nll ... */
78
 
 
79
 
}
80
 
 
81
 
/* Converts an Ascii NB Name (16 chars) to an RFCNB Name (32 chars)
82
 
 * Uses the encoding in RFC1001. Each nibble of byte is added to 'A'
83
 
 * to produce the next byte in the name.
84
 
 *
85
 
 * This routine assumes that AName is 16 bytes long and that NBName has
86
 
 * space for 32 chars, so be careful ...
87
 
 *
88
 
 */
89
 
 
90
 
void
91
 
RFCNB_AName_To_NBName(char *AName, char *NBName)
92
 
{
93
 
    char c, c1, c2;
94
 
    int i;
95
 
 
96
 
    for (i = 0; i < 16; i++) {
97
 
 
98
 
        c = AName[i];
99
 
 
100
 
        c1 = (char) ((c >> 4) + 'A');
101
 
        c2 = (char) ((c & 0xF) + 'A');
102
 
 
103
 
        NBName[i * 2] = c1;
104
 
        NBName[i * 2 + 1] = c2;
105
 
    }
106
 
 
107
 
    NBName[32] = 0;             /* Put in a null */
108
 
 
109
 
}
110
 
 
111
 
/* Do the reverse of the above ... */
112
 
 
113
 
void
114
 
RFCNB_NBName_To_AName(char *NBName, char *AName)
115
 
{
116
 
    char c, c1, c2;
117
 
    int i;
118
 
 
119
 
    for (i = 0; i < 16; i++) {
120
 
 
121
 
        c1 = NBName[i * 2];
122
 
        c2 = NBName[i * 2 + 1];
123
 
 
124
 
        c = (char) (((int) c1 - (int) 'A') * 16 + ((int) c2 - (int) 'A'));
125
 
 
126
 
        AName[i] = c;
127
 
 
128
 
    }
129
 
 
130
 
    AName[i] = 0;               /* Put a null on the end ... */
131
 
 
132
 
}
133
 
 
134
 
/* Print a string of bytes in HEX etc */
135
 
 
136
 
void
137
 
RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len)
138
 
{
139
 
    char c1, c2, outbuf1[33];
140
 
    unsigned char c;
141
 
    int i, j;
142
 
    struct RFCNB_Pkt *pkt_ptr = pkt;
143
 
    static char Hex_List[17] = "0123456789ABCDEF";
144
 
 
145
 
    j = 0;
146
 
 
147
 
    /* We only want to print as much as sepcified in Len */
148
 
 
149
 
    while (pkt_ptr != NULL) {
150
 
 
151
 
        for (i = 0;
152
 
                i < ((Len > (pkt_ptr->len) ? pkt_ptr->len : Len) - Offset);
153
 
                i++) {
154
 
 
155
 
            c = pkt_ptr->data[i + Offset];
156
 
            c1 = Hex_List[c >> 4];
157
 
            c2 = Hex_List[c & 0xF];
158
 
 
159
 
            outbuf1[j++] = c1;
160
 
            outbuf1[j++] = c2;
161
 
 
162
 
            if (j == 32) {      /* Print and reset */
163
 
                outbuf1[j] = 0;
164
 
                fprintf(fd, "    %s\n", outbuf1);
165
 
                j = 0;
166
 
            }
167
 
        }
168
 
 
169
 
        Offset = 0;
170
 
        Len = Len - pkt_ptr->len;       /* Reduce amount by this much */
171
 
        pkt_ptr = pkt_ptr->next;
172
 
 
173
 
    }
174
 
 
175
 
    /* Print last lot in the buffer ... */
176
 
 
177
 
    if (j > 0) {
178
 
 
179
 
        outbuf1[j] = 0;
180
 
        fprintf(fd, "    %s\n", outbuf1);
181
 
 
182
 
    }
183
 
    fprintf(fd, "\n");
184
 
 
185
 
}
186
 
 
187
 
/* Get a packet of size n */
188
 
 
189
 
struct RFCNB_Pkt *
190
 
RFCNB_Alloc_Pkt(int n) {
191
 
    RFCNB_Pkt *pkt;
192
 
 
193
 
    if ((pkt = (struct RFCNB_Pkt *) malloc(sizeof(struct RFCNB_Pkt))) == NULL) {
194
 
 
195
 
        RFCNB_errno = RFCNBE_NoSpace;
196
 
        RFCNB_saved_errno = errno;
197
 
        return (NULL);
198
 
 
199
 
    }
200
 
    pkt->next = NULL;
201
 
    pkt->len = n;
202
 
 
203
 
    if (n == 0)
204
 
        return (pkt);
205
 
 
206
 
    if ((pkt->data = (char *) malloc(n)) == NULL) {
207
 
 
208
 
        RFCNB_errno = RFCNBE_NoSpace;
209
 
        RFCNB_saved_errno = errno;
210
 
        free(pkt);
211
 
        return (NULL);
212
 
 
213
 
    }
214
 
    return (pkt);
215
 
 
216
 
}
217
 
 
218
 
/* Free up a packet */
219
 
 
220
 
void
221
 
RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt)
222
 
{
223
 
    struct RFCNB_Pkt *pkt_next;
224
 
    char *data_ptr;
225
 
 
226
 
    while (pkt != NULL) {
227
 
 
228
 
        pkt_next = pkt->next;
229
 
 
230
 
        data_ptr = pkt->data;
231
 
 
232
 
        if (data_ptr != NULL)
233
 
            free(data_ptr);
234
 
 
235
 
        free(pkt);
236
 
 
237
 
        pkt = pkt_next;
238
 
 
239
 
    }
240
 
 
241
 
}
242
 
 
243
 
/* Print an RFCNB packet */
244
 
 
245
 
void
246
 
RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len)
247
 
{
248
 
    char lname[17];
249
 
 
250
 
    /* We assume that the first fragment is the RFCNB Header  */
251
 
    /* We should loop through the fragments printing them out */
252
 
 
253
 
    fprintf(fd, "RFCNB Pkt %s:", dirn);
254
 
 
255
 
    switch (RFCNB_Pkt_Type(pkt->data)) {
256
 
 
257
 
    case RFCNB_SESSION_MESSAGE:
258
 
 
259
 
        fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt->data));
260
 
        RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len,
261
 
#ifdef RFCNB_PRINT_DATA
262
 
                        RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len);
263
 
#else
264
 
                        40);
265
 
#endif
266
 
 
267
 
        if (Prot_Print_Routine != 0) {  /* Print the rest of the packet */
268
 
 
269
 
            Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, RFCNB_Pkt_Hdr_Len,
270
 
                               RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len);
271
 
 
272
 
        }
273
 
        break;
274
 
 
275
 
    case RFCNB_SESSION_REQUEST:
276
 
 
277
 
        fprintf(fd, "SESSION REQUEST: Length = %i\n",
278
 
                RFCNB_Pkt_Len(pkt->data));
279
 
        RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Called_Offset), lname);
280
 
        fprintf(fd, "  Called Name: %s\n", lname);
281
 
        RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Calling_Offset), lname);
282
 
        fprintf(fd, "  Calling Name: %s\n", lname);
283
 
 
284
 
        break;
285
 
 
286
 
    case RFCNB_SESSION_ACK:
287
 
 
288
 
        fprintf(fd, "RFCNB SESSION ACK: Length = %i\n",
289
 
                RFCNB_Pkt_Len(pkt->data));
290
 
 
291
 
        break;
292
 
 
293
 
    case RFCNB_SESSION_REJ:
294
 
        fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n",
295
 
                RFCNB_Pkt_Len(pkt->data));
296
 
 
297
 
        if (RFCNB_Pkt_Len(pkt->data) < 1) {
298
 
            fprintf(fd, "   Protocol Error, short Reject packet!\n");
299
 
        } else {
300
 
            fprintf(fd, "   Error = %x\n", CVAL(pkt->data, RFCNB_Pkt_Error_Offset));
301
 
        }
302
 
 
303
 
        break;
304
 
 
305
 
    case RFCNB_SESSION_RETARGET:
306
 
 
307
 
        fprintf(fd, "RFCNB SESSION RETARGET: Length = %i\n",
308
 
                RFCNB_Pkt_Len(pkt->data));
309
 
 
310
 
        /* Print out the IP address etc and the port? */
311
 
 
312
 
        break;
313
 
 
314
 
    case RFCNB_SESSION_KEEP_ALIVE:
315
 
 
316
 
        fprintf(fd, "RFCNB SESSION KEEP ALIVE: Length = %i\n",
317
 
                RFCNB_Pkt_Len(pkt->data));
318
 
        break;
319
 
 
320
 
    default:
321
 
 
322
 
        break;
323
 
    }
324
 
 
325
 
}
326
 
 
327
 
/* Resolve a name into an address */
328
 
 
329
 
int
330
 
RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP)
331
 
{
332
 
    int addr;                   /* Assumes IP4, 32 bit network addresses */
333
 
    struct hostent *hp;
334
 
 
335
 
    /* Use inet_addr to try to convert the address */
336
 
 
337
 
    if ((addr = inet_addr(host)) == INADDR_NONE) {      /* Oh well, a good try :-) */
338
 
 
339
 
        /* Now try a name look up with gethostbyname */
340
 
 
341
 
        if ((hp = gethostbyname(host)) == NULL) {       /* Not in DNS */
342
 
 
343
 
            /* Try NetBIOS name lookup, how the hell do we do that? */
344
 
 
345
 
            RFCNB_errno = RFCNBE_BadName;       /* Is this right? */
346
 
            RFCNB_saved_errno = errno;
347
 
            return (RFCNBE_Bad);
348
 
 
349
 
        } else { /* We got a name */
350
 
            Dest_IP->s_addr = (*((struct in_addr*)hp->h_addr_list[0])).s_addr;
351
 
        }
352
 
    } else { /* It was an IP address */
353
 
        Dest_IP->s_addr = addr;
354
 
    }
355
 
 
356
 
    return 0;
357
 
 
358
 
}
359
 
 
360
 
/* Disconnect the TCP connection to the server */
361
 
 
362
 
int
363
 
RFCNB_Close(int aSocket)
364
 
{
365
 
 
366
 
    close(aSocket);
367
 
 
368
 
    /* If we want to do error recovery, here is where we put it */
369
 
 
370
 
    return 0;
371
 
 
372
 
}
373
 
 
374
 
/* Connect to the server specified in the IP address.
375
 
 * Not sure how to handle socket options etc.         */
376
 
 
377
 
int
378
 
RFCNB_IP_Connect(struct in_addr Dest_IP, int port)
379
 
{
380
 
    struct sockaddr_in Socket;
381
 
    int fd;
382
 
 
383
 
    /* Create a socket */
384
 
 
385
 
    if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {   /* Handle the error */
386
 
 
387
 
        RFCNB_errno = RFCNBE_BadSocket;
388
 
        RFCNB_saved_errno = errno;
389
 
        return (RFCNBE_Bad);
390
 
    }
391
 
    memset((char *) &Socket, 0, sizeof(Socket));
392
 
    memcpy((char *) &Socket.sin_addr, (char *) &Dest_IP, sizeof(Dest_IP));
393
 
 
394
 
    Socket.sin_port = htons(port);
395
 
    Socket.sin_family = PF_INET;
396
 
 
397
 
    /* Now connect to the destination */
398
 
 
399
 
    if (connect(fd, (struct sockaddr *) &Socket, sizeof(Socket)) < 0) {         /* Error */
400
 
 
401
 
        close(fd);
402
 
        RFCNB_errno = RFCNBE_ConnectFailed;
403
 
        RFCNB_saved_errno = errno;
404
 
        return (RFCNBE_Bad);
405
 
    }
406
 
    return (fd);
407
 
 
408
 
}
409
 
 
410
 
/* handle the details of establishing the RFCNB session with remote
411
 
 * end
412
 
 *
413
 
 */
414
 
 
415
 
int
416
 
RFCNB_Session_Req(struct RFCNB_Con *con,
417
 
                  char *Called_Name,
418
 
                  char *Calling_Name,
419
 
                  BOOL * redirect,
420
 
                  struct in_addr *Dest_IP,
421
 
                  int *port)
422
 
{
423
 
    char *sess_pkt;
424
 
 
425
 
    /* Response packet should be no more than 9 bytes, make 16 jic */
426
 
 
427
 
    char resp[16];
428
 
    int len;
429
 
    struct RFCNB_Pkt *pkt, res_pkt;
430
 
 
431
 
    /* We build and send the session request, then read the response */
432
 
 
433
 
    pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len);
434
 
 
435
 
    if (pkt == NULL) {
436
 
 
437
 
        return (RFCNBE_Bad);    /* Leave the error that RFCNB_Alloc_Pkt gives) */
438
 
 
439
 
    }
440
 
    sess_pkt = pkt->data;       /* Get pointer to packet proper */
441
 
 
442
 
    sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST;
443
 
    RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len - RFCNB_Pkt_Hdr_Len);
444
 
    sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32;
445
 
    sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32;
446
 
 
447
 
    RFCNB_CvtPad_Name(Called_Name, (sess_pkt + RFCNB_Pkt_Called_Offset));
448
 
    RFCNB_CvtPad_Name(Calling_Name, (sess_pkt + RFCNB_Pkt_Calling_Offset));
449
 
 
450
 
    /* Now send the packet */
451
 
 
452
 
#ifdef RFCNB_DEBUG
453
 
 
454
 
    fprintf(stderr, "Sending packet: ");
455
 
 
456
 
#endif
457
 
 
458
 
    if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) {
459
 
 
460
 
        return (RFCNBE_Bad);    /* Should be able to write that lot ... */
461
 
 
462
 
    }
463
 
#ifdef RFCNB_DEBUG
464
 
 
465
 
    fprintf(stderr, "Getting packet.\n");
466
 
 
467
 
#endif
468
 
 
469
 
    res_pkt.data = resp;
470
 
    res_pkt.len = sizeof(resp);
471
 
    res_pkt.next = NULL;
472
 
 
473
 
    if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) {
474
 
 
475
 
        return (RFCNBE_Bad);
476
 
 
477
 
    }
478
 
    /* Now analyze the packet ... */
479
 
 
480
 
    switch (RFCNB_Pkt_Type(resp)) {
481
 
 
482
 
    case RFCNB_SESSION_REJ:     /* Didnt like us ... too bad */
483
 
 
484
 
        /* Why did we get rejected ? */
485
 
 
486
 
        switch (CVAL(resp, RFCNB_Pkt_Error_Offset)) {
487
 
 
488
 
        case 0x80:
489
 
            RFCNB_errno = RFCNBE_CallRejNLOCN;
490
 
            break;
491
 
        case 0x81:
492
 
            RFCNB_errno = RFCNBE_CallRejNLFCN;
493
 
            break;
494
 
        case 0x82:
495
 
            RFCNB_errno = RFCNBE_CallRejCNNP;
496
 
            break;
497
 
        case 0x83:
498
 
            RFCNB_errno = RFCNBE_CallRejInfRes;
499
 
            break;
500
 
        case 0x8F:
501
 
            RFCNB_errno = RFCNBE_CallRejUnSpec;
502
 
            break;
503
 
        default:
504
 
            RFCNB_errno = RFCNBE_ProtErr;
505
 
            break;
506
 
        }
507
 
 
508
 
        return (RFCNBE_Bad);
509
 
        break;
510
 
 
511
 
    case RFCNB_SESSION_ACK:     /* Got what we wanted ...      */
512
 
 
513
 
        return (0);
514
 
        break;
515
 
 
516
 
    case RFCNB_SESSION_RETARGET:        /* Go elsewhere                */
517
 
 
518
 
        *redirect = TRUE;       /* Copy port and ip addr       */
519
 
 
520
 
        memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr));
521
 
        *port = SVAL(resp, RFCNB_Pkt_Port_Offset);
522
 
 
523
 
        return (0);
524
 
        break;
525
 
 
526
 
    default:                    /* A protocol error */
527
 
 
528
 
        RFCNB_errno = RFCNBE_ProtErr;
529
 
        return (RFCNBE_Bad);
530
 
        break;
531
 
    }
532
 
}