Ejemplo n.º 1
0
void startonehost(struct req_t *req, int ipchange)
{
	struct snmp_session s;
	struct snmp_pdu *snmpreq = NULL;

	if ((dataoperation < GET_DATA) && !req->currentkey) return;

	/* Are we retrying a cluster with a new IP? Then drop the current session */
	if (req->sess && ipchange) {
		/*
		 * Apparently, we cannot close a session while in a callback.
		 * So leave this for now - it will leak some memory, but
		 * this is not a problem as long as we only run once.
		 */
		/* snmp_close(req->sess); */
		req->sess = NULL;
	}

	/* Setup the SNMP session */
	if (!req->sess) {
		snmp_sess_init(&s);

		/* 
		 * snmp_session has a "remote_port" field, but it does not work.
		 * Instead, the peername should include a port number (IP:PORT)
		 * if (req->portnumber) s.remote_port = req->portnumber;
		 */
		s.peername = req->hostip[req->hostipidx];

		/* Set the SNMP version and authentication token(s) */
		s.version = req->version;
		switch (s.version) {
		  case SNMP_VERSION_1:
		  case SNMP_VERSION_2c:
			s.community = req->community;
			s.community_len = strlen((char *)req->community);
			break;

		  case SNMP_VERSION_3:
			/* set the SNMPv3 user name */
			s.securityName = strdup(req->username);
			s.securityNameLen = strlen(s.securityName);

			/* set the security level to authenticated, but not encrypted */
			s.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;

			/* set the authentication method */
			switch (req->authmethod) {
			  case SNMP_V3AUTH_MD5:
				s.securityAuthProto = usmHMACMD5AuthProtocol;
				s.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);
				s.securityAuthKeyLen = USM_AUTH_KU_LEN;
				break;

			  case SNMP_V3AUTH_SHA1:
				s.securityAuthProto = usmHMACSHA1AuthProtocol;
				s.securityAuthProtoLen = sizeof(usmHMACSHA1AuthProtocol)/sizeof(oid);
				s.securityAuthKeyLen = USM_AUTH_KU_LEN;
				break;
			}

			/*
			 * set the authentication key to a hashed version of our
			 * passphrase (which must be at least 8 characters long).
			 */
			if (generate_Ku(s.securityAuthProto, s.securityAuthProtoLen,
					(u_char *)req->passphrase, strlen(req->passphrase),
					s.securityAuthKey, &s.securityAuthKeyLen) != SNMPERR_SUCCESS) {
				errprintf("Failed to generate Ku from authentication pass phrase for host %s\n",
					  req->hostname);
				snmp_perror("generate_Ku");
				return;
			}
			break;
		}

		/* Set timeouts and retries */
		if (timeout > 0) s.timeout = timeout;
		if (retries > 0) s.retries = retries;

		/* Setup the callback */
		s.callback = asynch_response;
		s.callback_magic = req;

		if (!(req->sess = snmp_open(&s))) {
			snmp_sess_perror("snmp_open", &s);
			return;
		}
	}

	switch (dataoperation) {
	  case GET_KEYS:
		snmpreq = snmp_pdu_create(SNMP_MSG_GETNEXT);
		pducount++;
		snmp_add_null_var(snmpreq, req->currentkey->indexmethod->rootoid, req->currentkey->indexmethod->rootoidlen);
		break;

	  case GET_DATA:
		/* Build the request PDU and send it */
		snmpreq = generate_datarequest(req);
		break;
	}

	if (!snmpreq) return;

	if (snmp_send(req->sess, snmpreq))
		active_requests++;
	else {
		errorcount++;
		snmp_sess_perror("snmp_send", req->sess);
		snmp_free_pdu(snmpreq);
	}
}
Ejemplo n.º 2
0
/*! \fn void *snmp_host_init(int host_id, char *hostname, int snmp_version, 
 * char *snmp_community, char *snmp_username, char *snmp_password, int snmp_port, 
 * int snmp_timeout)
 *  \brief initializes an snmp_session object for a Cactid host
 * 
 *	This function will initialize NET-SNMP or UCD-SNMP for the Cactid host
 *  in question.
 *
 */
