Esempio n. 1
0
File: anp.c Progetto: fdgonthier/kas
/* This function reads the next element in the buffer. This function sets the
 * KMOD error string. It returns -1 on failure. If el is null just skip the
 * element.
 */
int anp_read_element(kbuffer *buf, struct anp_element *el) {
    int error = 0;
    uint8_t type;
    struct anp_element dummy;
    struct anp_element *work_el = &dummy;
    if (el != NULL)
        work_el = el;
	
    if (kbuffer_read8(buf, &type)) return -1;
    work_el->type = type;

    switch (work_el->type) {
        case ANP_UINT32:
            error = kbuffer_read32(buf, &work_el->uint32);
            break;
        case ANP_UINT64:
            error = kbuffer_read64(buf, &work_el->uint64);
            break;
        case ANP_STR:
            work_el->str = kstr_new();
            error = anp_read_element_string(buf, work_el->str);
            if (error) { kstr_destroy(work_el->str); work_el->str = NULL; }
            break;
        case ANP_BIN:
            work_el->bin = kbuffer_new();
            error = anp_read_element_bin(buf, work_el->bin);
            if (error) { kbuffer_destroy(work_el->bin); work_el->bin = NULL; }
            break;
    }

    if (el == NULL) anp_element_clean(&dummy);
    
    return error;
}
Esempio n. 2
0
static int recognize_blob(struct kmocrypt_signature2 *self, kbuffer *buffer, void **data_handle, uint32_t packet_len) {
    uint32_t len;
    struct kmo_blob *blob = kmo_calloc(sizeof(struct kmo_blob));
    
    do {
        if (kbuffer_left(buffer) < 2 * sizeof(uint32_t)) {
            kmo_seterror("KSP BLOB subpacket is malformed");
	    break;
	}

        blob->type = kbuffer_read32(buffer);
        len = kbuffer_read32(buffer);

        blob->buffer = kbuffer_new(len);
        if (kbuffer_read_into(buffer, blob->buffer, len) != len) {
	    kmo_seterror("KSP BLOB subpacket is malformed");
            break;
	}
	
	if (packet_len != 8 + len) {
	    kmo_seterror("KSP BLOB subpacket is malformed");
	    break;
	}

        *data_handle = blob;
        return 0;
	
    } while (0);
    
    kbuffer_destroy(blob->buffer);
    free(blob);
    return -1;
}
Esempio n. 3
0
File: anp.c Progetto: fdgonthier/kas
/* 'bin' can be NULL'. */
void anp_msg_write_bin(struct anp_msg *self, kbuffer *bin) {
    struct anp_element *el = anp_element_new();
    el->type = ANP_BIN;
    el->bin = kbuffer_new();
    if (bin) kbuffer_write_buffer(el->bin, bin);
    karray_push(&self->element_array, el);
    anp_write_bin(&self->payload, el->bin);
}
Esempio n. 4
0
int kddb_otut_login(apr_pool_t *pool, 
                    struct kd_user *user, 
                    const char *otut_str,
                    size_t otut_str_s,
                    struct kd_login_result **res) {
    kbuffer *otut_buf = kbuffer_new();

    DEBUG(_log_db_, "OTUT login attempted.");

    *res = apr_pcalloc(pool, sizeof(struct kd_login_result));

    if (kddbotut_login(db->otut_db, 
                       otut_str,
                       otut_str_s,
                       &user->key_id,
                       res) < 0) {
        KERROR_PUSH(_otut_, 0, "failed to login with OTUT");        
        return -1;
    }

    /* OTUT login is allowed or flat-out denied. */
    if ((*res)->rights == LOGIN_RIGHTS_DENIED) {
        DEBUG(_log_db_, "OTUT login failed.");
        return 0;
    }

    /* If the login has been successful, extricate the data from the
       OTUT. */
    user->type = KD_USER_OTUT;
    user->otut_info = apr_pcalloc(user->pool, sizeof(struct kd_otut));
    user->otut_info->otut_str = apr_pstrmemdup(user->pool, otut_str, otut_str_s);
    user->otut_info->otut_str_s = otut_str_s;
    
    /* Create the tagcrypt OTUT object. */
    user->otut_info->otut = apr_pcalloc(user->pool, sizeof(struct tagcrypt_otut));
    tagcrypt_otut_init(user->otut_info->otut);
    kbuffer_write(otut_buf, (uint8_t *)otut_str, otut_str_s);
    tagcrypt_otut_realize(otut_buf, user->otut_info->otut);
    kbuffer_destroy(otut_buf);   

    /* Make up an username.  It may be needed later on. */
    user->username = apr_pstrmemdup(user->pool,
                                    (const char *)user->otut_info->otut->addr->data,
                                    user->otut_info->otut->addr->len);

    apr_pool_cleanup_register(user->pool, 
                              user->otut_info->otut, 
                              kddb_otut_clean, 
                              kddb_otut_clean);

    DEBUG(_log_db_, "OTUT login succeeded.");

    return 0;
}
Esempio n. 5
0
/** Generate a ticket good for one OTUT.
 *
 * This function generates a ticket suitable to obtain an OTUT
 * on the Online Ticket Server and put it in a signature object as a blob
 * subpacket.  The signature object should not contain any other
 * subpackets.  The ticket is returned in the buffer 'out'.
 */
