static int secure_passwords() { void *d, *d1; int status; ni_index where; ni_id dir; ni_namelist nl; status = ni_open(NULL, ".", &d); while (status == NI_OK) { dir.nii_object = 0; status = ni_lookupprop(d, &dir, "security_options", &nl); if (status == NI_OK) { where = ni_namelist_match(nl, "secure_passwords"); if (where != NI_INDEX_NULL) { ni_free(d); return 1; } } d1 = d; status = ni_open(d1, "..", &d); ni_free(d1); } return 0; }
static int password_lifetime() { void *d, *d1; int status; ni_id dir; ni_namelist nl; status = ni_open(NULL, ".", &d); while (status == NI_OK) { status = ni_pathsearch(d, &dir, "/users"); if (status == NI_OK) { status = ni_lookupprop(d, &dir, "password_lifetime", &nl); if (status == NI_OK) { if (nl.ni_namelist_val[0] != NULL) { ni_free(d); /* free namelist? */ return atoi(nl.ni_namelist_val[0]); } } } d1 = d; status = ni_open(d1, "..", &d); ni_free(d1); } return -1; }
int NetInfoPrefsSource::GetValueByIndex(const char* inKey, UInt32 inIndex, char* ioValue) { ni_status status = NI_OK; ni_namelist nameList = {}; void* localDomain = NULL; ni_id qtssDir = {}; ioValue[0] = '\0'; status = ni_open(NULL, ".", &localDomain); if (status != NI_OK) return false; if (status == NI_OK) status = ni_pathsearch(localDomain, &qtssDir, gQTSSPropertiesPath); if (status == NI_OK) status = ni_lookupprop(localDomain, &qtssDir, inKey, &nameList); if (status == NI_OK) { if (nameList.ni_namelist_len > inIndex) strcpy(ioValue, nameList.ni_namelist_val[inIndex]); else status = NI_BADID; ni_namelist_free(&nameList); } ni_free(localDomain); return (status == NI_OK); }
krb5_error_code KRB5_LIB_FUNCTION krb5_config_parse_file (krb5_context context, const char *fname, krb5_config_section **res) { void *ni = NULL, *lastni = NULL; int i; ni_status nis; ni_id nid; ni_idlist children; krb5_config_section *s; int ret; s = NULL; for (i = 0; i < 256; i++) { if (i == 0) { nis = ni_open(NULL, ".", &ni); } else { if (lastni != NULL) ni_free(lastni); lastni = ni; nis = ni_open(lastni, "..", &ni); } if (nis != NI_OK) break; nis = ni_pathsearch(ni, &nid, "/locations/kerberos"); if (nis == NI_OK) { nis = ni_children(ni, &nid, &children); if (nis != NI_OK) break; nis = ni_idlist2binding(ni, &children, &s); break; } } if (ni != NULL) ni_free(ni); if (ni != lastni && lastni != NULL) ni_free(lastni); ret = (nis == NI_OK) ? 0 : -1; if (ret == 0) { *res = s; } else { *res = NULL; } return ret; }
void NetInfoPrefsSource::SetValueByIndex(char* inKey, char* inValue, UInt32 inIndex) { void* localDomain = NULL; ni_status status = NI_OK; ni_namelist nameList = {}; //ni_namelist_insert(&nameList, (char*)inValue, NI_INDEX_NULL); ni_namelist_insert(&nameList, inValue, inIndex); status = ni_open(NULL, ".", &localDomain); if (status == NI_OK) { //create the path if it doesn't already exist status = ni2_create(localDomain, gQTSSPropertiesPath); if (status == NI_OK) status = ni2_appendprop(localDomain, gQTSSPropertiesPath, inKey, nameList); } ni_namelist_free(&nameList); ni_free(localDomain); }
/* * Change a user's password in NetInfo. */ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags, int argc, const char **argv) { char *oldHash, *newHash; char *oldPassword = NULL, *newPassword = NULL; void *d; int status, isroot, tries, maxTries; int options = 0; int amChangingExpiredPassword; ni_id dir; ni_proplist pl; ni_property p; ni_namelist nl; int ni_uid, uid, secure, minlen, lifetime; ni_index where; struct pam_conv *appconv; struct pam_message msg, *pmsg; struct pam_response *resp; const char *cmiscptr = NULL; char *uname; char salt[9]; int i; amChangingExpiredPassword = flags & PAM_CHANGE_EXPIRED_AUTHTOK; status = pam_get_item(pamh, PAM_CONV, (void **) &appconv); if (status != PAM_SUCCESS) return status; status = pam_get_item(pamh, PAM_USER, (void **) &uname); if (status != PAM_SUCCESS) return status; if (uname == NULL) return PAM_USER_UNKNOWN; status = pam_get_item(pamh, PAM_OLDAUTHTOK, (void **) &oldPassword); if (status != PAM_SUCCESS) { return status; } if (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL) || pam_test_option(&options, PAM_OPT_TRY_FIRST_PASS, NULL)) { if (pam_get_item(pamh, PAM_AUTHTOK, (void **) &newPassword) != PAM_SUCCESS) newPassword = NULL; if (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL) && newPassword == NULL) return PAM_AUTHTOK_RECOVER_ERR; } d = domain_for_user(uname, NULL, &dir); if (d == (void *) NULL) { syslog(LOG_ERR, "user %s not found in NetInfo", uname); return PAM_USER_UNKNOWN; } /* * These should be configurable in NetInfo. */ secure = secure_passwords(); maxTries = secure ? 3 : 5; minlen = secure ? 8 : 5; /* * Read the passwd and uid from NetInfo. */ status = ni_lookupprop(d, &dir, "passwd", &nl); if (status == NI_NOPROP) nl.ni_namelist_len = 0; else if (status != NI_OK) { ni_free(d); syslog(LOG_ERR, "NetInfo read failed: %s", ni_error(status)); return netinfo2PamStatus(status); } oldHash = NULL; if (nl.ni_namelist_len > 0) oldHash = nl.ni_namelist_val[0]; status = ni_lookupprop(d, &dir, "uid", &nl); if (status != NI_OK) { ni_free(d); syslog(LOG_ERR, "NetInfo read failed: %s", ni_error(status)); return netinfo2PamStatus(status); } ni_uid = -2; if (nl.ni_namelist_len > 0) ni_uid = atoi(nl.ni_namelist_val[0]); /* * See if I'm uid 0 on the master host for the user's NetInfo domain. */ isroot = is_root_on_master(d); uid = getuid(); if (isroot) { if (flags & PAM_PRELIM_CHECK) { /* Don't need old password. */ return PAM_SUCCESS; } } else if (uid != ni_uid) { ni_free(d); return PAM_PERM_DENIED; } if (flags & PAM_PRELIM_CHECK) { /* * If we are not root, we should verify the old * password. */ char *encrypted; if (oldPassword != NULL && (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL) || pam_test_option(&options, PAM_OPT_TRY_FIRST_PASS, NULL))) { encrypted = crypt(oldPassword, oldHash); if (oldPassword[0] == '\0' && oldHash != '\0') encrypted = ":"; status = strcmp(encrypted, oldHash) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR; if (status != PAM_SUCCESS) { if (pam_test_option(&options, PAM_OPT_USE_FIRST_PASS, NULL)) sendConversationMessage(appconv, "NetInfo password incorrect", PAM_ERROR_MSG, &options); else sendConversationMessage(appconv, "NetInfo password incorrect: try again", PAM_ERROR_MSG, &options); } else { ni_free(d); return PAM_SUCCESS; } } tries = 0; while (oldPassword == NULL && tries++ < maxTries) { pmsg = &msg; msg.msg_style = PAM_PROMPT_ECHO_OFF; msg.msg = OLD_PASSWORD_PROMPT; resp = NULL; status = appconv->conv(1, (struct pam_message **) & pmsg, &resp, appconv->appdata_ptr); if (status != PAM_SUCCESS) { ni_free(d); return status; } oldPassword = resp->resp; free(resp); encrypted = crypt(oldPassword, oldHash); if (oldPassword[0] == '\0' && oldHash != '\0') encrypted = ":"; status = strcmp(encrypted, oldHash) == 0 ? PAM_SUCCESS : PAM_AUTH_ERR; if (status != PAM_SUCCESS) { int abortMe = 0; if (oldPassword != NULL && oldPassword[0] == '\0') abortMe = 1; _pam_overwrite(oldPassword); _pam_drop(oldPassword); if (!amChangingExpiredPassword & abortMe) { sendConversationMessage(appconv, "Password change aborted", PAM_ERROR_MSG, &options); ni_free(d); return PAM_AUTHTOK_RECOVER_ERR; } else { sendConversationMessage(appconv, "NetInfo password incorrect: try again", PAM_ERROR_MSG, &options); } } } if (oldPassword == NULL) { status = PAM_MAXTRIES; } (void) pam_set_item(pamh, PAM_OLDAUTHTOK, oldPassword); ni_free(d); return status; } /* PAM_PRELIM_CHECK */ status = PAM_ABORT; tries = 0; while (newPassword == NULL && tries++ < maxTries) { pmsg = &msg; msg.msg_style = PAM_PROMPT_ECHO_OFF; msg.msg = NEW_PASSWORD_PROMPT; resp = NULL; status = appconv->conv(1, &pmsg, &resp, appconv->appdata_ptr); if (status != PAM_SUCCESS) { ni_free(d); return status; } newPassword = resp->resp; free(resp); if (newPassword[0] == '\0') { free(newPassword); newPassword = NULL; } if (newPassword != NULL) { if (isroot == 0) { if (oldPassword != NULL && !strcmp(oldPassword, newPassword)) { cmiscptr = "Passwords must differ"; newPassword = NULL; } else if (strlen(newPassword) < minlen) { cmiscptr = "Password too short"; newPassword = NULL; } } } else { ni_free(d); return PAM_AUTHTOK_RECOVER_ERR; } if (cmiscptr == NULL) { /* get password again */ char *miscptr; pmsg = &msg; msg.msg_style = PAM_PROMPT_ECHO_OFF; msg.msg = AGAIN_PASSWORD_PROMPT; resp = NULL; status = appconv->conv(1, &pmsg, &resp, appconv->appdata_ptr); if (status != PAM_SUCCESS) { ni_free(d); return status; } miscptr = resp->resp; free(resp); if (miscptr[0] == '\0') { free(miscptr); miscptr = NULL; } if (miscptr == NULL) { if (!amChangingExpiredPassword) { sendConversationMessage(appconv, "Password change aborted", PAM_ERROR_MSG, &options); ni_free(d); return PAM_AUTHTOK_RECOVER_ERR; } } else if (!strcmp(newPassword, miscptr)) { miscptr = NULL; break; } sendConversationMessage(appconv, "You must enter the same password", PAM_ERROR_MSG, &options); miscptr = NULL; newPassword = NULL; } else { sendConversationMessage(appconv, cmiscptr, PAM_ERROR_MSG, &options); cmiscptr = NULL; newPassword = NULL; } } if (cmiscptr != NULL || newPassword == NULL) { ni_free(d); return PAM_MAXTRIES; } /* * Lock onto the master server. */ ni_needwrite(d, 1); /* * Authenticate if necessary */ if (isroot == 0) { ni_setuser(d, uname); ni_setpassword(d, oldPassword); } /* * Create a random salt */ srandom((int) time((time_t *) NULL)); salt[0] = saltchars[random() % strlen(saltchars)]; salt[1] = saltchars[random() % strlen(saltchars)]; salt[2] = '\0'; newHash = crypt(newPassword, salt); /* * Change the password in NetInfo. */ status = ni_read(d, &dir, &pl); if (status != NI_OK) { ni_free(d); syslog(LOG_ERR, "NetInfo read failed: %s", ni_error(status)); return netinfo2PamStatus(status); } p.nip_name = "passwd"; p.nip_val.ni_namelist_len = 1; p.nip_val.ni_namelist_val = (ni_name *) malloc(sizeof(ni_name)); p.nip_val.ni_namelist_val[0] = newHash; where = ni_proplist_match(pl, p.nip_name, NULL); if (where == NI_INDEX_NULL) status = ni_createprop(d, &dir, p, NI_INDEX_NULL); else status = ni_writeprop(d, &dir, where, p.nip_val); if (status != NI_OK) { ni_free(d); syslog(LOG_ERR, "NetInfo write property \"passwd\" failed: %s", ni_error(status)); return netinfo2PamStatus(status); } /* * Now, update "change" property. If this fails, we've still * updated the password... perhaps the user should be alerted * of this. */ lifetime = password_lifetime(); if (lifetime > 0) { struct timeval tp; char change[64]; where = ni_proplist_match(pl, "change", NULL); gettimeofday(&tp, NULL); tp.tv_sec += lifetime; snprintf(change, sizeof(change), "%ld", tp.tv_sec); p.nip_name = "change"; p.nip_val.ni_namelist_len = 1; p.nip_val.ni_namelist_val[0] = change; if (where == NI_INDEX_NULL) status = ni_createprop(d, &dir, p, NI_INDEX_NULL); else status = ni_writeprop(d, &dir, where, p.nip_val); if (status != NI_OK) { ni_free(d); syslog(LOG_ERR, "NetInfo write property \"change\" failed: %s", ni_error(status)); return netinfo2PamStatus(status); } } free(p.nip_val.ni_namelist_val); ni_free(d); /* tell lookupd to invalidate its cache */ { int i, proc = -1; unit lookup_buf[MAX_INLINE_UNITS]; #ifdef __NeXT__ port_t port; #else mach_port_t port; #endif port = _lookupd_port(0); (void) _lookup_link(port, "_invalidatecache", &proc); (void) _lookup_one(port, proc, NULL, 0, lookup_buf, &i); } return PAM_SUCCESS; }
static void * domain_for_user(char *uname, char *locn, ni_id * dir) { char *upath; int status; void *d, *d1; struct sockaddr_in server; char *tag; int bytag; if (uname == NULL) return NULL; /* * Find the user in NetInfo. */ upath = malloc(8 + strlen(uname)); sprintf(upath, "/users/%s", uname); if (locn != NULL) { bytag = 1; if (locn[0] == '/') bytag = 0; else if (!strncmp(locn, "./", 2)) bytag = 0; else if (!strncmp(locn, "../", 3)) bytag = 0; if (bytag == 1) { parse_server_tag(locn, &server, &tag); d = ni_connect(&server, tag); if (d == (void *) NULL) return (void *) NULL; } else status = ni_open(NULL, locn, &d); status = ni_pathsearch(d, dir, upath); free(upath); if (status == NI_OK) return d; ni_free(d); return (void *) NULL; } status = ni_open(NULL, ".", &d); while (status == NI_OK) { status = ni_pathsearch(d, dir, upath); if (status == NI_OK) break; d1 = d; status = ni_open(d1, "..", &d); ni_free(d1); } free(upath); if (status == NI_OK) return d; return (void *) NULL; }
void process(NetworkInterface* ni) { Packet* packet = ni_input(ni); if(!packet) return; if(arp_process(packet)) return; Ether* ether = (Ether*)(packet->buffer + packet->start); /* if(endian16(ether->type) == ETHER_TYPE_ARP) { // ARP response ARP* arp = (ARP*)ether->payload; if(endian16(arp->operation) == 1 && endian32(arp->tpa) == address) { ether->dmac = ether->smac; ether->smac = endian48(ni->mac); arp->operation = endian16(2); arp->tha = arp->sha; arp->tpa = arp->spa; arp->sha = ether->smac; arp->spa = endian32(address); printf("- Ethernet Header -\n"); printf("Dst Mac : %012lx Src Mac : %012lx\n Ether Type : %04hx\n", endian48(ether->dmac), endian48(ether->smac), ether->type); ni_output(ni, packet); packet = NULL; } }*/ if(endian16(ether->type) == ETHER_TYPE_IPv4) { IP* ip = (IP*)ether->payload; if(ip->protocol == IP_PROTOCOL_ICMP && endian32(ip->destination) == address){ // Echo reply ICMP* icmp = (ICMP*)ip->body; // Performance check // perf(); icmp->type = 0; icmp->checksum = 0; icmp->checksum = endian16(checksum(icmp, packet->end - packet->start - ETHER_LEN - IP_LEN)); ip->destination = ip->source; ip->source = endian32(address); ip->ttl = endian8(64); ip->checksum = 0; ip->checksum = endian16(checksum(ip, ip->ihl * 4)); ether->dmac = ether->smac; ether->smac = endian48(ni->mac); ni_output(ni, packet); packet = NULL; } /* } else if(ip->protocol == IP_PROTOCOL_TCP) { TCP* tcp = (TCP*)ip->body; printf("source=%u, destination=%u, sequence=%u, acknowledgement=%u\n", endian16(tcp->source), endian16(tcp->destination), endian32(tcp->sequence), endian32(tcp->acknowledgement)); printf("offset=%d, ns=%d, cwr=%d, ece=%d, urg=%d, ack=%d, psh=%d, rst=%d, syn=%d, fin=%d\n", tcp->offset, tcp->ns, tcp->cwr, tcp->ece, tcp->urg, tcp->ack, tcp->psh, tcp->rst, tcp->syn, tcp->fin); printf("window=%d, checksum=%x, urgent=%d\n", endian16(tcp->window), endian16(tcp->checksum), endian16(tcp->urgent)); */ } if(packet) ni_free(packet); }
void process(NetworkInterface* ni) { Packet* packet = ni_input(ni); if(!packet) return; if(arp_process(packet)) return; Ether* ether = (Ether*)(packet->buffer + packet->start); if(endian16(ether->type) == ETHER_TYPE_IPv4) { IP* ip = (IP*)ether->payload; if(ip->protocol == IP_PROTOCOL_UDP) { UDP* udp = (UDP*)ip->body; if(endian16(udp->destination) == SETKEY_PORT_NUM) { int orig_len = endian16(ip->length); Parameter* parameter = (Parameter*)udp->body; // ARP Request if(arp_request(ni, parameter->dst_ip) == true); //printf("ARP Request for destination IP\n"); int result = parse(parameter); memcpy(&(udp->body), &result, sizeof(result)); #ifdef _DEBUG_ for(int i = 0; i < 64 /* Packet Minimum Size */ - ETHER_LEN /* 14 */ - IP_LEN /* 20 */ - UDP_LEN /* 8 */ - sizeof(result); i++) udp->body[i + 4] = i; #endif uint16_t t = udp->destination; udp->destination = udp->source; udp->source = t; udp->checksum = 0; udp->length = endian16(64 - ETHER_LEN - IP_LEN); uint32_t t2 = ip->destination; ip->destination = ip->source; ip->source = t2; ip->ttl = 0x40; ip->length = endian16(64 - ETHER_LEN); ip->checksum = 0; ip->checksum = endian16(checksum(ip, ip->ihl * 4)); uint64_t t3 = ether->dmac; ether->dmac = ether->smac; ether->smac = t3; packet->end += (endian16(ip->length) - orig_len); ni_output(ni, packet); packet = NULL; } } if(ip->protocol == IP_PROTOCOL_ESP){ int orig_len = endian16(ip->length); #ifdef _DEBUG_ printf("Before Decryption - Packet : \n"); for(int i = 1; i < 1 + endian16(ip->length); i++) { printf("%02x ", ether->payload[i - 1]); // Packet - IP Header if( i % 16 == 0 ) printf("\n"); } printf("\n"); #endif if(decrypt(ip) >= 0) { packet->end += (endian16(ip->length) - orig_len); // ether->dmac = endian48(arp_get_mac(ni, endian32(ip->destination))); // ether->smac = endian48(ni->mac); #ifdef _DEBUG_ printf("- Ethernet Header After Decryption-\n"); printf("Dst Mac : %012lx Src Mac : %012lx\n Ether Type : %x\n", endian48(ether->dmac), endian48(ether->smac), ether->type); #endif if(ip->protocol == IP_PROTOCOL_ICMP){ // Echo reply ICMP* icmp = (ICMP*)ip->body; icmp->type = 0; icmp->checksum = 0; icmp->checksum = endian16(checksum(icmp, packet->end - packet->start - ETHER_LEN - IP_LEN)); uint32_t temp = ip->destination; ip->destination = ip->source; ip->source = temp; ip->ttl = endian8(64); ip->checksum = 0; ip->checksum = endian16(checksum(ip, ip->ihl * 4)); // ether->dmac = ether->smac; // ether->smac = endian48(ni->mac); // ni_output(ni, packet); // packet = NULL; } // ni_output(ni1, packet); // packet = NULL; } orig_len = endian16(ip->length); #ifdef _DEBUG_ printf("Before Encryption - Packet : \n"); for(int i = 1; i < 1 + endian16(ip->length); i++) { printf("%02x ", ether->payload[i - 1]); // Packet - IP Header if( i % 16 == 0 ) printf("\n"); } printf("\n"); #endif if(encrypt(ip) >= 0) { packet->end += (endian16(ip->length) - orig_len); ether->dmac = endian48(arp_get_mac(ni, endian32(ip->destination))); ether->smac = endian48(ni->mac); #ifdef _DEBUG_ printf("- Ethernet Header After Encryption-\n"); printf("Dst Mac : %012lx Src Mac : %012lx\n Ether Type : %x\n", endian48(ether->dmac), endian48(ether->smac), ether->type); #endif ni_output(ni, packet); packet = NULL; } } } if(packet) ni_free(packet); }