Exemple #1
0
Fichier : main.c Projet : tmbx/kas
/* This function should be called to log a message in the KMOD log.
 * Arguments:
 * Message logging level (1, 2, 3, 4) (higher number is lower priority).
 * Format is the usual printf() format, and the following args are the args that
 *   printf() takes.
 */
void kmod_log_msg(int level, const char *format, ...) {
    va_list arg;
    char date[256];
    kstr str, fmt;
    time_t now;

    if ((level & global_opts.log_level) != level) return;

    va_start(arg, format);

    kstr_init(&fmt);
    kstr_init(&str);

    time(&now);
    strftime(date, 256, "%Y/%m/%d %H:%M:%S", localtime(&now));

    kstr_sf(&fmt, "%s : %s", date, format);
    kstr_sfv(&str, fmt.data, arg);

    fprintf(global_opts.log_file, "%s", str.data);

    va_end(arg);
    kstr_clean(&str);
    kstr_clean(&fmt);
}
Exemple #2
0
/* This function normalizes a path. It simplifies the directory portion and
 * makes the path absolute if requested.
 */
void kpath_normalize(kstr *path, int absolute_flag, int format) {
    struct kpath_dir dir;
    kstr dir_path, filename, ext;
    
    kstr_init(&dir_path);
    kstr_init(&filename);
    kstr_init(&ext);
    kpath_dir_init(&dir);
    
    /* If requested, make the path absolute. */
    if (absolute_flag) kpath_make_absolute(path, format);
    
    /* Split the path. */
    kpath_split(path, &dir_path, &filename, &ext, format);
    
    /* Decompose, simplify and recompose the directory portion. */
    kpath_decompose_dir(&dir_path, &dir, format);
    kpath_simplify_dir(&dir);
    kpath_recompose_dir(&dir_path, &dir, format);
    
    /* Recompose the path. */
    kstr_assign_kstr(path, &dir_path);
    kstr_append_kstr(path, &filename);
    
    if (ext.slen) {
        kstr_append_char(path, '.');
        kstr_append_kstr(path, &ext);
    }
    
    kpath_dir_clean(&dir);
    kstr_clean(&dir_path);
    kstr_clean(&filename);
    kstr_clean(&ext);
}
Exemple #3
0
static void kdclient_log_very_internal(int is_err, 
                                       const char *file, 
                                       int line, 
                                       const char *log_channel,
                                       const char *msg, 
                                       va_list va) {
    struct kerror *error_instance = kerror_get_current();
    int i, level = (is_err ? LOG_ERR : LOG_WARNING);
    kstr err;
   
    kstr_init_sfv(&err, msg, va);     

    log_write_line(level, log_channel, file, line, "%s", err.data);

    if (error_instance->stack.size <= 0) {
        kstr_clean(&err);
        return;
    }
    
    if (is_err)
        log_write(level, log_channel, "*** Error stack ***");
    else
        log_write(level, log_channel, "*** Warning stack ***");

    for (i = 0; i < error_instance->stack.size; i++) {
        struct kerror_node *en = (struct kerror_node *)karray_get(&error_instance->stack, i);
        log_write(level, log_channel, "[%s:%d] %s", en->file, en->line, en->text.data);
    }

    log_write(level, log_channel, "*** End ***");

    kstr_clean(&err);
}
Exemple #4
0
static void kthread_specific_destroy(struct kthread_specific *self) {
    if (self) {
	kerror_clean(&self->error_stack);
	kstr_clean(&self->err_str);
	kfree(self);
    }
}
Exemple #5
0
/* Same as anp_dump(), but the header of the message is also dumped. */
int anp_msg_dump(struct anp_msg *self, kstr *dump_str) {
    int error = 0;
    kstr work_str;
    
    kstr_init(&work_str);
    kstr_reset(dump_str);

    kstr_sf(&work_str, "major> %u\n", self->major);
    kstr_append_kstr(dump_str, &work_str);

    kstr_sf(&work_str, "minor> %u\n", self->minor);
    kstr_append_kstr(dump_str, &work_str);

    kstr_sf(&work_str, "type> %u\n", self->minor);
    kstr_append_kstr(dump_str, &work_str);

    kstr_sf(&work_str, "id> "PRINTF_64"u\n", self->minor);
    kstr_append_kstr(dump_str, &work_str);

    if (anp_dump(&self->payload, &work_str)) {
        error = -1;
    } else {
        kstr_append_kstr(dump_str, &work_str);
    }

    kstr_clean(&work_str);
    return error;
}
Exemple #6
0
/** Tries to instanciate the key. 
 *
 * This call tagcrypt to instanciate a key.  This is useful to check
 * if the key was correctly loaded.
 * 
 * The object will be destroyed at pool destruction time.
 */
