Deleted Added
full compact
snmp.c (150921) snmp.c (216294)
1/*
2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4 * All rights reserved.
5 *
6 * Author: Harti Brandt <harti@freebsd.org>
7 *
1/*
2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4 * All rights reserved.
5 *
6 * Author: Harti Brandt <harti@freebsd.org>
7 *
8 * Copyright (c) 2010 The FreeBSD Foundation
9 * All rights reserved.
10 *
11 * Portions of this software were developed by Shteryana Sotirova Shopova
12 * under sponsorship from the FreeBSD Foundation.
13 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.

--- 250 unchanged lines hidden (view full) ---

266 v++;
267 }
268
269 b->asn_len = trailer;
270
271 return (err);
272}
273
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.

--- 250 unchanged lines hidden (view full) ---

272 v++;
273 }
274
275 b->asn_len = trailer;
276
277 return (err);
278}
279
280
281static enum asn_err
282parse_secparams(struct asn_buf *b, struct snmp_pdu *pdu)
283{
284 asn_len_t octs_len;
285 u_char buf[256]; /* XXX: calc max possible size here */
286 struct asn_buf tb;
287
288 memset(buf, 0, 256);
289 tb.asn_ptr = buf;
290 tb.asn_len = 256;
291
292 if (asn_get_octetstring(b, buf, &tb.asn_len) != ASN_ERR_OK) {
293 snmp_error("cannot parse usm header");
294 return (ASN_ERR_FAILED);
295 }
296
297 if (asn_get_sequence(&tb, &octs_len) != ASN_ERR_OK) {
298 snmp_error("cannot decode usm header");
299 return (ASN_ERR_FAILED);
300 }
301
302 octs_len = SNMP_ENGINE_ID_SIZ;
303 if (asn_get_octetstring(&tb, (u_char *)&pdu->engine.engine_id,
304 &octs_len) != ASN_ERR_OK) {
305 snmp_error("cannot decode msg engine id");
306 return (ASN_ERR_FAILED);
307 }
308 pdu->engine.engine_len = octs_len;
309
310 if (asn_get_integer(&tb, &pdu->engine.engine_boots) != ASN_ERR_OK) {
311 snmp_error("cannot decode msg engine boots");
312 return (ASN_ERR_FAILED);
313 }
314
315 if (asn_get_integer(&tb, &pdu->engine.engine_time) != ASN_ERR_OK) {
316 snmp_error("cannot decode msg engine time");
317 return (ASN_ERR_FAILED);
318 }
319
320 octs_len = SNMP_ADM_STR32_SIZ - 1;
321 if (asn_get_octetstring(&tb, (u_char *)&pdu->user.sec_name, &octs_len)
322 != ASN_ERR_OK) {
323 snmp_error("cannot decode msg user name");
324 return (ASN_ERR_FAILED);
325 }
326 pdu->user.sec_name[octs_len] = '\0';
327
328 octs_len = sizeof(pdu->msg_digest);
329 if (asn_get_octetstring(&tb, (u_char *)&pdu->msg_digest, &octs_len) !=
330 ASN_ERR_OK || ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0 &&
331 octs_len != sizeof(pdu->msg_digest))) {
332 snmp_error("cannot decode msg authentication param");
333 return (ASN_ERR_FAILED);
334 }
335
336 octs_len = sizeof(pdu->msg_salt);
337 if (asn_get_octetstring(&tb, (u_char *)&pdu->msg_salt, &octs_len) !=
338 ASN_ERR_OK ||((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0 &&
339 octs_len != sizeof(pdu->msg_salt))) {
340 snmp_error("cannot decode msg authentication param");
341 return (ASN_ERR_FAILED);
342 }
343
344 if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0) {
345 pdu->digest_ptr = b->asn_ptr - SNMP_USM_AUTH_SIZE;
346 pdu->digest_ptr -= octs_len + ASN_MAXLENLEN;
347 }
348
349 return (ASN_ERR_OK);
350}
351
352static enum snmp_code
353pdu_encode_secparams(struct asn_buf *b, struct snmp_pdu *pdu)
354{
355 u_char buf[256], *sptr;
356 struct asn_buf tb;
357 size_t auth_off, moved = 0;
358
359 auth_off = 0;
360 memset(buf, 0, 256);
361 tb.asn_ptr = buf;
362 tb.asn_len = 256;
363
364 if (asn_put_temp_header(&tb, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
365 &sptr) != ASN_ERR_OK)
366 return (SNMP_CODE_FAILED);
367
368 if (asn_put_octetstring(&tb, (u_char *)pdu->engine.engine_id,
369 pdu->engine.engine_len) != ASN_ERR_OK)
370 return (SNMP_CODE_FAILED);
371
372 if (asn_put_integer(&tb, pdu->engine.engine_boots) != ASN_ERR_OK)
373 return (SNMP_CODE_FAILED);
374
375 if (asn_put_integer(&tb, pdu->engine.engine_time) != ASN_ERR_OK)
376 return (SNMP_CODE_FAILED);
377
378 if (asn_put_octetstring(&tb, (u_char *)pdu->user.sec_name,
379 strlen(pdu->user.sec_name)) != ASN_ERR_OK)
380 return (SNMP_CODE_FAILED);
381
382 if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0) {
383 auth_off = sizeof(buf) - tb.asn_len + ASN_MAXLENLEN;
384 if (asn_put_octetstring(&tb, (u_char *)pdu->msg_digest,
385 sizeof(pdu->msg_digest)) != ASN_ERR_OK)
386 return (SNMP_CODE_FAILED);
387 } else {
388 if (asn_put_octetstring(&tb, (u_char *)pdu->msg_digest, 0)
389 != ASN_ERR_OK)
390 return (SNMP_CODE_FAILED);
391 }
392
393 if ((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0) {
394 if (asn_put_octetstring(&tb, (u_char *)pdu->msg_salt,
395 sizeof(pdu->msg_salt)) != ASN_ERR_OK)
396 return (SNMP_CODE_FAILED);
397 } else {
398 if (asn_put_octetstring(&tb, (u_char *)pdu->msg_salt, 0)
399 != ASN_ERR_OK)
400 return (SNMP_CODE_FAILED);
401 }
402
403 if (asn_commit_header(&tb, sptr, &moved) != ASN_ERR_OK)
404 return (SNMP_CODE_FAILED);
405
406 if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0)
407 pdu->digest_ptr = b->asn_ptr + auth_off - moved;
408
409 if (asn_put_octetstring(b, buf, sizeof(buf) - tb.asn_len) != ASN_ERR_OK)
410 return (SNMP_CODE_FAILED);
411 pdu->digest_ptr += ASN_MAXLENLEN;
412
413 if ((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0 && asn_put_temp_header(b,
414 ASN_TYPE_OCTETSTRING, &pdu->encrypted_ptr) != ASN_ERR_OK)
415 return (SNMP_CODE_FAILED);
416
417 return (SNMP_CODE_OK);
418}
419
274/*
420/*
275 * Parse the outer SEQUENCE value. ASN_ERR_TAG means 'bad version'.
421 * Decode the PDU except for the variable bindings itself.
422 * If decoding fails because of a bad binding, but the rest can be
423 * decoded, ip points to the index of the failed variable (errors
424 * OORANGE, BADLEN or BADVERS).
276 */
425 */
277enum asn_err
278snmp_parse_message_hdr(struct asn_buf *b, struct snmp_pdu *pdu, asn_len_t *lenp)
426enum snmp_code
427snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
279{
428{
429 enum snmp_code code;
430
431 if ((code = snmp_pdu_decode_header(b, pdu)) != SNMP_CODE_OK)
432 return (code);
433
434 if (pdu->version == SNMP_V3) {
435 if (pdu->security_model != SNMP_SECMODEL_USM)
436 return (SNMP_CODE_FAILED);
437 if ((code = snmp_pdu_decode_secmode(b, pdu)) != SNMP_CODE_OK)
438 return (code);
439 }
440
441 code = snmp_pdu_decode_scoped(b, pdu, ip);
442
443 switch (code) {
444 case SNMP_CODE_FAILED:
445 snmp_pdu_free(pdu);
446 break;
447
448 case SNMP_CODE_BADENC:
449 if (pdu->version == SNMP_Verr)
450 return (SNMP_CODE_BADVERS);
451
452 default:
453 break;
454 }
455
456 return (code);
457}
458
459enum snmp_code
460snmp_pdu_decode_header(struct asn_buf *b, struct snmp_pdu *pdu)
461{
280 int32_t version;
462 int32_t version;
281 u_char type;
282 u_int comm_len;
463 u_int octs_len;
464 asn_len_t len;
283
465
466 pdu->outer_ptr = b->asn_ptr;
467 pdu->outer_len = b->asn_len;
468
469 if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
470 snmp_error("cannot decode pdu header");
471 return (SNMP_CODE_FAILED);
472 }
473 if (b->asn_len < len) {
474 snmp_error("outer sequence value too short");
475 return (SNMP_CODE_FAILED);
476 }
477 if (b->asn_len != len) {
478 snmp_error("ignoring trailing junk in message");
479 b->asn_len = len;
480 }
481
284 if (asn_get_integer(b, &version) != ASN_ERR_OK) {
285 snmp_error("cannot decode version");
482 if (asn_get_integer(b, &version) != ASN_ERR_OK) {
483 snmp_error("cannot decode version");
286 return (ASN_ERR_FAILED);
484 return (SNMP_CODE_FAILED);
287 }
288
485 }
486
289 if (version == 0) {
487 if (version == 0)
290 pdu->version = SNMP_V1;
488 pdu->version = SNMP_V1;
291 } else if (version == 1) {
489 else if (version == 1)
292 pdu->version = SNMP_V2c;
490 pdu->version = SNMP_V2c;
293 } else {
491 else if (version == 3)
492 pdu->version = SNMP_V3;
493 else {
294 pdu->version = SNMP_Verr;
295 snmp_error("unsupported SNMP version");
494 pdu->version = SNMP_Verr;
495 snmp_error("unsupported SNMP version");
296 return (ASN_ERR_TAG);
496 return (SNMP_CODE_BADENC);
297 }
298
497 }
498
299 comm_len = SNMP_COMMUNITY_MAXLEN;
300 if (asn_get_octetstring(b, (u_char *)pdu->community,
301 &comm_len) != ASN_ERR_OK) {
302 snmp_error("cannot decode community");
303 return (ASN_ERR_FAILED);
499 if (pdu->version == SNMP_V3) {
500 if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
501 snmp_error("cannot decode pdu global data header");
502 return (SNMP_CODE_FAILED);
503 }
504
505 if (asn_get_integer(b, &pdu->identifier) != ASN_ERR_OK) {
506 snmp_error("cannot decode msg indetifier");
507 return (SNMP_CODE_FAILED);
508 }
509
510 if (asn_get_integer(b, &pdu->engine.max_msg_size)
511 != ASN_ERR_OK) {
512 snmp_error("cannot decode msg size");
513 return (SNMP_CODE_FAILED);
514 }
515
516 octs_len = 1;
517 if (asn_get_octetstring(b, (u_char *)&pdu->flags,
518 &octs_len) != ASN_ERR_OK) {
519 snmp_error("cannot decode msg flags");
520 return (SNMP_CODE_FAILED);
521 }
522
523 if (asn_get_integer(b, &pdu->security_model) != ASN_ERR_OK) {
524 snmp_error("cannot decode msg size");
525 return (SNMP_CODE_FAILED);
526 }
527
528 if (pdu->security_model != SNMP_SECMODEL_USM)
529 return (SNMP_CODE_FAILED);
530
531 if (parse_secparams(b, pdu) != ASN_ERR_OK)
532 return (SNMP_CODE_FAILED);
533 } else {
534 octs_len = SNMP_COMMUNITY_MAXLEN;
535 if (asn_get_octetstring(b, (u_char *)pdu->community,
536 &octs_len) != ASN_ERR_OK) {
537 snmp_error("cannot decode community");
538 return (SNMP_CODE_FAILED);
539 }
540 pdu->community[octs_len] = '\0';
304 }
541 }
305 pdu->community[comm_len] = '\0';
306
542
307 if (asn_get_header(b, &type, lenp) != ASN_ERR_OK) {
543 return (SNMP_CODE_OK);
544}
545
546enum snmp_code
547snmp_pdu_decode_scoped(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
548{
549 u_char type;
550 asn_len_t len, trailer;
551 enum asn_err err;
552
553 if (pdu->version == SNMP_V3) {
554 if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
555 snmp_error("cannot decode scoped pdu header");
556 return (SNMP_CODE_FAILED);
557 }
558
559 len = SNMP_ENGINE_ID_SIZ;
560 if (asn_get_octetstring(b, (u_char *)&pdu->context_engine,
561 &len) != ASN_ERR_OK) {
562 snmp_error("cannot decode msg context engine");
563 return (SNMP_CODE_FAILED);
564 }
565 pdu->context_engine_len = len;
566
567 len = SNMP_CONTEXT_NAME_SIZ;
568 if (asn_get_octetstring(b, (u_char *)&pdu->context_name,
569 &len) != ASN_ERR_OK) {
570 snmp_error("cannot decode msg context name");
571 return (SNMP_CODE_FAILED);
572 }
573 pdu->context_name[len] = '\0';
574 }
575
576 if (asn_get_header(b, &type, &len) != ASN_ERR_OK) {
308 snmp_error("cannot get pdu header");
577 snmp_error("cannot get pdu header");
309 return (ASN_ERR_FAILED);
578 return (SNMP_CODE_FAILED);
310 }
311 if ((type & ~ASN_TYPE_MASK) !=
312 (ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT)) {
313 snmp_error("bad pdu header tag");
579 }
580 if ((type & ~ASN_TYPE_MASK) !=
581 (ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT)) {
582 snmp_error("bad pdu header tag");
314 return (ASN_ERR_FAILED);
583 return (SNMP_CODE_FAILED);
315 }
316 pdu->type = type & ASN_TYPE_MASK;
317
318 switch (pdu->type) {
319
320 case SNMP_PDU_GET:
321 case SNMP_PDU_GETNEXT:
322 case SNMP_PDU_RESPONSE:
323 case SNMP_PDU_SET:
324 break;
325
326 case SNMP_PDU_TRAP:
327 if (pdu->version != SNMP_V1) {
328 snmp_error("bad pdu type %u", pdu->type);
584 }
585 pdu->type = type & ASN_TYPE_MASK;
586
587 switch (pdu->type) {
588
589 case SNMP_PDU_GET:
590 case SNMP_PDU_GETNEXT:
591 case SNMP_PDU_RESPONSE:
592 case SNMP_PDU_SET:
593 break;
594
595 case SNMP_PDU_TRAP:
596 if (pdu->version != SNMP_V1) {
597 snmp_error("bad pdu type %u", pdu->type);
329 return (ASN_ERR_FAILED);
598 return (SNMP_CODE_FAILED);
330 }
331 break;
332
333 case SNMP_PDU_GETBULK:
334 case SNMP_PDU_INFORM:
335 case SNMP_PDU_TRAP2:
336 case SNMP_PDU_REPORT:
337 if (pdu->version == SNMP_V1) {
338 snmp_error("bad pdu type %u", pdu->type);
599 }
600 break;
601
602 case SNMP_PDU_GETBULK:
603 case SNMP_PDU_INFORM:
604 case SNMP_PDU_TRAP2:
605 case SNMP_PDU_REPORT:
606 if (pdu->version == SNMP_V1) {
607 snmp_error("bad pdu type %u", pdu->type);
339 return (ASN_ERR_FAILED);
608 return (SNMP_CODE_FAILED);
340 }
341 break;
342
343 default:
344 snmp_error("bad pdu type %u", pdu->type);
609 }
610 break;
611
612 default:
613 snmp_error("bad pdu type %u", pdu->type);
345 return (ASN_ERR_FAILED);
614 return (SNMP_CODE_FAILED);
346 }
347
615 }
616
348
349 if (*lenp > b->asn_len) {
350 snmp_error("pdu length too long");
351 return (ASN_ERR_FAILED);
352 }
353
354 return (ASN_ERR_OK);
355}
356
357static enum asn_err
358parse_message(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
359{
360 enum asn_err err;
361 asn_len_t len, trailer;
362
363 err = snmp_parse_message_hdr(b, pdu, &len);
364 if (ASN_ERR_STOPPED(err))
365 return (err);
366
367 trailer = b->asn_len - len;
368 b->asn_len = len;
369
370 err = parse_pdus(b, pdu, ip);
371 if (ASN_ERR_STOPPED(err))
617 trailer = b->asn_len - len;
618 b->asn_len = len;
619
620 err = parse_pdus(b, pdu, ip);
621 if (ASN_ERR_STOPPED(err))
372 return (ASN_ERR_FAILED);
622 return (SNMP_CODE_FAILED);
373
374 if (b->asn_len != 0)
375 snmp_error("ignoring trailing junk after pdu");
376
377 b->asn_len = trailer;
378
623
624 if (b->asn_len != 0)
625 snmp_error("ignoring trailing junk after pdu");
626
627 b->asn_len = trailer;
628
379 return (err);
629 return (SNMP_CODE_OK);
380}
381
630}
631
382/*
383 * Decode the PDU except for the variable bindings itself.
384 * If decoding fails because of a bad binding, but the rest can be
385 * decoded, ip points to the index of the failed variable (errors
386 * OORANGE, BADLEN or BADVERS).
387 */
388enum snmp_code
632enum snmp_code
389snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
633snmp_pdu_decode_secmode(struct asn_buf *b, struct snmp_pdu *pdu)
390{
634{
391 asn_len_t len;
635 u_char type;
636 enum snmp_code code;
637 uint8_t digest[SNMP_USM_AUTH_SIZE];
392
638
393 memset(pdu, 0, sizeof(*pdu));
639 if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH &&
640 (pdu->flags & SNMP_MSG_AUTH_FLAG) == 0)
641 return (SNMP_CODE_BADSECLEVEL);
394
642
395 if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
396 snmp_error("cannot decode pdu header");
643 if ((code = snmp_pdu_calc_digest(b, pdu, digest)) !=
644 SNMP_CODE_OK)
397 return (SNMP_CODE_FAILED);
645 return (SNMP_CODE_FAILED);
398 }
399 if (b->asn_len < len) {
400 snmp_error("outer sequence value too short");
646
647 if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH &&
648 memcmp(digest, pdu->msg_digest, sizeof(pdu->msg_digest)) != 0)
649 return (SNMP_CODE_BADDIGEST);
650
651 if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV && (asn_get_header(b, &type,
652 &pdu->scoped_len) != ASN_ERR_OK || type != ASN_TYPE_OCTETSTRING)) {
653 snmp_error("cannot decode encrypted pdu");
401 return (SNMP_CODE_FAILED);
402 }
654 return (SNMP_CODE_FAILED);
655 }
403 if (b->asn_len != len) {
404 snmp_error("ignoring trailing junk in message");
405 b->asn_len = len;
406 }
656 pdu->scoped_ptr = b->asn_ptr;
407
657
408 switch (parse_message(b, pdu, ip)) {
658 if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV &&
659 (pdu->flags & SNMP_MSG_PRIV_FLAG) == 0)
660 return (SNMP_CODE_BADSECLEVEL);
409
661
410 case ASN_ERR_OK:
411 return (SNMP_CODE_OK);
412
413 case ASN_ERR_FAILED:
414 case ASN_ERR_EOBUF:
415 snmp_pdu_free(pdu);
662 if ((code = snmp_pdu_decrypt(b, pdu)) != SNMP_CODE_OK)
416 return (SNMP_CODE_FAILED);
417
663 return (SNMP_CODE_FAILED);
664
418 case ASN_ERR_BADLEN:
419 return (SNMP_CODE_BADLEN);
420
421 case ASN_ERR_RANGE:
422 return (SNMP_CODE_OORANGE);
423
424 case ASN_ERR_TAG:
425 if (pdu->version == SNMP_Verr)
426 return (SNMP_CODE_BADVERS);
427 else
428 return (SNMP_CODE_BADENC);
429 }
430
431 return (SNMP_CODE_OK);
665 return (code);
432}
433
434/*
435 * Check whether what we have is the complete PDU by snooping at the
436 * enclosing structure header. This returns:
437 * -1 if there are ASN.1 errors
438 * 0 if we need more data
439 * > 0 the length of this PDU

--- 55 unchanged lines hidden (view full) ---

495 * moving things around and assuming that the length field will never
496 * use more than 2 bytes.
497 * We need a number of pointers to apply the fixes afterwards.
498 */
499enum snmp_code
500snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
501{
502 enum asn_err err;
666}
667
668/*
669 * Check whether what we have is the complete PDU by snooping at the
670 * enclosing structure header. This returns:
671 * -1 if there are ASN.1 errors
672 * 0 if we need more data
673 * > 0 the length of this PDU

--- 55 unchanged lines hidden (view full) ---

729 * moving things around and assuming that the length field will never
730 * use more than 2 bytes.
731 * We need a number of pointers to apply the fixes afterwards.
732 */
733enum snmp_code
734snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
735{
736 enum asn_err err;
737 u_char *v3_hdr_ptr;
503
504 if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
505 &pdu->outer_ptr) != ASN_ERR_OK)
506 return (SNMP_CODE_FAILED);
507
508 if (pdu->version == SNMP_V1)
509 err = asn_put_integer(b, 0);
510 else if (pdu->version == SNMP_V2c)
511 err = asn_put_integer(b, 1);
738
739 if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
740 &pdu->outer_ptr) != ASN_ERR_OK)
741 return (SNMP_CODE_FAILED);
742
743 if (pdu->version == SNMP_V1)
744 err = asn_put_integer(b, 0);
745 else if (pdu->version == SNMP_V2c)
746 err = asn_put_integer(b, 1);
747 else if (pdu->version == SNMP_V3)
748 err = asn_put_integer(b, 3);
512 else
513 return (SNMP_CODE_BADVERS);
514 if (err != ASN_ERR_OK)
515 return (SNMP_CODE_FAILED);
516
749 else
750 return (SNMP_CODE_BADVERS);
751 if (err != ASN_ERR_OK)
752 return (SNMP_CODE_FAILED);
753
517 if (asn_put_octetstring(b, (u_char *)pdu->community,
518 strlen(pdu->community)) != ASN_ERR_OK)
519 return (SNMP_CODE_FAILED);
754 if (pdu->version == SNMP_V3) {
755 if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE |
756 ASN_TYPE_CONSTRUCTED), &v3_hdr_ptr) != ASN_ERR_OK)
757 return (SNMP_CODE_FAILED);
758
759 if (asn_put_integer(b, pdu->identifier) != ASN_ERR_OK)
760 return (SNMP_CODE_FAILED);
520
761
762 if (asn_put_integer(b, pdu->engine.max_msg_size) != ASN_ERR_OK)
763 return (SNMP_CODE_FAILED);
764
765 if (pdu->type != SNMP_PDU_RESPONSE &&
766 pdu->type != SNMP_PDU_TRAP &&
767 pdu->type != SNMP_PDU_REPORT)
768 pdu->flags |= SNMP_MSG_REPORT_FLAG;
769
770 if (asn_put_octetstring(b, (u_char *)&pdu->flags, 1)
771 != ASN_ERR_OK)
772 return (SNMP_CODE_FAILED);
773
774 if (asn_put_integer(b, pdu->security_model) != ASN_ERR_OK)
775 return (SNMP_CODE_FAILED);
776
777 if (asn_commit_header(b, v3_hdr_ptr, NULL) != ASN_ERR_OK)
778 return (SNMP_CODE_FAILED);
779
780 if (pdu->security_model != SNMP_SECMODEL_USM)
781 return (SNMP_CODE_FAILED);
782
783 if (pdu_encode_secparams(b, pdu) != SNMP_CODE_OK)
784 return (SNMP_CODE_FAILED);
785
786 /* View-based Access Conntrol information */
787 if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE |
788 ASN_TYPE_CONSTRUCTED), &pdu->scoped_ptr) != ASN_ERR_OK)
789 return (SNMP_CODE_FAILED);
790
791 if (asn_put_octetstring(b, (u_char *)pdu->context_engine,
792 pdu->context_engine_len) != ASN_ERR_OK)
793 return (SNMP_CODE_FAILED);
794
795 if (asn_put_octetstring(b, (u_char *)pdu->context_name,
796 strlen(pdu->context_name)) != ASN_ERR_OK)
797 return (SNMP_CODE_FAILED);
798 } else {
799 if (asn_put_octetstring(b, (u_char *)pdu->community,
800 strlen(pdu->community)) != ASN_ERR_OK)
801 return (SNMP_CODE_FAILED);
802 }
803
521 if (asn_put_temp_header(b, (ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT |
522 pdu->type), &pdu->pdu_ptr) != ASN_ERR_OK)
523 return (SNMP_CODE_FAILED);
524
525 if (pdu->type == SNMP_PDU_TRAP) {
526 if (pdu->version != SNMP_V1 ||
527 asn_put_objid(b, &pdu->enterprise) != ASN_ERR_OK ||
528 asn_put_ipaddress(b, pdu->agent_addr) != ASN_ERR_OK ||

--- 16 unchanged lines hidden (view full) ---

545
546 if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
547 &pdu->vars_ptr) != ASN_ERR_OK)
548 return (SNMP_CODE_FAILED);
549
550 return (SNMP_CODE_OK);
551}
552
804 if (asn_put_temp_header(b, (ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT |
805 pdu->type), &pdu->pdu_ptr) != ASN_ERR_OK)
806 return (SNMP_CODE_FAILED);
807
808 if (pdu->type == SNMP_PDU_TRAP) {
809 if (pdu->version != SNMP_V1 ||
810 asn_put_objid(b, &pdu->enterprise) != ASN_ERR_OK ||
811 asn_put_ipaddress(b, pdu->agent_addr) != ASN_ERR_OK ||

--- 16 unchanged lines hidden (view full) ---

828
829 if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
830 &pdu->vars_ptr) != ASN_ERR_OK)
831 return (SNMP_CODE_FAILED);
832
833 return (SNMP_CODE_OK);
834}
835
836static enum asn_err
837snmp_pdu_fix_padd(struct asn_buf *b, struct snmp_pdu *pdu)
838{
839 asn_len_t padlen;
840
841 if (pdu->user.priv_proto == SNMP_PRIV_DES && pdu->scoped_len % 8 != 0) {
842 padlen = 8 - (pdu->scoped_len % 8);
843 if (asn_pad(b, padlen) != ASN_ERR_OK)
844 return (ASN_ERR_FAILED);
845 pdu->scoped_len += padlen;
846 }
847
848 return (ASN_ERR_OK);
849}
850
553enum snmp_code
851enum snmp_code
554snmp_fix_encoding(struct asn_buf *b, const struct snmp_pdu *pdu)
852snmp_fix_encoding(struct asn_buf *b, struct snmp_pdu *pdu)
555{
853{
556 if (asn_commit_header(b, pdu->vars_ptr) != ASN_ERR_OK ||
557 asn_commit_header(b, pdu->pdu_ptr) != ASN_ERR_OK ||
558 asn_commit_header(b, pdu->outer_ptr) != ASN_ERR_OK)
854 size_t moved = 0;
855 enum snmp_code code;
856
857 if (asn_commit_header(b, pdu->vars_ptr, NULL) != ASN_ERR_OK ||
858 asn_commit_header(b, pdu->pdu_ptr, NULL) != ASN_ERR_OK)
559 return (SNMP_CODE_FAILED);
859 return (SNMP_CODE_FAILED);
860
861 if (pdu->version == SNMP_V3) {
862 if (asn_commit_header(b, pdu->scoped_ptr, NULL) != ASN_ERR_OK)
863 return (SNMP_CODE_FAILED);
864
865 pdu->scoped_len = b->asn_ptr - pdu->scoped_ptr;
866 if ((code = snmp_pdu_fix_padd(b, pdu))!= ASN_ERR_OK)
867 return (SNMP_CODE_FAILED);
868
869 if (pdu->security_model != SNMP_SECMODEL_USM)
870 return (SNMP_CODE_FAILED);
871
872 if (snmp_pdu_encrypt(b, pdu) != SNMP_CODE_OK)
873 return (SNMP_CODE_FAILED);
874
875 if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV &&
876 asn_commit_header(b, pdu->encrypted_ptr, NULL) != ASN_ERR_OK)
877 return (SNMP_CODE_FAILED);
878 }
879
880 if (asn_commit_header(b, pdu->outer_ptr, &moved) != ASN_ERR_OK)
881 return (SNMP_CODE_FAILED);
882
883 pdu->outer_len = b->asn_ptr - pdu->outer_ptr;
884 pdu->digest_ptr -= moved;
885
886 if (pdu->version == SNMP_V3) {
887 if ((code = snmp_pdu_calc_digest(b, pdu, pdu->msg_digest)) !=
888 SNMP_CODE_OK)
889 return (SNMP_CODE_FAILED);
890
891 if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0)
892 memcpy(pdu->digest_ptr, pdu->msg_digest,
893 sizeof(pdu->msg_digest));
894 }
895
560 return (SNMP_CODE_OK);
561}
562
563/*
564 * Encode a binding. Caller must ensure, that the syntax is ok for that version.
565 * Be sure not to cobber b, when something fails.
566 */
567enum asn_err