void *snmp_host_init(int host_id, char *hostname, int snmp_version, char *snmp_community, 
					char *snmp_username, char *snmp_password, int snmp_port, int snmp_timeout) {
	void *sessp = NULL;
	struct snmp_session session;
	char hostnameport[BUFSIZE];   

	/* initialize SNMP */
  	snmp_sess_init(&session);

	#ifdef USE_NET_SNMP
		/* Prevent update of the snmpapp.conf file */
		#ifdef NETSNMP_DS_LIB_DONT_PERSIST_STATE
			netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PERSIST_STATE, 1);
		#endif

		/* Prevent update of the snmpapp.conf file */
		#ifdef NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD
			netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DISABLE_PERSISTENT_LOAD, 1);
		#endif

		#ifdef NETSNMP_DS_LIB_DONT_PRINT_UNITS
			netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PRINT_UNITS, 1);
		#endif

		netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, 1);
		netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_BARE_VALUE, 1);
		netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_NUMERIC_TIMETICKS, 1);
	#else
		ds_set_boolean(DS_LIBRARY_ID, DS_LIB_QUICK_PRINT, 1);
		ds_set_boolean(DS_LIBRARY_ID, DS_LIB_PRINT_BARE_VALUE, 1);
		ds_set_boolean(DS_LIBRARY_ID, DS_LIB_NUMERIC_TIMETICKS, 1);
	#endif

	/* verify snmp version is accurate */
	if (snmp_version == 2) {
		session.version = SNMP_VERSION_2c;
	}else if (snmp_version == 1) {
		session.version = SNMP_VERSION_1;
	}else if (snmp_version == 3) {
		session.version = SNMP_VERSION_3;
	}else {
		CACTID_LOG(("Host[%i] ERROR: SNMP Version Error for Host '%s'\n", host_id, hostname));
		return 0;
	}		

	snprintf(hostnameport, sizeof(hostnameport), "%s:%i", hostname, snmp_port);
	session.peername = hostnameport;
	session.retries = 3;
	session.remote_port = snmp_port;
	session.timeout = (snmp_timeout * 1000); /* net-snmp likes microseconds */

	if ((snmp_version == 2) || (snmp_version == 1)) {
		session.community = snmp_community;
		session.community_len = strlen(snmp_community);
	}else {
	    /* set the SNMPv3 user name */
	    session.securityName = snmp_username;
	    session.securityNameLen = strlen(session.securityName);

		session.securityAuthKeyLen = USM_AUTH_KU_LEN;

	    /* set the authentication method to MD5 */
	    session.securityAuthProto = snmp_duplicate_objid(usmHMACMD5AuthProtocol, OIDSIZE(usmHMACMD5AuthProtocol));
	    session.securityAuthProtoLen = OIDSIZE(usmHMACMD5AuthProtocol);

		/* set the privacy protocol to none */
		session.securityPrivProto = usmNoPrivProtocol;
		session.securityPrivProtoLen = OIDSIZE(usmNoPrivProtocol);
		session.securityPrivKeyLen = USM_PRIV_KU_LEN;

	    /* set the security level to authenticate, but not encrypted */
		session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;

	    /* set the authentication key to the hashed version. The password must me at least 8 char */
	    if (generate_Ku(session.securityAuthProto, 
						session.securityAuthProtoLen,
						(u_char *) snmp_password,
						strlen(snmp_password),
	                    session.securityAuthKey,
	                    &(session.securityAuthKeyLen)) != SNMPERR_SUCCESS) {
	        CACTID_LOG(("SNMP: Error generating SNMPv3 Ku from authentication pass phrase."));
		}
	}

	/* open SNMP Session */
 	thread_mutex_lock(LOCK_SNMP);
	sessp = snmp_sess_open(&session);
	thread_mutex_unlock(LOCK_SNMP);

	if (!sessp) {
		CACTID_LOG(("ERROR: Problem initializing SNMP session '%s'\n", hostname));
	}
	
	return sessp;
}
Ejemplo n.º 3
0
/*
 * This method does the real work for snmp_parse_args.  It takes an
 * extra argument, proxy, and uses this to decide how to handle the lack of
 * of a community string.
 */
