Пример #1
0
void kmocrypt_get_kpg_host2(struct kmocrypt_signature2 *self, kstr *addr, int *port) {
    struct kpg_data *kpg = (struct kpg_data *) self->subpacket_array[KMO_SP_TYPE_KPG]->data;
    if (kpg->type == 0) {
	kstr_assign_kstr(addr, &kpg->addr);
	*port = kpg->port;
    }
}
Пример #2
0
static void test_kstr() {
    kstr str1, str2, str3;
    kstr_init(&str1);
    kstr_init_cstr(&str2, "bar");
    kstr_init_kstr(&str3, &str2);

    assert(kstr_equal_cstr(&str2, "bar"));
    assert(kstr_equal_kstr(&str2, &str3));

    kstr_assign_cstr(&str3, "foobar");
    kstr_assign_kstr(&str1, &str3);
    kstr_sf(&str2, "%sbar", "foo");
    
    assert(kstr_equal_kstr(&str3, &str2));
    assert(kstr_equal_kstr(&str1, &str2));

    kstr_sf(&str2, "%s buffer to grow", "I want my");
    assert(kstr_equal_cstr(&str2, "I want my buffer to grow"));

    kstr_clear(&str2);
    assert(kstr_equal_cstr(&str2, ""));
    
    kstr_append_char(&str2, 'f');
    kstr_append_char(&str2, 'o');
    kstr_assign_cstr(&str1, "ob");
    kstr_append_kstr(&str2, &str1);
    kstr_append_cstr(&str2, "ar");
    assert(kstr_equal_cstr(&str2, "foobar"));

    kstr_free(&str1);
    kstr_free(&str2);
    kstr_free(&str3);
}
Пример #3
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;
}
Пример #4
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);
}
Пример #5
0
void anp_msg_write_kstr(struct anp_msg *self, kstr *str) {
    struct anp_element *el = anp_element_new();
    el->type = ANP_STR;
    el->str = kstr_new();
    kstr_assign_kstr(el->str, str);
    karray_push(&self->element_array, el);
    anp_write_kstr(&self->payload, el->str);
}
Пример #6
0
void kmo_seterror(const char *format, ...) {
    /* Make the sprintf(). */
    va_list arg;
    va_start(arg, format);
    kstr_sfv(&kmo_scratch_str, format, arg);
    va_end(arg);
    
    /* Set the error string. */
    kstr_assign_kstr(&kmo_error_str, &kmo_scratch_str);
}
Пример #7
0
/* This function handles a connection error that occurred while processing a
 * query. Normally the connection error message should have been set by 
 * kmo_seterror(). The KNP connection is closed if it is open.
 */
static void knp_query_handle_conn_error(struct knp_query *query, int serv_error_id) {
    kmod_log_msg(3, "knp_query_handle_conn_error() called.\n");
    
    assert(! query->res_type && query->res_payload == NULL);
    query->res_type = KNP_RES_SERV_ERROR;
    query->serv_error_id = serv_error_id;
    query->serv_error_msg = kstr_new();
    kstr_assign_kstr(query->serv_error_msg, kmo_kstrerror());
    knp_query_disconnect(query);
}
Пример #8
0
/* This function recomposes a directory path from its subcomponents. If the
 * directory path has no absolute part and no other components, the directory
 * path will be empty. Otherwise, the directory path will end with a delimiter.
 */
void kpath_recompose_dir(kstr *path, struct kpath_dir *dir, int format) {
    int i;
    
    kstr_reset(path);
    
    if (dir->abs_part.slen) kstr_assign_kstr(path, &dir->abs_part);
    
    for (i = 0; i < dir->components.size; i++) {
        kstr_append_kstr(path, (kstr *) dir->components.data[i]);
        kstr_append_char(path, kpath_delim(format));
    }
}
Пример #9
0
/* This function creates and initializes a KNP query.
 * The login OTUT must be set manually if it's needed.
 */
