예제 #1
0
파일: client.c 프로젝트: key2/libuma
int send_sms(int sock, unsigned char *dest, unsigned  char *text){
	struct uma_msg_s *uma_msg;
	u_int8_t *titi, *tata;
	int j, i, len = 0;
	int rc = -1;
	uint8_t *tlv;

	uma_msg = uma_create_msg(GA_PROXY_GET_ID, 0, GA_PROXY);
	j = uma_create_buffer(&titi,uma_msg);

	for(i = 0; i < uma_msg->ntlv; i++){
		tlv_printf(uma_msg->tlv[i]);
	}

	printf("Requesting a fresh victim information...\n");
	write(sock, titi, j);
	uma_delete_msg(uma_msg);

	uma_msg = proxy_reply(sock, GA_PROXY);
	if(NULL == (tlv = handle_id_reply(uma_msg))){
		fprintf(stderr, "proxy hasn't cached subscriber info yet...\n");
		return -1;
	}

	if((rc = ga_csr_request(sock)) < 0){
		return rc;
	}

	/* skip type and length of tlv and pass tmsi as parameter */
	if((rc = ga_csr_uplink_dtap(sock, tlv+2, tlv_get_len(tlv))) < 0){
		return rc;
	}
	uma_delete_msg(uma_msg);

	printf("Waiting for AUTH COMPLETE message so we can continue MITM\n");
	uma_msg = proxy_reply(sock, GA_PROXY);
	if(!uma_msg){
		return -2;
	}
	if(uma_msg->msgtype != GA_PROXY_AUTH_COMPLETE){
		fprintf(stderr, "Expected GA_CSR_REQUEST_ACCEPT(%d) but got %s(%d)\n", GA_CSR_REQUEST_ACCEPT, ga_rc_csr[uma_msg->msgtype], uma_msg->msgtype);
		return -3;
	}
	printf("Received AUTH COMPLETE, continuing procedure\n");
	uma_delete_msg(uma_msg);

	if((rc = ga_csr_uplink_dtap_sms(sock, dest, text, 1, 1)) < 0){
		return rc;
	}

	return 0;
}
예제 #2
0
파일: client.c 프로젝트: key2/libuma
int ga_csr_request(int sock){
	struct uma_msg_s *uma_msg;
	u_int8_t *titi, *tata;
	int j, i, len = 0;
	uma_msg = uma_create_msg(GA_CSR_REQUEST ,0, GA_CSR);
	uma_msg->tlv[uma_msg->ntlv++] = create_IEI_Establishment_Cause(16);
	j = uma_create_buffer(&titi, uma_msg);

	printf("Sending GA-CSR REQUEST\n");
	write(sock, titi, j);
	uma_delete_msg(uma_msg);

	uma_msg = proxy_reply(sock, GA_CSR);
	if(!uma_msg){
		return -1;
	}

	if(uma_msg->msgtype != GA_CSR_REQUEST_ACCEPT){
		fprintf(stderr, "Expected GA_CSR_REQUEST_ACCEPT(%d) but got %s(%d)\n", GA_CSR_REQUEST_ACCEPT, ga_rc_csr[uma_msg->msgtype], uma_msg->msgtype);
		uma_delete_msg(uma_msg);
		return -2;
	}

	uma_delete_msg(uma_msg);
	return 0;
}
예제 #3
0
int
client_parse_cmd(struct session *s)
{
	if (strncasecmp("PASV", linebuf, 4) == 0)
		s->cmd = CMD_PASV;
	else if (strncasecmp("PORT ", linebuf, 5) == 0)
		s->cmd = CMD_PORT;
	else if (strncasecmp("EPSV", linebuf, 4) == 0)
		s->cmd = CMD_EPSV;
	else if (strncasecmp("EPRT ", linebuf, 5) == 0)
		s->cmd = CMD_EPRT;
	else
		return (1);

	if (ipv6_mode && (s->cmd == CMD_PASV || s->cmd == CMD_PORT)) {
		logmsg(LOG_CRIT, "PASV and PORT not allowed with IPv6");
		return (0);
	}

	if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT) {
		s->port = parse_port(s->cmd);
		if (s->port < MIN_PORT) {
			logmsg(LOG_CRIT, "#%d bad port in '%s'", s->id,
			    linebuf);
			return (0);
		}
		s->proxy_port = pick_proxy_port();
		proxy_reply(s->cmd, sstosa(&s->proxy_ss), s->proxy_port);
		logmsg(LOG_DEBUG, "#%d proxy: %s", s->id, linebuf);
	}

	return (1);
}
예제 #4
0
파일: client.c 프로젝트: key2/libuma
int modify_sms(int sock, unsigned char *dest, unsigned char *text){
	struct uma_msg_s *uma_msg;
	u_int8_t *titi, *tata;
	int j, i, len = 0;
	int rc = -1;
	uint8_t *tpdu, *ptr;
	uint8_t rpdu_mr;
	/* could be just one data type, but since I reuse my old submit decoder... */
	struct gsm_sms *sms;
	sms_t *csms;
	unsigned char *pdest, *ptext;

	uma_msg = uma_create_msg(GA_PROXY_GET_SMS, 0, GA_PROXY);
	j = uma_create_buffer(&titi,uma_msg);

	for(i = 0; i < uma_msg->ntlv; i++){
		tlv_printf(uma_msg->tlv[i]);
	}

	printf("Requesting SMS to be modified...\n");
	write(sock, titi, j);
	uma_delete_msg(uma_msg);

	uma_msg = proxy_reply(sock, GA_CSR);
	if(NULL == (tpdu = extract_tpdu(uma_msg, &rpdu_mr))){
		return -1;
	}

	if(NULL == (csms = malloc(sizeof(sms_t)))){
		perror("malloc()");
		return -2;
	}
	memset(csms, 0, sizeof(sms_t));
	if(NULL == (ptext = malloc(SMS_TEXT_SIZE))){
		perror("malloc()");
		return -2;
	}

	if(NULL == (ptr = parse_pdu_header(csms, tpdu))){
		fprintf(stderr, "Something went wrong while decoding the submit PDU\n");
		return -3;
	}
	for(i=0;i<csms->msisdn_l;i++){
		printf("%0.2x", csms->msisdn[i]);
	}
	printf("\n");{
		printf("%0.2x", csms->msisdn[i]);
	}
	printf("\n");{
		printf("%0.2x", csms->msisdn[i]);
	}
	printf("\n");{
		printf("%0.2x", csms->msisdn[i]);
	}
	printf("\n");{
		printf("%0.2x", csms->msisdn[i]);
	}
	printf("\n");{
		printf("%0.2x", csms->msisdn[i]);
	}
	printf("\n");{
		printf("%0.2x", csms->msisdn[i]);
	}
	printf("\n");
	pdest = decode_msisdn(csms->msisdn, csms->msisdn_l);

	/* workaround libosmocore bug to work with octets rather
	   than septets
	*/
	csms->tp_ud_l = csms->tp_ud_l * 7/8 + 1;
	gsm_7bit_decode(ptext, ptr, csms->tp_ud_l);
	printf("Original destination: %s\n", pdest);
	printf("Original text message: %s\n", ptext);

	if(dest){
		printf("Replacing destination number %s with %s\n", pdest, dest);
		pdest = dest;
	}
	if(text){
		printf("Replacing text '%s' with '%s'\n", ptext, text);
		free(ptext);
		ptext = text;
	}

	printf("Attempting to send modified SMS\n");
	rc = ga_csr_uplink_dtap_sms(sock, pdest, ptext, csms->msg_ref, rpdu_mr);

	uma_delete_msg(uma_msg);
	destroy_sms(csms);
	free(tpdu);

	return rc;
}
예제 #5
0
int
allow_data_connection(struct session *s)
{
	struct sockaddr *client_sa, *orig_sa, *proxy_sa, *server_sa;
	int prepared = 0;

	/*
	 * The pf rules below do quite some NAT rewriting, to keep up
	 * appearances.  Points to keep in mind:
	 * 1)  The client must think it's talking to the real server,
	 *     for both control and data connections.  Transparently.
	 * 2)  The server must think that the proxy is the client.
	 * 3)  Source and destination ports are rewritten to minimize
	 *     port collisions, to aid security (some systems pick weak
	 *     ports) or to satisfy RFC requirements (source port 20).
	 */
	
	/* Cast this once, to make code below it more readable. */
	client_sa = sstosa(&s->client_ss);
	server_sa = sstosa(&s->server_ss);
	proxy_sa = sstosa(&s->proxy_ss);
	if (fixed_server)
		/* Fixed server: data connections must appear to come
		   from / go to the original server, not the fixed one. */
		orig_sa = sstosa(&s->orig_server_ss);
	else
		/* Server not fixed: orig_server == server. */
		orig_sa = sstosa(&s->server_ss);

	/* Passive modes. */
	if (s->cmd == CMD_PASV || s->cmd == CMD_EPSV) {
		s->port = parse_port(s->cmd);
		if (s->port < MIN_PORT) {
			logmsg(LOG_CRIT, "#%d bad port in '%s'", s->id,
			    linebuf);
			return (0);
		}
		s->proxy_port = pick_proxy_port();
		logmsg(LOG_INFO, "#%d passive: client to server port %d"
		    " via port %d", s->id, s->port, s->proxy_port);

		if (prepare_commit(s->id) == -1)
			goto fail;
		prepared = 1;

		proxy_reply(s->cmd, orig_sa, s->proxy_port);
		logmsg(LOG_DEBUG, "#%d proxy: %s", s->id, linebuf);

		/* pass in from $client to $orig_server port $proxy_port
		    rdr-to $server port $port */
		if (add_rdr(s->id, client_sa, s->client_rd, orig_sa,
		    s->proxy_port, server_sa, s->port, getrtable()) == -1)
			goto fail;

		/* pass out from $client to $server port $port nat-to $proxy */
		if (add_nat(s->id, client_sa, getrtable(), server_sa,
		    s->port, proxy_sa, PF_NAT_PROXY_PORT_LOW,
		    PF_NAT_PROXY_PORT_HIGH) == -1)
			goto fail;
	}

	/* Active modes. */
	if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT) {
		logmsg(LOG_INFO, "#%d active: server to client port %d"
		    " via port %d", s->id, s->port, s->proxy_port);

		if (prepare_commit(s->id) == -1)
			goto fail;
		prepared = 1;

		/* pass in from $server to $proxy port $proxy_port
		    rdr-to $client port $port */
		if (add_rdr(s->id, server_sa, getrtable(), proxy_sa,
		    s->proxy_port, client_sa, s->port, s->client_rd) == -1)
			goto fail;

		/* pass out from $server to $client port $port
		    nat-to $orig_server port $natport */
		if (rfc_mode && s->cmd == CMD_PORT) {
			/* Rewrite sourceport to RFC mandated 20. */
			if (add_nat(s->id, server_sa, s->client_rd, client_sa,
			    s->port, orig_sa, 20, 20) == -1)
				goto fail;
		} else {
			/* Let pf pick a source port from the standard range. */
			if (add_nat(s->id, server_sa, s->client_rd, client_sa,
			    s->port, orig_sa, PF_NAT_PROXY_PORT_LOW,
			    PF_NAT_PROXY_PORT_HIGH) == -1)
			    	goto fail;
		}
	}

	/* Commit rules if they were prepared. */
	if (prepared && (do_commit() == -1)) {
		if (errno != EBUSY)
			goto fail;
		/* One more try if busy. */
		usleep(5000);
		if (do_commit() == -1)
			goto fail;
	}

	s->cmd = CMD_NONE;
	s->port = 0;

	return (1);

 fail:
	logmsg(LOG_CRIT, "#%d pf operation failed: %s", s->id, strerror(errno));
	if (prepared)
		do_rollback();
	return (0);
}
예제 #6
0
파일: proxy_id.c 프로젝트: pavka/sssd
void proxy_get_account_info(struct be_req *breq)
{
    struct be_acct_req *ar;
    struct proxy_id_ctx *ctx;
    struct sysdb_ctx *sysdb;
    struct sss_domain_info *domain;
    uid_t uid;
    gid_t gid;
    int ret;
    char *endptr;

    ar = talloc_get_type(breq->req_data, struct be_acct_req);
    ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data,
                          struct proxy_id_ctx);
    sysdb = breq->be_ctx->sysdb;
    domain = breq->be_ctx->domain;

    if (be_is_offline(breq->be_ctx)) {
        return proxy_reply(breq, DP_ERR_OFFLINE, EAGAIN, "Offline");
    }

    /* for now we support only core attrs */
    if (ar->attr_type != BE_ATTR_CORE) {
        return proxy_reply(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type");
    }

    switch (ar->entry_type & 0xFFF) {
    case BE_REQ_USER: /* user */
        switch (ar->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_users(breq, ctx, sysdb, domain);
            break;

        case BE_FILTER_NAME:
            ret = get_pw_name(breq, ctx, sysdb, domain, ar->filter_value);
            break;

        case BE_FILTER_IDNUM:
            uid = (uid_t) strtouint32(ar->filter_value, &endptr, 10);
            if (errno || *endptr || (ar->filter_value == endptr)) {
                return proxy_reply(breq, DP_ERR_FATAL,
                                   EINVAL, "Invalid attr type");
            }
            ret = get_pw_uid(breq, ctx, sysdb, domain, uid);
            break;
        default:
            return proxy_reply(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        break;

    case BE_REQ_GROUP: /* group */
        switch (ar->filter_type) {
        case BE_FILTER_ENUM:
            ret = enum_groups(breq, ctx, sysdb, domain);
            break;
        case BE_FILTER_NAME:
            ret = get_gr_name(breq, ctx, sysdb, domain, ar->filter_value);
            break;
        case BE_FILTER_IDNUM:
            gid = (gid_t) strtouint32(ar->filter_value, &endptr, 10);
            if (errno || *endptr || (ar->filter_value == endptr)) {
                return proxy_reply(breq, DP_ERR_FATAL,
                                   EINVAL, "Invalid attr type");
            }
            ret = get_gr_gid(breq, ctx, sysdb, domain, gid, 0);
            break;
        default:
            return proxy_reply(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        break;

    case BE_REQ_INITGROUPS: /* init groups for user */
        if (ar->filter_type != BE_FILTER_NAME) {
            return proxy_reply(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        if (ctx->ops.initgroups_dyn == NULL) {
            return proxy_reply(breq, DP_ERR_FATAL,
                               ENODEV, "Initgroups call not supported");
        }
        ret = get_initgr(breq, ctx, sysdb, domain, ar->filter_value);
        break;

    case BE_REQ_NETGROUP:
        if (ar->filter_type != BE_FILTER_NAME) {
            return proxy_reply(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        if (ctx->ops.setnetgrent == NULL || ctx->ops.getnetgrent_r == NULL ||
            ctx->ops.endnetgrent == NULL) {
            return proxy_reply(breq, DP_ERR_FATAL,
                               ENODEV, "Netgroups are not supported");
        }

        ret = get_netgroup(ctx, sysdb, domain, ar->filter_value);
        break;

    case BE_REQ_SERVICES:
        switch (ar->filter_type) {
        case BE_FILTER_NAME:
            if (ctx->ops.getservbyname_r == NULL) {
                return proxy_reply(breq, DP_ERR_FATAL,
                                   ENODEV, "Services are not supported");
            }
            ret = get_serv_byname(ctx, sysdb, domain,
                                  ar->filter_value,
                                  ar->extra_value);
            break;
        case BE_FILTER_IDNUM:
            if (ctx->ops.getservbyport_r == NULL) {
                return proxy_reply(breq, DP_ERR_FATAL,
                                   ENODEV, "Services are not supported");
            }
            ret = get_serv_byport(ctx, sysdb, domain,
                                  ar->filter_value,
                                  ar->extra_value);
            break;
        case BE_FILTER_ENUM:
            if (!ctx->ops.setservent
                    || !ctx->ops.getservent_r
                    || !ctx->ops.endservent) {
                return proxy_reply(breq, DP_ERR_FATAL,
                                   ENODEV, "Services are not supported");
            }
            ret = enum_services(ctx, sysdb, domain);
            break;
        default:
            return proxy_reply(breq, DP_ERR_FATAL,
                               EINVAL, "Invalid filter type");
        }
        break;

    default: /*fail*/
        return proxy_reply(breq, DP_ERR_FATAL,
                           EINVAL, "Invalid request type");
    }

    if (ret) {
        if (ret == ENXIO) {
            DEBUG(2, ("proxy returned UNAVAIL error, going offline!\n"));
            be_mark_offline(breq->be_ctx);
        }
        proxy_reply(breq, DP_ERR_FATAL, ret, NULL);
        return;
    }
    proxy_reply(breq, DP_ERR_OK, EOK, NULL);
}