int
snmp_parse_args(int argc,
                char **argv,
                netsnmp_session * session, const char *localOpts,
                void (*proc) (int, char *const *, int))
{
    static char	   *sensitive[4] = { NULL, NULL, NULL, NULL };
    int             arg, sp = 0, zero_sensitive = 1, testcase = 0;
    char           *cp;
    char           *Apsz = NULL;
    char           *Xpsz = NULL;
    char           *Cpsz = NULL;
    char            Opts[BUF_SIZE];
    int             logopt = 0;

    /*
     * initialize session to default values
     */
    snmp_sess_init(session);
    strcpy(Opts, "Y:VhHm:M:O:I:P:D:dv:r:t:c:Z:e:E:n:u:l:x:X:a:A:p:T:-:3:s:S:L:");
    if (localOpts)
        strcat(Opts, localOpts);

    if (strcmp(argv[0], "snmpd-trapsess") == 0 ||
            strcmp(argv[0], "snmpd-proxy")    == 0) {
        /*  Don't worry about zeroing sensitive parameters as they are not
            on the command line anyway (called from internal config-line
            handler).  */
        zero_sensitive = 0;
    }

    /*
     * get the options
     */
    DEBUGMSGTL(("snmp_parse_args", "starting: %d/%d\n", optind, argc));
    for (arg = 0; arg < argc; arg++) {
        DEBUGMSGTL(("snmp_parse_args", " arg %d = %s\n", arg, argv[arg]));
    }

    optind = 1;
    while ((arg = getopt(argc, argv, Opts)) != EOF) {
        DEBUGMSGTL(("snmp_parse_args", "handling (#%d): %c\n", optind, arg));
        switch (arg) {
        case '-':
            if (strcasecmp(optarg, "help") == 0) {
                return (-1);
            }
            if (strcasecmp(optarg, "version") == 0) {
                fprintf(stderr,"NET-SNMP version: %s\n",netsnmp_get_version());
                return (-2);
            }

            handle_long_opt(optarg);
            break;

        case 'V':
            fprintf(stderr, "NET-SNMP version: %s\n", netsnmp_get_version());
            return (-2);

        case 'h':
            return (-1);
            break;

        case 'H':
            init_snmp("snmpapp");
            fprintf(stderr, "Configuration directives understood:\n");
            read_config_print_usage("  ");
            return (-2);

        case 'Y':
            netsnmp_config_remember(optarg);
            break;

#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 'm':
            setenv("MIBS", optarg, 1);
            break;

        case 'M':
            netsnmp_get_mib_directory(); /* prepare the default directories */
            netsnmp_set_mib_directory(optarg);
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */

        case 'O':
            cp = snmp_out_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr, "Unknown output option passed to -O: %c.\n",
                        *cp);
                return (-1);
            }
            break;

        case 'I':
            cp = snmp_in_options(optarg, argc, argv);
            if (cp != NULL) {
                fprintf(stderr, "Unknown input option passed to -I: %c.\n",
                        *cp);
                return (-1);
            }
            break;

#ifndef NETSNMP_DISABLE_MIB_LOADING
        case 'P':
            cp = snmp_mib_toggle_options(optarg);
            if (cp != NULL) {
                fprintf(stderr,
                        "Unknown parsing option passed to -P: %c.\n", *cp);
                return (-1);
            }
            break;
#endif /* NETSNMP_DISABLE_MIB_LOADING */

        case 'D':
            debug_register_tokens(optarg);
            snmp_set_do_debugging(1);
            break;

        case 'd':
            netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
                                   NETSNMP_DS_LIB_DUMP_PACKET, 1);
            break;

        case 'v':
            session->version = -1;
#ifndef NETSNMP_DISABLE_SNMPV1
            if (!strcmp(optarg, "1")) {
                session->version = SNMP_VERSION_1;
            }
#endif
#ifndef NETSNMP_DISABLE_SNMPV2C
            if (!strcasecmp(optarg, "2c")) {
                session->version = SNMP_VERSION_2c;
            }
