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 --- |