struct knp_query * knp_query_new(int contact, int login_type, int cmd_type, kbuffer *cmd_payload,
                                 kstr *all_req_str) {
    struct knp_query *query = (struct knp_query *) kmo_calloc(sizeof(struct knp_query));
    query->contact = contact;
    kstr_init(&query->server_addr);
    query->login_type = login_type;
    query->cmd_type = cmd_type;
    query->cmd_payload = cmd_payload;
    kmo_data_transfer_init(&query->transfer);
    query->transfer.driver = kmo_sock_driver;
    kstr_assign_kstr(&query->all_req_str, all_req_str);

    return query;
}
Пример #10
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);
}
Пример #11
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);
}
Пример #12
0
void kmo_setkerror(kstr *str) {
    kstr_assign_kstr(&kmo_error_str, str);
}
Пример #13
0
/* This function loops communicating with the proxy. It returns 0 or -1. */
static int kcd_vnc_proxy_comm_loop(struct kcd_vnc_mode_state *vms) {
    int error = 0;
    struct kcd_ticket_mode_state *tms = vms->tms;
    struct kcd_client *client = tms->client;
    struct kproxy_end client_end, proxy_end;
    
    /* select() doesn't like huge values for time. */
    int64_t deadline = ktime_set_deadline(MIN(tms->license_info.vnc_session_time * 1000llu, 10*24*60*60*1000llu));
    int64_t remaining;
    
    kmod_log_msg(KCD_LOG_BRIEF, "kcd_vnc_proxy_comm_loop() called.\n");
        
    kproxy_end_init(&client_end, client->sock, &client->conn, "client", TRANS_BUF_SIZE);
    kproxy_end_init(&proxy_end, vms->proxy_sock, NULL, "proxy", TRANS_BUF_SIZE);
    
    do {
        /* Receive the initial synchronization byte. */
        kmod_log_msg(KCD_LOG_VNC, "kcd_vnc_proxy_comm_loop: receiving sync byte.\n");
         
        while (1) {
            char byte;
            
            int r = ktls_recv(&client->conn, &byte, 1);
            if (r == 1) break;
            if (r == -1) { error = -4; break; }
            
            kcd_ticket_mode_prepare_wait(tms);
	    kselect_add_read(&tms->sel, client->sock);
            error = kcd_ticket_mode_wait(tms, -1);
	    if (error) break;
        }
        
        if (error) break;
        
        /* Enter the proxy loop. */
        kmod_log_msg(KCD_LOG_VNC, "kcd_vnc_proxy_comm_loop: entering proxy loop.\n");
        
        while (1) {
            
            /* Transfer data as required. */
            kproxy_do_xfer(&client_end, &proxy_end, NULL);
            kcd_process_do_xfer(&vms->process);
            
            /* At least one side of the connection was lost, check if we're done. */
            if (kproxy_is_finished(&client_end, &proxy_end)) {
                error = -4;
                break;
            }
            
            /* Check deadline, compute remaining. */
            if (ktime_check_deadline(deadline, &remaining)) {
                error = -4;
                kmod_set_error("maximum screen sharing session time reached");
                vms->end_error_code = KANP_RES_FAIL_RESOURCE_QUOTA;
                kstr_assign_kstr(&vms->end_error_msg, kmod_kstrerror());
                break;
            }
            
            /* Block in select. */
            kcd_ticket_mode_prepare_wait(tms);
            kproxy_prepare_select(&tms->sel, &client_end, &proxy_end);
            kcd_process_prepare_select(&vms->process, &tms->sel);
            
            kmod_log_msg(KCD_LOG_VNC, "kproxy_loop: about to wait in select().\n");
            error = kcd_ticket_mode_wait(tms, remaining);
            kmod_log_msg(KCD_LOG_VNC, "kproxy_loop: out of select().\n");
            if (error) break;
        }
        
        if (error) break;
        
    } while (0);
    
    kmod_log_msg(KCD_LOG_BRIEF, "kcd_vnc_proxy_comm_loop(): exiting: %s.\n", kmod_strerror());
        
    kproxy_end_clean(&client_end);
    kproxy_end_clean(&proxy_end);
    
    if (error == -4) {
        
        /* Set a generic end error code and message. */
        if (!vms->end_error_code) {
            vms->end_error_code = KANP_RES_FAIL_GEN;
            kstr_assign_kstr(&vms->end_error_msg, kmod_kstrerror());
        }
        
        error = 0;
    }
    
    return error;
}
Пример #14
0
/* This function connects to the specified server (possibly through a proxy) and
 * negociates a SSL session. REMARK: a backport was applied to this function. It
 * was ugly in the first place, the backport didn't help any. All of it is
 * rewritten in the next version. REMARK 2: whooops, modified it again. It's
 * getting prettier by the minute.
 * This function sets the KMO error string. It returns 0, -1, -2, or -3.
 */