#endif
            if (!strcasecmp(optarg, "3")) {
                session->version = SNMP_VERSION_3;
            }
            if (session->version == -1) {
                fprintf(stderr,
                        "Invalid version specified after -v flag: %s\n",
                        optarg);
                return (-1);
            }
            break;

        case 'p':
            fprintf(stderr, "Warning: -p option is no longer used - ");
            fprintf(stderr, "specify the remote host as HOST:PORT\n");
            return (-1);
            break;

        case 'T':
            fprintf(stderr, "Warning: -T option is no longer used - ");
            fprintf(stderr, "specify the remote host as TRANSPORT:HOST\n");
            return (-1);
            break;

        case 't':
            session->timeout = (long)(atof(optarg) * 1000000L);
            if (session->timeout <= 0) {
                fprintf(stderr, "Invalid timeout in seconds after -t flag.\n");
                return (-1);
            }
            break;

        case 'r':
            session->retries = atoi(optarg);
            if (session->retries < 0 || !isdigit(optarg[0])) {
                fprintf(stderr, "Invalid number of retries after -r flag.\n");
                return (-1);
            }
            break;

        case 'c':
            if (zero_sensitive) {
                if ((sensitive[sp] = strdup(optarg)) != NULL) {
                    Cpsz = sensitive[sp];
                    memset(optarg, '\0', strlen(optarg));
                    sp++;
                } else {
                    fprintf(stderr, "malloc failure processing -c flag.\n");
                    return -1;
                }
            } else {
                Cpsz = optarg;
            }
            break;

#ifndef NO_SNMPV3
        case '3':
            /*  TODO: This needs to zero things too.  */
            if (snmpv3_options(optarg, session, &Apsz, &Xpsz, argc, argv) < 0) {
                return (-1);
            }
            break;

        case 'L':
            if (snmp_log_options(optarg, argc, argv) < 0) {
                return (-1);
            }
            logopt = 1;
            break;
#endif

#ifndef NO_SNMPV3
#define SNMPV3_CMD_OPTIONS
#endif
#ifdef  SNMPV3_CMD_OPTIONS
        case 'Z':
            errno = 0;
            session->engineBoots = strtoul(optarg, &cp, 10);
            if (errno || cp == optarg) {
                fprintf(stderr, "Need engine boots value after -Z flag.\n");
                return (-1);
            }
            if (*cp == ',') {
                char *endptr;
                cp++;
                session->engineTime = strtoul(cp, &endptr, 10);
                if (errno || cp == endptr) {
                    fprintf(stderr, "Need engine time after \"-Z engineBoot,\".\n");
                    return (-1);
                }
            }
            /*
             * Handle previous '-Z boot time' syntax
             */
            else if (optind < argc) {
                session->engineTime = strtoul(argv[optind], &cp, 10);
                if (errno || cp == argv[optind]) {
                    fprintf(stderr, "Need engine time after \"-Z engineBoot\".\n");
                    return (-1);
                }
            } else {
                fprintf(stderr, "Need engine time after \"-Z engineBoot\".\n");
                return (-1);
            }
            break;

        case 'e': {
            size_t ebuf_len = 32, eout_len = 0;
            u_char *ebuf = (u_char *)malloc(ebuf_len);

            if (ebuf == NULL) {
                fprintf(stderr, "malloc failure processing -e flag.\n");
                return (-1);
            }
            if (!snmp_hex_to_binary
                    (&ebuf, &ebuf_len, &eout_len, 1, optarg)) {
                fprintf(stderr, "Bad engine ID value after -e flag.\n");
                free(ebuf);
                return (-1);
            }
            if ((eout_len < 5) || (eout_len > 32)) {
                fprintf(stderr, "Invalid engine ID value after -e flag.\n");
                free(ebuf);
                return (-1);
            }
            session->securityEngineID = ebuf;
            session->securityEngineIDLen = eout_len;
            break;
        }

        case 'E': {
            size_t ebuf_len = 32, eout_len = 0;
            u_char *ebuf = (u_char *)malloc(ebuf_len);

            if (ebuf == NULL) {
                fprintf(stderr, "malloc failure processing -E flag.\n");
                return (-1);
            }
            if (!snmp_hex_to_binary(&ebuf, &ebuf_len,
                                    &eout_len, 1, optarg)) {
                fprintf(stderr, "Bad engine ID value after -E flag.\n");
                free(ebuf);
                return (-1);
            }
            if ((eout_len < 5) || (eout_len > 32)) {
                fprintf(stderr, "Invalid engine ID value after -E flag.\n");
                free(ebuf);
                return (-1);
            }
            session->contextEngineID = ebuf;
            session->contextEngineIDLen = eout_len;
            break;
        }

        case 'n':
            session->contextName = optarg;
            session->contextNameLen = strlen(optarg);
            break;

        case 'u':
            if (zero_sensitive) {
                if ((sensitive[sp] = strdup(optarg)) != NULL) {
                    session->securityName = sensitive[sp];
                    session->securityNameLen = strlen(sensitive[sp]);
                    memset(optarg, '\0', strlen(optarg));
                    sp++;
                } else {
                    fprintf(stderr, "malloc failure processing -u flag.\n");
                    return -1;
                }
            } else {
                session->securityName = optarg;
                session->securityNameLen = strlen(optarg);
            }
            break;

        case 'l':
            if (!strcasecmp(optarg, "noAuthNoPriv") || !strcmp(optarg, "1")
                    || !strcasecmp(optarg, "noauth")
                    || !strcasecmp(optarg, "nanp")) {
                session->securityLevel = SNMP_SEC_LEVEL_NOAUTH;
            } else if (!strcasecmp(optarg, "authNoPriv")
                       || !strcmp(optarg, "2")
                       || !strcasecmp(optarg, "auth")
                       || !strcasecmp(optarg, "anp")) {
                session->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
            } else if (!strcasecmp(optarg, "authPriv")
                       || !strcmp(optarg, "3")
                       || !strcasecmp(optarg, "priv")
                       || !strcasecmp(optarg, "ap")) {
                session->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
            } else {
                fprintf(stderr,
                        "Invalid security level specified after -l flag: %s\n",
                        optarg);
                return (-1);
            }

            break;

        case 'a':