--- 66 unchanged lines hidden (view full) ---

634 break;
635 }
636
637 if (err != ASN_ERR_OK) {
638 *b = save;
639 return (err);
640 }
641
896 return (SNMP_CODE_OK);
897}
898
899/*
900 * Encode a binding. Caller must ensure, that the syntax is ok for that version.
901 * Be sure not to cobber b, when something fails.
902 */
903enum asn_err

--- 66 unchanged lines hidden (view full) ---

970 break;
971 }
972
973 if (err != ASN_ERR_OK) {
974 *b = save;
975 return (err);
976 }
977
642 err = asn_commit_header(b, ptr);
978 err = asn_commit_header(b, ptr, NULL);
643 if (err != ASN_ERR_OK) {
644 *b = save;
645 return (err);
646 }
647
648 return (ASN_ERR_OK);
649}
650

--- 119 unchanged lines hidden (view full) ---

770 [SNMP_PDU_TRAP2] = "TRAPv2",
771 [SNMP_PDU_REPORT] = "REPORT",
772 };
773
774 if (pdu->version == SNMP_V1)
775 vers = "SNMPv1";
776 else if (pdu->version == SNMP_V2c)
777 vers = "SNMPv2c";
979 if (err != ASN_ERR_OK) {
980 *b = save;
981 return (err);
982 }
983
984 return (ASN_ERR_OK);
985}
986