static int knp_query_connect(struct knp_query *self, struct knp_proto *knp) {
    assert(self->transfer.fd == -1);
    assert(self->ssl_driver == NULL);
    
    kmod_log_msg(3, "knp_query_connect() called.\n");
    
    int error = 0;
    kstr str;
    int use_srv = 0;
    int use_proxy = 0;
    kstr proxy_addr;
    uint32_t proxy_port = 0;
    kstr proxy_login;
    kstr proxy_pwd;
    char *cert = NULL;
    struct kmo_data_transfer *transfer = &self->transfer;
    
    kstr_init(&str);
    kstr_init(&proxy_addr);
    kstr_init(&proxy_login);
    kstr_init(&proxy_pwd);
    
    /* Try. */
    do {
	/* We're contacting the KPS. */
	if (self->contact == KNP_CONTACT_KPS && k3p_is_using_kps(knp->server_info)) {
	    kstr_assign_kstr(&self->server_addr, &knp->server_info->kps_net_addr);
	    self->server_port = knp->server_info->kps_port_num;
	    
	    if (knp->server_info->kps_use_proxy) {
	    	use_proxy = 1;
	    	kstr_assign_kstr(&proxy_addr, &knp->server_info->kps_proxy_net_addr);
		proxy_port = knp->server_info->kps_proxy_port_num;
		kstr_assign_kstr(&proxy_login, &knp->server_info->kps_proxy_login);
		kstr_assign_kstr(&proxy_pwd, &knp->server_info->kps_proxy_pwd);
	    }
	}
	
	/* We're contacting the KOS. */
	else {
	    #ifdef __DEBUG_KOS_ADDRESS__
	    kstr_assign_cstr(&self->server_addr, __DEBUG_KOS_ADDRESS__);
	    if (ops_address || ous_address || ots_address || iks_address || eks_address) {}
	    #else

            /* This is the option to use a one-stop server for all
               online service requests. */
            if (self->all_req_str.slen > 0) {
                kstr_assign_kstr(&self->server_addr, &self->all_req_str);
            }
	    
	    else if (knp->server_info->kos_use_proxy || knp->use_kpg) {
		switch (self->contact) {
		    case KNP_CONTACT_KPS: kstr_assign_cstr(&self->server_addr, ops_address); break;
		    case KNP_CONTACT_OPS: kstr_assign_cstr(&self->server_addr, ops_address); break;
		    case KNP_CONTACT_OUS: kstr_assign_cstr(&self->server_addr, ous_address); break;
		    case KNP_CONTACT_OTS: kstr_assign_cstr(&self->server_addr, ots_address); break;
		    case KNP_CONTACT_IKS: kstr_assign_cstr(&self->server_addr, iks_address); break;
		    case KNP_CONTACT_EKS: kstr_assign_cstr(&self->server_addr, eks_address); break;
		    default: assert(0);
		};
		
		if (knp->use_kpg) {
		    switch (self->contact) {
			case KNP_CONTACT_OPS: kstr_assign_cstr(&self->server_addr, knp->kpg_addr.data); break;
			case KNP_CONTACT_OUS: kstr_assign_cstr(&self->server_addr, knp->kpg_addr.data); break;
			case KNP_CONTACT_OTS: kstr_assign_cstr(&self->server_addr, knp->kpg_addr.data); break;
		    };
		}
	    }
	    
	    else {
		use_srv = 1;
		
		switch (self->contact) {
		    case KNP_CONTACT_KPS: kstr_assign_cstr(&self->server_addr, srv_ops_address); break;
		    case KNP_CONTACT_OPS: kstr_assign_cstr(&self->server_addr, srv_ops_address); break;
		    case KNP_CONTACT_OUS: kstr_assign_cstr(&self->server_addr, srv_ous_address); break;
		    case KNP_CONTACT_OTS: kstr_assign_cstr(&self->server_addr, srv_ots_address); break;
		    case KNP_CONTACT_IKS: kstr_assign_cstr(&self->server_addr, srv_iks_address); break;
		    case KNP_CONTACT_EKS: kstr_assign_cstr(&self->server_addr, srv_eks_address); break;
		    default: assert(0);
		};
	    }
	    #endif
	    
	    #ifdef __DEBUG_KOS_PORT__
	    self->server_port = __DEBUG_KOS_PORT__;
	    if (kos_port) {}
	    #else
	    self->server_port = kos_port;
	    
	    if (knp->use_kpg) {
		switch (self->contact) {
		    case KNP_CONTACT_OPS: self->server_port = knp->kpg_port; break;
		    case KNP_CONTACT_OUS: self->server_port = knp->kpg_port; break;
		    case KNP_CONTACT_OTS: self->server_port = knp->kpg_port; break;
		};
	    }
	    #endif
	    
	    if (knp->server_info->kos_use_proxy) {
	    	use_proxy = 1;
	    	kstr_assign_kstr(&proxy_addr, &knp->server_info->kos_proxy_net_addr);
		proxy_port = knp->server_info->kos_proxy_port_num;
		kstr_assign_kstr(&proxy_login, &knp->server_info->kos_proxy_login);
		kstr_assign_kstr(&proxy_pwd, &knp->server_info->kos_proxy_pwd);
	    }
	    
	    #ifdef NDEBUG
	    cert = kos_cert;
	    #else
	    if (kos_cert) {}
	    #endif
	}
	
	/* Validate our contact information. */
	if (self->server_addr.slen == 0 || self->server_port == 0) {
	    kmo_seterror("invalid server information");
    	    knp_query_handle_conn_error(self, KMO_SERROR_MISC);
	    error = -1;
    	    break;
	}
	
	if (use_proxy && (proxy_addr.slen == 0 || proxy_port == 0)) {
	    kmo_seterror("invalid proxy information");
    	    knp_query_handle_conn_error(self, KMO_SERROR_MISC);
	    error = -1;
	    break;
	}
    	
	/* Connect to the proxy or the end server directly. */
	if (! use_srv) {
	    error = kmo_sock_create(&transfer->fd);
	    if (error) break;
	
	    error = kmo_sock_set_unblocking(transfer->fd);
	    if (error) break;
	
	    error = kmo_sock_connect(transfer->fd, 
				     use_proxy ? proxy_addr.data : self->server_addr.data,
				     use_proxy ? proxy_port : self->server_port);
	    if (error) {
		knp_query_handle_conn_error(self, KMO_SERROR_UNREACHABLE);
		break;
	    }
	    
	    kstr_sf(&str, "cannot connect to %s", use_proxy ? proxy_addr.data : self->server_addr.data);
	    error = knp_query_wait_for_data(self, 0, str.data, knp->k3p);
	    
	    if (error) {
		if (error == -1) self->serv_error_id = KMO_SERROR_UNREACHABLE;
		break;
	    }
	    
	    error = kmo_sock_connect_check(transfer->fd, use_proxy ? proxy_addr.data : self->server_addr.data);
	    
	    if (error) {
		knp_query_handle_conn_error(self, KMO_SERROR_UNREACHABLE);
		break;
	    }
	    
	    /* If there is a proxy, asks it to connect us to the end server. */
	    if (use_proxy) {
		error = knp_handle_proxy(self, knp->k3p, &proxy_login, &proxy_pwd);
		if (error) break;
	    }
	}
	
	/* Connect using the SRV entries. */
	else {
	    error = knp_query_srv_connect(self, knp, self->server_addr.data);
	    if (error) break;
	}
	
	/* Negociate the SSL session. */
	error = knp_negociate_ssl_session(self, cert, knp->k3p);
	if (error) break;
	
    } while (0);
    
    if (error) knp_query_disconnect(self);
    
    kstr_free(&str);
    kstr_free(&proxy_addr);
    kstr_free(&proxy_login);
    kstr_free(&proxy_pwd);
    
    return error;
}
Пример #15
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);
}
Пример #16
0
/* This function gets the element at pos in an anp_msg as a string. This
 * function sets the KMOD error string. It returns -1 on failure.
 */
int anp_msg_get_kstr(struct anp_msg *self, int pos, kstr *str) {
    struct anp_element *el = (struct anp_element *) karray_get(&self->element_array, pos);
    if (anp_msg_get_ensure_type(el, pos, ANP_STR)) return -1;
    kstr_assign_kstr(str, el->str);
    return 0;
}