#ifndef NETSNMP_DISABLE_MD5
            if (!strcasecmp(optarg, "MD5")) {
                session->securityAuthProto = usmHMACMD5AuthProtocol;
                session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
            } else
#endif
                if (!strcasecmp(optarg, "SHA")) {
                    session->securityAuthProto = usmHMACSHA1AuthProtocol;
                    session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
                } else {
                    fprintf(stderr,
                            "Invalid authentication protocol specified after -a flag: %s\n",
                            optarg);
                    return (-1);
                }
            break;

        case 'x':
            testcase = 0;
#ifndef NETSNMP_DISABLE_DES
            if (!strcasecmp(optarg, "DES")) {
                testcase = 1;
                session->securityPrivProto = usmDESPrivProtocol;
                session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
            }
#endif
#ifdef HAVE_AES
            if (!strcasecmp(optarg, "AES128") ||
                    !strcasecmp(optarg, "AES")) {
                testcase = 1;
                session->securityPrivProto = usmAESPrivProtocol;
                session->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
            }
#endif
            if (testcase == 0) {
                fprintf(stderr,
                        "Invalid privacy protocol specified after -x flag: %s\n",
                        optarg);
                return (-1);
            }
            break;

        case 'A':
            if (zero_sensitive) {
                if ((sensitive[sp] = strdup(optarg)) != NULL) {
                    Apsz = sensitive[sp];
                    memset(optarg, '\0', strlen(optarg));
                    sp++;
                } else {
                    fprintf(stderr, "malloc failure processing -A flag.\n");
                    return -1;
                }
            } else {
                Apsz = optarg;
            }
            break;

        case 'X':
            if (zero_sensitive) {
                if ((sensitive[sp] = strdup(optarg)) != NULL) {
                    Xpsz = sensitive[sp];
                    memset(optarg, '\0', strlen(optarg));
                    sp++;
                } else {
                    fprintf(stderr, "malloc failure processing -X flag.\n");
                    return -1;
                }
            } else {
                Xpsz = optarg;
            }
            break;
