~ubuntu-branches/ubuntu/saucy/hplip/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/CVE-2010-4267.dpatch/io/hpmud/pml.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2012-05-26 11:20:39 UTC
  • mfrom: (1.5.6) (31.1.3 precise)
  • Revision ID: package-import@ubuntu.com-20120526112039-bevxczegxnbyr5m7
Tags: 3.12.4-1
* New upstream release
* Switch to source/format 3.0 (quilt) - drop dpatch
* Refreshed debian/patches
* dh_autoreconf debian/autogen.sh & set local-options single-debian-patch
* Update to debian/compat -> 9
* Fix "hardened build flags" patch from Moritz - thanks (Closes: #667828)
* Fix "duplex descriptor uninitialized" patch from Matej (Closes: #583273)
* Fix "please migrate to kde-runtime" patch from Pino (Closes: #666544)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************\
 
2
 
 
3
  pml.c - get/set pml api for hpmud
 
4
 
 
5
  The get/set pml commands are a high level interface to hpmud. This hpmud system
 
6
  interface sits on top of the hpmud core interface. The system interface does 
 
7
  not use the hpmud memory map file system.
 
8
 
 
9
  (c) 2004-2007 Copyright Hewlett-Packard Development Company, LP
 
10
 
 
11
  Permission is hereby granted, free of charge, to any person obtaining a copy 
 
12
  of this software and associated documentation files (the "Software"), to deal 
 
13
  in the Software without restriction, including without limitation the rights 
 
14
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
 
15
  of the Software, and to permit persons to whom the Software is furnished to do 
 
16
  so, subject to the following conditions:
 
17
 
 
18
  The above copyright notice and this permission notice shall be included in all
 
19
  copies or substantial portions of the Software.
 
20
 
 
21
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 
22
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 
 
23
  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 
 
24
  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
 
25
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 
26
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
 
 
28
\*****************************************************************************/
 
29
 
 
30
#ifndef _GNU_SOURCE
 
31
#define _GNU_SOURCE
 
32
#endif
 
33
 
 
34
#include <stdlib.h>
 
35
#include <string.h>
 
36
#include "hpmud.h"
 
37
#include "hpmudi.h"
 
38
 
 
39
#ifdef HAVE_LIBNETSNMP
 
40
#ifdef HAVE_UCDSNMP
 
41
#include <ucd-snmp/ucd-snmp-config.h>
 
42
#include <ucd-snmp/ucd-snmp-includes.h>
 
43
#else
 
44
#include <net-snmp/net-snmp-config.h>
 
45
#include <net-snmp/net-snmp-includes.h>
 
46
#endif
 
47
static const char *SnmpPort[] = { "","public.1","public.2","public.3" };
 
48
#endif
 
49
 
 
50
static int PmlOidToHex(const char *szoid, unsigned char *oid, int oidSize)
 
51
{
 
52
   char *tail;
 
53
   int i=0, val;
 
54
 
 
55
   if (szoid[0] == 0)
 
56
      goto bugout;
 
57
 
 
58
   val = strtol(szoid, &tail, 10);
 
59
 
 
60
   while (i < oidSize)
 
61
   {
 
62
      if (val > 128)
 
63
      {
 
64
         BUG("invalid oid size: oid=%s\n", szoid);
 
65
         goto bugout;
 
66
      }
 
67
      oid[i++] = (unsigned char)val;
 
68
 
 
69
      if (*tail == 0)
 
70
         break;         /* done */
 
71
 
 
72
      val = strtol(tail+1, &tail, 10);
 
73
   }
 
74
 
 
75
bugout:
 
76
   return i;
 
77
}
 
78
 
 
79
/* Convert ascii snmp oid to pml hex oid. */
 
80
static int SnmpToPml(const char *snmp_oid, unsigned char *oid, int oidSize)
 
81
{
 
82
   static const char hp_pml_mib_prefix[] = "1.3.6.1.4.1.11.2.3.9.4.2";
 
83
   static const char standard_printer_mib_prefix[] = "1.3.6.1.2.1.43";
 
84
   static const char host_resource_mib_prefix[] = "1.3.6.1.2.1.25";
 
85
   int len=0;
 
86
 
 
87
   if (strncmp(snmp_oid, hp_pml_mib_prefix, sizeof(hp_pml_mib_prefix)-1) == 0)
 
88
   {
 
89
      /* Strip out snmp prefix and convert to hex. */
 
90
      len = 0;
 
91
      len += PmlOidToHex(&snmp_oid[sizeof(hp_pml_mib_prefix)], &oid[0], oidSize);
 
92
      len--; /* remove trailing zero in pml mib */
 
93
   }
 
94
   else if   (strncmp(snmp_oid, standard_printer_mib_prefix, sizeof(standard_printer_mib_prefix)-1) == 0)
 
95
   {
 
96
      /* Replace snmp prefix with 2 and convert to hex. */
 
97
      len = 1;
 
98
      oid[0] = 0x2;
 
99
      len += PmlOidToHex(&snmp_oid[sizeof(standard_printer_mib_prefix)], &oid[1], oidSize);  
 
100
   }
 
101
   else if   (strncmp(snmp_oid, host_resource_mib_prefix, sizeof(host_resource_mib_prefix)-1) == 0)
 
102
   {
 
103
      /* Replace snmp prefix with 3 and convert to hex. */
 
104
      len = 1;
 
105
      oid[0] = 0x3;
 
106
      len += PmlOidToHex(&snmp_oid[sizeof(host_resource_mib_prefix)], &oid[1], oidSize);
 
107
   }
 
108
   else
 
109
      BUG("SnmpToPml failed snmp oid=%s\n", snmp_oid);
 
110
 
 
111
   return len;
 
112
}
 
113
 
 
114
#ifdef HAVE_LIBNETSNMP
 
115
 
 
116
static int SnmpErrorToPml(int snmp_error)
 
117
{
 
118
   int err;
 
119
 
 
120
   switch (snmp_error)
 
121
   {
 
122
      case SNMP_ERR_NOERROR:
 
123
         err = PML_EV_OK;
 
124
         break;
 
125
      case SNMP_ERR_TOOBIG:
 
126
         err = PML_EV_ERROR_BUFFER_OVERFLOW;
 
127
         break;
 
128
      case SNMP_ERR_NOSUCHNAME:
 
129
         err = PML_EV_ERROR_UNKNOWN_OBJECT_IDENTIFIER;
 
130
         break;
 
131
      case SNMP_ERR_BADVALUE:
 
132
         err = PML_EV_ERROR_INVALID_OR_UNSUPPORTED_VALUE;
 
133
         break;
 
134
      case SNMP_ERR_READONLY:
 
135
         err = PML_EV_ERROR_OBJECT_DOES_NOT_SUPPORT_REQUESTED_ACTION;
 
136
         break;
 
137
      case SNMP_ERR_GENERR:
 
138
      default:
 
139
         err = PML_EV_ERROR_UNKNOWN_REQUEST;
 
140
         break;
 
141
   }
 
142
 
 
143
   return err;
 
144
}
 
145
 
 
146
static int SetSnmp(const char *ip, int port, const char *szoid, int type, void *buffer, unsigned int size, int *pml_result, int *result)
 
147
{
 
148
   struct snmp_session session, *ss=NULL;
 
149
   struct snmp_pdu *pdu=NULL;
 
150
   struct snmp_pdu *response=NULL;
 
151
   oid anOID[MAX_OID_LEN];
 
152
   size_t anOID_len = MAX_OID_LEN;
 
153
   unsigned int i, len=0;
 
154
   uint32_t val;
 
155
 
 
156
   *result = HPMUD_R_IO_ERROR;
 
157
   *pml_result = PML_EV_ERROR_UNKNOWN_REQUEST;
 
158
 
 
159
   init_snmp("snmpapp");
 
160
 
 
161
   snmp_sess_init(&session );                   /* set up defaults */
 
162
   session.peername = (char *)ip;
 
163
   session.version = SNMP_VERSION_1;
 
164
   session.community = (unsigned char *)SnmpPort[port];
 
165
   session.community_len = strlen((const char *)session.community);
 
166
   ss = snmp_open(&session);                     /* establish the session */
 
167
   if (ss == NULL)
 
168
      goto bugout;
 
169
 
 
170
   pdu = snmp_pdu_create(SNMP_MSG_SET);
 
171
   read_objid(szoid, anOID, &anOID_len);
 
172
 
 
173
   switch (type)
 
174
   {
 
175
      case PML_DT_ENUMERATION:
 
176
      case PML_DT_SIGNED_INTEGER:
 
177
         /* Convert PML big-endian to SNMP little-endian byte stream. */
 
178
         for(i=0, val=0; i<size && i<sizeof(val); i++)    
 
179
            val = ((val << 8) | ((unsigned char *)buffer)[i]);
 
180
         snmp_pdu_add_variable(pdu, anOID, anOID_len, ASN_INTEGER, (unsigned char *)&val, sizeof(val));
 
181
         break;
 
182
      case PML_DT_REAL:
 
183
      case PML_DT_STRING:
 
184
      case PML_DT_BINARY:
 
185
      case PML_DT_NULL_VALUE:
 
186
      case PML_DT_COLLECTION:
 
187
      default:
 
188
         snmp_pdu_add_variable(pdu, anOID, anOID_len, ASN_OCTET_STR, buffer, size);
 
189
         break;
 
190
   }
 
191
 
 
192
  
 
193
   /* Send the request and get response. */
 
194
   if (snmp_synch_response(ss, pdu, &response) != STAT_SUCCESS)
 
195
      goto bugout;
 
196
 
 
197
   if (response->errstat == SNMP_ERR_NOERROR) 
 
198
   {
 
199
      len = size;
 
200
   }
 
201
 
 
202
   *pml_result = SnmpErrorToPml(response->errstat);
 
203
   *result = HPMUD_R_OK;
 
204
 
 
205
bugout:
 
206
   if (response != NULL)
 
207
      snmp_free_pdu(response);
 
208
   if (ss != NULL)
 
209
      snmp_close(ss);
 
210
   return len;
 
211
}
 
212
 
 
213
int __attribute__ ((visibility ("hidden"))) GetSnmp(const char *ip, int port, const char *szoid, void *buffer, unsigned int size, int *type, int *pml_result, int *result)
 
214
{
 
215
   struct snmp_session session, *ss=NULL;
 
216
   struct snmp_pdu *pdu=NULL;
 
217
   struct snmp_pdu *response=NULL;
 
218
   unsigned int i, len=0;
 
219
   oid anOID[MAX_OID_LEN];
 
220
   size_t anOID_len = MAX_OID_LEN;
 
221
   struct variable_list *vars;
 
222
   uint32_t val;
 
223
   unsigned char tmp[sizeof(uint32_t)];
 
224
 
 
225
   *result = HPMUD_R_IO_ERROR;
 
226
   *type = PML_DT_NULL_VALUE;
 
227
   *pml_result = PML_EV_ERROR_UNKNOWN_REQUEST;
 
228
 
 
229
   init_snmp("snmpapp");
 
230
 
 
231
   snmp_sess_init(&session );                   /* set up defaults */
 
232
   session.peername = (char *)ip;
 
233
   session.version = SNMP_VERSION_1;
 
234
   session.community = (unsigned char *)SnmpPort[port];
 
235
   session.community_len = strlen((const char *)session.community);
 
236
   session.retries = 2;
 
237
   session.timeout = 1000000;         /* 1 second */
 
238
   ss = snmp_open(&session);                     /* establish the session */
 
239
   if (ss == NULL)
 
240
      goto bugout;
 
241
 
 
242
   pdu = snmp_pdu_create(SNMP_MSG_GET);
 
243
   read_objid(szoid, anOID, &anOID_len);
 
244
   snmp_add_null_var(pdu, anOID, anOID_len);
 
245
  
 
246
   /* Send the request and get response. */
 
247
   if (snmp_synch_response(ss, pdu, &response) != STAT_SUCCESS)
 
248
      goto bugout;
 
249
 
 
250
   if (response->errstat == SNMP_ERR_NOERROR) 
 
251
   {
 
252
      vars = response->variables;
 
253
      switch (vars->type)
 
254
      {
 
255
         case ASN_INTEGER:
 
256
            *type = PML_DT_SIGNED_INTEGER;
 
257
 
 
258
            /* Convert SNMP little-endian to PML big-endian byte stream. */
 
259
            len = (sizeof(uint32_t) < size) ? sizeof(uint32_t) : size;
 
260
            val = *vars->val.integer;
 
261
            for(i=len; i>0; i--)
 
262
            {
 
263
               tmp[i-1] = val & 0xff;
 
264
               val >>= 8;
 
265
            }
 
266
 
 
267
            /* Remove any in-significant bytes. */
 
268
            for (; tmp[i]==0 && i<len; i++)
 
269
               ;
 
270
            len -= i;
 
271
 
 
272
            memcpy(buffer, tmp+i, len);
 
273
            break;
 
274
         case ASN_NULL:
 
275
            *type = PML_DT_NULL_VALUE;
 
276
            break;
 
277
         case ASN_OCTET_STR:
 
278
            *type = PML_DT_STRING;
 
279
            len = (vars->val_len < size) ? vars->val_len : size;
 
280
            memcpy(buffer, vars->val.string, len);
 
281
            break;
 
282
         default:
 
283
            BUG("unable to GetSnmp: data type=%d\n", vars->type);
 
284
            goto bugout;
 
285
            break;
 
286
      }
 
287
   }
 
288
 
 
289
   *pml_result = SnmpErrorToPml(response->errstat);
 
290
   *result = HPMUD_R_OK;
 
291
 
 
292
bugout:
 
293
   if (response != NULL)
 
294
      snmp_free_pdu(response);
 
295
   if (ss != NULL)
 
296
      snmp_close(ss);
 
297
   return len;
 
298
}
 
299
 
 
300
#else
 
301
 
 
302
int __attribute__ ((visibility ("hidden"))) SetSnmp(const char *ip, int port, const char *szoid, int type, void *buffer, unsigned int size, int *pml_result, int *result)
 
303
{
 
304
   BUG("no JetDirect support enabled\n");
 
305
   return 0;
 
306
}
 
307
 
 
308
int __attribute__ ((visibility ("hidden"))) GetSnmp(const char *ip, int port, const char *szoid, void *buffer, unsigned int size, int *type, int *pml_result, int *result)
 
309
{
 
310
   BUG("no JetDirect support enabled\n");
 
311
   return 0;
 
312
}
 
313
 
 
314
#endif /* HAVE_LIBSNMP */
 
315
 
 
316
/* Set a PML object in the hp device. */
 
317
enum HPMUD_RESULT hpmud_set_pml(HPMUD_DEVICE device, HPMUD_CHANNEL channel, const char *snmp_oid, int type, void *data, int data_size, int *pml_result)
 
318
{
 
319
   unsigned char message[HPMUD_BUFFER_SIZE];
 
320
   unsigned char oid[HPMUD_LINE_SIZE];
 
321
   char ip[HPMUD_LINE_SIZE], *psz, *tail;
 
322
   unsigned char *p=message;
 
323
   int len, dLen, result, reply, status, port;
 
324
   struct hpmud_dstat ds;
 
325
   enum HPMUD_RESULT stat = HPMUD_R_IO_ERROR;
 
326
 
 
327
   DBG("[%d] hpmud_set_pml() dd=%d cd=%d oid=%s type=%d data=%p size=%d\n", getpid(), device, channel, snmp_oid, type, data, data_size);
 
328
 
 
329
   if ((result = hpmud_get_dstat(device, &ds)) != HPMUD_R_OK)
 
330
   {
 
331
      stat = result;
 
332
      goto bugout;
 
333
   }
 
334
 
 
335
   if (strcasestr(ds.uri, "net/") != NULL)
 
336
   {
 
337
      /* Process pml via snmp. */
 
338
 
 
339
      hpmud_get_uri_datalink(ds.uri, ip, sizeof(ip));
 
340
 
 
341
      if ((psz = strstr(ds.uri, "port=")) != NULL)
 
342
         port = strtol(psz+5, &tail, 10);
 
343
      else
 
344
         port = 1;
 
345
 
 
346
      SetSnmp(ip, port, snmp_oid, type, data, data_size, &status, &result);
 
347
      if (result != HPMUD_R_OK)
 
348
      {
 
349
         BUG("SetPml failed ret=%d\n", result);
 
350
         stat = result;
 
351
         goto bugout;       
 
352
      }
 
353
   }       
 
354
   else
 
355
   {
 
356
      /* Process pml via local transport. */
 
357
 
 
358
      /* Convert snmp ascii oid to pml hex oid. */
 
359
      dLen = SnmpToPml(snmp_oid, oid, sizeof(oid));
 
360
   
 
361
      *p++ = PML_SET_REQUEST;
 
362
      *p++ = PML_DT_OBJECT_IDENTIFIER;
 
363
      *p++ = dLen;                          /* assume oid length is < 10 bits */
 
364
      memcpy(p, oid, dLen);
 
365
      p+=dLen;
 
366
      *p = type;
 
367
      *p |= data_size >> 8;                   /* assume data length is 10 bits */
 
368
      *(p+1) = data_size & 0xff;    
 
369
      p += 2; 
 
370
      memcpy(p, data, data_size);
 
371
 
 
372
      result = hpmud_write_channel(device, channel, message, dLen+data_size+3+2, HPMUD_EXCEPTION_SEC_TIMEOUT, &len);  
 
373
      if (result != HPMUD_R_OK)
 
374
      {
 
375
         BUG("SetPml channel_write failed ret=%d\n", result);
 
376
         stat = result;
 
377
         goto bugout;       
 
378
      }    
 
379
 
 
380
      result = hpmud_read_channel(device, channel, message, sizeof(message), HPMUD_EXCEPTION_SEC_TIMEOUT, &len);
 
381
      if (result != HPMUD_R_OK || len == 0)
 
382
      {
 
383
         BUG("SetPml channel_read failed ret=%d len=%d\n", result, len);
 
384
         goto bugout;       
 
385
      }    
 
386
 
 
387
      p = message;
 
388
      reply = *p++;       /* read command reply */
 
389
      status = *p++;      /* read execution outcome */
 
390
 
 
391
      if (reply != (PML_SET_REQUEST | 0x80) && status & 0x80)
 
392
      {
 
393
         BUG("SetPml failed reply=%x outcome=%x\n", reply, status);
 
394
         DBG_DUMP(p, len-2);
 
395
         goto bugout;       
 
396
      }   
 
397
   }
 
398
   
 
399
   *pml_result = status;
 
400
   stat = HPMUD_R_OK;
 
401
 
 
402
   DBG("set_pml result pmlresult=%x\n", status);
 
403
 
 
404
bugout:
 
405
   return stat;
 
406
}
 
407
 
 
408
/* Get a PML object from the hp device. */
 
409
enum HPMUD_RESULT hpmud_get_pml(HPMUD_DEVICE device, HPMUD_CHANNEL channel, const char *snmp_oid, void *buf, int buf_size, int *bytes_read, int *type, int *pml_result)
 
410
{
 
411
   unsigned char message[HPMUD_BUFFER_SIZE];
 
412
   unsigned char oid[HPMUD_LINE_SIZE];
 
413
   char ip[HPMUD_LINE_SIZE], *psz, *tail;
 
414
   unsigned char *p=message;
 
415
   int len, dLen, result, reply, status, dt, port;
 
416
   struct hpmud_dstat ds;
 
417
   enum HPMUD_RESULT stat = HPMUD_R_IO_ERROR;
 
418
 
 
419
   DBG("[%d] hpmud_get_pml() dd=%d cd=%d oid=%s data=%p size=%d\n", getpid(), device, channel, snmp_oid, buf, buf_size);
 
420
 
 
421
   if ((result = hpmud_get_dstat(device, &ds)) != HPMUD_R_OK)
 
422
   {
 
423
      stat = result;
 
424
      goto bugout;
 
425
   }
 
426
 
 
427
   if (strcasestr(ds.uri, "net/") != NULL)
 
428
   {
 
429
      /* Process pml via snmp. */
 
430
 
 
431
      hpmud_get_uri_datalink(ds.uri, ip, sizeof(ip));
 
432
 
 
433
      if ((psz = strstr(ds.uri, "port=")) != NULL)
 
434
         port = strtol(psz+5, &tail, 10);
 
435
      else
 
436
         port = 1;
 
437
 
 
438
      dLen = GetSnmp(ip, port, snmp_oid, message, sizeof(message), &dt, &status, &result);
 
439
      if (result != HPMUD_R_OK)
 
440
      {
 
441
         BUG("GetPml failed ret=%d\n", result);
 
442
         stat = result;
 
443
         goto bugout;       
 
444
      }
 
445
      p = message;    
 
446
   }       
 
447
   else
 
448
   {
 
449
      /* Process pml via local transport. */
 
450
 
 
451
      /* Convert snmp ascii oid to pml hex oid. */
 
452
      dLen = SnmpToPml(snmp_oid, oid, sizeof(oid));
 
453
   
 
454
      *p++ = PML_GET_REQUEST;
 
455
      *p++ = PML_DT_OBJECT_IDENTIFIER;
 
456
      *p++ = dLen;                          /* assume oid length is < 10 bits */
 
457
      memcpy(p, oid, dLen);
 
458
      result = hpmud_write_channel(device, channel, message, dLen+3, HPMUD_EXCEPTION_SEC_TIMEOUT, &len);
 
459
      if (result != HPMUD_R_OK)
 
460
      {
 
461
         BUG("GetPml channel_write failed ret=%d\n", result);
 
462
         stat = result;
 
463
         goto bugout;       
 
464
      }    
 
465
 
 
466
      result = hpmud_read_channel(device, channel, message, sizeof(message), HPMUD_EXCEPTION_SEC_TIMEOUT, &len);
 
467
      if (result != HPMUD_R_OK || len == 0)
 
468
      {
 
469
         BUG("GetPml channel_read failed ret=%d len=%d\n", result, len);
 
470
         goto bugout;       
 
471
      }    
 
472
 
 
473
      p = message;
 
474
      reply = *p++;       /* read command reply */
 
475
      status = *p++;      /* read execution outcome */
 
476
 
 
477
      if (reply != (PML_GET_REQUEST | 0x80) && status & 0x80)
 
478
      {
 
479
         BUG("GetPml failed reply=%x outcome=%x\n", reply, status);
 
480
         DBG_DUMP(p, len-2);
 
481
         goto bugout;       
 
482
      }   
 
483
 
 
484
      dt = *p++;       /* read data type */
 
485
 
 
486
      if (dt == PML_DT_ERROR_CODE)
 
487
      {
 
488
         /* Ok, but invalid data type requested, get new data type. */
 
489
         p += 2;       /* eat length and err code */
 
490
         dt = *p++;  /* read data type */
 
491
      } 
 
492
 
 
493
      if (dt != PML_DT_OBJECT_IDENTIFIER)
 
494
      {
 
495
         BUG("GetPml failed data type=%x\n", dt);
 
496
         goto bugout;       
 
497
      }   
 
498
 
 
499
      dLen = *p++;     /* read oid length */
 
500
      p += dLen;       /* eat oid */
 
501
 
 
502
      dt = *p;    /* read data type. */
 
503
      dLen = ((*p & 0x3) << 8 | *(p+1));         /* read 10 bit len from 2 byte field */
 
504
      p += 2;                               /* eat type and length */
 
505
   }
 
506
   
 
507
   memcpy(buf, p, dLen);
 
508
   *bytes_read = dLen; 
 
509
   *type = dt;
 
510
   *pml_result = status;
 
511
   stat = HPMUD_R_OK;
 
512
 
 
513
   DBG("get_pml result len=%d datatype=%x pmlresult=%x\n", dLen, dt, status);
 
514
   DBG_DUMP(buf, dLen);
 
515
 
 
516
bugout:
 
517
   return stat;
 
518
}
 
519
 
 
520