int kdkey_load_key(apr_pool_t *pool, struct kdkey_info *ki) {
    kbuffer key_data;
    kstr key_data_str;
    int r = -1;

    kstr_init_buf(&key_data_str, ki->data, ki->data_s);
    if (kbuffer_init_b64(&key_data, &key_data_str) < 0) {
        KERROR_SET(_keys_, 1, "failed to read key");
        return -1;
    }

    switch (ki->type) {
    case SKEY_ENCRYPTION:
    case SKEY_SIGNATURE:
        r = kdkey_load_skey(pool, &key_data, ki);
        break;
    case PKEY_ENCRYPTION:
    case PKEY_SIGNATURE:
        r = kdkey_load_pkey(pool, ki->type, &key_data, ki);
        break;
    default:
        KERROR_SET(_keys_, 1, "unknown key type");
        return -1;
    }

    kstr_clean(&key_data_str);
    kbuffer_clean(&key_data);

    return r;
}
Exemple #7
0
kstr *kdclient_format_error(const char *file, int line, const char *msg, va_list va) {
    char *p;
    kstr *err_msg, *err;
    kstr err_fmt;
    
    /* Search for @ */  
    p = strstr(msg, "@");
    if (p) {
        kstr_init_buf(&err_fmt, msg, p - msg);
        err_msg = kerror_str_n(0);        
        kstr_append_kstr(&err_fmt, err_msg);
        kstr_destroy(err_msg);
        kstr_append_cstr(&err_fmt, p + 1);
    } 
    else kstr_init_cstr(&err_fmt, msg);
    
    err = kmalloc(sizeof(kstr)); 
    kstr_init_sfv(err, err_fmt.data, va);  
    
    /* Add [file:line] before error message. */
    kstr_sf(&err_fmt, "[%s:%d] %s", file, line, err->data);
    kstr_assign_kstr(err, &err_fmt);
    
    kstr_clean(&err_fmt);

    return err;
}
Exemple #8
0
void kcd_client_destroy(struct kcd_client *self) {
    if (self) {
	ksock_close(&self->sock);
	kstr_clean(&self->addr);
	ktls_clean(&self->conn);
	kfree(self);
    }
}
Exemple #9
0
/* This function ensures that the string specified does not get too large. If
 * the internal memory associated to the string is bigger than the threshold
 * specified, the memory associated to the string is released and a new, small
 * buffer is allocated for the string. In all cases, the string is cleared.
 */
void kstr_shrink(kstr *self, int max_size) {
    if (self->slen > max_size) {
    	kstr_clean(self);
	kstr_init(self);
    }
    
    kstr_reset(self);
}
Exemple #10
0
/** Create a new unsigned public key.
 *
 * This is used to support older version of the key.  This does not
 * allocate anything on the pool but register a cleanup function to
 * remove the key.
 */
int kdkey_new_unsigned_pkey(apr_pool_t *pool, 
                            const char *pkey, 
                            size_t pkey_s, 
                            enum key_type ktype,
                            struct kdkey_info *ki) {
    tagcrypt_pkey *pk;
    kbuffer pkey_buf;
    int err = 0;
    kstr str;

    kstr_init_buf(&str, pkey, pkey_s);
    err = kbuffer_init_b64(&pkey_buf, &str);
    
    if (err != 0) {
        KERROR_SET(_keys_, 0, "cannot create public key");
        kstr_clean(&str);
        return -1;
    }
       
    do {
        pk = tagcrypt_pkey_new(&pkey_buf, ktype);
        if (pk == NULL) {
            KERROR_SET(_keys_, 0, "cannot create public key");
            err = -1;
            break;
        }

        ki->owner = KEY_OWNER;
        ki->owner_s = KEY_OWNER_S;
        ki->data = NULL;
        ki->data_s = 0;
        ki->key = pk;

        /* Register the key cleanup function. */
        apr_pool_cleanup_register(pool, pk, kdkey_destroy_pkey, kdkey_destroy_pkey);

    } while (0);

    kstr_clean(&str);
    kbuffer_clean(&pkey_buf);

    return err;
}
Exemple #11
0
/* Sign ki_in into ki_out, using signing_key. The buffered format of
   ki_in and ki_out does not match. */