--- 119 unchanged lines hidden (view full) ---

1106 [SNMP_PDU_TRAP2] = "TRAPv2",
1107 [SNMP_PDU_REPORT] = "REPORT",
1108 };
1109
1110 if (pdu->version == SNMP_V1)
1111 vers = "SNMPv1";
1112 else if (pdu->version == SNMP_V2c)
1113 vers = "SNMPv2c";
1114 else if (pdu->version == SNMP_V3)
1115 vers = "SNMPv3";
778 else
779 vers = "v?";
780
781 switch (pdu->type) {
782 case SNMP_PDU_TRAP:
783 snmp_printf("%s %s '%s'", types[pdu->type], vers, pdu->community);
784 snmp_printf(" enterprise=%s", asn_oid2str_r(&pdu->enterprise, buf));
785 snmp_printf(" agent_addr=%u.%u.%u.%u", pdu->agent_addr[0],

--- 47 unchanged lines hidden (view full) ---

833 from->v.octetstring.octets, to->v.octetstring.len);
834 }
835 } else
836 to->v = from->v;
837 return (0);
838}
839
840void
1116 else
1117 vers = "v?";
1118
1119 switch (pdu->type) {
1120 case SNMP_PDU_TRAP:
1121 snmp_printf("%s %s '%s'", types[pdu->type], vers, pdu->community);
1122 snmp_printf(" enterprise=%s", asn_oid2str_r(&pdu->enterprise, buf));
1123 snmp_printf(" agent_addr=%u.%u.%u.%u", pdu->agent_addr[0],

--- 47 unchanged lines hidden (view full) ---

1171 from->v.octetstring.octets, to->v.octetstring.len);
1172 }
1173 } else
1174 to->v = from->v;
1175 return (0);
1176}
1177
1178void
1179snmp_pdu_init_secparams(struct snmp_pdu *pdu, struct snmp_engine *eng,
1180 struct snmp_user *user)
1181{
1182 int32_t rval;
1183
1184 memcpy(&pdu->engine, eng, sizeof(pdu->engine));
1185 memcpy(&pdu->user, user, sizeof(pdu->user));
1186
1187 if (user->auth_proto != SNMP_AUTH_NOAUTH)
1188 pdu->flags |= SNMP_MSG_AUTH_FLAG;
1189
1190 switch (user->priv_proto) {
1191 case SNMP_PRIV_DES:
1192 memcpy(pdu->msg_salt, &eng->engine_boots,
1193 sizeof(eng->engine_boots));
1194 rval = random();
1195 memcpy(pdu->msg_salt + sizeof(eng->engine_boots), &rval,
1196 sizeof(int32_t));
1197 pdu->flags |= SNMP_MSG_PRIV_FLAG;
1198 break;
1199 case SNMP_PRIV_AES:
1200 rval = random();
1201 memcpy(pdu->msg_salt, &rval, sizeof(int32_t));
1202 rval = random();
1203 memcpy(pdu->msg_salt + sizeof(int32_t), &rval, sizeof(int32_t));
1204 pdu->flags |= SNMP_MSG_PRIV_FLAG;
1205 break;
1206 default:
1207 break;
1208 }
1209}
1210
1211void
841snmp_pdu_free(struct snmp_pdu *pdu)
842{
843 u_int i;
844
845 for (i = 0; i < pdu->nbindings; i++)
846 snmp_value_free(&pdu->bindings[i]);
847}
848

--- 237 unchanged lines hidden ---
1212snmp_pdu_free(struct snmp_pdu *pdu)
1213{
1214 u_int i;
1215
1216 for (i = 0; i < pdu->nbindings; i++)
1217 snmp_value_free(&pdu->bindings[i]);
1218}
1219

--- 237 unchanged lines hidden ---