#endif                          /* SNMPV3_CMD_OPTIONS */

        case '?':
            return (-1);
            break;

        default:
            proc(argc, argv, arg);
            break;
        }
    }
    DEBUGMSGTL(("snmp_parse_args", "finished: %d/%d\n", optind, argc));

    if (!logopt)
        snmp_enable_stderrlog();

    /*
     * read in MIB database and initialize the snmp library
     */
    init_snmp("snmpapp");

    /*
     * session default version
     */
    if (session->version == SNMP_DEFAULT_VERSION) {
        /*
         * run time default version
         */
        session->version = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
                                              NETSNMP_DS_LIB_SNMPVERSION);

        /*
         * compile time default version
         */
        if (!session->version) {
            switch (NETSNMP_DEFAULT_SNMP_VERSION) {
#ifndef NETSNMP_DISABLE_SNMPV1
            case 1:
                session->version = SNMP_VERSION_1;
                break;
#endif

#ifndef NETSNMP_DISABLE_SNMPV2C
            case 2:
                session->version = SNMP_VERSION_2c;
                break;
#endif

#ifndef NO_SNMPV3
            case 3:
                session->version = SNMP_VERSION_3;
                break;
#endif

            default:
                snmp_log(LOG_ERR, "Can't determine a valid SNMP version for the session\n");
                return(-2);
            }
        } else {
#ifndef NETSNMP_DISABLE_SNMPV1
            if (session->version == NETSNMP_DS_SNMP_VERSION_1)  /* bogus value.  version 1 actually = 0 */
                session->version = SNMP_VERSION_1;
#endif
        }
    }

#ifndef NO_SNMPV3
    /*
     * make master key from pass phrases
     */
    if (Apsz) {
        session->securityAuthKeyLen = USM_AUTH_KU_LEN;
        if (session->securityAuthProto == NULL) {
            /*
             * get .conf set default
             */
            const oid      *def =
                get_default_authtype(&session->securityAuthProtoLen);
            session->securityAuthProto =
                snmp_duplicate_objid(def, session->securityAuthProtoLen);
        }
        if (session->securityAuthProto == NULL) {
#ifndef NETSNMP_DISABLE_MD5
            /*
             * assume MD5
             */
            session->securityAuthProto =
                snmp_duplicate_objid(usmHMACMD5AuthProtocol,
                                     USM_AUTH_PROTO_MD5_LEN);
            session->securityAuthProtoLen = USM_AUTH_PROTO_MD5_LEN;
#else
            session->securityAuthProto =
                snmp_duplicate_objid(usmHMACSHA1AuthProtocol,
                                     USM_AUTH_PROTO_SHA_LEN);
            session->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
#endif
        }
        if (generate_Ku(session->securityAuthProto,
                        session->securityAuthProtoLen,
                        (u_char *) Apsz, strlen(Apsz),
                        session->securityAuthKey,
                        &session->securityAuthKeyLen) != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr,
                    "Error generating a key (Ku) from the supplied authentication pass phrase. \n");
            return (-2);
        }
    }
    if (Xpsz) {
        session->securityPrivKeyLen = USM_PRIV_KU_LEN;
        if (session->securityPrivProto == NULL) {
            /*
             * get .conf set default
             */
            const oid      *def =
                get_default_privtype(&session->securityPrivProtoLen);
            session->securityPrivProto =
                snmp_duplicate_objid(def, session->securityPrivProtoLen);
        }
        if (session->securityPrivProto == NULL) {
            /*
             * assume DES
             */
#ifndef NETSNMP_DISABLE_DES
            session->securityPrivProto =
                snmp_duplicate_objid(usmDESPrivProtocol,
                                     USM_PRIV_PROTO_DES_LEN);
            session->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
#else
            session->securityPrivProto =
                snmp_duplicate_objid(usmAESPrivProtocol,
                                     USM_PRIV_PROTO_AES_LEN);
            session->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
#endif

        }
        if (generate_Ku(session->securityAuthProto,
                        session->securityAuthProtoLen,
                        (u_char *) Xpsz, strlen(Xpsz),
                        session->securityPrivKey,
                        &session->securityPrivKeyLen) != SNMPERR_SUCCESS) {
            snmp_perror(argv[0]);
            fprintf(stderr,
                    "Error generating a key (Ku) from the supplied privacy pass phrase. \n");
            return (-2);
        }
    }
#endif

    /*
     * get the hostname
     */
    if (optind == argc) {
        fprintf(stderr, "No hostname specified.\n");
        return (-1);
    }
    session->peername = argv[optind++]; /* hostname */