int kdkey_sign_key(struct kdkey_info *ki_in, kbuffer *out, int for_enc_hack) {
    int err = -1;
    enum key_type type;
    kbuffer buf;
    tagcrypt_pkey *pkey_in = NULL;
    tagcrypt_skey *signing_key = NULL;

    type = kdkey_to_tagcrypt(ki_in->type);
    kstr str;

    /* TRY */
    do {
        /* put the key in a buffer */
        kstr_init_cstr(&str, ki_in->data);
        err = kbuffer_init_b64(&buf, &str);
        kstr_clean(&str);
        if (err) {
            err = -2;
            break;
        }
        err = -1;
        /* instanciate the key */
        pkey_in = tagcrypt_pkey_new(&buf, type);
        if (pkey_in == NULL)
            break;

        /* FIXME: ugly hack */
        if (for_enc_hack) signing_key = NULL;
        else {
            /* get the timestamp key */
            signing_key = tm_skey_info.key;
            if (signing_key == NULL)
                break;
        }
        /* sign the key */
        if (tagcrypt_sign_pkey(out, signing_key, pkey_in)) {
            KERROR_SET(_keys_, 0, "failed to sign key");
            break;
        }
        kbuffer_write8(out, '\0');
        
        err = 0;
    } while (0);
    
    if (err != -2) kbuffer_clean(&buf);
    tagcrypt_pkey_destroy (pkey_in);

    return err;
}
Exemple #12
0
/* This function converts a path to an absolute path, if needed. */
void kpath_make_absolute(kstr *path, int format) {
    kstr tmp;

    /* Return if the path is already absolute. */
    if (kpath_is_absolute(path, format)) return;
    
    kstr_init(&tmp);
    
    /* Get the current working directory and append the relative path to the
     * current working directory.
     */
    kpath_getcwd(&tmp);
    kstr_append_kstr(&tmp, path);
    kstr_assign_kstr(path, &tmp);
    
    kstr_clean(&tmp);
}
Exemple #13
0
/** Converts a DNS name to a domain DN.
 * 
 * Example: AD.LOCAL => DC=AD,DC=LOCAL.
 *
 * This is very much AD specific.  It won't work for Lotus Domino DNs.
 */
char *kdldap_DNS_to_dn(apr_pool_t *pool, const char *dns_dom) {
    kstr r;
    const char *s = dns_dom;
    char *dn;
    
    kstr_init_cstr(&r, "DC=");
    
    while (*s) {
        if (*s == '.') kstr_append_cstr(&r, ",DC=");
        else kstr_append_char(&r, *s);
        s++;
    }
    
    dn = apr_pstrdup(pool, r.data);
    kstr_clean(&r);
    
    return dn;
}
Exemple #14
0
/* Replace all occurences of the string 'from' with the string 'to' in the
 * string specified.
 */
void kstr_replace(kstr *self, char *from, char *to) {
    kstr tmp;
    int i = 0;
    int l = strlen(from);
    
    assert(l);
    kstr_init(&tmp);
    
    while (i < self->slen) {
        if (! strncmp(self->data + i, from, l)) {
            kstr_append_cstr(&tmp, to);
            i += l;
        }
        
        else {
            kstr_append_char(&tmp, self->data[i]);
            i++;
        }
    }
    
    kstr_assign_kstr(self, &tmp);
    kstr_clean(&tmp);
}
Exemple #15
0
Fichier : main.c Projet : tmbx/kas
static void kdaemon_clean() {
    kstr_clean(&global_opts.ssl_cert_path);
}
Exemple #16
0
void kpath_dir_clean(struct kpath_dir *self) {
    kpath_dir_reset(self);
    kstr_clean(&self->abs_part);
    karray_clean(&self->components);
}
Exemple #17
0
/** Return an ordinary key object.  Returns -1 on error, 0 on missing
    key, and 1 on success. */