int tagcrypt_gen_ticket(tagcrypt_skey *skey, uint32_t reply_count, 
                        kbuffer *otut_addr,
                        kbuffer *out) {
    int r = 0;
    struct tagcrypt_ticket ticket;
    kbuffer *ticket_buffer = NULL;
    tagcrypt_signature *ticket_sign;
    struct tagcrypt_blob_params bp;

    if (gettimeofday(&ticket.tv, NULL) < 0) 
        return -1;
    
    do {
        /* Create the signature which will hold the ticket. */
        if ((ticket_sign = tagcrypt_sign_new(TAG_P_TYPE_SIGN, 2, 1, skey)) == NULL) {
            r = -1;
            break;
        }

        ticket.mid = skey->keyid;
        ticket.reply_count = reply_count;        
        ticket.otut_addr = otut_addr;
        
        /* Create a buffer for the ticket data. */
        ticket_buffer = kbuffer_new(256);

        /* Write the ticket data in the buffer. */
        kbuffer_write64(ticket_buffer, ticket.mid);
        kbuffer_write(ticket_buffer, (uint8_t *)&ticket.tv, sizeof(struct timeval));
        kbuffer_serialize(otut_addr, ticket_buffer);
        kbuffer_write32(ticket_buffer, reply_count);

        bp.type = 0;
        bp.blob = ticket_buffer;

        /* Add the signature data as a BLOB. */
        if (tagcrypt_sign_add_subpacket(ticket_sign, TAG_SP_TYPE_BLOB, &bp) < 0) {
            r = -1;
            break;
        }

        /* Serialize the signed ticket. */
        tagcrypt_sign_serialize(ticket_sign, out);

    } while (0);

    if (ticket_sign != NULL)
        tagcrypt_sign_destroy(ticket_sign);
    if (ticket_buffer != NULL)
        kbuffer_destroy(ticket_buffer);

    return r;
}
Esempio n. 6
0
/** Crack a ticket, check its signature and validity vs. the DB. */
int otut_extract_ticket(apr_pool_t *ticket_pool, 
                        const char *ticket_str,
                        size_t ticket_str_s,
                        struct tagcrypt_ticket **ticket) {
    int error = -1;
    uint64_t tkt_keyid;
    kbuffer *signed_tkt_buf;
    struct kdkey_info *tkt_pkey;
    apr_pool_t *pool;
        
    // FIXME: Make sure this may or may not fail. */
    tkt_keyid = tagcrypt_signature_get_keyid(ticket_str, ticket_str_s);
    
    apr_pool_create(&pool, ticket_pool);

    /* Fetch the key for the ticket. */
    if (kdkey_get_sig_pkey(pool, tkt_keyid, &tkt_pkey) <= 0) {
        KERROR_PUSH(_otut_, 0, "failed to fetch key for ticket");
        return -1;
    }

    signed_tkt_buf = kbuffer_new();

    do {
        /* Write the ticket data in the signed ticket buffer for
           conversion. */
        kbuffer_write(signed_tkt_buf, (uint8_t *)ticket_str, ticket_str_s);

        *ticket = apr_pcalloc(ticket_pool, sizeof(struct tagcrypt_ticket));
	tagcrypt_ticket_init(*ticket);

        if (tagcrypt_get_ticket(tkt_pkey->key, signed_tkt_buf, *ticket) < 0) {
            KERROR_SET(_otut_, 0, "failed to extract ticket");
            break;
        }
        
        /* Validate the ticket with the DB. */
        if (kddb_otut_ticket_store(tkt_keyid, &(*ticket)->tv) < 0) {
            KERROR_PUSH(_otut_, 0, "the ticket has been refused by the database");
            break;
        }
	
	error = 0;

    } while (0);

    kbuffer_destroy(signed_tkt_buf);
    apr_pool_destroy(pool);

    return error;
}
Esempio n. 7
0
//--------------------------------------------------------------------------------
// SERVER
void acceptTcpHandler(epoller *epoll, int fd, void *privdata, int mask) {

	int cport, cfd = -1;
	char cip[128] = {0, };
	echoServerContext *server = (echoServerContext *)privdata;

	NOTUSED(server);
	NOTUSED(epoll);
	NOTUSED(mask);

	struct sockaddr_in sa;
	socklen_t salen = sizeof(sa);

	while(1) {
		cfd = accept(fd, (struct sockaddr *)&sa, &salen);
		if (cfd == -1) {
			if (errno == EINTR)
				continue;
			else {
				oom("accept error : %s", strerror(errno));
				return;
			}
		}
		break;
	}

	if (cfd == -1) {
		printf("failed to accepting client connection\n");
		return;
	}

	strcpy(cip, inet_ntoa(sa.sin_addr));
	cport = ntohs(sa.sin_port);

	printf("Accepted %s:%d\n", cip, cport);

	// client object create..
	echoClientContext *c = (echoClientContext *)malloc(sizeof(echoClientContext));
	c->writebuffer = kbuffer_new();
	if (epollAddEvent(epoll, cfd, EPOLLIN, readDataFromClient, c) != 0)
		oom("failed to add client event..");
}
Esempio n. 8
0
    }

    gcry_sexp_release(param);

    return 0;