#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
    /*
     * If v1 or v2c, check community has been set, either by a -c option above,
     * or via a default token somewhere.
     * If neither, it will be taken from the incoming request PDU.
     */

#if defined(NETSNMP_DISABLE_SNMPV1)
    if (session->version == SNMP_VERSION_2c)
#else
#if defined(NETSNMP_DISABLE_SNMPV2C)
    if (session->version == SNMP_VERSION_1)
#else
    if (session->version == SNMP_VERSION_1 ||
            session->version == SNMP_VERSION_2c)
#endif
#endif
    {
        if (Cpsz == NULL) {
            Cpsz = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                         NETSNMP_DS_LIB_COMMUNITY);
            if (Cpsz == NULL) {
                if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                           NETSNMP_DS_LIB_IGNORE_NO_COMMUNITY)) {
                    DEBUGMSGTL(("snmp_parse_args",
                                "ignoring that the community string is not present\n"));
                    session->community = NULL;
                    session->community_len = 0;
                } else {
                    fprintf(stderr, "No community name specified.\n");
                    return (-1);
                }
            }
        } else {
            session->community = (unsigned char *)Cpsz;
            session->community_len = strlen(Cpsz);
        }
    }
#endif /* support for community based SNMP */

    return optind;
}
Ejemplo n.º 4
0
static void csnmp_host_open_session (host_definition_t *host)
{
  struct snmp_session sess;
  int error;

  if (host->sess_handle != NULL)
    csnmp_host_close_session (host);

  snmp_sess_init (&sess);
  sess.peername = host->address;
  switch (host->version)
  {
    case 1:
      sess.version = SNMP_VERSION_1;
      break;
    case 3:
      sess.version = SNMP_VERSION_3;
      break;
    default:
      sess.version = SNMP_VERSION_2c;
      break;
  }

  if (host->version == 3)
  {
    sess.securityName = host->username;
    sess.securityNameLen = strlen (host->username);
    sess.securityLevel = host->security_level;

    if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV)
    {
      sess.securityAuthProto = host->auth_protocol;
      sess.securityAuthProtoLen = host->auth_protocol_len;
      sess.securityAuthKeyLen = USM_AUTH_KU_LEN;
      error = generate_Ku (sess.securityAuthProto,
	    sess.securityAuthProtoLen,
	    (u_char *) host->auth_passphrase,
	    strlen(host->auth_passphrase),
	    sess.securityAuthKey,
	    &sess.securityAuthKeyLen);
      if (error != SNMPERR_SUCCESS) {
	ERROR ("snmp plugin: host %s: Error generating Ku from auth_passphrase. (Error %d)", host->name, error);
      }
    }

    if (sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV)
    {
      sess.securityPrivProto = host->priv_protocol;
      sess.securityPrivProtoLen = host->priv_protocol_len;
      sess.securityPrivKeyLen = USM_PRIV_KU_LEN;
      error = generate_Ku (sess.securityAuthProto,
	    sess.securityAuthProtoLen,
	    (u_char *) host->priv_passphrase,
	    strlen(host->priv_passphrase),
	    sess.securityPrivKey,
	    &sess.securityPrivKeyLen);
      if (error != SNMPERR_SUCCESS) {
	ERROR ("snmp plugin: host %s: Error generating Ku from priv_passphrase. (Error %d)", host->name, error);
      }
    }

    if (host->context != NULL)
    {
      sess.contextName = host->context;
      sess.contextNameLen = strlen (host->context);
    }
  }
  else /* SNMPv1/2 "authenticates" with community string */
  {
    sess.community = (u_char *) host->community;
    sess.community_len = strlen (host->community);
  }

  /* snmp_sess_open will copy the `struct snmp_session *'. */
  host->sess_handle = snmp_sess_open (&sess);

  if (host->sess_handle == NULL)
  {
    char *errstr = NULL;

    snmp_error (&sess, NULL, NULL, &errstr);

    ERROR ("snmp plugin: host %s: snmp_sess_open failed: %s",
        host->name, (errstr == NULL) ? "Unknown problem" : errstr);
    sfree (errstr);
  }
} /* void csnmp_host_open_session */