int kdkey_get_key(apr_pool_t *pool, 
                  uint64_t key_id, 
                  enum kdkey_type ktype, 
                  struct kdkey_info **ki) {
    kbuffer buf;
    enum key_type type;
    kstr str;
    int err = 0;
    
    assert((ktype > SKEY_START && ktype < SKEY_END) ||
           (ktype > PKEY_START && ktype < PKEY_END));

    switch (ktype) {
        /* Those go through the database object. */
    case SKEY_ENCRYPTION:
    case SKEY_SIGNATURE:
    case PKEY_ENCRYPTION:
    case PKEY_SIGNATURE:
        err = kddb_fetch_key(pool, key_id, ktype, ki);
        /* Key fetch error. */
        if (err < 0) {
            KERROR_PUSH(_keys_, 0, "failed to fetch key "PRINTF_64"u", key_id);
            err = -1;
            break;
        }
        /* Key not found. */
        if (err == 0) return 0;

        type = kdkey_to_tagcrypt(ktype);
        kstr_init_buf(&str, (*ki)->data, (*ki)->data_s);
        err = kbuffer_init_b64(&buf, &str);
        kstr_clean(&str);

        if (err) break;

        if (ktype == SKEY_ENCRYPTION || ktype == SKEY_SIGNATURE) {
            (*ki)->key = tagcrypt_skey_new(&buf);        

            if ((*ki)->key == NULL) {
                KERROR_SET(_keys_, 0, "ill-formed secret key in database");
                err = -1;
                break;
            }

            /* Check for inconsistent key ID. */
            if (((tagcrypt_skey *)(*ki)->key)->keyid != (*ki)->key_id) {
                KERROR_SET(_keys_, 0, 
                           "ill-formed key, internal key ID: "PRINTF_64"u, external key ID: "PRINTF_64"u", 
                           ((tagcrypt_skey *)(*ki)->key)->keyid, (*ki)->key_id);
                err = -1;
                break;
            }

            /* Register memory cleanup function. */
            if ((*ki)->key != NULL)
                apr_pool_cleanup_register(pool, (*ki)->key, kdkey_destroy_skey, kdkey_destroy_skey);
        } 
        else if (ktype == PKEY_ENCRYPTION || ktype == PKEY_SIGNATURE) {
            (*ki)->key = tagcrypt_pkey_new(&buf, type);        

            if ((*ki)->key == NULL) {
                KERROR_SET(_keys_, 0, "ill-formed public key in database");
                err = -1;
                break;
            }

            /* Check for inconsistent key ID. */
            if (((tagcrypt_pkey *)(*ki)->key)->keyid != (*ki)->key_id) {
                KERROR_SET(_keys_, 0, 
                           "ill-formed key, internal key ID: "PRINTF_64"u, external key ID: "PRINTF_64"u", 
                           ((tagcrypt_pkey *)(*ki)->key)->keyid, (*ki)->key_id);
                err = -1;
                break;
            }
            
            /* Register memory cleanup function. */
            if ((*ki)->key != NULL)
                apr_pool_cleanup_register(pool, (*ki)->key, kdkey_destroy_pkey, kdkey_destroy_pkey);
        }

        if ((*ki)->key == NULL) {
            err = -1;
            KERROR_SET(_keys_, 0, "failed to create key "PRINTF_64"u", key_id);
        }

        kbuffer_clean(&buf);
        err = 1;
        break;

    case PKEY_TIMESTAMP:
        *ki = &tm_pkey_info;
        break;

    case PKEY_LICENSE:
        *ki = &license_pkey_info;
        break;

#ifdef REQUEST_GETSIG
    case SKEY_TIMESTAMP:
        *ki = &tm_skey_info;
        break;

#endif // REQUEST_GETSIG

    default:
        abort();
    }
    
    return err;
}
Exemple #18
0
/* This function starts the VNC session. */
int kcd_vnc_start_session(struct kcd_ticket_mode_state *tms) {
    int error = 0;
    struct kcd_vnc_mode_state vms;
    kstr subject;
    kbuffer *kbb = &tms->kws_bound_buf, *in_buf = &tms->aq.input_buf, *out_buf = &tms->aq.output_buf;
    
    kcd_vnc_mode_state_init(&vms, tms);
    kstr_init(&subject);
    
    do {
        /* Check the right to start/join a VNC session. */
        error = kcd_vnc_check_right(tms);
        if (error) break;
        
        /* Get the extra information from the command. */
        if (anp_read_kstr(&tms->in_msg->payload, &subject)) {
            error = -2;
            break;
        }
        
	/* Start the proxy server. */
	error = kcd_vnc_start_proxy(&vms);
	if (error) break;
        
        /* Start the session in Postgres. This has to be done after the proxy
         * has been started so that the session does not get collected early.
         */
        anp_write_kstr(kbb, &subject);
        anp_write_uint32(kbb, vms.proxy_port);
        error = kcd_ticket_mode_kws_bound_query(tms, "start_vnc", ktime_now_sec(), NULL);
        if (error) break;
        
        error = anp_read_uint64(out_buf, &vms.session_id);
        if (error) break;
	
	/* Send the "OK" to the client. */
        kcd_ticket_mode_new_out_msg(tms, KANP_RES_OK);
        
        if (tms->client->effective_minor > 2) {
            tms->out_msg->type = KANP_RES_VNC_START_SESSION;
            anp_write_uint64(&tms->out_msg->payload, vms.session_id);
        }
	    
        error = kcd_ticket_mode_send_msg(tms);
	if (error) break;
	
	/* Loop communicating with the proxy. */
	error = kcd_vnc_proxy_comm_loop(&vms);
	if (error) break;
        
        /* Terminate the session. */
        anp_write_uint64(in_buf, tms->kws_id);
        anp_write_uint32(in_buf, tms->user_id);
        anp_write_uint64(in_buf, vms.session_id);
        anp_write_uint32(in_buf, tms->client->effective_minor >= 5 ? 5 : 2);
        anp_write_uint32(in_buf, vms.end_error_code);
        anp_write_kstr(in_buf, &vms.end_error_msg);
        error = kcd_exec_safe_pg_anp_query(&tms->db_conn, &tms->aq, "end_vnc");
        if (error) break;
    
    } while (0);
    
    /* Kill and collect the proxy server. */
    if (error != -1) {
        if (kcd_process_kill_and_collect(&vms.process)) {
            error = -1;
        }
    }
    
    /* Log the proxy output. */
    kcd_process_log_output(&vms.process, 1, 1);
    
    kcd_vnc_mode_state_clean(&vms);
    kstr_clean(&subject);
    
    return error;
}
Exemple #19
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;
}
Exemple #20
0
void kstr_destroy(kstr *str) {
    kstr_clean(str);
    kfree(str);
}
Exemple #21
0
/* This function decomposes the directory path specified into an array of
 * subcomponents. If the path is absolute, the absolute part will be something
 * like 'C:\' on Windows and '/' on UNIX, otherwise it will be empty. The
 * remaining components will not contain delimiters.
 *
 * The path 'C:/toto/bar' will yield ('C:\', 'toto', 'bar') on Windows with alt
 * support.
 * The path '/toto/bar/' will yield ('/', 'toto', 'bar') on UNIX.
 * The path './../foo/' will yield ('.', '..', 'foo').
 * The path '' will yield ().
 */