ERR:
    if (param) gcry_sexp_release (param);
    return -1;
}


int tagcrypt_gen_public_secret(kbuffer *pkey, kbuffer *skey, uint64_t keyid, int size) {
    tagcrypt_pkey pkey_st = { .keyid = keyid };
    tagcrypt_skey skey_st = { .keyid = keyid };
    kbuffer *tmp = kbuffer_new(128);
    gcry_sexp_t key_pair;
    int err;

    err = tagcrypt_key_gen (&key_pair, size);
    if (err)
        return err;

    skey_st.key = gcry_sexp_find_token (key_pair, "private-key", 11);
    tagcrypt_skey_serialize (&skey_st, tmp);
    kbin2b64(tmp, skey);

    kbuffer_reset (tmp);

    pkey_st.key = gcry_sexp_find_token (key_pair, "public-key", 10);
    tagcrypt_pkey_serialize (&pkey_st, tmp);
Esempio n. 9
0
static int kdkey_read_key_file(apr_pool_t *pool, apr_file_t *f, struct kdkey_info *ki) {
    apr_status_t s;
    char start[256];
    char key_id_str[256];
    char owner_str[256];
    char key[256];
    size_t sz;
    kbuffer *key_buffer;
    int r = -1;

    ki->owner = NULL;
    ki->owner_s = 0;
    ki->data = NULL;
    ki->data_s = 0;

    do {
        key_buffer = kbuffer_new();

        s = apr_file_gets(start, sizeof(start), f);
        if (s != APR_SUCCESS) {
            KERROR_SET_APR(_keys_, 0, s);
            break;
        }

        if (strcmp(start, start_sig_pkey) == 0) 
            ki->type = PKEY_SIGNATURE;
        else if (strcmp(start, start_sig_skey) == 0) 
            ki->type = SKEY_SIGNATURE;
        else if (strcmp(start, start_enc_pkey) == 0) 
            ki->type = PKEY_ENCRYPTION;
        else if (strcmp(start, start_enc_skey) == 0) 
            ki->type = SKEY_ENCRYPTION;
        else {
            KERROR_SET(_kctl_, 1, "Incorrect key format.  Unknown key type in %s.\n", start);
            break;
        }

        /* Read the key ID. */
        s = apr_file_gets(key_id_str, sizeof(key_id_str), f);            
        if (s != APR_SUCCESS) {
            KERROR_SET_APR(_keys_, 0, s);
            break;
        }

        /* Check the key number. */
        if (sscanf(key_id_str, PRINTF_64"u", &ki->key_id) < 1) {
            KERROR_SET(_kctl_, 1, "Invalid number: %s\n", key_id_str);
            break;
        }
        
        /* Read the key owner. */
        s = apr_file_gets(owner_str, sizeof(owner_str), f);
        if (s != APR_SUCCESS) {
            KERROR_SET_APR(_keys_, 0, s);
            break;
        }

        sz = strlen(owner_str);
        ki->owner = apr_pmemdup(pool, owner_str, sz - 1);
        ki->owner_s = sz - 1;

        /* Loop until we find the end delimiter, removing newlines on the
           way. */
        s = apr_file_gets(key, sizeof(key), f);
        if (s != APR_SUCCESS) {
            KERROR_SET_APR(_keys_, 0, s);
            break;
        }
        do {
            sz = strlen(key);
            if (key[sz - 1] == '\n')
                kbuffer_write(key_buffer, (uint8_t *)key, sz - 1);
            else
                kbuffer_write(key_buffer, (uint8_t *)key, sz);

            s = apr_file_gets(key, sizeof(key), f);
            if (s != APR_SUCCESS) {
                KERROR_SET_APR(_keys_, 0, s);
                break;
            }

        } while (strncmp(key, "---", 3) != 0);

        /* Copy the content of the buffer. */
        ki->data = apr_pmemdup(pool, key_buffer->data, key_buffer->len);
        ki->data_s = key_buffer->len;
   
        r = 0;
    } while (0);

    kbuffer_destroy(key_buffer);

    /* We don't create the tagcrypt right now. */
    ki->key = NULL;

    return r;
}
Esempio n. 10
0
/* 
 * Passing NULL as the timestamp_pkey is a dirty hack to bypass
 * the signature verification. 
 *
 * This function does not, in fact, allocate anything on the pool, but
 * uses it to destroy the key.
 */
int kdkey_extract_signed_pkey(apr_pool_t *pool,
                              struct kdkey_info *tm_pkey,
                              const char *str_key,
                              size_t str_key_s,
                              struct kdkey_info *ki) {
    int error = -1;
    kbuffer *pkey_buffer;
    struct kdsh_tm_pkey_time tm_pkey_time[2];
    struct tagcrypt_signed_pkey *signed_pkey = NULL;
    int cur_key, old_key;
    struct timeval tm;
    tagcrypt_pkey *key;

    pkey_buffer = kbuffer_new();

    /* No locking is needed as we only want to store an approximate
       time. If there's a race, we'll still have an approximation of
       the time anyway. */

    do {
        cur_key = kdsh_get_cur_tm_pkey();
        old_key = !cur_key;

        kdsh_get_cur_tm_pkey_time(&tm_pkey_time[cur_key]);
        kdsh_get_old_tm_pkey_time(&tm_pkey_time[old_key]);

        kbuffer_write(pkey_buffer, (uint8_t *)str_key, str_key_s);
      
        if (tm_pkey == NULL) key = NULL; else key = tm_pkey->key;                                 
        if ((signed_pkey = tagcrypt_sign_get_pkey(pkey_buffer, key)) == NULL) {
            KERROR_SET(_keys_, 0, "cannot create public key from signed key");
            break;
        }

        if (tm_pkey == NULL && signed_pkey->mid != 0) {
            KERROR_SET(_keys_, 0, "invalid timestamp key for the signature");
            tagcrypt_signed_pkey_destroy(signed_pkey);
            break;
        }

        kdsh_get_timestamp(&tm);

        if (tm.tv_sec == 0 || tm.tv_sec - KSH_KEY_TIMEOUT <= signed_pkey->time.tv_sec) {
            if (tm_pkey != NULL) 
                tm.tv_sec = signed_pkey->time.tv_sec;
            
            ki->owner = KEY_OWNER;
            ki->owner_s = KEY_OWNER_S;
            ki->data = NULL;
            ki->data_s = 0;
            ki->key = signed_pkey->key;

            /* HACK: We should not free structure memory under the
               nose of tagcrypt that way. */
            kfree(signed_pkey);

            apr_pool_cleanup_register(pool, ki->key, 
                                      kdkey_destroy_pkey, kdkey_destroy_pkey);
        } 
        else {
            KERROR_SET(_keys_, 0, "received an outdated public key");
            tagcrypt_signed_pkey_destroy(signed_pkey);
        }
	
	error = 0;
    } while (0);

    if (error) {
        tagcrypt_signed_pkey_destroy(signed_pkey);
        signed_pkey = NULL;
    }

    kbuffer_destroy(pkey_buffer);

    return error;
}
Esempio n. 11
0
/* FIXME: This is a rather nasty possible failure point.  I have no
   idea how to test this. */
int kdkey_extract_tm_pkey(apr_pool_t *pool,
                          const char *str_key, 
                          size_t str_key_s, 
                          struct kdkey_info *ki) {
    int error = -1;
    struct kdsh_tm_pkey_time tm_pkey_time[2];
    struct tagcrypt_signed_pkey *tm_pkey_obj[2] = {NULL, NULL};
    struct tagcrypt_signed_pkey *signed_pkey;
    kbuffer *buf = kbuffer_new();
    int cur_key, old_key;
    
    /* TRY */
    do {
        kbuffer_write(buf, (uint8_t *)str_key, str_key_s);
        signed_pkey = tagcrypt_sign_get_pkey(buf, master_pkey_info.key);

        if (!signed_pkey) {
            KERROR_SET(_shared_, 0, "error getting the signed public timestamp key");
            break;
        }

        kdsh_lock();
        cur_key = kdsh_get_cur_tm_pkey();
        old_key = !cur_key;

        kdsh_get_cur_tm_pkey_time(&tm_pkey_time[cur_key]);
        kdsh_get_old_tm_pkey_time(&tm_pkey_time[old_key]);

        /* This is the first tm key we receive */
        if (tm_pkey_time[cur_key].status == 0) {
            if (kdsh_set_cur_tm_pkey_time(signed_pkey)) {
                KERROR_PUSH(_shared_, 0, "error saving new timestamp key");
                break;
            }
            kdsh_set_cur_tm_pkey_time(signed_pkey);
        }

        /* We are receiving the current key (Normal path) */
        else if (tm_pkey_time[cur_key].activation_time.tv_sec == signed_pkey->time.tv_sec) {
            struct timeval tv;
            /* Is there an old key ? */
            if (tm_pkey_time[old_key].status == 1) {
                if (gettimeofday(&tv, NULL) == -1) {
                    KERROR_SET(_shared_, 0, "could not gettimeofday: %s", strerror(errno));
                    break;
                }
                /* Flush it if it's too old */
                if (tm_pkey_time[cur_key].received_time.tv_sec + KSH_KEY_TIMEOUT < tv.tv_sec) {
                    tm_pkey_time[old_key].status = 0;
                    tagcrypt_signed_pkey_destroy(tm_pkey_obj[old_key]);
                }
            }

            /* Check if an instance of the current_key is available */
            if (tm_pkey_obj[cur_key] == NULL) { /* not in cache for this process */
                tm_pkey_obj[cur_key] = signed_pkey;
            } else {
                tagcrypt_signed_pkey_destroy(signed_pkey);
                signed_pkey = tm_pkey_obj[cur_key];
            }
        }

        /* We are receiving a new key for the first time */
        else if (tm_pkey_time[old_key].status == 0) {

            /* This new key is older than the current one */
            if (tm_pkey_time[cur_key].activation_time.tv_sec > signed_pkey->time.tv_sec) {
                KERROR_SET(_shared_, 0, "received an outdated timestamp key");
                break;
            }

            kdsh_switch_tm_pkey_time();
            cur_key = kdsh_get_cur_tm_pkey();
            old_key = !cur_key;

            kdsh_get_cur_tm_pkey_time(&tm_pkey_time[cur_key]);
            kdsh_get_old_tm_pkey_time(&tm_pkey_time[old_key]);

            if (kdsh_set_cur_tm_pkey_time(signed_pkey) < 0) {
                kdsh_switch_tm_pkey_time();
                KERROR_PUSH(_shared_, 0, "error saving new timestamp key");
                break;
            }
            tm_pkey_obj[cur_key] = signed_pkey;
        }

        /* We are receiving an old key, let's see if it's still valid. */
        else if (tm_pkey_time[old_key].activation_time.tv_sec == signed_pkey->time.tv_sec) {
            /* Check if an instance of the current_key is available */
            if (tm_pkey_obj[old_key] == NULL) { /* not in cache for this process */
                tm_pkey_obj[old_key] = signed_pkey;
            } else {
                tagcrypt_signed_pkey_destroy(signed_pkey);
                signed_pkey = tm_pkey_obj[old_key];
            }
        }
        /* This is an unknown old key */
        else 
            KERROR_SET(_shared_, 0, "received an outdated timestamp key");
	
	error = 0;

    } while (0);

    if (error) {
        tagcrypt_signed_pkey_destroy(signed_pkey);
        signed_pkey = NULL;
    } 
    else {
        ki->owner = KEY_OWNER;
        ki->owner_s = KEY_OWNER_S;
        ki->data = NULL;
        ki->data_s = 0;
        ki->key = signed_pkey->key;
        /* HACK: We should not free structures under the nose of
           tagcryp.t */
        kfree(signed_pkey);

        apr_pool_cleanup_register(pool, ki->key,
                                  kdkey_destroy_pkey, kdkey_destroy_pkey);
    }

    kdsh_unlock();
    kbuffer_destroy(buf);

    return error;
}
Esempio n. 12
0
/** Prepare the reply to an OTUT request. */
int otut_gen_otuts(apr_pool_t *pool, 
                   struct tagcrypt_ticket *ticket,
                   uint32_t otut_count,
                   uint32_t *otut_replies,
                   char ***otut_str,
                   size_t **otut_str_s) {
    size_t i;
    kbuffer *otut_str_buf;
    struct tagcrypt_otut otut;
    int nb_attempts;
    int nb_tries;

    /* Allocate the string array. */
    *otut_str = apr_pcalloc(pool, otut_count * sizeof(char *));
    *otut_str_s = apr_pcalloc(pool, otut_count * sizeof(size_t));

    /* Produce all the required OTUTs. */
    for (i = 0; i < otut_count; i++) {
	int error = -1;
	
        do {       
            /* Generate the OTUT string. */
            tagcrypt_otut_init(&otut);

            if (tagcrypt_gen_otut(ticket, &otut) < 0) {
                KERROR_SET(_otut_, 0, "failed to generate OTUT");
                tagcrypt_otut_clean(&otut);
                break;
            }

            otut_str_buf = kbuffer_new();
            tagcrypt_otut_serialize(&otut, otut_str_buf);
            
            /* Copy the newly serialized string locally. */
            (*otut_str)[i] = apr_pcalloc(pool, otut_str_buf->len);
            (*otut_str_s)[i] = otut_str_buf->len;
            memcpy((*otut_str)[i], otut_str_buf->data, (*otut_str_s)[i]);
            
            /* Store the OTUT string in the DB. */
            nb_attempts = otut_replies[i];
            nb_tries = OTUT_DEFAULT_ATTEMPTS * nb_attempts;

            if (kddb_otut_store((*otut_str)[i],
                                (*otut_str_s)[i],
                                ticket->mid,
                                nb_attempts, 
                                nb_tries) < 0) 
                KERROR_PUSH(_otut_, 0, "failed to store OTUT");            

            tagcrypt_otut_clean(&otut);
            kbuffer_destroy(otut_str_buf);
	    
	    error = 0;

        } while (0);                
	
	if (error) return -1;
    }

    return 0;
}
Esempio n. 13
0
int otut_gen_ticket(apr_pool_t *parent_pool,
                    struct kd_user *self, 
                    uint32_t nb_valid, 
                    const char *otut_addr, 
                    kbuffer *sign_buf) {    
    int error = -1;
    char *real_addr;
    kbuffer skey_buffer;
    kbuffer *otut_addr_buf = NULL;
    tagcrypt_skey *skey = NULL;
    int is_allowed;
    apr_pool_t *pool;
    int err;
    kstr str;

    /* Check if there is a key. */
    assert(self->sig_skey->key_id != 0);

    apr_pool_create(&pool, parent_pool);

    do {
        /* Make sure the OTUT address is an SMTP address. */
        if (otut_addr[0] != '/') real_addr = (char *)otut_addr;

        /* it's not? well, convert it. */
        else if (kddb_convert_address(pool, 
                                      otut_addr, 
                                      self->primary_email_addr, 
                                      &real_addr) < 0) {
            KERROR_PUSH(_db_, 0, "failed to convert %s to SMTP address.", otut_addr);
            break;
        } 

        /* Check if the user owns the address he is asking the user to
           answer to.  This disallows potential freebies. */
        if (kddb_is_email_allowed(pool, self, real_addr, &is_allowed, NULL) < 0) {
            KERROR_PUSH(_db_, 0, "failed to check if the email address is allowable");
            break;
        }            
        if (!is_allowed) {
            KERROR_SET(_db_, 0, "user is not allowed to request a ticket for the address %s", 
                               real_addr);
            break;
        }

        /* Put the key in a buffer. */
        kstr_init_cstr(&str, self->sig_skey->data);
        err = kbuffer_init_b64(&skey_buffer, &str);
        kstr_clean(&str);
        if (err != 0) {
            KERROR_PUSH(_db_, 0, "failed to convert the key to binary format from base64");
            kbuffer_clean(&skey_buffer);
            break;
        }
            
        /* Instanciate the private signature key. */    
        if ((skey = tagcrypt_skey_new(&skey_buffer)) == NULL) {
            KERROR_SET(_db_, 0, "failed to instanciate key");
            kbuffer_clean(&skey_buffer);
            break;
        }
        kbuffer_clean(&skey_buffer);
    
        /* Make a buffer for the address to keep tagcrypt happy. */
        otut_addr_buf = kbuffer_new();
        kbuffer_write(otut_addr_buf, (uint8_t *)real_addr, strlen(real_addr));
        
        /* Generate the ticket. */
        if (tagcrypt_gen_ticket(skey, nb_valid, otut_addr_buf, sign_buf) < 0) {
            KERROR_SET(_db_, 0, "failed to produce ticket");
            break;
        }
	
	error = 0;
	
    } while (0);

    /* Cleanup. */
    if (otut_addr_buf != NULL) kbuffer_destroy(otut_addr_buf);
    if (skey != NULL)          tagcrypt_skey_destroy(skey);

    return error;
}
Esempio n. 14
0
/* This function executes a server query. The function expects that the server
 * info have been set. Furthermore, it expects that there is something to do,
 * i.e. login and/or perform a query. If the function manages to login to the
 * server, the connection is not closed until the query is destroyed or the
 * connection is lost. It is possible to execute another query to the server by
 * calling knp_query_set_cmd() (still unimplemented since it's not needed ATM).
 * This function sets the KMO error string. It returns 0, -2, or -3.
 */
int knp_query_exec(struct knp_query *self, struct knp_proto *knp) {
    kmod_log_msg(3, "knp_query_exec() called.\n");

    assert(knp != NULL);
    assert(knp->k3p != NULL);
    assert(knp->k3p->state == K3P_INTERACTING);
    assert(knp->k3p->transfer.fd != -1);
    assert(knp->server_info != NULL);
    assert(self->transfer.fd == -1 || self->cmd_type);
    assert(self->res_type == 0);
    assert(self->res_payload == NULL);
    assert(self->serv_error_msg == NULL);
    
    int error = 0;
    uint32_t msg_type;
    
    /* The local payload is used to transfer the data of the messages. It may
     * eventually become the result payload of the query.
     */
    kbuffer *local_payload = kbuffer_new(1024);
    
    /* Set the operation timeout. */
    self->transfer.op_timeout = knp->timeout;

     /* Try. */
    do {
	/* If we're not connected, connect to the server. */
	if (self->transfer.fd == -1) {
    	    error = knp_query_connect(self, knp);
	    if (error) break;
	    
	    /* Do login. */
	    if (self->login_type != KNP_CMD_LOGIN_ANON) {
	    	
		/* Write the login message. */
		if (self->login_type == KNP_CMD_LOGIN_USER) {
	    	    knp_msg_write_kstr(local_payload, &knp->server_info->kps_login);
		    knp_msg_write_kstr(local_payload, &knp->server_info->kps_pwd);
		    knp_msg_write_uint32(local_payload, knp->server_info->encrypted_pwd_flag);
		}

		else {
	    	    assert(self->login_type == KNP_CMD_LOGIN_OTUT);
		    assert(self->login_otut != NULL);
		    knp_msg_write_kstr(local_payload, self->login_otut);
		}

		/* Send the login message. */
    		error = knp_query_send_msg(self, self->login_type, local_payload, knp->k3p);
		if (error) break;

		/* Receive the reply. */
		error = knp_query_recv_msg(self, &msg_type, local_payload, knp->k3p);
		if (error) break;

		/* Upgrade required. */
		if (msg_type == KNP_RES_UPGRADE_PLUGIN || msg_type == KNP_RES_UPGRADE_KPS) {
		    knp_query_disconnect(self);
		    self->res_type = msg_type;
		    error = 0;
		    break;
		}
		
		/* Login failed. There are two cases here. If we were only doing a login
		 * to the server, the result type is the error returned by the server.
		 * Otherwise, we set the result type to 'KNP_RES_LOGIN_ERROR', to allow
		 * the caller to distinguish between a login failure and the command
		 * failure. The semantics here are pretty messy :-/.
		 */
		if (msg_type != KNP_RES_LOGIN_OK) {
		    knp_query_disconnect(self);
		    
		    if (self->cmd_type)
		    	self->res_type = KNP_RES_LOGIN_ERROR;
		    else
		    	self->res_type = msg_type;
		    
		    error = -1;
		    break;
		}
		
		/* Assign the result message type and payload to the query. */
		self->res_type = msg_type;
		self->res_payload = local_payload;
	    }
	}
	
	/* If there is a command, process it. */
	if (self->cmd_type) {
	    assert(self->cmd_payload);
	    
	    /* Clear the result message type and payload, if any. */
	    self->res_type = 0;
	    self->res_payload = NULL;
	    
	    /* Send the command message. */
	    error = knp_query_send_msg(self, self->cmd_type, self->cmd_payload, knp->k3p);
	    if (error) break;

	    /* Receive the result. */
	    error = knp_query_recv_msg(self, &msg_type, local_payload, knp->k3p);
	    if (error) break;
	
	    /* Assign the result message type and payload to the query. */
	    self->res_type = msg_type;
	    self->res_payload = local_payload;
	}
	
    } while (0);
    
    /* A miscellaneous error occured. */
    if (error == -1) {
    	
	/* We did not handle the error yet. Convert it to a server error. */
    	if (! self->res_type) {
	    knp_query_handle_conn_error(self, KMO_SERROR_MISC);
	}
	
	/* It's handled. */
	error = 0;
    }
    
    /* Destroy the local buffer, if it did not become the result payload. */
    if (self->res_payload != local_payload)
    	kbuffer_destroy(local_payload);
    
    assert((self->res_type && ! error) || (! self->res_type && (error == -2 || error == -3)));
    return error;
}
Esempio n. 15
0
/** initialize an otut structure. */
int tagcrypt_otut_init(struct tagcrypt_otut *otut) {
    otut->addr = kbuffer_new(1);
    otut->data = kbuffer_new(1);

    return 0;
}
Esempio n. 16
0
int tagcrypt_ticket_init(struct tagcrypt_ticket * ticket) {
    ticket->otut_addr = kbuffer_new(256);
    return 0;
}