void kpath_decompose_dir(kstr *path, struct kpath_dir *dir, int format) {
    int scan_pos = 0;
    kstr cur_component;
    
    /* Get the platform format. */
    int platform_format = kpath_get_platform_format(format);
    
    /* Determine if the path is absolute. */
    int is_absolute = kpath_is_absolute(path, format);
    
    kstr_init(&cur_component);
    kpath_dir_reset(dir);
    
    /* If the path is absolute, obtain the absolute part. */
    if (is_absolute) {
    
        if (platform_format == KPATH_FORMAT_UNIX) {
            kstr_append_char(&dir->abs_part, '/');
            scan_pos = 1;
        }
        
        else {
            kstr_append_buf(&dir->abs_part, path->data, 2);
            kstr_append_char(&dir->abs_part, kpath_delim(format));
            scan_pos = 3;
        }
    }
    
    /* Scan the rest of the path. */
    while (scan_pos < path->slen) {
        
        /* We encountered a delimiter. */
        if (kpath_is_delim(path->data[scan_pos], format)) {
            
            /* If the current component is empty, ignore it. Otherwise, add the
             * component in the component array.
             */
            if (cur_component.slen) {
                kstr *s = kstr_new();
                kstr_assign_kstr(s, &cur_component);
                karray_push(&dir->components, s);
            }
            
            /* Reset the current component. */
            kstr_reset(&cur_component);
        }
        
        /* Append the current character. */
        else kstr_append_char(&cur_component, path->data[scan_pos]);
        
        scan_pos++;
    }
    
    /* Add the last component, if any, in the component array. */
    if (cur_component.slen) {
        kstr *s = kstr_new();
        kstr_assign_kstr(s, &cur_component);
        karray_push(&dir->components, s);
    }
    
    kstr_clean(&cur_component);
}
Exemple #22
0
/* This function handles a connection in VNC proxy mode. */
static int kcd_frontend_handle_vnc(struct kcd_client *client) {
    int error = 0;
    int proxy_sock = -1;
    char begin_string[KCD_VNC_BEGIN_STRING_LENGTH + 1];
    kstr cred_path;
    
    kdaemon_set_task("VNC proxy | %s", client->addr.data);
    kmod_log_msg(KCD_LOG_BRIEF, "kcd_frontend_handle_vnc() called.\n");
    
    assert(strlen(KCD_VNC_TEST_KCD_VNC_BEGIN_STRING) == KCD_VNC_BEGIN_STRING_LENGTH);
    
    begin_string[KCD_VNC_BEGIN_STRING_LENGTH] = 0;
    kstr_init(&cred_path);
    
    do {
        int port;
        
        if (!global_opts.vnc_mode) {
            kmod_set_error("VNC proxy mode disabled");
            error = -1;
            break;
        }
        
        /* Receive the file name. */
        error = kcd_frontend_tls_xfer(&client->conn, begin_string, KCD_VNC_BEGIN_STRING_LENGTH, 1);
        if (error) break;

        /* This is a test. */
        if (! strncmp(begin_string, KCD_VNC_TEST_KCD_VNC_BEGIN_STRING, KCD_VNC_BEGIN_STRING_LENGTH)) {
            kmod_log_msg(KCD_LOG_MISC, "kcd_proxy_handle_vnc(): test connection.\n");
            error = kcd_frontend_tls_xfer(&client->conn, KCD_VNC_TEST_RESPONSE, KCD_VNC_TEST_RESPONSE_LENGTH, 0);
            if (error) break;
        }
        
        /* This is a genuine VNC connection. */
        else {
            
            /* 'begin_string' is a credential file. */
            char *file_name = begin_string;

            /* Check if that file exists. */
            kstr_sf(&cred_path, "%s/%s", global_opts.vnc_cred_path.data, file_name);
        
            if (! kfs_regular(cred_path.data)) {
                kmod_set_error("credential file %s does not exist", file_name);
                error = -1;
                break;
            }
        
            /* Get the port. */
            port = atoi(file_name + KCD_VNC_PORT_OFFSET);
        
            /* Note: don't delete the credential file, IE sucks and connects
             * twice.
             */
        
            /* Connect to the VNC proxy. */
            error = kproxy_connect_tcp(&proxy_sock, global_opts.kcd_host.data, port);
            if (error) break;
        
            /* Loop within the proxy. */
            error = kcd_frontend_proxy_loop(&client->conn, proxy_sock, "VNC proxy");
            if (error) break;
        }
        
    } while (0);
    
    ksock_close(&proxy_sock);
    kstr_clean(&cred_path); 
    
    return error;
}
Exemple #23
0
static void kcd_vnc_mode_state_clean(struct kcd_vnc_mode_state *self) {
    ksock_close(&self->proxy_sock);
    kstr_clean(&self->end_error_msg);
    kcd_process_clean(&self->process);
}
Exemple #24
0
/* MAIN entry point */
int main(int argc, char *argv[]) {
    int i, n, ret = 0;
    int config_loop;
    int verbosity;
    int detach;
    kstr *err_msg;
    struct kdsignal_info sigs[] = { {SIGALRM, kd_SIGALRM_handler },
                                    {SIGINT,  kd_SIGINT_handler  },
                                    {SIGTERM, kd_SIGTERM_handler },
                                    {SIGCHLD, kd_SIGCHLD_handler },
                                    {SIGUSR1, kd_SIGUSR1_handler },
                                    {SIGHUP,  kd_SIGHUP_handler  } };
    int ignored_sigs[] = {SIGPIPE, 0};
    apr_pool_t *server_pool;

    printf("Teambox Sign-On Server daemon\n");
    printf("Copyright (C) 2006-2012 Opersys inc.\n\n");

    ktools_initialize();
    kmem_set_handler(NULL, NULL, NULL, NULL, kd_abort_handler, NULL);

    /* Configuration and option setup.
       1 - Load the internal defaults.  They have the least priority.
       2 - Load the configuration file.
       3 - Load the command line options, overriding 2 and 1. */

    /* Initializes APR. */
    apr_initialize();
    apr_pool_create(&main_pool, NULL);

    /* Configuration. */
    do {
        log_open(main_pool);
        log_set_all_level("syslog", 0);

        if (options_load(main_pool, 
                         opts_tbl, 
                         opts_tbl_cnt, 
                         CONFIG_PATH "/tbxsosd.conf",
                         kd_options_error_handler,
                         0) < 0) {
	    kstr str;
	    kstr_init(&str);
	    format_current_error_for_user(&str);
	    fprintf(stderr, "config read error: %s.\n", str.data);
	    kstr_clean(&str);
            break;
        }

        kd_init_logging();

        /* Command line stuff. */
        if (kd_options_parse(argc, argv) < 0) {
            ret = -1;
            break;
        }      

        /* Load options for local use.  No need to check the return
           value since the values should have been set earlier when
           parsing the command line. */
        detach = options_get_bool("server.detach");
        verbosity = options_get_uint32("server.log_verbosity");

        log_set_verbosity(verbosity);

        /* Proceed to static initialization of modules. */
        if (kdssl_static_init(main_pool) < 0) {
            kd_dump_error();
            err_msg = kerror_str_n(0);
            CRITICAL(_log_server_, "SSL initialization failed: %s.", err_msg->data);
            kstr_destroy(err_msg);
            ret = -1;
            break;
        }        
        if (kdclient_static_init(main_pool) < 0) {
            kd_dump_error();
            err_msg = kerror_str_n(0);
            ERROR(_log_server_, "Basic initialization failed: %s", err_msg->data);
            kstr_destroy(err_msg);
            ret = -1;
            break;
        }
        if (kdkey_static_init() < 0) {
            kd_dump_error();
            err_msg = kerror_str_n(0);
            ERROR(_log_server_, "Basic initialization failed: %s", err_msg->data);
            kstr_destroy(err_msg);
            ret = -1;
            break;
        }
   
        /* Spawn the master process. */
        if (detach && kd_spawn(main_pool) == 0) break;        

        kdsignal_handled(sizeof(sigs) / sizeof(struct kdsignal_info), sigs);
        kdsignal_ignored(ignored_sigs);

        apr_pool_create(&server_pool, main_pool);
        
        /* Block all signals we say we are handling since it's the job
           of the server object to handle them. */
        kdsignal_block_all_handled();

        /* Create the new server object. */
        if ((server = kdserver_new(server_pool)) == NULL) {
            kd_dump_error();
            err_msg = kerror_str_n(0);
            CRITICAL(_log_server_, "Error initializing the server: %s", err_msg->data);
            kstr_destroy(err_msg);
            ret = -1;
            break;
        }        
           
        /* At this point, the expected behavior in signal handling can
           resume. */
        kdsignal_unblock_all_handled();

        for (i = 0; i < server->ssl_sock_count; i++)
            INFO(_log_server_, "Listening for SSL on %s:%ld.",
                 inet_ntoa(server->ssl_sock_addr[i]->sin_addr),
                 ntohs(server->ssl_sock_addr[i]->sin_port));
        for (i = 0; i < server->n_sock_count; i++)
            INFO(_log_server_, "Listening on %s:%ld.",
                 inet_ntoa(server->n_sock_addr[i]->sin_addr),
                 ntohs(server->n_sock_addr[i]->sin_port));

        /* Loop in the server.  This will block until the server
           quits. */
        config_loop = 1;
        while (config_loop && !ret) {
            n = kdserver_main(server, main_pool);

            if (n < 0) {
                err_msg = kerror_str_n(0);
                CRITICAL(_log_server_, "Server error: %s", err_msg->data);
		kstr_destroy(err_msg);
                ret = - 1;
                break;
            } 
            /* Reloading configuration was demanded. */
            else if (n == 0 && server->sig_flag & FLAG_REHASH) {
                INFO(_log_server_, "Reloading configuration.");

                /* Get rid of this block. */
                kdsignal_block_all_handled();

                apr_pool_destroy(server_pool);
                server = NULL;

                kdsignal_unblock_all_handled();

                if (options_reload(main_pool, CONFIG_PATH "/tbxsosd.conf") < 0) {
                    kd_dump_error();
                    CRITICAL(_log_server_, "config read error");
                    ret = -1;
                }
               
                if (kdclient_static_init(main_pool) < 0) {
                    kd_dump_error();
                    err_msg = kerror_str_n(0);
                    CRITICAL(_log_server_, "Basic initialization failed: %s", err_msg->data);
                    kstr_destroy(err_msg);
                    ret = -1;
                }    

                apr_pool_create(&server_pool, main_pool);

                /* Block all signals we say we are handling since it's the job
                   of the server object to handle them. */
                kdsignal_block_all_handled();

                /* Create the new server object. */
                if ((server = kdserver_new(server_pool)) == NULL) {
                    kd_dump_error();
                    err_msg = kerror_str_n(0);
                    CRITICAL(_log_server_, "Error initializing the server: %s", err_msg->data);
                    kstr_destroy(err_msg);
                    ret = -1;
                    break;
                }        
           
                /* At this point, the expected behavior in signal handling can
                   resume. */
                kdsignal_unblock_all_handled();
            }
            /* Clean quit. */
            else if (n == 0) {
                INFO(_log_server_, "Server terminating.");
                config_loop = 0;
            }
        }

    } while (0);

    kdkey_static_clean();

    apr_pool_destroy(main_pool);

    apr_terminate();    
    ktools_finalize();

    return ret;
}
Exemple #25
0
/* This function dumps the content of a ANP message buffer in the string
 * specified. This function sets the KMOD error string when it encounters an
 * error in the buffer. It returns -1 on failure.
 */
int anp_dump(kbuffer *buf, kstr *dump_str) {
    int error = 0;
    kstr work_str;
    kstr data_str;
    kbuffer bin_buf;
    
    kstr_init(&work_str);
    kstr_init(&data_str);
    kbuffer_init(&bin_buf);
    kstr_reset(dump_str);

    while (! kbuffer_eof(buf)) {
	uint8_t type = buf->data[buf->pos];
	
	if (type == ANP_UINT32) {
	    uint32_t val;
	    error = anp_read_uint32(buf, &val);
	    if (error) break;
	    
	    kstr_sf(&work_str, "uint32> %u\n", val);
	    kstr_append_kstr(dump_str, &work_str);
	}
	
	else if (type == ANP_UINT64) {
	    uint64_t val;
	    error = anp_read_uint64(buf, &val);
	    if (error) break;
	    
	    kstr_sf(&work_str, "uint64> "PRINTF_64"u\n", val);
	    kstr_append_kstr(dump_str, &work_str);
	}
	
	else if (type == ANP_STR) {
	    error = anp_read_kstr(buf, &data_str);
	    if (error) break;
	
	    kstr_sf(&work_str, "string %u> ", data_str.slen);
	    kstr_append_kstr(dump_str, &work_str);
	    kstr_append_kstr(dump_str, &data_str);
	    kstr_append_cstr(dump_str, "\n");
	}
	
	else if (type == ANP_BIN) {
	    error = anp_read_bin(buf, &bin_buf);
	    if (error) break;
	
	    kstr_sf(&work_str, "binary %u> ", bin_buf.len);
	    kstr_append_kstr(dump_str, &work_str);
	    kstr_append_cstr(dump_str, "\n");
	}
	
	else {
	    kmod_set_error("invalid ANP identifier (%u)\n", type);
	    error = -1;
	    break;
	}
    }
    
    kstr_clean(&work_str);
    kstr_clean(&data_str);
    kbuffer_clean(&bin_buf);
    
    /* Reset the buffer position to 0. */
    buf->pos = 0;
    
    return error;
}
Exemple #26
0
/** Initialize common data for the kdkey object. */
int kdkey_static_init() {
    kbuffer buf, mk_buf, lk_buf;
    kstr str;
    int err;

    master_pkey_info.data = master_pkey_str;
    master_pkey_info.data_s = strlen(master_pkey_str);

    license_pkey_info.data = license_pkey_str;
    license_pkey_info.data_s = strlen(license_pkey_str);

    do {
        /* Load the master public key. */
        kstr_init_cstr(&str, master_pkey_str);
        kbuffer_init_b64(&mk_buf, &str);
        kstr_clean(&str);
        master_pkey_info.key = tagcrypt_pkey_new(&mk_buf, KEY_TYPE_MASTER);

        /* Load the license public key. */
        kstr_init_cstr(&str, license_pkey_str);
        kbuffer_init_b64(&lk_buf, &str);
        kstr_clean(&str);
        license_pkey_info.key = tagcrypt_pkey_new(&lk_buf, KEY_TYPE_MASTER);

        kbuffer_clean(&lk_buf);
        kbuffer_clean(&mk_buf);

#ifdef REQUEST_GETSIG
        tm_pkey_str = options_get_str("keysign.public");
        tm_skey_str = options_get_str("keysign.private");

        tm_pkey_info.data = tm_pkey_str;
        tm_pkey_info.data_s = strlen(tm_pkey_str);
        tm_skey_info.data = tm_skey_str;
        tm_skey_info.data_s = strlen(tm_skey_str);

        kstr_init_buf(&str, tm_skey_info.data, tm_skey_info.data_s);
        err = kbuffer_init_b64(&buf, &str);
        kstr_clean(&str);
        if (err) {
            KERROR_SET(_keys_, 0, "cannot convert the secret key from base64 to binary");
            break;
        }
        else
            /* FIXME: I believe this is actually a bug in libktools.
               Errors are pushed by libktools even where there is no
               returned errors. */
            kerror_reset();

        tm_skey_info.key = tagcrypt_skey_new(&buf);
        kbuffer_clean(&buf);

        if (tm_skey_info.key == NULL) {
            KERROR_SET(_keys_, 0, "cannot create internal timestamp key object");
            err = -1;
            break;
        }
#endif // REQUEST_GETSIG

        /* Cleans libktools error. */
        kerror_reset();
        err = 0;

    } while (0);

    return err ? -1 : 0;
}